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.

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?

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