On Fri, Mar 31, 2023 at 06:28:14PM +1000, David Gwynne wrote:
> 
> i got a quectel ec25 to play with recently, and got side tracked
> thinking the usb controller was not talking to the modem correctly
> because when it attached it looked like this:
> 
> umb0 at uhub2 port 1 "Android Android" rev 2.00/3.18 addr
> umb0: missing MBIM descriptor
> 
> and the usb descriptors looked weird. i thought clocking or power
> or something was wrong. turns out that the host controller is fine,
> but the devices are complicated because they're based on the qualcomm
> qmi stuff, and in a lot of cases openbsd could do a better job of
> talking to them.

When I added support for ec25, I had already set it to mbim mode on Linux.
Because I didn't want to use any other mode (ppp & qmi, ecm), I didn't notice 
the error message that would appear if it was in qmi mode.
It wasn't until dlg@ brought up this issue that I became aware of its existence.

> fortunately quectel seem to do a better job than a lot of other vendors
> usign the qmi stuff and try to make all their products support a common
> set of features. their linux driver guide is also very good, and is very
> clear about what to expect on these devices. basically, these modems
> are supposed to present a bunch of umsm interfaces, and at least
> one network interface. the usb network interface type can be changed by
> talking to the umsm interfaces, and could be qmi, ecm, or mbim.
> 
> openbsd is currently hardcoded to attach umb(4) to these devices, and it
> will attach only umb at the device level. this means that the usms
> interfaces are hidden, and if the device is not in mbim mode then umb
> complains that the descriptors dont look right. which is fair.
> 
> this diff tweaks the umsm and umb matches to follow the quectel doco.
> this allos umsm to attach to the correct interfaces, but leaves the
> network interface alone. this allows umb to attach to the network
> interface if the modem is configured in mbim mode based on class,
> otherwise ugen gets to attach to it. if we ever get qmi or ecm drivers,
> this will allow them to attach instead of ugen.
> 
> eg, with these diffs and when the modem is in qmi mode:
> 
> umsm0 at uhub2 port 1 configuration 1 interface 0 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom0 at umsm0
> umsm1 at uhub2 port 1 configuration 1 interface 1 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom1 at umsm1
> umsm2 at uhub2 port 1 configuration 1 interface 2 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom2 at umsm2
> umsm3 at uhub2 port 1 configuration 1 interface 3 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom3 at umsm3
> ugen0 at uhub2 port 1 configuration 1 "Android Android" rev 2.00/3.18 addr 2
> 
> now that umsm is exposed i can tell it to expose mbim instead. next time
> it attaches i see this:
> 
> umsm0 at uhub2 port 1 configuration 1 interface 0 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom0 at umsm0
> umsm1 at uhub2 port 1 configuration 1 interface 1 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom1 at umsm1
> umsm2 at uhub2 port 1 configuration 1 interface 2 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom2 at umsm2
> umsm3 at uhub2 port 1 configuration 1 interface 3 "Android Android" rev 
> 2.00/3.18 addr 2
> ucom3 at umsm3
> umb0 at uhub2 port 1 configuration 1 interface 4 "Android Android" rev 
> 2.00/3.18 addr 2
> 
> and umb0 shows up in ifconfig and lets me configure an apn and stuff.
> 
> thanks to kevlo for helping me out and testing.
> 
> a follow up diff could (should) add the rest of the quectel usbids
> listed in their doco.
> 
> the umsm chunk looks big because i made it return early if there's no
> umsm_lookup value, which lets me reduce the indentation of most of the
> code.
> 
> ok?

With this patch, I'm able to send AT commands to ec25 modem without the
umsm attachments.

ok kevlo@, thanks!

> Index: if_umb.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/if_umb.c,v
> retrieving revision 1.49
> diff -u -p -r1.49 if_umb.c
> --- if_umb.c  11 Jan 2022 10:34:13 -0000      1.49
> +++ if_umb.c  31 Mar 2023 08:27:04 -0000
> @@ -238,13 +238,6 @@ const struct umb_quirk umb_quirks[] = {
>         UMATCH_VENDOR_PRODUCT
>       },
>  
> -     { { USB_VENDOR_QUECTEL, USB_PRODUCT_QUECTEL_EC25 },
> -       0,
> -       1,
> -       UMATCH_VENDOR_PRODUCT
> -     },
> -
> -
>       { { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_ME906S },
>         UMBFLG_NDP_AT_END,
>         3,
> Index: umsm.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/umsm.c,v
> retrieving revision 1.122
> diff -u -p -r1.122 umsm.c
> --- umsm.c    23 Aug 2022 08:12:30 -0000      1.122
> +++ umsm.c    31 Mar 2023 08:27:04 -0000
> @@ -293,53 +293,66 @@ int
>  umsm_match(struct device *parent, void *match, void *aux)
>  {
>       struct usb_attach_arg *uaa = aux;
> +     const struct umsm_type *umsmt;
>       usb_interface_descriptor_t *id;
>       uint16_t flag;
>  
>       if (uaa->iface == NULL)
>               return UMATCH_NONE;
>  
> +     umsmt = umsm_lookup(uaa->vendor, uaa->product);
> +     if (umsmt == NULL)
> +             return UMATCH_NONE;
> +
>       /*
>        * Some devices (eg Huawei E220) have multiple interfaces and some
>        * of them are of class umass. Don't claim ownership in such case.
>        */
> -     if (umsm_lookup(uaa->vendor, uaa->product) != NULL) {
> -             id = usbd_get_interface_descriptor(uaa->iface);
> -             flag = umsm_lookup(uaa->vendor, uaa->product)->umsm_flag;
> -
> -             if (id == NULL || id->bInterfaceClass == UICLASS_MASS) {
> -                     /*
> -                      * Some high-speed modems require special care.
> -                      */
> -                     if (flag & DEV_HUAWEI) {
> -                             if (uaa->ifaceno != 2)
> -                                     return UMATCH_VENDOR_IFACESUBCLASS;
> -                             else
> -                                     return UMATCH_NONE;
> -                     } else if (flag & DEV_UMASS) {
> -                             return UMATCH_VENDOR_IFACESUBCLASS;
> -                     } else if (flag & DEV_TRUINSTALL) {
> -                             return UMATCH_VENDOR_IFACESUBCLASS;
> -                     } else
> -                             return UMATCH_NONE;
> +
> +     id = usbd_get_interface_descriptor(uaa->iface);
> +     flag = umsmt->umsm_flag;
> +
> +     if (id == NULL || id->bInterfaceClass == UICLASS_MASS) {
>               /*
> -              * Some devices have interfaces which fail to attach but in
> -              * addition seem to make the remaining interfaces unusable. Only
> -              * attach whitelisted interfaces in this case.
> +              * Some high-speed modems require special care.
>                */
> -             } else if ((uaa->vendor == USB_VENDOR_MEDIATEK &&
> -                         uaa->product == USB_PRODUCT_MEDIATEK_DC_4COM) &&
> -                        !(id->bInterfaceClass == UICLASS_VENDOR &&
> -                         ((id->bInterfaceSubClass == 0x02 &&
> -                           id->bInterfaceProtocol == 0x01) ||
> -                          (id->bInterfaceSubClass == 0x00 &&
> -                           id->bInterfaceProtocol == 0x00)))) {
> -                     return UMATCH_NONE;
> -             } else
> +             if (flag & DEV_HUAWEI) {
> +                     if (uaa->ifaceno != 2)
> +                             return UMATCH_VENDOR_IFACESUBCLASS;
> +                     else
> +                             return UMATCH_NONE;
> +             } else if (flag & DEV_UMASS) {
>                       return UMATCH_VENDOR_IFACESUBCLASS;
> +             } else if (flag & DEV_TRUINSTALL) {
> +                     return UMATCH_VENDOR_IFACESUBCLASS;
> +             } else
> +                     return UMATCH_NONE;
> +     /*
> +      * Some devices have interfaces which fail to attach but in
> +      * addition seem to make the remaining interfaces unusable. Only
> +      * attach whitelisted interfaces in this case.
> +      */
> +     } else if ((uaa->vendor == USB_VENDOR_MEDIATEK &&
> +                 uaa->product == USB_PRODUCT_MEDIATEK_DC_4COM) &&
> +                !(id->bInterfaceClass == UICLASS_VENDOR &&
> +                 ((id->bInterfaceSubClass == 0x02 &&
> +                   id->bInterfaceProtocol == 0x01) ||
> +                  (id->bInterfaceSubClass == 0x00 &&
> +                   id->bInterfaceProtocol == 0x00)))) {
> +             return UMATCH_NONE;
> +
> +     /* See the Quectel LTE&5G Linux USB Driver User Guide */ 
> +     } else if (uaa->vendor == USB_VENDOR_QUECTEL) {
> +             /* Some interfaces can be used as network devices */
> +             if (id->bInterfaceClass != UICLASS_VENDOR)
> +                     return UMATCH_NONE;
> +
> +             /* Interface 4 can be used as a network device */
> +             if (uaa->ifaceno >= 4)
> +                     return UMATCH_NONE;
>       }
>  
> -     return UMATCH_NONE;
> +     return UMATCH_VENDOR_IFACESUBCLASS;
>  }
>  
>  void
> 

Reply via email to