converting IMX6 board to DM_ETH and DM_USB - usb_ether gadget support

Tim Harvey tharvey at gateworks.com
Thu Feb 10 01:45:12 CET 2022


On Mon, Feb 7, 2022 at 12:47 AM Heiko Schocher <hs at denx.de> wrote:
>
> Hello Tim,
>
> On 28.01.22 07:06, Heiko Schocher wrote:
> > Hello Tim,
> >
> > On 28.01.22 01:20, Tim Harvey wrote:
> >> On Fri, Jan 14, 2022 at 6:55 AM Heiko Schocher <hs at denx.de> wrote:
> >>>
> >>> Hello Tim,
> >>>
> >>> On 25.02.21 02:21, Tim Harvey wrote:
> >>>> Greetings,
> >>>>
> >>>> I'm trying to convert the gwventana board support to DM_ETH and DM_USB
> >>>> and one item I have not resolved yet is USB Ethernet gadget support.
> >>>>
> >>>> For non-dm a call to 'usb_eth_initialize' creates a usb_ether gadget
> >>>> that can be used for ethernet communication between the IMX6 OTG
> >>>> controller in device mode to a USB host. How is that accomplished via
> >>>> dm?
> >>>>
> >>>> I find that drivers/usb/gadget/ether.c has dm support but it would
> >>>> appear that a controller of UCLASS_USB_GADGET_GENERIC must bind for it
> >>>> to work yet I don't see how this works with CI_UDC.
> >>>>
> >>>> Other IMX6 boards that have gone through dm conversion have simply
> >>>> dropped the call to usb_eth_initialize and I don't see what else they
> >>>> enable that provides this functionality.
> >>>>
> >>>> Any ideas?
> >>>
> >>> Late ... but I stumbled just over the same problem... do you have solved
> >>> it?
> >>>
> >>> I just tried this on an imx6ull based board and get it not fully working,
> >>> but usb ethernet with DM_ETH enabled at least starts for me...
> >>>
> >>>
> >>> => setenv ethact usb_ether
> >>> => setenv ipaddr 192.168.7.2
> >>>
> >>> The magic call for me is:
> >>>
> >>> => bind usb 0 usb_ether
> >>>
> >>>
> >>> After this I see in "dm tree" output:
> >>>
> >>>  simple_bus    5  [ + ]   simple_bus            |   |-- aips-bus at 2100000
> >>>  usb           0  [   ]   ehci_mx6              |   |   |-- usb at 2184000
> >>>  eth           1  [   ]   usb_ether             |   |   |   `-- usb_ether
> >>>
> >>> And issuing a ping starts usb_ether with (some DBG are enabled)
> >>>
> >>> => ping 192.168.71.
> >>> using ci_udc, OUT ep2out-bulk IN ep1in-bulk STATUS ep3in-int
> >>> MAC 8e:79:6a:94:5f:09
> >>> HOST MAC 5a:d1:77:da:0e:7a
> >>> RNDIS ready
> >>> -- suspend --
> >>> -- reset --
> >>> -- portchange 2 High
> >>> handle setup GET_DESCRIPTOR, 80, 6 index 0 value 100 length 40
> >>> handle_setup: Set ep0 to IN for Data Stage
> >>> [...]
> >>> -- reset --
> >>> -- portchange 2 High
> >>> [...]
> >>> ci_ep_enable: from 512 to 16
> >>> ci_ep_enable: num=3 maxpacket=16
> >>> ci_ep_enable: num=1 maxpacket=512
> >>> ci_ep_enable: num=2 maxpacket=512
> >>> high speed config #2: 2 mA, Ethernet Gadget, using RNDIS
> >>> [...]
> >>>
> >>> [remark] until here same log as for the case with DM_ETH not enabled
> >>>
> >>> [...]
> >>> ept0 out req 9bf78be0, complete 0
> >>> handle setup GET_STATUS, 21, 0 index 0 value 0 length 18
> >>> handle_setup: Set ep0 to OUT for Data Stage
> >>> ept0 out pre-queue req 9bf78be0, buffer 9bf91e80
> >>> ept0 out queue len 18, req 9bf78be0, buffer 9bf91e80
> >>> handle_setup: end status: 0
> >>> ept0 out req 9bf78be0, complete 0
> >>>
> >>>
> >>> And than the board makes a reset (no crash dump)
> >>>
> >>> on the other side I see:
> >>>
> >>> [2114399.914244] usb 1-1.3.1.2: new high-speed USB device number 46 using dwc_otg
> >>> [2114400.311239] usb 1-1.3.1.2: config 1 has 0 interfaces, different from the descriptor's value: 1
> >>> [2114400.436155] usb 1-1.3.1.2: New USB device found, idVendor=0525, idProduct=a4a5, bcdDevice= 3.21
> >>> [2114400.436175] usb 1-1.3.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> >>> [2114400.436190] usb 1-1.3.1.2: Product: RNDIS/Ethernet Gadget
> >>> [2114400.436204] usb 1-1.3.1.2: Manufacturer: U-Boot
> >>> [2114400.569248] usb-storage 1-1.3.1.2:2.0: USB Mass Storage device detected
> >>> [2114400.569721] usb-storage 1-1.3.1.2:2.0: Quirks match for vid 0525 pid a4a5: 10000
> >>> [2114400.597702] rndis_host 1-1.3.1.2:2.0: RNDIS init failed, -71
> >>> [2114400.597799] rndis_host: probe of 1-1.3.1.2:2.0 failed with error -71
> >>> [2114400.598336] rndis_wlan 1-1.3.1.2:2.0: RNDIS init failed, -71
> >>> [2114400.598591] rndis_wlan: probe of 1-1.3.1.2:2.0 failed with error -71
> >>> [2114400.599839] usb-storage 1-1.3.1.2:2.1: USB Mass Storage device detected
> >>> [2114400.600254] usb-storage 1-1.3.1.2:2.1: Quirks match for vid 0525 pid a4a5: 10000
> >>> [2114400.656387] usb 1-1.3.1.2: USB disconnect, device number 46
> >>>
> >>> If I disable DM_ETH... usb_ether works fine on the board ...
> >>>
> >>> Any ideas?
> >>>
> >>
> >> Heiko,
> >>
> >> Sorry for the late reply - I've been out of the office and unable to
> >
> > No problem, thanks for your time!
> >
> >> test. I don't know if/how I got around this issue but would love to
> >> compare notes.
> >>
> >> On a gwventana IMX6 board with emmc and a USB OTG connector
> >> USB_MASS_STORAGE gadget works via 'ums 0 mmc 0'.
> >
> > okay, good hint.
> >
> >> I'm not familiar with the bind method you are using but reading about
> >> it in doc/develop/driver-model/bind.rst it seems like a nice generic
> >> way to bind to various USB gadget devices. What configs do you need
> >> enabled for the usb_ether class and did you end up getting this to
> >> work? What other gadgets are available like this?
> >
> > I just stumbled over the doc and tried the bind approach, which I think
> > is a good way ... just need to find out, what is missing.. ideas
> > are welcome!
> >
> > I had not yet time to dig again into it, hope I find time for it next
> > week.
>
> I have it now working on imx6ull based board... only one big hack...
> Now I see bootmessage:
>
> │   │    <> Net:   eth2: usb_ether0, eth0: ethernet at 2188000
>
> => setenv ethact usb_ether
> => setenv ipaddr 192.168.7.3
> => setenv serverip 192.168.7.1
> => ping 192.168.7.1
> using ci_udc, OUT ep2out-bulk IN ep1in-bulk STATUS ep3in-int
> MAC 8e:79:6a:94:5f:09
> HOST MAC 5a:d1:77:da:0e:7a
> RNDIS ready
> high speed config #2: 2 mA, Ethernet Gadget, using RNDIS
> USB RNDIS network up!
> Using usb_ether0 device
> host 192.168.7.1 is alive
> =>
>
> And I can switch to fec based ethernet "ethernet at 2188000" with
>
> => setenv ethact ethernet at 2188000
>
>
> What changes are needed now to get it working:
>
> - 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),
>
> - Added in your boards u-boot.dts:
>
> +&usbotg1 {
> +       usb_ether0 {
> +               compatible = "gadget,usb_ether";
> +               status = "okay";
> +       };
> +};
>

Heiko,'

I was of the opinion that using the 'bind' command would allow you to
avoid the need to hard-code this but I would agree that without this
the driver never probes.

> (If DTS based approach is not preffered, it works also to call usb_ether_init()
>  from board code, but you need to replace in ether.c UCLASS_USB_GADGET_GENERIC
>  with UCLASS_USB or make the usb driver to support UCLASS_USB_GADGET_GENERIC)

Previously you reported that you would use 'bind usb 0 usb_ether' to
get the driver to probe. I assume you had some hacks to make that
work?

I would think the idea would be you could have a number of useful
gadget drivers such as ums and usb_ether that you could bind then use.
Perhaps usb_ether needs a command to probe it kind of like how the ums
command registers it.

>
> - Add in defconfig:
>
> +CONFIG_USB_ETHER=y
>
> - remove in board code board_eth_init()
>
> - and now the devil patch:
>
> diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
> index 0924a575f5..f0bb58b4fc 100644
> --- a/drivers/core/device-remove.c
> +++ b/drivers/core/device-remove.c
> @@ -169,6 +169,9 @@ int device_remove(struct udevice *dev, uint flags)
>         if (!(dev->flags & DM_FLAG_ACTIVATED))
>                 return 0;
>
> +       if (!strncmp(dev->name, "usb_ether", 8))
> +               return 0;
> +
>         drv = dev->driver;
>         assert(drv);
>
>
>
> I did not (yet) found out, why before using the driver first device_remove()
> is called (for usb and usb_ether device) and later only probe() for usb is called,
> so never probe() for ether is called again, which breaks ether gadget usage.
> (On boot probe() foer ether.c is called ...)
>

It looks like usb_eth_start calls usb_gadget_register_driver which is
what is removing the usb host device which removes its children
causing this.

> May someone has an idea ? And may I get more time for digging into it...
>
> Could you try the above steps on your board?

I get the same results as you on a imx6q-ventana board. I also noticed
on the Linux host I had the OTG connected to I saw:
[9272549.212430] usb 3-4.4: new high-speed USB device number 68 using xhci_hcd
[9272549.312998] usb 3-4.4: New USB device found, idVendor=0525,
idProduct=a4a5, bcdDevice= 3.21
[9272549.313001] usb 3-4.4: New USB device strings: Mfr=1, Product=2,
SerialNumber=0
[9272549.313002] usb 3-4.4: Product: Ethernet Gadget
[9272549.313004] usb 3-4.4: Manufacturer: Gateworks
[9272549.319857] usb-storage 3-4.4:1.0: USB Mass Storage device detected
[9272549.319958] usb-storage 3-4.4:1.0: Quirks match for vid 0525 pid
a4a5: 10000
[9272549.350083] cdc_ether 3-4.4:1.0 usb0: register 'cdc_ether' at
usb-0000:00:14.0-4.4, CDC Ethernet Device, de:ad:be:ef:00:00
[9272549.367280] cdc_ether 3-4.4:1.0 enp0s20u4u4: renamed from usb0

which I believe matches what you see. I guess the reason for the 'USB
Mass Storage device detected' is that we are using a PID of 0xa4a5
which is identified in Linux:
drivers/usb/gadget/legacy/mass_storage.c:#define FSG_PRODUCT_ID 0xa4a5
 /* Linux-USB File-backed Storage Gadget */
drivers/usb/gadget/legacy/tcm_usb_gadget.c:#define UAS_PRODUCT_ID
 0xa4a5  /* Linux-USB File-backed Storage Gadget */
drivers/usb/storage/unusual_devs.h:COMPLIANT_DEV(0x0525, 0xa4a5, 0x0000, 0x9999,

Best Regards,

Tim


More information about the U-Boot mailing list