From 418b692e21226d76fb292fbbcc04f0c07a1b0996 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Tue, 16 Jul 2024 11:59:04 +0800 Subject: [PATCH] usbdev/cdcmbim: add response notify when the host is needed to read the data, RESPONSE_AVAILABLE must first be sent. Signed-off-by: zhanghongyu --- drivers/usbdev/cdcncm.c | 47 +++++++++++++++++++++++++++++++---------- include/nuttx/usb/cdc.h | 2 ++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/drivers/usbdev/cdcncm.c b/drivers/usbdev/cdcncm.c index 959a54c4d4..1134a04692 100644 --- a/drivers/usbdev/cdcncm.c +++ b/drivers/usbdev/cdcncm.c @@ -150,9 +150,10 @@ enum ncm_notify_state_e { - NCM_NOTIFY_NONE, /* Don't notify */ - NCM_NOTIFY_CONNECT, /* Issue CONNECT next */ - NCM_NOTIFY_SPEED, /* Issue SPEED_CHANGE next */ + NCM_NOTIFY_NONE, /* Don't notify */ + NCM_NOTIFY_CONNECT, /* Issue CONNECT next */ + NCM_NOTIFY_SPEED, /* Issue SPEED_CHANGE next */ + NCM_NOTIFY_RESPONSE_AVAILABLE, /* Issue RESPONSE_AVAILABLE next */ }; struct ndp_parser_opts_s @@ -392,6 +393,8 @@ static int cdcncm_ioctl(FAR struct netdev_lowerhalf_s *dev, int cmd, unsigned long arg); #endif +static void cdcncm_notify_worker(FAR void *arg); + /* USB Device Class Driver **************************************************/ /* USB Device Class methods */ @@ -724,6 +727,9 @@ static ssize_t cdcmbim_write(FAR struct file *filep, FAR const char *buffer, } uinfo("wrote %zd bytes\n", buflen); + DEBUGASSERT(self->ncmdriver.notify == NCM_NOTIFY_RESPONSE_AVAILABLE); + work_queue(ETHWORK, &self->ncmdriver.notifywork, cdcncm_notify_worker, + self, 0); errout: nxmutex_unlock(&self->lock); @@ -1521,12 +1527,12 @@ static void cdcncm_resetconfig(FAR struct cdcncm_driver_s *self) EP_DISABLE(self->epint); EP_DISABLE(self->epbulkin); EP_DISABLE(self->epbulkout); + self->notify = NCM_NOTIFY_SPEED; } self->parseropts = &g_ndp16_opts; self->ndpsign = self->isncm ? self->parseropts->ndpsign : CDC_MBIM_NDP16_NOCRC_SIGN; - self->notify = NCM_NOTIFY_NONE; } /**************************************************************************** @@ -1627,11 +1633,11 @@ error: } /**************************************************************************** - * Name: ncm_notify + * Name: cdcncm_notify * ****************************************************************************/ -static int ncm_notify(FAR struct cdcncm_driver_s *self) +static int cdcncm_notify(FAR struct cdcncm_driver_s *self) { FAR struct usb_ctrlreq_s *req = (FAR struct usb_ctrlreq_s *)self->notifyreq->buf; @@ -1677,7 +1683,20 @@ static int ncm_notify(FAR struct cdcncm_driver_s *self) self->notify = NCM_NOTIFY_CONNECT; break; } - } + + case NCM_NOTIFY_RESPONSE_AVAILABLE: + { + req->req = MBIM_RESPONSE_AVAILABLE; + req->value[0] = LSBYTE(0); + req->value[1] = MSBYTE(0); + req->len[0] = LSBYTE(0); + req->len[1] = MSBYTE(0); + ret = sizeof(*req); + + self->notify = NCM_NOTIFY_NONE; + break; + } + } req->type = 0xa1; req->index[0] = LSBYTE(self->devinfo.ifnobase); @@ -1687,18 +1706,18 @@ static int ncm_notify(FAR struct cdcncm_driver_s *self) } /**************************************************************************** - * Name: ncm_do_notify + * Name: cdcncm_notify_worker * ****************************************************************************/ -static void ncm_do_notify(FAR void *arg) +static void cdcncm_notify_worker(FAR void *arg) { FAR struct cdcncm_driver_s *self = arg; int ret; while (self->notify != NCM_NOTIFY_NONE) { - ret = ncm_notify(self); + ret = cdcncm_notify(self); if (ret > 0) { FAR struct usbdev_req_s *notifyreq = self->notifyreq; @@ -1709,6 +1728,12 @@ static void ncm_do_notify(FAR void *arg) EP_SUBMIT(self->epint, notifyreq); } } + + /* After the NIC information is synchronized, subsequent notifications + * are all related to the mbim control + */ + + self->notify = NCM_NOTIFY_RESPONSE_AVAILABLE; } /**************************************************************************** @@ -1727,7 +1752,7 @@ static int cdcncm_setinterface(FAR struct cdcncm_driver_s *self, } netdev_lower_carrier_on(&self->dev); - work_queue(ETHWORK, &self->notifywork, ncm_do_notify, self, + work_queue(ETHWORK, &self->notifywork, cdcncm_notify_worker, self, MSEC2TICK(100)); } else diff --git a/include/nuttx/usb/cdc.h b/include/nuttx/usb/cdc.h index 75886f9114..b304ac88de 100644 --- a/include/nuttx/usb/cdc.h +++ b/include/nuttx/usb/cdc.h @@ -341,6 +341,7 @@ /* Table 15: Notifications, Networking Control Model */ #define NCM_NETWORK_CONNECTION ECM_NETWORK_CONNECTION +#define NCM_RESPONSE_AVAILABLE ECM_RESPONSE_AVAILABLE #define NCM_SPEED_CHANGE ECM_SPEED_CHANGE /* Table 16: Requests, Mobile Broadband Interface Model */ @@ -351,6 +352,7 @@ /* Table 17: Notifications, Networking Control Model */ #define MBIM_NETWORK_CONNECTION NCM_NETWORK_CONNECTION +#define MBIM_RESPONSE_AVAILABLE NCM_RESPONSE_AVAILABLE #define MBIM_SPEED_CHANGE NCM_SPEED_CHANGE /* Descriptors ***************************************************************/