usbdev: add ncm driver

The compilation and verification commands are shown below:
./tools/configure.sh sim:usbdev
make -j
sudo ./nuttx
nsh> conn 2
nsh> dhcpd_start eth1

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu 2024-03-18 20:06:54 +08:00 committed by Xiang Xiao
parent b328b35e2b
commit 4e79741e7d
12 changed files with 3172 additions and 12 deletions

View File

@ -79,7 +79,11 @@
#define UDC_NAME_LENGTH_MAX 128
#define USB_RAW_EP0_MAX_LEN 256
#define USB_RAW_EP_MAX_LEN 1024
#ifdef CONFIG_NET_CDCNCM
# define USB_RAW_EP_MAX_LEN 16384
#else
# define USB_RAW_EP_MAX_LEN 1024
#endif
#define USB_RAW_RX_BUF_NUM 8

View File

@ -7,7 +7,6 @@
#
# CONFIG_SIM_UART_DMA is not set
CONFIG_ADBD_FILE_SERVICE=y
CONFIG_ADBD_SHELL_SERVICE=y
CONFIG_ADBD_USB_BOARDCTL=y
CONFIG_ADBD_USB_SERVER=y
CONFIG_ARCH="sim"
@ -21,6 +20,7 @@ CONFIG_BUILTIN=y
CONFIG_CDCACM=y
CONFIG_CDCACM_COMPOSITE=y
CONFIG_CDCECM_COMPOSITE=y
CONFIG_CDCNCM_COMPOSITE=y
CONFIG_COMPOSITE_IAD=y
CONFIG_COMPOSITE_PRODUCTID=0x0042
CONFIG_COMPOSITE_VENDORID=0x1630
@ -35,25 +35,57 @@ CONFIG_DEBUG_USB_WARN=y
CONFIG_EXAMPLES_DHCPD=y
CONFIG_FS_PROCFS=y
CONFIG_FS_TMPFS=y
CONFIG_HAVE_CXX=y
CONFIG_ICMPv6_AUTOCONF_RDNSS=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_IOB_NBUFFERS=512
CONFIG_IOB_NCHAINS=36
CONFIG_LIBC_DLFCN=y
CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBUV=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSCLIENT_MAXRESPONSE=1024
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0xDF050505
CONFIG_NETDB_MAX_IPADDR=1
CONFIG_NETDEV_PHY_IOCTL=y
CONFIG_NETDOWN_NOTIFIER=y
CONFIG_NETINIT_DRIPADDR=0x0a000101
CONFIG_NETINIT_IPADDR=0x0a000102
CONFIG_NETUTILS_DHCPD=y
CONFIG_NETUTILS_IPERF=y
CONFIG_NETUTILS_TELNETC=y
CONFIG_NETUTILS_TELNETD=y
CONFIG_NET_BINDTODEVICE=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_CDCECM=y
CONFIG_NET_CDCNCM=y
CONFIG_NET_ETH_PKTSIZE=1518
CONFIG_NET_ICMP_SOCKET=y
CONFIG_NET_ICMPv6=y
CONFIG_NET_ICMPv6_ALLOC_CONNS=1
CONFIG_NET_ICMPv6_AUTOCONF=y
CONFIG_NET_ICMPv6_NEIGHBOR=y
CONFIG_NET_ICMPv6_ROUTER=y
CONFIG_NET_ICMPv6_SOCKET=y
CONFIG_NET_IPFORWARD=y
CONFIG_NET_IPFORWARD_NSTRUCT=100
CONFIG_NET_IPv6=y
CONFIG_NET_MAX_RECV_BUFSIZE=65535
CONFIG_NET_MAX_SEND_BUFSIZE=65535
CONFIG_NET_NAT=y
CONFIG_NET_RECV_BUFSIZE=16384
CONFIG_NET_SEND_BUFSIZE=16384
CONFIG_NET_TCP=y
CONFIG_NET_TCPBACKLOG=y
CONFIG_NET_TCP_ALLOC_CONNS=1
CONFIG_NET_TCP_DELAYED_ACK=y
CONFIG_NET_TCP_KEEPALIVE=y
CONFIG_NET_TCP_NOTIFIER=y
CONFIG_NET_TCP_SELECTIVE_ACK=y
CONFIG_NET_TCP_WRITE_BUFFERS=y
CONFIG_NET_UDP=y
CONFIG_NET_UDP_NOTIFIER=y
CONFIG_NET_UDP_WRITE_BUFFERS=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_READLINE=y

View File

@ -34,6 +34,7 @@
#include <nuttx/usb/rndis.h>
#include <nuttx/usb/cdcacm.h>
#include <nuttx/usb/cdcecm.h>
#include <nuttx/usb/cdcncm.h>
#include <nuttx/usb/composite.h>
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
@ -210,6 +211,53 @@ static void *board_composite1_connect(int port)
return composite_initialize(composite_getdevdescs(), dev, dev_idx);
}
/****************************************************************************
* Name: board_composite2_connect
*
* Description:
* Connect the USB composite device on the specified USB device port for
* configuration 2.
*
* Input Parameters:
* port - The USB device port.
*
* Returned Value:
* A non-NULL handle value is returned on success. NULL is returned on
* any failure.
*
****************************************************************************/
static void *board_composite2_connect(int port)
{
struct composite_devdesc_s dev[1];
int dev_idx = 0;
#ifdef CONFIG_NET_CDCNCM
/* Configure the CDC/NCM device */
cdcncm_get_composite_devdesc(&dev[dev_idx]);
/* Interfaces */
dev[dev_idx].devinfo.ifnobase = 0;
dev[dev_idx].minor = 0;
/* Strings */
dev[dev_idx].devinfo.strbase = COMPOSITE_NSTRIDS - 1;
/* Endpoints */
dev[dev_idx].devinfo.epno[CDCNCM_EP_INTIN_IDX] = 5;
dev[dev_idx].devinfo.epno[CDCNCM_EP_BULKIN_IDX] = 6;
dev[dev_idx].devinfo.epno[CDCNCM_EP_BULKOUT_IDX] = 7;
dev_idx += 1;
#endif
return composite_initialize(composite_getdevdescs(), dev, dev_idx);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -251,10 +299,14 @@ void *board_composite_connect(int port, int configid)
{
return board_composite0_connect(port);
}
else
else if (configid == 1)
{
return board_composite1_connect(port);
}
else
{
return board_composite2_connect(port);
}
}
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */

View File

@ -59,6 +59,10 @@ if(CONFIG_USBDEV)
list(APPEND SRCS cdcecm.c)
endif()
if(CONFIG_NET_CDCNCM)
list(APPEND SRCS cdcncm.c)
endif()
if(CONFIG_USBDEV_FS)
list(APPEND SRCS usbdev_fs.c)
endif()

View File

@ -1226,6 +1226,171 @@ config CDCECM_PRODUCTSTR
endif # !CDCECM_COMPOSITE
endif # CDCECM
menuconfig NET_CDCNCM
bool "CDC-NCM Ethernet-over-USB"
default n
depends on SCHED_WORKQUEUE
depends on NETDEVICES
depends on NET
depends on NET_ETHERNET
---help---
References:
- "Universal Serial Bus - Communications Class - Subclass
Specification for Ethernet Control Model Devices,
Revision 1.2, February 9, 2007"
This option may require CONFIG_NETDEV_LATEINIT=y, otherwise the
power-up initialization may call the non-existent xxx_netinitialize().
This option is not automatically selected because it may be that
you have an additional network device that requires the early
xxx_netinitialize() call.
if NET_CDCNCM
menuconfig CDCNCM_COMPOSITE
bool "CDC/NCM composite support"
default n
depends on USBDEV_COMPOSITE
---help---
Configure the CDC Ethernet Control Model driver as part of a
composite driver (only if USBDEV_COMPOSITE is also defined)
if !CDCNCM_COMPOSITE
# In a composite device the EP0 config comes from the composite device
# and the EP-Number is configured dynamically via composite_initialize
config CDCNCM_EP0MAXPACKET
int "Endpoint 0 max packet size"
default 64
---help---
Endpoint 0 max packet size. Default 64.
config CDCNCM_EPINTIN
int "Interrupt IN endpoint number"
default 1
---help---
The logical 7-bit address of a hardware endpoint that supports
interrupt IN operation. Default 1.
endif # !CDCNCM_COMPOSITE
config CDCNCM_EPINTIN_FSSIZE
int "Interrupt IN full speed MAXPACKET size"
default 16
---help---
Max package size for the interrupt IN endpoint if full speed mode.
Default 16.
if USBDEV_DUALSPEED
config CDCNCM_EPINTIN_HSSIZE
int "Interrupt IN high speed MAXPACKET size"
default 64
---help---
Max package size for the interrupt IN endpoint if high speed mode.
Default 64.
endif # USBDEV_DUALSPEED
if !CDCNCM_COMPOSITE
# In a composite device the EP-Number is configured dynamically via
# composite_initialize
config CDCNCM_EPBULKOUT
int "Bulk OUT endpoint number"
default 5
---help---
The logical 7-bit address of a hardware endpoint that supports
bulk OUT operation. Default: 5
endif # !CDCNCM_COMPOSITE
config CDCNCM_EPBULKOUT_FSSIZE
int "Bulk OUT full speed MAXPACKET size"
default 64
---help---
Max package size for the bulk OUT endpoint if full speed mode.
Default 64.
if USBDEV_DUALSPEED
config CDCNCM_EPBULKOUT_HSSIZE
int "Bulk OUT out high speed MAXPACKET size"
default 512
---help---
Max package size for the bulk OUT endpoint if high speed mode.
Default 512.
endif # USBDEV_DUALSPEED
if !CDCNCM_COMPOSITE
# In a composite device the EP-Number is configured dynamically via
# composite_initialize
config CDCNCM_EPBULKIN
int "Bulk IN endpoint number"
default 2
---help---
The logical 7-bit address of a hardware endpoint that supports
bulk IN operation. Default: 2
endif # !CDCNCM_COMPOSITE
config CDCNCM_EPBULKIN_FSSIZE
int "Bulk IN full speed MAXPACKET size"
default 64
---help---
Max package size for the bulk IN endpoint if full speed mode.
Default 64.
if USBDEV_DUALSPEED
config CDCNCM_EPBULKIN_HSSIZE
int "Bulk IN high speed MAXPACKET size"
default 512
---help---
Max package size for the bulk IN endpoint if high speed mode.
Default 512.
endif # USBDEV_DUALSPEED
if !CDCNCM_COMPOSITE
# In a composite device the Vendor- and Product-ID is given by the composite
# device
config CDCNCM_VENDORID
hex "Vendor ID"
default 0x0525
---help---
The vendor ID code/string. Default 0x0525 and "NuttX"
0x0525 is the Netchip vendor and should not be used in any
products. This default VID was selected for compatibility with
the Linux CDC NCM default VID.
config CDCNCM_PRODUCTID
hex "Product ID"
default 0xa4a2
---help---
The product ID code/string. Default 0xa4a2 and "CDC/NCM Ethernet"
0xa4a2 was selected for compatibility with the Linux CDC NCM
default PID.
config CDCNCM_VENDORSTR
string "Vendor string"
default "NuttX"
config CDCNCM_PRODUCTSTR
string "Product string"
default "CDC/NCM Ethernet"
endif # !CDCNCM_COMPOSITE
endif # CDCNCM
config USBDEV_FS
bool
default n

View File

@ -62,6 +62,10 @@ ifeq ($(CONFIG_NET_CDCECM),y)
CSRCS += cdcecm.c
endif
ifeq ($(CONFIG_NET_CDCNCM),y)
CSRCS += cdcncm.c
endif
ifeq ($(CONFIG_USBDEV_FS),y)
CSRCS += usbdev_fs.c
endif

View File

@ -58,4 +58,7 @@
#define CDCECM_SELFPOWERED (0)
#define CDCECM_REMOTEWAKEUP (0)
#define CDCECM_LOW_BITRATE (19 * 64 * 1 * 1000 * 8)
#define CDCECM_HIGH_BITRATE (13 * 512 * 8 * 1000 * 8)
#endif /* __DRIVERS_USBDEV_CDCECM_H */

2733
drivers/usbdev/cdcncm.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1253,7 +1253,7 @@ static int usbhost_cfgdesc(FAR struct usbhost_cdcmbim_s *priv,
else if (ifdesc->classid == USB_CLASS_CDC_DATA &&
ifdesc->subclass == CDC_SUBCLASS_NONE &&
ifdesc->protocol == CDC_DATA_PROTO_NTB)
ifdesc->protocol == CDC_DATA_PROTO_MBIMNTB)
{
priv->dataif = ifdesc->ifno;
found |= USBHOST_DATAIFFOUND;

View File

@ -57,8 +57,9 @@
#define CDC_SUBCLASS_CAPI 0x05 /* CAPI Control Model */
#define CDC_SUBCLASS_ECM 0x06 /* Ethernet Networking Control Model */
#define CDC_SUBCLASS_ATM 0x07 /* ATM Networking Control Model */
/* 0x08-0x0d Reserved (future use) */
#define CDC_SUBCLASS_MBIM 0x0e /* MBIM Control Model */
/* 0x08-0x0c Reserved (future use) */
#define CDC_SUBCLASS_NCM 0x0d /* Network Control Model */
#define CDC_SUBCLASS_MBIM 0x0e /* Mobile Broadband Interface Model */
/* 0x0f-0x7f Reserved (future use) */
/* 0x80-0xfe Reserved (vendor specific) */
@ -85,7 +86,8 @@
#define CDC_DATA_PROTO_NONE 0x00 /* No class specific protocol required */
/* 0x01-0x2f Reserved (future use) */
#define CDC_DATA_PROTO_NTB 0x02 /* Network Transfer Block protocol */
#define CDC_DATA_PROTO_NCMNTB 0x01 /* NCM Network Transfer Block protocol */
#define CDC_DATA_PROTO_MBIMNTB 0x02 /* MBIM Network Transfer Block protocol */
#define CDC_DATA_PROTO_ISDN 0x30 /* Physical interface protocol for ISDN BRI */
#define CDC_DATA_PROTO_HDLC 0x31 /* HDLC */
#define CDC_DATA_PROTO_TRANSP 0x32 /* Transparent */
@ -328,6 +330,19 @@
*/
#define ECM_SPEED_CHANGE ATM_SPEED_CHANGE
/* Table 14: Requests, Networking Control Model */
#define NCM_GET_NTB_PARAMETERS 0x80
#define NCM_SET_NTB_FORMAT 0x84
#define NCM_GET_NTB_INPUT_SIZE 0x85
#define NCM_SET_NTB_INPUT_SIZE 0x86
#define NCM_SET_CRC_MODE 0x8a
/* Table 15: Notifications, Networking Control Model */
#define NCM_NETWORK_CONNECTION ECM_NETWORK_CONNECTION
#define NCM_SPEED_CHANGE ECM_SPEED_CHANGE
/* Descriptors ***************************************************************/
/* Table 25: bDescriptor SubType in Functional Descriptors */
@ -352,8 +367,9 @@
#define CDC_DSUBTYPE_CAPI 0x0e /* CAPI Control Management Functional Descriptor */
#define CDC_DSUBTYPE_ECM 0x0f /* Ethernet Networking Functional Descriptor */
#define CDC_DSUBTYPE_ATM 0x10 /* ATM Networking Functional Descriptor */
#define CDC_DSUBTYPE_NCM 0x1a /* Networking Functional Descriptor */
#define CDC_DSUBTYPE_MBIM 0x1b /* MBIM Functional Descriptor */
/* 0x11-0xff Reserved (future use) */
/* 0x11-0x19 and 0x1c-0xff Reserved (future use) */
/* Table 42: Ethernet Statistics Capabilities */
@ -880,6 +896,23 @@ struct cdc_ecm_funcdesc_s
#define SIZEOF_ECM_FUNCDESC 13
/* Table 42: NCM Control Model Functional Descriptor */
struct cdc_ncm_funcdesc_s
{
uint8_t size; /* bLength, Size of this descriptor */
uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */
uint8_t subtype; /* bDescriptorSubType, CDC_DSUBTYPE_NCM as defined in
* Table 25.
*/
uint8_t version[2]; /* bcdNcmVersion, the NCM version 0x0100 */
uint8_t netcaps; /* bmNetworkCapabilities, The NCM net types the device
* supports.
*/
};
#define SIZEOF_NCM_FUNCDESC 6
/* Table 43: ATM Networking Functional Descriptor */
struct cdc_atm_funcdesc_s

105
include/nuttx/usb/cdcncm.h Normal file
View File

@ -0,0 +1,105 @@
/****************************************************************************
* include/nuttx/usb/cdcncm.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_USB_CDCNCM_H
#define __INCLUDE_NUTTX_USB_CDCNCM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_CDCNCM_COMPOSITE
# include <nuttx/usb/composite.h>
#endif
/****************************************************************************
* Preprocessor definitions
****************************************************************************/
#define CDCNCM_EP_INTIN_IDX (0)
#define CDCNCM_EP_BULKIN_IDX (1)
#define CDCNCM_EP_BULKOUT_IDX (2)
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
# define EXTERN extern "C"
extern "C"
{
#else
# define EXTERN extern
#endif
/****************************************************************************
* Public Functions Definitions
****************************************************************************/
/****************************************************************************
* Name: cdcncm_initialize
*
* Description:
* Register CDC/NCM USB device interface. Register the corresponding
* network driver to NuttX and bring up the network.
*
* Input Parameters:
* minor - Device minor number.
* handle - An optional opaque reference to the CDC/NCM class object that
* may subsequently be used with cdcncm_uninitialize().
*
* Returned Value:
* Zero (OK) means that the driver was successfully registered. On any
* failure, a negated errno value is returned.
*
****************************************************************************/
#ifndef CONFIG_CDCNCM_COMPOSITE
int cdcncm_initialize(int minor, FAR void **handle);
#endif
/****************************************************************************
* Name: cdcncm_get_composite_devdesc
*
* Description:
* Helper function to fill in some constants into the composite
* configuration struct.
*
* Input Parameters:
* dev - Pointer to the configuration struct we should fill
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_CDCNCM_COMPOSITE
void cdcncm_get_composite_devdesc(FAR struct composite_devdesc_s *dev);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_USB_CDCNCM_H */

View File

@ -65,10 +65,35 @@
#define MSBYTE(u16) ((u16) >> 8) /* Get MS byte from uint16_t */
#define LSBYTE(u16) ((u16) & 0xff) /* Get LS byte from uint16_t */
#define GETUINT16(p) ((uint16_t)((uint16_t)(p[1] << 8) | (uint16_t)p[0]))
#define GETUINT32(p) ((uint32_t)((uint32_t)p[3] << 24) | \
((uint32_t)p[2] << 16) | \
((uint32_t)p[1] << 8) | (uint32_t)p[0])
#define GETUINT16(p) ((uint16_t)(((uint16_t)(p)[1] << 8) | \
(uint16_t)(p)[0]))
#define PUTUINT16(p, v) do \
{ \
uint8_t *__p; \
__p = (FAR uint8_t *)(p); \
*__p++ = ((uint16_t)(v) & 0xff); \
*__p = ((uint16_t)(v) >> 8); \
} \
while (0)
/* All 32-bit values must be little-endian */
#define GETUINT32(p) ((uint32_t)(((uint32_t)(p)[3] << 24) | \
((uint32_t)(p)[2] << 16) | \
((uint32_t)(p)[1] << 8) | \
(uint32_t)(p)[0]))
#define PUTUINT32(p, v) do \
{ \
uint8_t *__p; \
__p = (FAR uint8_t *)(p); \
*__p++ = ((uint32_t)(v) & 0xff); \
*__p++ = ((uint32_t)(v) >> 8) & 0xff; \
*__p++ = ((uint32_t)(v) >> 16) & 0xff; \
*__p = ((uint32_t)(v) >> 24); \
} \
while (0)
/* USB directions (in endpoint addresses) */