forked from nuttx/nuttx-update
Merged in paimonen/nuttx/pullreq_RNDIS_composite_support (pull request #753)
RNDIS composite support * NuttX usb/composite.h: Forward-declare composite_devdesc_s. This avoids "error: conflicting types for 'composite_initialize'" on some versions of GCC. Because of the cross-inclusion between usbdev.h and composite.h, the full declaration is not always available. * NuttX: USB Composite driver: Fix strid comparison The last string ID used by composite driver is 4, and the number of IDs used is 5 (0..4). The comparison strid <= COMPOSITE_NSTRIDS caused composite driver to reply with -EINVAL for id 5, even though it should be available for subdevices to use. * NuttX: RNDIS USB driver: Add support for composite configuration. Approved-by: GregoryN <gnutt@nuttx.org>
This commit is contained in:
parent
ec6c7839d3
commit
99adc36352
5 changed files with 295 additions and 75 deletions
|
@ -677,6 +677,16 @@ menuconfig RNDIS
|
|||
|
||||
if RNDIS
|
||||
|
||||
config RNDIS_COMPOSITE
|
||||
bool "RNDIS composite support"
|
||||
default n
|
||||
depends on USBDEV_COMPOSITE
|
||||
---help---
|
||||
Configure the RNDIS driver as part of a composite driver
|
||||
(only if USBDEV_COMPOSITE is also defined)
|
||||
|
||||
if !RNDIS_COMPOSITE
|
||||
|
||||
config RNDIS_VENDORID
|
||||
hex "RNDIS Vendor ID"
|
||||
default 0x584e
|
||||
|
@ -712,6 +722,8 @@ config RNDIS_VERSIONNO
|
|||
|
||||
endif # RNDIS
|
||||
|
||||
endif # RNDIS_COMPOSITE
|
||||
|
||||
menuconfig NET_CDCECM
|
||||
bool "CDC-ECM Ethernet-over-USB"
|
||||
default n
|
||||
|
|
|
@ -486,7 +486,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
|
|||
uint8_t strid = ctrl->value[0];
|
||||
FAR struct usb_strdesc_s *buf = (FAR struct usb_strdesc_s *)ctrlreq->buf;
|
||||
|
||||
if (strid <= COMPOSITE_NSTRIDS)
|
||||
if (strid < COMPOSITE_NSTRIDS)
|
||||
{
|
||||
ret = composite_mkstrdesc(strid, buf);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include <nuttx/usb/cdc.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/usbdev_trace.h>
|
||||
#include <nuttx/usb/rndis.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
|
@ -77,10 +78,12 @@
|
|||
#define RNDIS_NCONFIGS (1)
|
||||
#define RNDIS_CONFIGID (1)
|
||||
#define RNDIS_CONFIGIDNONE (0)
|
||||
#define RNDIS_NINTERFACES (2)
|
||||
|
||||
#define RNDIS_EPINTIN_ADDR USB_EPIN(3)
|
||||
#define RNDIS_EPBULKIN_ADDR USB_EPIN(1)
|
||||
#define RNDIS_EPBULKOUT_ADDR USB_EPOUT(2)
|
||||
#define RNDIS_NUM_EPS (3)
|
||||
|
||||
#define RNDIS_MANUFACTURERSTRID (1)
|
||||
#define RNDIS_PRODUCTSTRID (2)
|
||||
|
@ -128,6 +131,8 @@ struct rndis_req_s
|
|||
struct rndis_dev_s
|
||||
{
|
||||
struct net_driver_s netdev; /* Network driver structure */
|
||||
struct usbdev_devinfo_s devinfo;
|
||||
|
||||
FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
|
||||
FAR struct usbdev_ep_s *epintin; /* Interrupt IN endpoint structure */
|
||||
FAR struct usbdev_ep_s *epbulkin; /* Bulk IN endpoint structure */
|
||||
|
@ -145,6 +150,8 @@ struct rndis_dev_s
|
|||
WDOG_ID txpoll; /* TX poll watchdog */
|
||||
struct work_s pollwork; /* TX poll worker */
|
||||
|
||||
bool registered; /* Has netdev_register() been called */
|
||||
|
||||
uint8_t config; /* USB Configuration number */
|
||||
FAR struct rndis_req_s *net_req; /* Pointer to request whose buffer is assigned to network */
|
||||
FAR struct rndis_req_s *rx_req; /* Pointer request container that holds RX buffer */
|
||||
|
@ -182,7 +189,9 @@ struct rndis_alloc_s
|
|||
|
||||
struct rndis_cfgdesc_s
|
||||
{
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
struct usb_cfgdesc_s cfgdesc; /* Configuration descriptor */
|
||||
#endif
|
||||
struct usb_iaddesc_s assoc_desc; /* Interface association descriptor */
|
||||
struct usb_ifdesc_s comm_ifdesc; /* Communication interface descriptor */
|
||||
struct usb_epdesc_s epintindesc; /* Interrupt endpoint descriptor */
|
||||
|
@ -245,6 +254,7 @@ const static struct usbdevclass_driverops_s g_driverops =
|
|||
NULL
|
||||
};
|
||||
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
static const struct usb_devdesc_s g_devdesc =
|
||||
{
|
||||
USB_SIZEOF_DEVDESC, /* len */
|
||||
|
@ -265,24 +275,27 @@ static const struct usb_devdesc_s g_devdesc =
|
|||
RNDIS_SERIALSTRID, /* serno */
|
||||
RNDIS_NCONFIGS /* nconfigs */
|
||||
};
|
||||
#endif
|
||||
|
||||
const static struct rndis_cfgdesc_s g_rndis_cfgdesc =
|
||||
{
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
{
|
||||
.len = USB_SIZEOF_CFGDESC,
|
||||
.type = USB_DESC_TYPE_CONFIG,
|
||||
.totallen = {0, 0},
|
||||
.ninterfaces = 2,
|
||||
.ninterfaces = RNDIS_NINTERFACES,
|
||||
.cfgvalue = RNDIS_CONFIGID,
|
||||
.icfg = 0,
|
||||
.attr = USB_CONFIG_ATTR_ONE | USB_CONFIG_ATTR_SELFPOWER,
|
||||
.mxpower = (CONFIG_USBDEV_MAXPOWER + 1) / 2
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.len = USB_SIZEOF_IADDESC,
|
||||
.type = USB_DESC_TYPE_INTERFACEASSOCIATION,
|
||||
.firstif = 0,
|
||||
.nifs = 2,
|
||||
.nifs = RNDIS_NINTERFACES,
|
||||
.classid = 0xef,
|
||||
.subclass = 0x04,
|
||||
.protocol = 0x01,
|
||||
|
@ -1766,8 +1779,7 @@ static FAR struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int usbclass_mkstrdesc(FAR struct rndis_dev_s *priv, uint8_t id,
|
||||
FAR struct usb_strdesc_s *strdesc)
|
||||
static int usbclass_mkstrdesc(uint8_t id, FAR struct usb_strdesc_s *strdesc)
|
||||
{
|
||||
FAR const char *str;
|
||||
int len;
|
||||
|
@ -1776,6 +1788,7 @@ static int usbclass_mkstrdesc(FAR struct rndis_dev_s *priv, uint8_t id,
|
|||
|
||||
switch (id)
|
||||
{
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
case 0:
|
||||
{
|
||||
/* Descriptor 0 is the language id */
|
||||
|
@ -1798,6 +1811,7 @@ static int usbclass_mkstrdesc(FAR struct rndis_dev_s *priv, uint8_t id,
|
|||
case RNDIS_SERIALSTRID:
|
||||
str = CONFIG_RNDIS_SERIALSTR;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -1832,9 +1846,10 @@ static int usbclass_mkstrdesc(FAR struct rndis_dev_s *priv, uint8_t id,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf)
|
||||
static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
|
||||
FAR struct usbdev_devinfo_s *devinfo)
|
||||
{
|
||||
FAR struct usb_cfgdesc_s *cfgdesc = (FAR struct usb_cfgdesc_s *)buf;
|
||||
FAR struct rndis_cfgdesc_s *dest = (FAR struct rndis_cfgdesc_s*)buf;
|
||||
uint16_t totallen;
|
||||
|
||||
/* This is the total length of the configuration (not necessarily the
|
||||
|
@ -1842,12 +1857,22 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf)
|
|||
*/
|
||||
|
||||
totallen = sizeof(g_rndis_cfgdesc);
|
||||
memcpy(cfgdesc, &g_rndis_cfgdesc, totallen);
|
||||
memcpy(dest, &g_rndis_cfgdesc, totallen);
|
||||
|
||||
/* Finally, fill in the total size of the configuration descriptor */
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
/* For a stand-alone device, just fill in the total length */
|
||||
dest->cfgdesc.totallen[0] = LSBYTE(totallen);
|
||||
dest->cfgdesc.totallen[1] = MSBYTE(totallen);
|
||||
#else
|
||||
/* For composite device, apply possible offset to the interface numbers */
|
||||
dest->assoc_desc.firstif += devinfo->ifnobase;
|
||||
dest->comm_ifdesc.ifno += devinfo->ifnobase;
|
||||
dest->epintindesc.addr = USB_EPIN(devinfo->epno[RNDIS_EP_INTIN_IDX]);
|
||||
dest->data_ifdesc.ifno += devinfo->ifnobase;
|
||||
dest->epbulkindesc.addr = USB_EPIN(devinfo->epno[RNDIS_EP_BULKIN_IDX]);
|
||||
dest->epbulkoutdesc.addr = USB_EPOUT(devinfo->epno[RNDIS_EP_BULKOUT_IDX]);
|
||||
#endif
|
||||
|
||||
cfgdesc->totallen[0] = LSBYTE(totallen);
|
||||
cfgdesc->totallen[1] = MSBYTE(totallen);
|
||||
return totallen;
|
||||
}
|
||||
|
||||
|
@ -1904,7 +1929,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
|
|||
|
||||
/* Pre-allocate the IN interrupt endpoint */
|
||||
|
||||
priv->epintin = DEV_ALLOCEP(dev, RNDIS_EPINTIN_ADDR, true, USB_EP_ATTR_XFER_INT);
|
||||
priv->epintin = DEV_ALLOCEP(dev, USB_EPIN(priv->devinfo.epno[RNDIS_EP_INTIN_IDX]), true, USB_EP_ATTR_XFER_INT);
|
||||
if (!priv->epintin)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINALLOCFAIL), 0);
|
||||
|
@ -1926,7 +1951,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
|
|||
|
||||
/* Pre-allocate the IN bulk endpoint */
|
||||
|
||||
priv->epbulkin = DEV_ALLOCEP(dev, RNDIS_EPBULKIN_ADDR, true, USB_EP_ATTR_XFER_BULK);
|
||||
priv->epbulkin = DEV_ALLOCEP(dev, USB_EPIN(priv->devinfo.epno[RNDIS_EP_BULKIN_IDX]), true, USB_EP_ATTR_XFER_BULK);
|
||||
if (!priv->epbulkin)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINALLOCFAIL), 0);
|
||||
|
@ -1938,7 +1963,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
|
|||
|
||||
/* Pre-allocate the OUT bulk endpoint */
|
||||
|
||||
priv->epbulkout = DEV_ALLOCEP(dev, RNDIS_EPBULKOUT_ADDR, false, USB_EP_ATTR_XFER_BULK);
|
||||
priv->epbulkout = DEV_ALLOCEP(dev, USB_EPOUT(priv->devinfo.epno[RNDIS_EP_BULKOUT_IDX]), false, USB_EP_ATTR_XFER_BULK);
|
||||
if (!priv->epbulkout)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTALLOCFAIL), 0);
|
||||
|
@ -2003,7 +2028,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
|
|||
}
|
||||
|
||||
/* Report if we are selfpowered */
|
||||
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
#ifdef CONFIG_USBDEV_SELFPOWERED
|
||||
DEV_SETSELFPOWERED(dev);
|
||||
#endif
|
||||
|
@ -2011,6 +2036,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
|
|||
/* And pull-up the data line for the soft connect function */
|
||||
|
||||
DEV_CONNECT(dev);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
|
@ -2205,16 +2231,18 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
|
|||
|
||||
switch (ctrl->value[1])
|
||||
{
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
case USB_DESC_TYPE_DEVICE:
|
||||
{
|
||||
ret = USB_SIZEOF_DEVDESC;
|
||||
memcpy(ctrlreq->buf, &g_devdesc, ret);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case USB_DESC_TYPE_CONFIG:
|
||||
{
|
||||
ret = usbclass_mkcfgdesc(ctrlreq->buf);
|
||||
ret = usbclass_mkcfgdesc(ctrlreq->buf, &priv->devinfo);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2222,7 +2250,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
|
|||
{
|
||||
/* index == language code. */
|
||||
|
||||
ret = usbclass_mkstrdesc(priv, ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf);
|
||||
ret = usbclass_mkstrdesc(ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2517,6 +2545,98 @@ errout:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbclass_classobject
|
||||
*
|
||||
* Description:
|
||||
* Allocate memory for the RNDIS driver class object
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negative error code on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
static int usbclass_classobject(int minor,
|
||||
FAR struct usbdev_devinfo_s *devinfo,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
FAR struct rndis_alloc_s *alloc;
|
||||
FAR struct rndis_dev_s *priv;
|
||||
FAR struct rndis_driver_s *drvr;
|
||||
int ret;
|
||||
|
||||
/* Allocate the structures needed */
|
||||
|
||||
alloc = (FAR struct rndis_alloc_s *)kmm_zalloc(sizeof(struct rndis_alloc_s));
|
||||
if (!alloc)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Convenience pointers into the allocated blob */
|
||||
|
||||
priv = &alloc->dev;
|
||||
drvr = &alloc->drvr;
|
||||
*classdev = &drvr->drvr;
|
||||
|
||||
#ifdef CONFIG_RNDIS_COMPOSITE
|
||||
priv->devinfo = *devinfo;
|
||||
#else
|
||||
priv->devinfo.epno[RNDIS_EP_INTIN_IDX] = USB_EPNO(RNDIS_EPINTIN_ADDR);
|
||||
priv->devinfo.epno[RNDIS_EP_BULKIN_IDX] = USB_EPNO(RNDIS_EPBULKIN_ADDR);
|
||||
priv->devinfo.epno[RNDIS_EP_BULKOUT_IDX] = USB_EPNO(RNDIS_EPBULKOUT_ADDR);
|
||||
#endif
|
||||
|
||||
/* Initialize the USB ethernet driver structure */
|
||||
|
||||
sq_init(&priv->reqlist);
|
||||
memcpy(priv->host_mac_address, g_rndis_default_mac_addr, 6);
|
||||
priv->txpoll = wd_create();
|
||||
priv->netdev.d_private = priv;
|
||||
priv->netdev.d_ifup = &rndis_ifup;
|
||||
priv->netdev.d_ifdown = &rndis_ifdown;
|
||||
priv->netdev.d_txavail = &rndis_txavail;
|
||||
|
||||
/* MAC address filtering is purposefully left out of this driver. Since
|
||||
* in the RNDIS USB scenario there are only two devices in the network
|
||||
* (host and us), there shouldn't be any packets received that don't
|
||||
* belong to us.
|
||||
*/
|
||||
|
||||
/* Initialize the USB class driver structure */
|
||||
|
||||
drvr->drvr.speed = USB_SPEED_FULL;
|
||||
drvr->drvr.ops = &g_driverops;
|
||||
drvr->dev = priv;
|
||||
|
||||
ret = netdev_register(&priv->netdev, NET_LL_ETHERNET);
|
||||
if (ret)
|
||||
{
|
||||
uerr("Failed to register net device");
|
||||
return ret;
|
||||
}
|
||||
|
||||
drvr->dev->registered = true;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void usbclass_uninitialize(FAR struct usbdevclass_driver_s *classdev)
|
||||
{
|
||||
FAR struct rndis_driver_s *drvr = (FAR struct rndis_driver_s*)classdev;
|
||||
FAR struct rndis_alloc_s *alloc = (FAR struct rndis_alloc_s *)drvr->dev;
|
||||
|
||||
if (drvr->dev->registered)
|
||||
{
|
||||
netdev_unregister(&drvr->dev->netdev);
|
||||
drvr->dev->registered = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
kmm_free(alloc);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -2536,81 +2656,110 @@ errout:
|
|||
* 0 on success, -errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
int usbdev_rndis_initialize(FAR const uint8_t *mac_address)
|
||||
{
|
||||
FAR struct rndis_alloc_s *alloc;
|
||||
FAR struct rndis_dev_s *priv;
|
||||
FAR struct rndis_driver_s *drvr;
|
||||
int ret;
|
||||
FAR struct usbdevclass_driver_s *classdev;
|
||||
FAR struct rndis_driver_s *drvr;
|
||||
|
||||
/* Allocate the structures needed */
|
||||
|
||||
alloc = (FAR struct rndis_alloc_s *)kmm_malloc(sizeof(struct rndis_alloc_s));
|
||||
if (!alloc)
|
||||
ret = usbclass_classobject(0, NULL, &classdev);
|
||||
if (ret)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0);
|
||||
return -ENOMEM;
|
||||
nerr("usbclass_classobject failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Convenience pointers into the allocated blob */
|
||||
|
||||
priv = &alloc->dev;
|
||||
drvr = &alloc->drvr;
|
||||
|
||||
/* Initialize the USB ethernet driver structure */
|
||||
|
||||
memset(priv, 0, sizeof(struct rndis_dev_s));
|
||||
sq_init(&priv->reqlist);
|
||||
drvr = (FAR struct rndis_driver_s*)classdev;
|
||||
|
||||
if (mac_address)
|
||||
{
|
||||
memcpy(priv->host_mac_address, mac_address, 6);
|
||||
memcpy(drvr->dev->host_mac_address, mac_address, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(priv->host_mac_address, g_rndis_default_mac_addr, 6);
|
||||
}
|
||||
|
||||
priv->txpoll = wd_create();
|
||||
|
||||
memset(&priv->netdev, 0, sizeof(struct net_driver_s));
|
||||
priv->netdev.d_private = priv;
|
||||
priv->netdev.d_ifup = &rndis_ifup;
|
||||
priv->netdev.d_ifdown = &rndis_ifdown;
|
||||
priv->netdev.d_txavail = &rndis_txavail;
|
||||
|
||||
/* MAC address filtering is purposefully left out of this driver. Since
|
||||
* in the RNDIS USB scenario there are only two devices in the network
|
||||
* (host and us), there shouldn't be any packets received that don't
|
||||
* belong to us.
|
||||
*/
|
||||
|
||||
/* Initialize the USB class driver structure */
|
||||
|
||||
drvr->drvr.speed = USB_SPEED_FULL;
|
||||
drvr->drvr.ops = &g_driverops;
|
||||
drvr->dev = priv;
|
||||
|
||||
/* Register the USB serial class driver */
|
||||
|
||||
ret = usbdev_register(&drvr->drvr);
|
||||
if (ret)
|
||||
{
|
||||
nerr("usbdev_register failed: %d\n", ret);
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_DEVREGISTER), (uint16_t)-ret);
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
ret = netdev_register(&priv->netdev, NET_LL_ETHERNET);
|
||||
if (ret)
|
||||
{
|
||||
uerr("Failed to register net device");
|
||||
goto errout_with_alloc;
|
||||
usbclass_uninitialize(classdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout_with_alloc:
|
||||
kmm_free(alloc);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbdev_rndis_set_host_mac_addr
|
||||
*
|
||||
* Description:
|
||||
* Set host MAC address. Mainly for use with composite devices where
|
||||
* the MAC cannot be given directly to usbdev_rndis_initialize().
|
||||
*
|
||||
* Input Parameters:
|
||||
* netdev: pointer to the network interface. Can be obtained from
|
||||
* e.g. netdev_findbyname().
|
||||
*
|
||||
* mac_address: pointer to an array of six octets which is the MAC address
|
||||
* of the host side of the interface. May be NULL to use the
|
||||
* default MAC address.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
int usbdev_rndis_set_host_mac_addr(FAR struct net_driver_s *netdev, FAR const uint8_t *mac_address)
|
||||
{
|
||||
FAR struct rndis_dev_s *dev = (FAR struct rndis_dev_s*)netdev;
|
||||
|
||||
if (mac_address)
|
||||
{
|
||||
memcpy(dev->host_mac_address, mac_address, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dev->host_mac_address, g_rndis_default_mac_addr, 6);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbdev_rndis_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_RNDIS_COMPOSITE
|
||||
void usbdev_rndis_get_composite_devdesc(struct composite_devdesc_s *dev)
|
||||
{
|
||||
memset(dev, 0, sizeof(struct composite_devdesc_s));
|
||||
|
||||
dev->mkconfdesc = usbclass_mkcfgdesc;
|
||||
dev->mkstrdesc = usbclass_mkstrdesc;
|
||||
dev->classobject = usbclass_classobject;
|
||||
dev->uninitialize = usbclass_uninitialize;
|
||||
dev->nconfigs = RNDIS_NCONFIGS;
|
||||
dev->configid = RNDIS_CONFIGID;
|
||||
dev->cfgdescsize = sizeof(g_rndis_cfgdesc);
|
||||
dev->devinfo.ninterfaces = RNDIS_NINTERFACES;
|
||||
dev->devinfo.nstrings = 0;
|
||||
dev->devinfo.nendpoints = RNDIS_NUM_EPS;
|
||||
|
||||
/* Default endpoint indexes, board-specific logic can override these */
|
||||
dev->devinfo.epno[RNDIS_EP_INTIN_IDX] = USB_EPNO(RNDIS_EPINTIN_ADDR);
|
||||
dev->devinfo.epno[RNDIS_EP_BULKIN_IDX] = USB_EPNO(RNDIS_EPBULKIN_ADDR);
|
||||
dev->devinfo.epno[RNDIS_EP_BULKOUT_IDX] = USB_EPNO(RNDIS_EPBULKOUT_ADDR);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -76,6 +76,12 @@ extern "C"
|
|||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Forward declarations
|
||||
****************************************************************************/
|
||||
|
||||
struct composite_devdesc_s;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -42,6 +42,16 @@
|
|||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Indexes for devinfo.epno[] array. Used for composite device configuration. */
|
||||
#define RNDIS_EP_INTIN_IDX (0)
|
||||
#define RNDIS_EP_BULKIN_IDX (1)
|
||||
#define RNDIS_EP_BULKOUT_IDX (2)
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
|
@ -76,7 +86,50 @@ extern "C"
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef CONFIG_RNDIS_COMPOSITE
|
||||
int usbdev_rndis_initialize(FAR const uint8_t *mac_address);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbdev_rndis_set_host_mac_addr
|
||||
*
|
||||
* Description:
|
||||
* Set host MAC address. Mainly for use with composite devices where
|
||||
* the MAC cannot be given directly to usbdev_rndis_initialize().
|
||||
*
|
||||
* Input Parameters:
|
||||
* netdev: pointer to the network interface. Can be obtained from
|
||||
* e.g. netdev_findbyname().
|
||||
*
|
||||
* mac_address: pointer to an array of six octets which is the MAC address
|
||||
* of the host side of the interface. May be NULL to use the
|
||||
* default MAC address.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int usbdev_rndis_set_host_mac_addr(FAR struct net_driver_s *netdev, FAR const uint8_t *mac_address);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbdev_rndis_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_RNDIS_COMPOSITE
|
||||
void usbdev_rndis_get_composite_devdesc(struct composite_devdesc_s *dev);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
Loading…
Reference in a new issue