Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite of NCM device driver #2227

Merged
merged 20 commits into from May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 12 additions & 2 deletions examples/device/net_lwip_webserver/src/tusb_config.h
Expand Up @@ -82,6 +82,16 @@
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif

// number of NCM transfer blocks for reception side (only valid if NCM is selected below)
#ifndef CFG_TUD_NCM_OUT_NTB_N
#define CFG_TUD_NCM_OUT_NTB_N 2
#endif

// number of NCM transfer blocks for transmission side (only valid if NCM is selected below)
#ifndef CFG_TUD_NCM_IN_NTB_N
#define CFG_TUD_NCM_IN_NTB_N 3
#endif

//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
Expand All @@ -94,8 +104,8 @@

// Network class has 2 drivers: ECM/RNDIS and NCM.
// Only one of the drivers can be enabled
#define CFG_TUD_ECM_RNDIS 1
#define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS)
#define CFG_TUD_ECM_RNDIS 1
#define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS)

#ifdef __cplusplus
}
Expand Down
115 changes: 105 additions & 10 deletions src/class/net/ncm.h
Expand Up @@ -2,6 +2,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2021, Ha Thach (tinyusb.org)
* Copyright (c) 2024, Hardy Griech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -29,16 +30,51 @@
#define _TUSB_NCM_H_

#include "common/tusb_common.h"
#include "lwipopts.h"

#ifdef __cplusplus
extern "C" {
#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE
#define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100)
#endif
#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE
#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100)
#endif

// Table 4.3 Data Class Interface Protocol Codes
typedef enum
{
NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01
} ncm_data_interface_protocol_code_t;
#ifndef CFG_TUD_NCM_OUT_NTB_N
rgrr marked this conversation as resolved.
Show resolved Hide resolved
/// number of NTB buffers for reception side
/// 1 - good performance
/// 2 - up to 30% more performance with iperf with small packets
/// >2 - no performance gain
/// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements
#define CFG_TUD_NCM_OUT_NTB_N 1
#endif

#ifndef CFG_TUD_NCM_IN_NTB_N
rgrr marked this conversation as resolved.
Show resolved Hide resolved
/// number of NTB buffers for transmission side
/// 1 - good performance but SystemView shows lost events (on load test)
/// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked"
/// happens from time to time with SystemView
/// 3 - "tud_network_can_xmit: request blocked" never happens
/// >2 - no performance gain
/// -> for performance optimizations this parameter could be increased with the cost of additional RAM requirements
#define CFG_TUD_NCM_IN_NTB_N 1
#endif

#ifndef CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB
/// this is for the transmission side for allocation of \a ndp16_datagram_t
#define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8
#endif

#ifndef CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB
/// this tells the host how many datagrams it is allowed to put into an NTB
#define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6
#endif

#ifndef CFG_TUD_NCM_ALIGNMENT
#define CFG_TUD_NCM_ALIGNMENT 4
#endif
#if (CFG_TUD_NCM_ALIGNMENT != 4)
#error "CFG_TUD_NCM_ALIGNMENT must be 4, otherwise the headers and start of datagrams have to be aligned (which they are currently not)"
#endif


// Table 6.2 Class-Specific Request Codes for Network Control Model subclass
Expand All @@ -62,8 +98,67 @@ typedef enum
NCM_SET_CRC_MODE = 0x8A,
} ncm_request_code_t;

#ifdef __cplusplus
}
#endif

#define NTH16_SIGNATURE 0x484D434E
#define NDP16_SIGNATURE_NCM0 0x304D434E
#define NDP16_SIGNATURE_NCM1 0x314D434E

typedef struct TU_ATTR_PACKED {
uint16_t wLength;
uint16_t bmNtbFormatsSupported;
uint32_t dwNtbInMaxSize;
uint16_t wNdbInDivisor;
uint16_t wNdbInPayloadRemainder;
uint16_t wNdbInAlignment;
uint16_t wReserved;
uint32_t dwNtbOutMaxSize;
uint16_t wNdbOutDivisor;
uint16_t wNdbOutPayloadRemainder;
uint16_t wNdbOutAlignment;
uint16_t wNtbOutMaxDatagrams;
} ntb_parameters_t;

typedef struct TU_ATTR_PACKED {
uint32_t dwSignature;
uint16_t wHeaderLength;
uint16_t wSequence;
uint16_t wBlockLength;
uint16_t wNdpIndex;
} nth16_t;

typedef struct TU_ATTR_PACKED {
uint16_t wDatagramIndex;
uint16_t wDatagramLength;
} ndp16_datagram_t;

typedef struct TU_ATTR_PACKED {
uint32_t dwSignature;
uint16_t wLength;
uint16_t wNextNdpIndex;
//ndp16_datagram_t datagram[];
} ndp16_t;

typedef union TU_ATTR_PACKED {
struct {
nth16_t nth;
ndp16_t ndp;
ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1];
};
uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE];
} xmit_ntb_t;

typedef union TU_ATTR_PACKED {
struct {
nth16_t nth;
// only the header is at a guaranteed position
};
uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE];
} recv_ntb_t;

struct ncm_notify_t {
tusb_control_request_t header;
uint32_t downlink, uplink;
};


#endif