
Greetings,
I'm trying to understand how to use the U-Boot bind command to bind the usb_ether driver to the usb class to register a USB ethernet gadget network device as referenced in: commit 02291d83fdaaf ("doc: add bind/unbind command documentation") commit 49c752c93a78 ("cmd: Add bind/unbind commands to bind a device to a driver from the command line")
I have enabled: CONFIG_DM_USB=y CONFIG_USB_GADGET=y CONFIG_USB_ETHER=y
However the 'usb_ether' driver is never registered and thus doesn't appear in a 'dm tree' list and can't be bound to the usb controller.
With the help of Heiko I've found two ways to get the usb_ether driver to register:
dt-way: - add of match in ether.c: diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 63d552bc8b..8e2a05a5af 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2690,10 +2690,16 @@ int usb_ether_init(void) return 0; }
+static const struct udevice_id usb_ether_ids[] = { + { .compatible = "gadget,usb_ether" }, + { } +}; + U_BOOT_DRIVER(eth_usb) = { .name = "usb_ether", .id = UCLASS_ETH, .probe = usb_eth_probe, + .of_match = usb_ether_ids, .ops = &usb_eth_ops, .priv_auto_alloc_size = sizeof(struct ether_priv), .platdata_auto_alloc_size = sizeof(struct eth_pdata), - then add it directly in your board u-boot.dts: +&usbotg1 { + usb_ether0 { + compatible = "gadget,usb_ether"; + status = "okay"; + }; +};
The non-dt way: - bind it manually in board code with: { struct udevice *dev; struct udevice *usb_dev; int ret;
ret = uclass_first_device(UCLASS_USB, &usb_dev); if (!usb_dev || ret) printf("%s: No USB device found\n", __func__);
ret = device_bind_driver(usb_dev, "usb_ether", "usb_ether", &dev); if (!dev || ret) printf("%s: usb - not able to bind usb_ether device\n", __func__); } - Note that this is the same code from usb_ether_init() but with UCLASS_USB instead of UCLASS_USB_GADGET_GENERIC
What is the intended way to bind the usb_ether gadget device at runtime?
Additionally Heiko found that once bound and usb_ether is registered as a network device using a network command like ping/tftpboot calls usb_setup_ehci_gadget() which removes the USB driver ... and so also the child usb ethernet gadget device then re-probes only the usb driver and not the gadget thus fails. I compared this to how the 'ums' command works and that also removes the usb driver and child nodes but because ums isn't a gadget driver it doesn't get removed and works.
Best Regards,
Tim