-
Notifications
You must be signed in to change notification settings - Fork 8.4k
subsys: usb: host: support for usb host cdc-ecm class #100289
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
base: main
Are you sure you want to change the base?
subsys: usb: host: support for usb host cdc-ecm class #100289
Conversation
Add a "struct usbh_status" that contains a bitmask of flags to keep track of the global state of the host context, like done for the device_next implementation. Signed-off-by: Josuah Demangeon <[email protected]>
Add missing copyright notice for the linker script to help with check_compliance.py. Signed-off-by: Josuah Demangeon <[email protected]>
Add a "struct usbh_class_api" for the host implementation, and move all the function poitners to it. Add more fields to "struct usbh_class_data". Signed-off-by: Josuah Demangeon <[email protected]>
Add API wrappers around the function pointers in struct usbh_class_api, while also documenting the USB host class internal API. Signed-off-by: Josuah Demangeon <[email protected]>
Add functions to probe/remove all classes as part of a new usbh_class.c and a matching usbh_class.h. These functions are called from the function usbh_init_device_intl() in usbh_core.c to initialize every class upon connection of a device. Every class driver provide filters to match the interfaces of the device. Co-authored-by: Aiden Hu <[email protected]> Signed-off-by: Josuah Demangeon <[email protected]>
Move the UVC header with all the definitions from the UVC standard to share it between USB host and device class implementation. Signed-off-by: Josuah Demangeon <[email protected]>
Add tests making sure the USB Host class APIs introduced build and run as expected. Signed-off-by: Josuah Demangeon <[email protected]>
Add tests making sure the USB Host class APIs introduced build and run as expected. Signed-off-by: Josuah Demangeon <[email protected]>
Move the UVC header with all the definitions from the UVC standard to share it between USB host and device class implementation. Signed-off-by: Josuah Demangeon <[email protected]>
Move UVC helper functions to a file shared between UVC host and device. The arrays are not visible anymore from either USB host or device, but instead accessed through a front-end funciton. Signed-off-by: Josuah Demangeon <[email protected]>
The USB control size field was wrong for UVC_PU_CONTRAST_CONTROL. Correct it to the correct value from the standard. Signed-off-by: Josuah Demangeon <[email protected]>
Loop through each of the VideoStreaming and VideoControl descriptor to parse them. This is meant as a stub for the purpose of testing the class API. Signed-off-by: Josuah Demangeon <[email protected]>
Add a test to run the USB Video Class host support by using the existing Zephyr USB Video Class device support. This allows running implementing the host side from the device side. A draft implementation of UVC is added leveraging this test. Signed-off-by: Josuah Demangeon <[email protected]>
The public API file <zephyr/usb/class/usbd_uvc.h> lacked an include to <zephyr/drivers/video.h> making it fail depending on the order of the includes. Signed-off-by: Josuah Demangeon <[email protected]>
Modify the USB device int sequence to read the device descriptor only after setting a valid device address. Signed-off-by: Santhosh Charles <[email protected]>
When hub is used, need to consider about multiple devices are attached. Signed-off-by: Aiden Hu <[email protected]>
add usbh_device_get_root and usbh_device_is_root function to check root device Signed-off-by: Aiden Hu <[email protected]>
For usb xfer, set endpoint type and interval by the selected endpoint desc. Signed-off-by: Aiden Hu <[email protected]>
Convert xfer's interval to actual value because mcux_ep->interval is already calculated. Signed-off-by: Aiden Hu <[email protected]>
maxPacketSize and numberPerUframe of pipe should be set considering additional transactions. Signed-off-by: Aiden Hu <[email protected]>
Add two functions: usbh_connect_device() for device connection usbh_disconnect_device() for device disconnection These functions centralize the logic for device attach/detach, including class probe and remove handling. They can be invoked by the hub class as well as dev_connected_handler and dev_removed_handler, improving code clarity and reuse. Signed-off-by: Aiden Hu <[email protected]>
Add support for the USB CDC ECM (Ethernet Control Model) class to the USB host subsystem. This implementation enables Ethernet functionality for USB host. Signed-off-by: Santhosh Charles <[email protected]>
Add devicetree binding file describing the USB Host CDC Ethernet Control Model (ECM) implementation for Zephyr. Signed-off-by: Santhosh Charles <[email protected]>
Introduce subsys/usb/common as a new directory intended to hold sources and configuration that are shared between USB host and device implementations. Integrate the new common directory into the build system. Signed-off-by: Santhosh Charles <[email protected]> Signed-off-by: Josuah Demangeon <[email protected]>
This reverts commit a01c220.
Add missing include for usbh_class.h header file in usbh_core.c to fix implicit declaration of function 'usbh_class_init_all' in usbh_core.c Signed-off-by: Dv Alan <[email protected]>
Add usbh_req_desc_str() helper function to retrieve USB string descriptors from a device. This function wraps the generic descriptor request with proper handling for string descriptors, including memory allocation, data copying, and endianness conversion for the bString field. Signed-off-by: Dv Alan <[email protected]>
Add Ethernet Statistics Feature Selector enumeration defining all standard CDC ECM statistics counters (XMIT_OK, RCV_OK, etc.) as per the USB CDC specification. Add CDC notification packet structure for handling device notifications. Add CONNECTION_SPEED_CHANGE notification code and Ethernet Power Management Pattern activation constants. Signed-off-by: Dv Alan <[email protected]>
Complete rewrite of the USB host CDC-ECM (Ethernet Control Model) driver with improved architecture and functionality: - Restructure driver to use proper Ethernet API with ETH_NET_DEVICE_DT_INST_DEFINE - Implement asynchronous RX handling using k_poll signals and dedicated thread - Add support for fragmented network buffers with linearization - Implement proper packet filter management (promiscuous, multicast, broadcast) - Add support for connection speed change notifications and link capabilities - Implement MAC address retrieval from USB string descriptors with multi-language support - Add comprehensive CDC-ECM class requests (SET_ETHERNET_PACKET_FILTER, GET_ETHERNET_STATISTIC, SET_ETHERNET_MULTICAST_FILTERS, etc.) - Use separate buffer pools for TX and RX data transfers - Add proper ZLP (Zero Length Packet) handling for bulk transfers - Implement automatic RX restart mechanism with error recovery - Add network interface up/down state management - Update Kconfig with configurable buffer counts and stack size - Rename Kconfig file from Kconfig.cdc_ecm_host to Kconfig.cdc_ecm - Change DT compatible from "zephyr,usbh-cdc-ecm" to "zephyr,cdc-ecm-host" - Mark driver as EXPERIMENTAL in Kconfig The rewritten driver provides better error handling, improved performance through asynchronous operations, and more complete CDC-ECM feature support. Signed-off-by: Dv Alan <[email protected]>
Rename the CDC-ECM host device tree binding file from zephyr,usbh-cdc-ecm.yaml to zephyr,cdc-ecm-host.yaml to align with the updated compatible string used in the rewritten driver. Update the binding description to clarify that each CDC-ECM instance represents an ethernet interface visible to Zephyr's networking stack. Remove the local-mac-address property as MAC address retrieval is now handled directly from USB string descriptors in the driver implementation. Signed-off-by: Dv Alan <[email protected]>
| @@ -0,0 +1,1157 @@ | |||
| /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a ethernet driver, so it belongs in drivers/ethernet/. I know there are already others there, but these should probably be moved too. I don't like ethernet drivers and its api be scattered all over the tree. (should be limited to the ethernet and wifi drivers and the net subsystem)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is blocking
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like a bit of discussion would help to decide:
-
Where USB classes (host/device) that implement a driver API are implemented. This would imply most USB classes move, or it would be an exception just for CDC-ECM.
-
Whether source in
drivers/are allowed to call functions fromsubsystem/. I've not seen anything in the doc but suspect this could interest several parties to review which model to use.
How about pursuing with the implementation details in the meantime that the location of tes code is discussed?
Thank you for the review!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drivers are allowed to use subsystems.
For example there is the random subsystem subsys/random/, it implements /include/zephyr/random/random.h, which includes sys_rand_get(). Btw the random subsystem uses the entropy_driver_api, if that is selected to be the source of randomness.
For the ethernet drivers, we have a common dt prop zephyr,random-mac-address if that is set, the ethernet mac address is randomly generated with sys_rand_get() during the init of the ethernet driver.
Other example are sd cards in zephyr. (that might be similar enough to usb, as it also has a sd subsystem above the sdhc drivers and api)
The sd card or disk (dt compatible zephyr,sdmmc-disk, drivers/disk/sdmmc_subsys.c) implements the disk api (zephyr/drivers/disk.h) and uses the SD subsystem (subsys/sd) and that uses the sdhc drivers (include/zephyr/drivers/sdhc.h).
We also have drivers for a SDIO wifi card in tree, which uses the sd subsystem it is in
drivers/wifi/infineon/airoc_whd_hal_sdio.c and not in subsys/sd.
Even bigger: We have a crypto device api and one of the drivers is zephyr/drivers/crypto/crypto_mbedtls_shim.c and it is using mbedTLS, which even is a separate module.
Drivers can use anything what they need.
Another thing is control and ensuring quality. There is a reason we have Driver Areas in the maintainers.yml and that in addition to the vendor specific areas for their drivers.
For this PR I wasn't added because I'm the ethernet maintainer, no it was just because I'm also a collaborator for DHCP in the networking subsystem and it's sample got changed.
How about pursuing with the implementation details in the meantime that the location of tes code is discussed?
Sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your overview of driver <-> subsystem dependencies. I think I heard this "subsystem/driver" split about a particular driver, not as a general guideline.
For this PR I wasn't added because I'm the ethernet maintainer, no it was just because I'm also a collaborator for DHCP in the networking subsystem and it's sample got changed.
Regardless the solution, there would need to make sure that MAINTAINERS.yml pings correctly everyone involved.
Refactor the CDC-ECM host driver to improve MAC address handling and network interface lifecycle management: - Remove eth_usbh_cdc_ecm_get_capabilities() of eth_usbh_cdc_ecm_api, since it is static information about the ethernet capability, usb host does not match it - Remove manual net_if_up/down calls from probe and removed functions - Remove net_mgmt call for setting MAC address - Add upload_speed and download_speed fields to track connection speeds - Add interface and carrier state checks in RX callback to discard packets when interface is down Signed-off-by: Dv Alan <[email protected]>
| err = usbh_init(&uhs_ctx); | ||
| if (err) { | ||
| LOG_ERR("Failed to initialize %s: %d", uhs_ctx.name, err); | ||
| return err; | ||
| } | ||
|
|
||
| err = usbh_enable(&uhs_ctx); | ||
| if (err) { | ||
| LOG_ERR("Failed to enable %s: %d", uhs_ctx.name, err); | ||
| return err; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be part of the ethernet drivers init. also don't forget to handle the return of -EALREADY which should not be treated as an error.
| usbh_cdc_ecm { | ||
| compatible = "zephyr,cdc-ecm-host"; | ||
| status = "okay"; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be child of a usb host controller? so it knows what host controller hhas to be init and started
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, the first USB host interface that is initialized inherits all the classes.
This is probably a design flaw of the WIP APIs...
What about letting classes independent from a physical interface? This way regardless which physical interface is used, the same classes can be assigned to one or the other whenever a device is connected and match the class.
That allows to support i.e. 3 CDC NCM devices OS-wise, rather than require 2 CDC NCM devices on the first root HUB and 2 CDC NCM devices on the second root HUB (resource sharing).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Root hub refers to the ports of single controller, so in that sense binding interface to controller would not have impact. But if you have multiple USB host controllers, then there would be a difference.
While quite often there is 1-to-1 relationship between USB host controller and root hub, there is nothing preventing USB host controller from having multiple root hubs. In other words, multiple USB Type-A ports can be used by single host controller.
Updates: - Remove unnecessary loop and switch statement in connection speed change notification - Add debug log in notification callback Signed-off-by: Dv Alan <[email protected]>
|
|
It is possible to have a "demo" branch with all the commits from API4 like now, but this "demo" branch will not be merged until a lot of dependencies are reviewed and merged. Therefore, if you wished to have this PR merged soon, you might be interested in only using the minimum amount of dependencies, such as only API2 and not the commits from API3 and API4. If you needed to also have a "demo" pull request with all the experimental features from API3 and API4, then you can have an additional pull request just for demo purpose that will not be merged. Does it make sense? Feel free to ask clarifications here or on Discord. |
|
API2 is currently being reviewed, as soon as it is merged, it should be possible to write this current PR on top of Note that API2 recently got updated with new adjustments, including light API changes (suspend/resume removed). You might want to adjust this current PR to the latest API. Thank you! |




Dependencies:
This implementation contains all commits from #99775 & some necessary commits from #99097 and in addition:
samples/net/dhcpv4_client(CDC-ECM feature can be verified at boardrd_rw612_bga)It is fixed & improved the implementation in #99097: