mirror of
https://github.com/FUjr/gl-infra-builder.git
synced 2025-12-16 09:10:02 +00:00
309 lines
13 KiB
Diff
309 lines
13 KiB
Diff
From 388d6f8e4ce6f79a2db19624e9fb48225bcb367f Mon Sep 17 00:00:00 2001
|
|
From: lincolnzh <hongjian.zhang@gl-inet.com>
|
|
Date: Sat, 5 Nov 2022 16:22:05 +0800
|
|
Subject: [PATCH] add-modem-support
|
|
|
|
---
|
|
.../hack-5.10/781-add-modem-support.patch | 289 ++++++++++++++++++
|
|
1 file changed, 289 insertions(+)
|
|
create mode 100644 target/linux/generic/hack-5.10/781-add-modem-support.patch
|
|
|
|
diff --git a/target/linux/generic/hack-5.10/781-add-modem-support.patch b/target/linux/generic/hack-5.10/781-add-modem-support.patch
|
|
new file mode 100644
|
|
index 0000000000..fb8027d366
|
|
--- /dev/null
|
|
+++ b/target/linux/generic/hack-5.10/781-add-modem-support.patch
|
|
@@ -0,0 +1,289 @@
|
|
+Index: b/drivers/net/usb/qmi_wwan.c
|
|
+===================================================================
|
|
+--- a/drivers/net/usb/qmi_wwan.c 2022-11-05 10:51:47.850881548 +0800
|
|
++++ b/drivers/net/usb/qmi_wwan.c 2022-11-05 14:22:07.494961215 +0800
|
|
+@@ -485,6 +485,24 @@ static const u8 default_modem_addr[ETH_A
|
|
+
|
|
+ static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00};
|
|
+
|
|
++#if 1 //Added by Quectel
|
|
++#include <linux/etherdevice.h>
|
|
++struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
|
|
++{
|
|
++ if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C))
|
|
++ return skb;
|
|
++ // Skip Ethernet header from message
|
|
++ if (skb_pull(skb, ETH_HLEN)) {
|
|
++ return skb;
|
|
++ } else {
|
|
++ dev_err(&dev->intf->dev, "Packet Dropped ");
|
|
++ }
|
|
++ // Filter the packet out, release it
|
|
++ dev_kfree_skb_any(skb);
|
|
++ return NULL;
|
|
++}
|
|
++#endif
|
|
++
|
|
+ /* Make up an ethernet header if the packet doesn't have one.
|
|
+ *
|
|
+ * A firmware bug common among several devices cause them to send raw
|
|
+@@ -779,6 +797,20 @@ static int qmi_wwan_bind(struct usbnet *
|
|
+ }
|
|
+ dev->net->netdev_ops = &qmi_wwan_netdev_ops;
|
|
+ dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
|
|
++#if 1 //Added by Quectel
|
|
++ if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
|
|
++ dev_info(&intf->dev, "QuectelEC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96&AG35 work on RawIP mode\n");
|
|
++ dev->net->flags |= IFF_NOARP;
|
|
++ usb_control_msg(
|
|
++ interface_to_usbdev(intf),
|
|
++ usb_sndctrlpipe(interface_to_usbdev(intf), 0),
|
|
++ 0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE
|
|
++ 0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
|
|
++ 1, //active CDC DTR
|
|
++ intf->cur_altsetting->desc.bInterfaceNumber,
|
|
++ NULL, 0, 100);
|
|
++ }
|
|
++#endif
|
|
+ err:
|
|
+ return status;
|
|
+ }
|
|
+@@ -869,7 +901,10 @@ static const struct driver_info qmi_wwan
|
|
+ .bind = qmi_wwan_bind,
|
|
+ .unbind = qmi_wwan_unbind,
|
|
+ .manage_power = qmi_wwan_manage_power,
|
|
+- .rx_fixup = qmi_wwan_rx_fixup,
|
|
++ #if 1 //Added by Quectel
|
|
++ .tx_fixup = qmi_wwan_tx_fixup,
|
|
++ .rx_fixup = qmi_wwan_rx_fixup,
|
|
++ #endif
|
|
+ };
|
|
+
|
|
+ static const struct driver_info qmi_wwan_info_quirk_dtr = {
|
|
+@@ -916,6 +951,17 @@ static const struct driver_info qmi_wwan
|
|
+ .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr
|
|
+
|
|
+ static const struct usb_device_id products[] = {
|
|
++#if 1 //Added by Quectel
|
|
++ { QMI_FIXED_INTF(0x05C6, 0x9003, 4) }, /* Quectel UC20 */
|
|
++ { QMI_FIXED_INTF(0x2C7C, 0x0125, 4) }, /* Quectel EC25 */
|
|
++ { QMI_FIXED_INTF(0x2C7C, 0x0121, 4) }, /* Quectel EC21 */
|
|
++ { QMI_FIXED_INTF(0x05C6, 0x9215, 4) }, /* Quectel EC20 */
|
|
++ { QMI_FIXED_INTF(0x2C7C, 0x0191, 4) }, /* Quectel EG91 */
|
|
++ { QMI_FIXED_INTF(0x2C7C, 0x0195, 4) }, /* Quectel EG95 */
|
|
++ { QMI_FIXED_INTF(0x2C7C, 0x0306, 4) }, /* Quectel EG06/EP06/EM06 */
|
|
++ { QMI_FIXED_INTF(0x2C7C, 0x0296, 4) }, /* Quectel BG96 */
|
|
++ { QMI_FIXED_INTF(0x2C7C, 0x0435, 4) }, /* Quectel AG35 */
|
|
++#endif
|
|
+ /* 1. CDC ECM like devices match on the control interface */
|
|
+ { /* Huawei E392, E398 and possibly others sharing both device id and more... */
|
|
+ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 9),
|
|
+@@ -1381,7 +1427,6 @@ static const struct usb_device_id produc
|
|
+ {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */
|
|
+ {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */
|
|
+ {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */
|
|
+- {QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
|
|
+ {QMI_FIXED_INTF(0x05c6, 0x9215, 4)}, /* Quectel EC20 Mini PCIe */
|
|
+ {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */
|
|
+ {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */
|
|
+Index: b/drivers/usb/serial/option.c
|
|
+===================================================================
|
|
+--- a/drivers/usb/serial/option.c 2022-11-05 10:51:47.854881501 +0800
|
|
++++ b/drivers/usb/serial/option.c 2022-11-05 14:31:45.431899880 +0800
|
|
+@@ -579,6 +579,23 @@ static void option_instat_callback(struc
|
|
+ #define WETELECOM_PRODUCT_6802 0x6802
|
|
+ #define WETELECOM_PRODUCT_WMD300 0x6803
|
|
+
|
|
++#define LONGSUNG_PRODUCT_U9300C 0x9b3c
|
|
++
|
|
++/* FORGE PRODUCT */
|
|
++#define FORGE_VENDOR_ID 0x05c6
|
|
++
|
|
++#define FORGE_PRODUCT_SLM750 0xf601
|
|
++
|
|
++/* NODECOM PRODUCT */
|
|
++#define NODECOM_VENDOR_ID 0x1508
|
|
++
|
|
++#define NODECOM_PRODUCT_NL660 0x1001
|
|
++
|
|
++/* NEOWAY PRODUCT */
|
|
++#define NEOWAY_VENDOR_ID 0x2949
|
|
++
|
|
++#define NEOWAY_PRODUCT_N720 0x8243
|
|
++
|
|
+ /* OPPO products */
|
|
+ #define OPPO_VENDOR_ID 0x22d9
|
|
+ #define OPPO_PRODUCT_R11 0x276c
|
|
+@@ -603,6 +620,29 @@ static void option_instat_callback(struc
|
|
+
|
|
+
|
|
+ static const struct usb_device_id option_ids[] = {
|
|
++#if 1 //Added by Quectel
|
|
++ { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
|
|
++ { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
|
|
++ { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0700) }, /* Quectel BG95 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
|
|
++ { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */
|
|
++ { USB_DEVICE(0x2C7C, 0x6026) }, /* Quectel EC200t */
|
|
++#endif
|
|
++ { USB_DEVICE(0x19d2, 0x0536) },/* MZ386 */
|
|
++ { USB_DEVICE(0x19d2, 0x0117) },
|
|
++ { USB_DEVICE(0x19d2, 0x0199) },
|
|
++ { USB_DEVICE(0x19d2, 0x1476) },
|
|
++ { USB_DEVICE(LONGCHEER_VENDOR_ID, LONGSUNG_PRODUCT_U9300C) },
|
|
++ { USB_DEVICE(FORGE_VENDOR_ID, FORGE_PRODUCT_SLM750) },
|
|
++ { USB_DEVICE(NODECOM_VENDOR_ID, NODECOM_PRODUCT_NL660) },
|
|
++ { USB_DEVICE(NEOWAY_VENDOR_ID, NEOWAY_PRODUCT_N720) },
|
|
++
|
|
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
|
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
|
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
|
|
+@@ -2218,6 +2258,9 @@ static struct usb_serial_driver option_1
|
|
+ #ifdef CONFIG_PM
|
|
+ .suspend = usb_wwan_suspend,
|
|
+ .resume = usb_wwan_resume,
|
|
++#if 1 //Added by Quectel
|
|
++ .reset_resume = usb_wwan_resume,
|
|
++#endif
|
|
+ #endif
|
|
+ };
|
|
+
|
|
+@@ -2240,6 +2283,7 @@ static int option_probe(struct usb_seria
|
|
+ {
|
|
+ struct usb_interface_descriptor *iface_desc =
|
|
+ &serial->interface->cur_altsetting->desc;
|
|
++ struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
|
|
+ unsigned long device_flags = id->driver_info;
|
|
+
|
|
+ /* Never bind to the CD-Rom emulation interface */
|
|
+@@ -2261,9 +2305,84 @@ static int option_probe(struct usb_seria
|
|
+ if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2)
|
|
+ return -ENODEV;
|
|
+
|
|
+- /* Store the device flags so we can use them during attach. */
|
|
+- usb_set_serial_data(serial, (void *)device_flags);
|
|
+-
|
|
++#if 1 //Added by Quectel
|
|
++ //Quectel UC20's interface 4 can be used as USB network device
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && \
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9003) \
|
|
++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
|
|
++ return -ENODEV;
|
|
++ //Quectel EC20's interface 4 can be used as USB network device
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && \
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9215) \
|
|
++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
|
|
++ return -ENODEV;
|
|
++ //Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as USB network device
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C) && \
|
|
++ serial->dev->descriptor.idProduct != cpu_to_le16(0x6026) \
|
|
++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
|
|
++ return -ENODEV;
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C) && \
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x6026) \
|
|
++ && serial->interface->cur_altsetting->desc.bInterfaceNumber<= 1)
|
|
++ return -ENODEV;
|
|
++#endif
|
|
++#if 1 //Added by Quectel
|
|
++ //For USB Auto Suspend
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9090)) {
|
|
++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);
|
|
++ usb_enable_autosuspend(serial->dev);
|
|
++ }
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)) {
|
|
++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);
|
|
++ usb_enable_autosuspend(serial->dev);
|
|
++ }
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)) {
|
|
++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);
|
|
++ usb_set_serial_data(serial, (void *)device_flags);
|
|
++ usb_enable_autosuspend(serial->dev);
|
|
++ }
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
|
|
++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);
|
|
++ usb_enable_autosuspend(serial->dev);
|
|
++ }
|
|
++#endif
|
|
++#if 1 //Added by Quectel
|
|
++ //For USB Remote Wakeup
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9090)) {
|
|
++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup
|
|
++ }
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)) {
|
|
++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup
|
|
++ }
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)) {
|
|
++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup
|
|
++ }
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
|
|
++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup
|
|
++ }
|
|
++#endif
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1476) &&
|
|
++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 3)
|
|
++ return -ENODEV;
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1476) &&
|
|
++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 4)
|
|
++ return -ENODEV;
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1509) &&
|
|
++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 4)
|
|
++ return -ENODEV;
|
|
++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) &&
|
|
++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1509) &&
|
|
++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 5)
|
|
++ return -ENODEV;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+Index: b/drivers/usb/serial/qcserial.c
|
|
+===================================================================
|
|
+--- a/drivers/usb/serial/qcserial.c 2022-09-28 17:10:41.000000000 +0800
|
|
++++ b/drivers/usb/serial/qcserial.c 2022-11-05 14:33:03.286949351 +0800
|
|
+@@ -88,7 +88,6 @@ static const struct usb_device_id id_tab
|
|
+ {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */
|
|
+ {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */
|
|
+ {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */
|
|
+- {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
|
|
+ {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */
|
|
+ {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */
|
|
+ {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */
|
|
+Index: b/drivers/usb/serial/usb_wwan.c
|
|
+===================================================================
|
|
+--- a/drivers/usb/serial/usb_wwan.c 2022-09-28 17:10:41.000000000 +0800
|
|
++++ b/drivers/usb/serial/usb_wwan.c 2022-11-05 14:35:10.057401819 +0800
|
|
+@@ -478,6 +478,20 @@ static struct urb *usb_wwan_setup_urb(st
|
|
+ usb_sndbulkpipe(serial->dev, endpoint) | dir,
|
|
+ buf, len, callback, ctx);
|
|
+
|
|
++#if 1 //Added by Quectel for zero packet
|
|
++ if (dir == USB_DIR_OUT) {
|
|
++ struct usb_device_descriptor *desc = &serial->dev->descriptor;
|
|
++ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
|
|
++ urb->transfer_flags |= URB_ZERO_PACKET;
|
|
++ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
|
|
++ urb->transfer_flags |= URB_ZERO_PACKET;
|
|
++ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
|
|
++ urb->transfer_flags |= URB_ZERO_PACKET;
|
|
++ if (desc->idVendor == cpu_to_le16(0x2C7C))
|
|
++ urb->transfer_flags |= URB_ZERO_PACKET;
|
|
++ }
|
|
++#endif
|
|
++
|
|
+ if (intfdata->use_zlp && dir == USB_DIR_OUT)
|
|
+ urb->transfer_flags |= URB_ZERO_PACKET;
|
|
+
|
|
--
|
|
2.17.1
|
|
|