
Hi Tim
On 2/10/22 18:04, Tim Harvey wrote:
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")
For example, i made some trial on STM32MP1 platform:
At boot, we got :
STM32MP> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver firmware 0 [ ] psci |-- psci sysreset 0 [ ] psci-sysreset | `-- psci-sysreset ..... blk 0 [ + ] mmc_blk | | `-- mmc@58005000.blk ethernet 0 [ + ] eth_eqos | |-- ethernet@5800a000 eth_phy_ge 0 [ + ] eth_phy_generic_drv | | `-- ethernet-phy@0 usb 0 [ ] ehci_generic | |-- usb@5800d000 video 0 [ ] stm32_display | |-- display-controller@5a001000 .....
As you can see, there is already an ethernet interface used. We unbind the ethernet interface before binding the usb_ether gadget to the usb class. First unbind the generic ethernet phy (eth_phy_generic_drv) and the ethernet driver (eth_eqos).
STM32MP> unbind eth_phy_generic 0 STM32MP> unbind ethernet 0 STM32MP> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver firmware 0 [ ] psci |-- psci sysreset 0 [ ] psci-sysreset | `-- psci-sysreset .... blk 0 [ + ] mmc_blk | | `-- mmc@58005000.blk usb 0 [ ] ehci_generic | |-- usb@5800d000 video 0 [ ] stm32_display | |-- display-controller@5a001000 ....
Ethernet and phy driver are both unbinded. Now we can bind the usb_eher to the usb class
STM32MP> bind usb 0 usb_ether STM32MP> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver firmware 0 [ ] psci |-- psci sysreset 0 [ ] psci-sysreset | `-- psci-sysreset .... blk 0 [ + ] mmc_blk | | `-- mmc@58005000.blk usb 0 [ ] ehci_generic | |-- usb@5800d000 ethernet 0 [ ] usb_ether | | `-- usb_ether video 0 [ ] stm32_display | |-- display-controller@5a001000 ....
usb_ether is now binded. As example, if you can then use some ethernet command as dhcp or ping :
STM32MP> dhcp using dwc2-udc, OUT ep2out-bulk IN ep1in-bulk STATUS ep3in-int MAC de:ad:be:ef:00:01 HOST MAC de:ad:be:ef:00:00 RNDIS ready high speed config #2: 2 mA, Ethernet Gadget, using RNDIS USB RNDIS network up! BOOTP broadcast 1
I have enabled: CONFIG_DM_USB=y CONFIG_USB_GADGET=y CONFIG_USB_ETHER=y
In my case i enabled also CONFIG_USB_ETH_RNDIS=y
Patrice
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