enum qmi_wwan_quirks {
        QMI_WWAN_QUIRK_DTR = 1 << 0,    /* needs "set DTR" request */
-       QMI_WWAN_QUIRK_QUECTEL_DYNCFG = 1 << 1, /* check num. endpoints */
 };
 
 struct qmimux_hdr {
        .data           = QMI_WWAN_QUIRK_DTR,
 };
 
-static const struct driver_info        qmi_wwan_info_quirk_quectel_dyncfg = {
-       .description    = "WWAN/QMI device",
-       .flags          = FLAG_WWAN | FLAG_SEND_ZLP,
-       .bind           = qmi_wwan_bind,
-       .unbind         = qmi_wwan_unbind,
-       .manage_power   = qmi_wwan_manage_power,
-       .rx_fixup       = qmi_wwan_rx_fixup,
-       .data           = QMI_WWAN_QUIRK_DTR | QMI_WWAN_QUIRK_QUECTEL_DYNCFG,
-};
-
 #define HUAWEI_VENDOR_ID       0x12D1
 
 /* map QMI/wwan function by a fixed interface number */
 #define QMI_GOBI_DEVICE(vend, prod) \
        QMI_FIXED_INTF(vend, prod, 0)
 
-/* Quectel does not use fixed interface numbers on at least some of their
- * devices. We need to check the number of endpoints to ensure that we bind to
- * the correct interface.
+/* Many devices have QMI and DIAG functions which are distinguishable
+ * from other vendor specific functions by class, subclass and
+ * protocol all being 0xff. The DIAG function has exactly 2 endpoints
+ * and is silently rejected when probed.
+ *
+ * This makes it possible to match dynamically numbered QMI functions
+ * as seen on e.g. many Quectel modems.
  */
-#define QMI_QUIRK_QUECTEL_DYNCFG(vend, prod) \
+#define QMI_MATCH_FF_FF_FF(vend, prod) \
        USB_DEVICE_AND_INTERFACE_INFO(vend, prod, USB_CLASS_VENDOR_SPEC, \
                                      USB_SUBCLASS_VENDOR_SPEC, 0xff), \
-       .driver_info = (unsigned long)&qmi_wwan_info_quirk_quectel_dyncfg
+       .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr
 
 static const struct usb_device_id products[] = {
        /* 1. CDC ECM like devices match on the control interface */
                USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
                .driver_info = (unsigned long)&qmi_wwan_info,
        },
-       {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0125)},     /* Quectel EC25, EC20 R2.0  Mini PCIe */
-       {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0306)},     /* Quectel EP06/EG06/EM06 */
-       {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0512)},     /* Quectel EG12/EM12 */
-       {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0800)},     /* Quectel RM500Q-GL */
+       {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)},   /* Quectel EC25, EC20 R2.0  Mini PCIe */
+       {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)},   /* Quectel EP06/EG06/EM06 */
+       {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)},   /* Quectel EG12/EM12 */
+       {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)},   /* Quectel RM500Q-GL */
 
        /* 3. Combined interface devices matching on interface number */
        {QMI_FIXED_INTF(0x0408, 0xea42, 4)},    /* Yota / Megafon M100-1 */
 {
        struct usb_device_id *id = (struct usb_device_id *)prod;
        struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
-       const struct driver_info *info;
 
        /* Workaround to enable dynamic IDs.  This disables usbnet
         * blacklisting functionality.  Which, if required, can be
         * different. Ignore the current interface if the number of endpoints
         * equals the number for the diag interface (two).
         */
-       info = (void *)id->driver_info;
-
-       if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) {
-               if (desc->bNumEndpoints == 2)
-                       return -ENODEV;
-       }
+       if (desc->bNumEndpoints == 2)
+               return -ENODEV;
 
        return usbnet_probe(intf, id);
 }