converting IMX6 board to DM_ETH and DM_USB - usb_ether gadget support

Heiko Schocher hs at denx.de
Thu Feb 10 08:27:09 CET 2022


Hello Tim,

On 10.02.22 01:45, Tim Harvey wrote:
> 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?

Hmm... I wrote, that I tried the bind command and usb ethernet starts,
but it is not fully working ... problem was IIRC probe was not called.

> 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.

Yes, sounds as a nice approach. I first was happy, that I got it working,
okay with a not nice hack, we should investigate... but I hope it is not
to fare away from a nice solution?

>> - 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.

Exactly. usb_setup_ehci_gadget() removes the USB driver ... and so also
the (child) usb ethernet gadget ... and than only probes the usb driver,
so the underlying gadget gets not probed ... and dm flag DM_FLAG_ACTIVATED
is not set which prevents "ping" going further..

I have no idea yet, where usb ethernet gadget should be probed ...

Yes, for testing I also had this hack:

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 8773824e05..0babb6fa06 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -408,6 +408,19 @@ int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
                return ret;
        *ctlrp = dev_get_priv(dev);

+       if (1) {
+               struct udevice *pos, *n;
+
+               printf("%s: ------------- probing childs\n", __func__);
+               list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
+                       int ret;
+
+                       printf("%s: probe child : %p %s\n", __func__, pos, pos->name);
+                       ret = device_probe(pos);
+                       printf("%s: ret: %d\n", __func__, ret);
+               }
+       }
+
        return 0;
 }

but did not helped...

>> 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
> 

Thanks for testing.

bye,
Heiko
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52   Fax: +49-8142-66989-80   Email: hs at denx.de


More information about the U-Boot mailing list