summaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorKristian Evensen <kristian.evensen@gmail.com>2019-03-02 07:32:26 -0500
committerDavid S. Miller <davem@davemloft.net>2019-03-04 00:39:50 -0500
commit822e44b45eb991c63487c5e2ce7d636411870a8d (patch)
treedb477b96f3f974400abb9bc8f07ab86a5b255382 /drivers/net/usb
parent95150f29ae480276e76368cdf8a9524b5a96c0ca (diff)
qmi_wwan: Add support for Quectel EG12/EM12
Quectel EG12 (module)/EM12 (M.2 card) is a Cat. 12 LTE modem. The modem behaves in the same way as the EP06, so the "set DTR"-quirk must be applied and the diagnostic-interface check performed. Since the diagnostic-check now applies to more modems, I have renamed the function from quectel_ep06_diag_detected() to quectel_diag_detected(). Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com> Acked-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/qmi_wwan.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 18af2f8eee96..74bebbdb4b15 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -976,6 +976,13 @@ static const struct usb_device_id products[] = {
976 0xff), 976 0xff),
977 .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr, 977 .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr,
978 }, 978 },
979 { /* Quectel EG12/EM12 */
980 USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x0512,
981 USB_CLASS_VENDOR_SPEC,
982 USB_SUBCLASS_VENDOR_SPEC,
983 0xff),
984 .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr,
985 },
979 986
980 /* 3. Combined interface devices matching on interface number */ 987 /* 3. Combined interface devices matching on interface number */
981 {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ 988 {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
@@ -1343,17 +1350,20 @@ static bool quectel_ec20_detected(struct usb_interface *intf)
1343 return false; 1350 return false;
1344} 1351}
1345 1352
1346static bool quectel_ep06_diag_detected(struct usb_interface *intf) 1353static bool quectel_diag_detected(struct usb_interface *intf)
1347{ 1354{
1348 struct usb_device *dev = interface_to_usbdev(intf); 1355 struct usb_device *dev = interface_to_usbdev(intf);
1349 struct usb_interface_descriptor intf_desc = intf->cur_altsetting->desc; 1356 struct usb_interface_descriptor intf_desc = intf->cur_altsetting->desc;
1357 u16 id_vendor = le16_to_cpu(dev->descriptor.idVendor);
1358 u16 id_product = le16_to_cpu(dev->descriptor.idProduct);
1350 1359
1351 if (le16_to_cpu(dev->descriptor.idVendor) == 0x2c7c && 1360 if (id_vendor != 0x2c7c || intf_desc.bNumEndpoints != 2)
1352 le16_to_cpu(dev->descriptor.idProduct) == 0x0306 && 1361 return false;
1353 intf_desc.bNumEndpoints == 2)
1354 return true;
1355 1362
1356 return false; 1363 if (id_product == 0x0306 || id_product == 0x0512)
1364 return true;
1365 else
1366 return false;
1357} 1367}
1358 1368
1359static int qmi_wwan_probe(struct usb_interface *intf, 1369static int qmi_wwan_probe(struct usb_interface *intf,
@@ -1390,13 +1400,13 @@ static int qmi_wwan_probe(struct usb_interface *intf,
1390 return -ENODEV; 1400 return -ENODEV;
1391 } 1401 }
1392 1402
1393 /* Quectel EP06/EM06/EG06 supports dynamic interface configuration, so 1403 /* Several Quectel modems supports dynamic interface configuration, so
1394 * we need to match on class/subclass/protocol. These values are 1404 * we need to match on class/subclass/protocol. These values are
1395 * identical for the diagnostic- and QMI-interface, but bNumEndpoints is 1405 * identical for the diagnostic- and QMI-interface, but bNumEndpoints is
1396 * different. Ignore the current interface if the number of endpoints 1406 * different. Ignore the current interface if the number of endpoints
1397 * the number for the diag interface (two). 1407 * the number for the diag interface (two).
1398 */ 1408 */
1399 if (quectel_ep06_diag_detected(intf)) 1409 if (quectel_diag_detected(intf))
1400 return -ENODEV; 1410 return -ENODEV;
1401 1411
1402 return usbnet_probe(intf, id); 1412 return usbnet_probe(intf, id);