1 Scope of Document This document describes 4G hardware design, support quectel ec20 4G module/ Simcom 7600 CE 4G module 2 Requiremen 2.1 Function Req ...
1 Scope of Document
This document describes 4G hardware design, support quectel ec20 4G module/ Simcom 7600 CE 4G module
2 Requiremen
2.1 Function Requirement
support ec20 qmi driver/ simcom 7600 ce ndis driver
2.2 Performance Requirement
NA
3 Hardware Overview
Figure 1 4g interface block diagram
4 Functional Description
4.1 Functional Block Diagram
PCIE-USB connect to 4G module. Port4 connect usb hub, usb hub connect to CPU usb port0
4.2 USB-CDC
4.2.1 Overview QMI
Qualcomm MSM Interface(QMI) is a messaging format used to communicate
between software components in the modem and other peripheral subsystems.
This document proposes an architecture to introduce the QMI messaging
into the kernel. This document proposes introducing a QMI encode/decode
library to enable QMI message marshaling and an interface library to enable
sending and receiving QMI messages through MSM IPC Router.
https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/Documentation/arm/msm/msm_qmi.txt
4.2.2 Overview NDIS
It was jointly developed by Microsoft and 3Com Corporation and is mostly used in Microsoft Windows. However, the open-source NDISwrapper and Project Evil driver wrapper projects allow many NDIS-compliant NICs to be used with Linux, FreeBSD and NetBSD. magnussoft ZETA, a derivative of BeOS, supports a number of NDIS drivers.
The NDIS forms the logical link control (LLC) sublayer, which is the upper sublayer of the OSI data link layer (layer 2). Therefore, the NDIS acts as the interface between the media access control (MAC) sublayer, which is the lower sublayer of the data link layer, and the network layer (layer 3).
The NDIS is a library of functions often referred to as a "wrapper" that hides the underlying complexity of the NIC hardware and serves as a standard interface for level 3 network protocol drivers and hardware level MAC drivers. Another common LLC is the Open Data-Link Interface (ODI).
The NDIS versions supported by various Windows versions are as follows:
NDIS 2.0: MS-DOS, Windows for Workgroups 3.1, OS/2
NDIS 3.0: Windows for Workgroups 3.11
NDIS 3.1: Windows 95
NDIS 4.0: Windows 95 OSR2, NT 4.0, Windows CE 3.0
NDIS 5.0: Windows 98, 98 SE, Me, 2000
NDIS 5.1: Windows XP, Server 2003, Windows CE 4.x, 5.0, 6.0[1]
NDIS 5.2: Windows Server 2003 SP2
NDIS 6.0: Windows Vista
NDIS 6.1: Windows Vista SP1, Server 2008, Windows Embedded Compact 7,[2] Windows Embedded Compact 2013
NDIS 6.20: Windows 7, Server 2008 R2
NDIS 6.30: Windows 8, Windows Server 2012
NDIS 6.40: Windows 8.1, Windows Server 2012 R2
NDIS 6.50: Windows 10, version 1507[3]
NDIS 6.60: Windows Server 2016 and Windows 10, version 1607[3]
NDIS 6.70: Windows 10, version 1703[3]
NDIS 6.80: Windows 10, version 1709[3]
NDIS 6.81: Windows 10, version 1803[3]
NDIS 6.82: Windows 10, version 1809[3]
The traffic accepted by the NIC is controlled by an NDIS miniport Driver while various protocols, such as TCP/IP, are implemented by NDIS Protocol Drivers. A single miniport may be associated with one or more protocols. This means that traffic coming into the miniport may be received in parallel by several protocol drivers. For example, Winpcap adds a second protocol driver on the selected miniport in order to capture incoming packets. Furthermore, it is possible to simulate several virtual NICs by implementing virtual miniport drivers that send and receive traffic from a single physical NIC. One example of virtual miniport driver usage is to add virtual NICs, each with a different Virtual LAN. Because implementations cannot assume that other drivers received the same buffers, one must treat the incoming buffers as read only and a driver that changes the packet content must allocate its own buffers.
A miniport is a type of hardware driver, part of the Windows Driver Model. These are USB, Audio, SCSI and network card adapters. They should usually be source and binary compatible between Windows 98 and Windows 2000 and are hardware specific but control access to the hardware through a specific bus class driver. [4]
Another driver type is NDIS Intermediate Driver. Intermediate drivers sit in-between the MAC and IP layers and can control all traffic being accepted by the NIC. In practice, intermediate drivers implement both miniport and protocol interfaces. The miniport driver and protocol driver actually communicate with the corresponding miniport and protocol interfaces that reside in the intermediate driver. This design enables adding several chained intermediate drivers between the miniport and protocol drivers. Therefore, driver vendors cannot assume that the interface that they send traffic to is implemented by the last driver in the chain. In order to write applications using NDIS one can use samples that accompany Microsoft's Windows Driver Kit (WDK). The "PassThru" sample is a good starting point for intermediate drivers as it implements all the necessary details required in this driver type, but just passes the traffic through to the next driver in the chain.
https://en.wikipedia.org/wiki/Network_Driver_Interface_Specification
5 Porting
5.1 Uboot porting
NA
5.2 Kernel porting
for ec20
Index: trunk/linux-4.14.40/drivers/net/usb/qmi_wwan.c
===================================================================
--- trunk/linux-4.14.40/drivers/net/usb/qmi_wwan.c (revision 244)
+++ trunk/linux-4.14.40/drivers/net/usb/qmi_wwan.c (revision 245)
@@ -23,6 +23,68 @@
#include <linux/usb/usbnet.h>
#include <linux/usb/cdc-wdm.h>
+
+#if 1 //add by Quectel
+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;
+}
+
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,9,1 ))
+static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ __be16 proto;
+
+ if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C))
+ return 1;
+
+ /* This check is no longer done by usbnet */
+ if (skb->len < dev->net->hard_header_len)
+ return 0;
+
+ switch (skb->data[0] & 0xf0) {
+ case 0x40:
+ proto = htons(ETH_P_IP);
+ break;
+ case 0x60:
+ proto = htons(ETH_P_IPV6);
+ break;
+ case 0x00:
+ if (is_multicast_ether_addr(skb->data))
+ return 1;
+ /* possibly bogus destination - rewrite just in case */
+ skb_reset_mac_header(skb);
+ goto fix_dest;
+ default:
+ /* pass along other packets without modifications */
+ return 1;
+ }
+ if (skb_headroom(skb) < ETH_HLEN)
+ return 0;
+ skb_push(skb, ETH_HLEN);
+ skb_reset_mac_header(skb);
+ eth_hdr(skb)->h_proto = proto;
+ memset(eth_hdr(skb)->h_source, 0, ETH_ALEN);
+fix_dest:
+ memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);
+ return 1;
+}
+#endif
+#endif
+
/* This driver supports wwan (3G/LTE/?) devices using a vendor
* specific management protocol called Qualcomm MSM Interface (QMI) -
* in addition to the more common AT commands over serial interface
@@ -740,6 +802,20 @@
}
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
+#if 1 //add by Quectel
+ if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
+ dev_info(&intf->dev, "Quectel EC21&EC25 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,
+ 0x21,
+ 1, //active CDC DTR
+ intf->cur_altsetting->desc.bInterfaceNumber,
+ NULL, 0, 100);
+ }
+#endif
err:
return status;
}
@@ -830,6 +906,9 @@
.bind = qmi_wwan_bind,
.unbind = qmi_wwan_unbind,
.manage_power = qmi_wwan_manage_power,
+#if 1 //add by Quectel
+ .tx_fixup = qmi_wwan_tx_fixup,
+#endif
.rx_fixup = qmi_wwan_rx_fixup,
};
@@ -840,6 +919,9 @@
.unbind = qmi_wwan_unbind,
.manage_power = qmi_wwan_manage_power,
.rx_fixup = qmi_wwan_rx_fixup,
+#if 1 //add by Quectel
+ .tx_fixup = qmi_wwan_tx_fixup,
+#endif
.data = QMI_WWAN_QUIRK_DTR,
};
@@ -1247,6 +1329,7 @@
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */
{QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */
{QMI_QUIRK_SET_DTR(0x2c7c, 0x0306, 4)}, /* Quectel EP06 Mini PCIe */
+ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0435, 4)}, /* Quectel AG35 */
/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
Index: trunk/linux-4.14.40/drivers/usb/serial/usb_wwan.c
===================================================================
--- trunk/linux-4.14.40/drivers/usb/serial/usb_wwan.c (revision 244)
+++ trunk/linux-4.14.40/drivers/usb/serial/usb_wwan.c (revision 245)
@@ -501,6 +501,18 @@
usb_fill_bulk_urb(urb, serial->dev,
usb_sndbulkpipe(serial->dev, endpoint) | dir,
buf, len, callback, ctx);
+#if 1 //Added by Quectel for Zero Packet
+ if (dir == USB_DIR_OUT) {
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9090))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ }
+#endif
return urb;
}
Index: trunk/linux-4.14.40/drivers/usb/serial/option.c
===================================================================
--- trunk/linux-4.14.40/drivers/usb/serial/option.c (revision 244)
+++ trunk/linux-4.14.40/drivers/usb/serial/option.c (revision 245)
@@ -247,6 +247,7 @@
#define QUECTEL_PRODUCT_EC25 0x0125
#define QUECTEL_PRODUCT_BG96 0x0296
#define QUECTEL_PRODUCT_EP06 0x0306
+#define QUECTEL_PRODUCT_AG35 0x0435
#define CMOTECH_VENDOR_ID 0x16d8
#define CMOTECH_PRODUCT_6001 0x6001
@@ -1970,6 +1971,9 @@
.suspend = usb_wwan_suspend,
.resume = usb_wwan_resume,
#endif
+#if 1 //add by Quectel
+ .reset_resume = usb_wwan_resume,
+#endif
};
static struct usb_serial_driver * const serial_drivers[] = {
@@ -1986,6 +1990,21 @@
struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
unsigned long device_flags = id->driver_info;
+#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 's interface 4 can be used as USB Network device
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)
+ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
+ return -ENODEV;
+#endif
+
/* Never bind to the CD-Rom emulation interface */
if (iface_desc->bInterfaceClass == 0x08)
return -ENODEV;
Index: trunk/linux-4.14.40/drivers/usb/serial/qcserial.c
===================================================================
--- trunk/linux-4.14.40/drivers/usb/serial/qcserial.c (revision 244)
+++ trunk/linux-4.14.40/drivers/usb/serial/qcserial.c (revision 245)
@@ -92,7 +92,7 @@
{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, 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: trunk/linux-4.14.40/drivers/usb/class/cdc-acm.c
===================================================================
--- trunk/linux-4.14.40/drivers/usb/class/cdc-acm.c (revision 244)
+++ trunk/linux-4.14.40/drivers/usb/class/cdc-acm.c (revision 245)
@@ -1484,6 +1484,10 @@
usb_fill_bulk_urb(snd->urb, usb_dev, acm->out,
NULL, acm->writesize, acm_write_bulk, snd);
snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#if 1 //add by Quectel
+ if (usb_dev->descriptor.idVendor == 0x1519 && usb_dev->descriptor.idProduct == 0x0020)
+ snd->urb->transfer_flags |= URB_ZERO_PACKET;
+#endif
if (quirks & SEND_ZERO_PACKET)
snd->urb->transfer_flags |= URB_ZERO_PACKET;
snd->instance = acm;
for simcom7600ce
Index: trunk/linux-4.14.40/arch/arm/configs/tisdk_am335x-evm_defconfig
===================================================================
--- trunk/linux-4.14.40/arch/arm/configs/tisdk_am335x-evm_defconfig (revision 245)
+++ trunk/linux-4.14.40/arch/arm/configs/tisdk_am335x-evm_defconfig (revision 246)
@@ -1977,7 +1977,7 @@
CONFIG_USB_USBNET=y
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_AX88179_178A=m
-CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_CDCETHER=y
# CONFIG_USB_NET_CDC_EEM is not set
CONFIG_USB_NET_CDC_NCM=m
# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
@@ -4229,8 +4229,6 @@
# CONFIG_USB_G_MULTI is not set
# CONFIG_USB_G_HID is not set
# CONFIG_USB_G_DBGP is not set
-# CONFIG_USB_G_DBGP_PRINTK is not set
-# CONFIG_USB_G_DBGP_SERIAL is not set
# CONFIG_USB_G_WEBCAM is not set
#
Index: trunk/linux-4.14.40/drivers/net/usb/simcom_wwan.c
===================================================================
--- trunk/linux-4.14.40/drivers/net/usb/simcom_wwan.c (nonexistent)
+++ trunk/linux-4.14.40/drivers/net/usb/simcom_wwan.c (revision 246)
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2016 Xiaobin Wang <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+/*
+ * history
+ * V1.00 - first release -20160822
+*/
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+
+
+/* very simplistic detection of IPv4 or IPv6 headers */
+static bool possibly_iphdr(const char *data)
+{
+ return (data[0] & 0xd0) == 0x40;
+}
+
+/* SIMCOM devices combine the "control" and "data" functions into a
+ * single interface with all three endpoints: interrupt + bulk in and
+ * out
+ */
+static int simcom_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int rv = -EINVAL;
+
+ //struct usb_driver *subdriver = NULL;
+ atomic_t *pmcount = (void *)&dev->data[1];
+
+ /* ignore any interface with additional descriptors */
+ if (intf->cur_altsetting->extralen)
+ goto err;
+
+ /* Some makes devices where the interface descriptors and endpoint
+ * configurations of two or more interfaces are identical, even
+ * though the functions are completely different. If set, then
+ * driver_info->data is a bitmap of acceptable interface numbers
+ * allowing us to bind to one such interface without binding to
+ * all of them
+ */
+ if (dev->driver_info->data &&
+ !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) {
+ dev_info(&intf->dev, "not on our whitelist - ignored");
+ rv = -ENODEV;
+ goto err;
+ }
+
+ atomic_set(pmcount, 0);
+
+ /* collect all three endpoints */
+ rv = usbnet_get_endpoints(dev, intf);
+ if (rv < 0)
+ goto err;
+
+ /* require interrupt endpoint for subdriver */
+ if (!dev->status) {
+ rv = -EINVAL;
+ goto err;
+ }
+
+ /* can't let usbnet use the interrupt endpoint */
+ dev->status = NULL;
+
+ printk("simcom usbnet bind here\n");
+
+ /*
+ * SIMCOM SIM7600 only support the RAW_IP mode, so the host net driver would
+ * remove the arp so the packets can transmit to the modem
+ */
+ dev->net->flags |= IFF_NOARP;
+
+ /* make MAC addr easily distinguishable from an IP header */
+ if (possibly_iphdr(dev->net->dev_addr)) {
+ dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */
+ dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */
+ }
+
+ /*
+ * SIMCOM SIM7600 need set line state
+ */
+ 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, //line state 1
+ intf->cur_altsetting->desc.bInterfaceNumber,
+ NULL,0,100);
+
+err:
+ return rv;
+}
+
+static void simcom_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct usb_driver *subdriver = (void *)dev->data[0];
+
+ if (subdriver && subdriver->disconnect)
+ subdriver->disconnect(intf);
+
+ dev->data[0] = (unsigned long)NULL;
+}
+
+#ifdef CONFIG_PM
+static int simcom_wwan_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct usbnet *dev = usb_get_intfdata(intf);
+ int ret;
+
+ ret = usbnet_suspend(intf, message);
+ if (ret < 0)
+ goto err;
+
+err:
+ return ret;
+}
+
+static int simcom_wwan_resume(struct usb_interface *intf)
+{
+ struct usbnet *dev = usb_get_intfdata(intf);
+ int ret = 0;
+
+ ret = usbnet_resume(intf);
+
+err:
+ return ret;
+}
+#endif
+
+struct sk_buff *simcom_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+{
+
+ //skip ethernet header
+ if(skb_pull(skb, ETH_HLEN))
+ {
+ return skb;
+ }else
+ {
+ dev_err(&dev->intf->dev, "Packet Dropped\n");
+ }
+
+ if (skb != NULL)
+ dev_kfree_skb_any(skb);
+
+ return NULL;
+}
+
+static int simcom_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ __be16 proto;
+
+ /* This check is no longer done by usbnet */
+ if (skb->len < dev->net->hard_header_len)
+ return 0;
+
+ switch (skb->data[0] & 0xf0) {
+ case 0x40:
+ //printk("packetv4 coming ,,,\n");
+ proto = htons(ETH_P_IP);
+ break;
+ case 0x60:
+ //printk("packetv6 coming ,,,\n");
+ proto = htons(ETH_P_IPV6);
+ break;
+ case 0x00:
+ //printk("packet coming ,,,\n");
+ if (is_multicast_ether_addr(skb->data))
+ return 1;
+ /* possibly bogus destination - rewrite just in case */
+ skb_reset_mac_header(skb);
+ goto fix_dest;
+ default:
+ /* pass along other packets without modifications */
+ return 1;
+ }
+ if (skb_headroom(skb) < ETH_HLEN)
+ return 0;
+ skb_push(skb, ETH_HLEN);
+ skb_reset_mac_header(skb);
+ eth_hdr(skb)->h_proto = proto;
+ memset(eth_hdr(skb)->h_source, 0, ETH_ALEN);
+fix_dest:
+ memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);
+ return 1;
+}
+
+static const struct driver_info simcom_wwan_usbnet_driver_info = {
+ .description = "SIMCOM wwan/QMI device",
+ .flags = FLAG_WWAN,
+ .bind = simcom_wwan_bind,
+ .unbind = simcom_wwan_unbind,
+ .rx_fixup = simcom_wwan_rx_fixup,
+ .tx_fixup = simcom_wwan_tx_fixup,
+};
+
+static const struct usb_device_id products[] = {
+ {USB_DEVICE(0x1e0e, 0x9025), .driver_info = (unsigned long)&simcom_wwan_usbnet_driver_info },
+ {USB_DEVICE(0x1e0e, 0x9001), .driver_info = (unsigned long)&simcom_wwan_usbnet_driver_info },
+ { } /* END */
+};
+
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver simcom_wwan_usb_driver = {
+ .name = "simcom_wwan",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+#ifdef CONFIG_PM
+ .suspend = simcom_wwan_suspend,
+ .resume = simcom_wwan_resume,
+ .reset_resume = simcom_wwan_resume,
+ .supports_autosuspend = 1,
+#endif
+};
+
+static int __init simcom_wwan_init(void)
+{
+ return usb_register(&simcom_wwan_usb_driver);
+}
+module_init(simcom_wwan_init);
+
+static void __exit simcom_wwan_exit(void)
+{
+ usb_deregister(&simcom_wwan_usb_driver);
+}
+module_exit(simcom_wwan_exit);
+
+MODULE_AUTHOR("Xiaobin Wang <[email protected]>");
+MODULE_DESCRIPTION("SIM7600 RMNET WWAN driver");
+MODULE_LICENSE("GPL");
Property changes on: trunk/linux-4.14.40/drivers/net/usb/simcom_wwan.c
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/linux-4.14.40/drivers/net/usb/Makefile
===================================================================
--- trunk/linux-4.14.40/drivers/net/usb/Makefile (revision 245)
+++ trunk/linux-4.14.40/drivers/net/usb/Makefile (revision 246)
@@ -27,7 +27,7 @@
obj-$(CONFIG_USB_NET_CDC_SUBSET_ENABLE) += cdc_subset.o
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
-obj-$(CONFIG_USB_USBNET) += usbnet.o
+obj-$(CONFIG_USB_USBNET) += usbnet.o simcom_wwan.o
obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
obj-$(CONFIG_USB_NET_KALMIA) += kalmia.o
Index: trunk/linux-4.14.40/drivers/usb/serial/option.c
===================================================================
--- trunk/linux-4.14.40/drivers/usb/serial/option.c (revision 245)
+++ trunk/linux-4.14.40/drivers/usb/serial/option.c (revision 246)
@@ -2005,6 +2005,12 @@
return -ENODEV;
#endif
+ /* add for sim7600 by panzidong*/
+ if (serial->dev->descriptor.idVendor == 0x1e0e &&
+ serial->dev->descriptor.idProduct == 0x9001 &&
+ serial->interface->cur_altsetting->desc.bInterfaceNumber == 5 )
+ return -ENODEV;
+
/* Never bind to the CD-Rom emulation interface */
if (iface_desc->bInterfaceClass == 0x08)
return -ENODEV;
5.3 Application Interface
wwan0
6 Follow-up
EC20 use :
quectel-CM
SIMCOM7600CE use:
echo “at$qcrmcall=1.1” > /dev/ttyUSB2
dhcpcd –m 3 wwan0