Migration and testing of Linux driver for EC20 4G module

Posted by buttercupgreen on Sat, 19 Feb 2022 09:16:28 +0100

https://blog.csdn.net/u011728480/article/details/78588827

#PS: if you want to reprint, please indicate the source. I own the copyright

#PS: This is only "myself" understand, if with your

#If the principles conflict, please understand and don't spray

Introduction to EC20

EC20 is a 4G module of all Netcom, and provides detailed driver migration materials (source code + documents). I just follow the documents, change it a little, and establish a usable environment.

EC20 drive transplant preparation

1 first, you will get a data file from the manufacturer and unzip it (similar to Quectel_GobiNetSR01A02V16.zip)

2 you will find a PDF of the user manual to open (similar to quectel_wcdma & lte_linux_usb_driver_user_guide_v1.6. PDF)

There is also a readme Txt tells you what you need to read the pdf above. It may be as follows:

About GobiNet driver, please refer to the chapter 3.2,3.4,5.4,6
About ConnectManager,please refer to the chapter 5.4

4 follow the instructions below.

EC20 Linux driver porting

1. Add PID & vid (for two unknown, it is recommended to look for information, which can be simply understood as the unique identification of the equipment)

[KERNEL]/drivers/usb/serial/option.c

static const struct usb_device_id option_ids[] = {
    #if 1 //Added by Sky 
    { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */  
    { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */  
    { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */  
    { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25/EC20 R2.0 */  
    { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */ 
    #endif 

In fact, only {usb_device (0x05c6, 0x9215)}, / * quectel EC20 * / is needed here. Other items are irrelevant and can not be put in. option_ids [] is a usb serial device pid and vid table.

2. Comment out the conflicting vid and pid devices (I guess the existence of the same vid and pid is the historical reason)

[KERNEL]/drivers/usb/serial/qcserial.c

//Comment by Sky,
    //{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

[KERNEL]/drivers/net/usb/qmi_wwan.c

//comment by Sky
    //{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

Note that there seems to be only EC20 conflict here.

3. Add zero packet processing (this is related to batch transmission in usb protocol)

For Linux Kernel Version newer than 2.6.34:

File: [KERNEL]/drivers/usb/serial/usb_wwan.c

usb_fill_bulk_urb(urb, serial->dev,      usb_sndbulkpipe(serial->dev, endpoint) | dir,      buf, len, callback, ctx);
    #if 1 //Added by Sky 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 

Note that there are also contents of For Linux Kernel Version older than 2.6.35 on the pdf. Please check it by yourself according to the kernel version.

4. Add wake-up interface after sleep

For Linux Kernel Version newer than 3.4:

File: [KERNEL]/drivers/usb/serial/option.c

static struct usb_serial_driver option_1port_device = {
    .driver = {
        .owner =    THIS_MODULE,
        .name =     "option1",
    },
    .description       = "GSM modem (1-port)",
    .id_table          = option_ids,
    .num_ports         = 1,
    .probe             = option_probe,
    .open              = usb_wwan_open,
    .close             = usb_wwan_close,
    .dtr_rts       = usb_wwan_dtr_rts,
    .write             = usb_wwan_write,
    .write_room        = usb_wwan_write_room,
    .chars_in_buffer   = usb_wwan_chars_in_buffer,
    .set_termios       = usb_wwan_set_termios,
    .tiocmget          = usb_wwan_tiocmget,
    .tiocmset          = usb_wwan_tiocmset,
    .ioctl             = usb_wwan_ioctl,
    .attach            = option_attach,
    .release           = option_release,
    .port_probe        = usb_wwan_port_probe,
    .port_remove       = usb_wwan_port_remove,
    .read_int_callback = option_instat_callback,
#ifdef CONFIG_PM
    .suspend           = usb_wwan_suspend,
    .resume            = usb_wwan_resume,
    #if 1 //Added by Sky 
    .reset_resume   = usb_wwan_resume, 
    #endif 
#endif
};

5 if you want to use GobiNet or QMI WWAN, you need to prevent the fourth interface from registering as a serial port.

For Linux Kernel Version newer than 2.6.30:

File: [KERNEL]/drivers/usb/serial/option.c

static int option_probe(struct usb_serial *serial,
            const struct usb_device_id *id)
{
    struct usb_interface_descriptor *iface_desc =
                &serial->interface->cur_altsetting->desc;
    struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
<span class="hljs-comment"><span class="hljs-comment">/* Never bind to the CD-Rom emulation interface */</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (iface_desc-&gt;bInterfaceClass == <span class="hljs-number"><span class="hljs-number">0x08</span></span>)
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> -ENODEV;

<span class="hljs-comment"><span class="hljs-comment">/* * Don't bind reserved interfaces (like network ones) which often have * the same class/subclass/protocol as the serial interfaces. Look at * the Windows driver .INF files for reserved interface numbers. */</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (is_blacklisted(
    iface_desc-&gt;bInterfaceNumber,
    OPTION_BLACKLIST_RESERVED_IF,
    (<span class="hljs-keyword"><span class="hljs-keyword">const</span></span> <span class="hljs-keyword">struct</span> option_blacklist_info *) id-&gt;driver_info))
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> -ENODEV;
<span class="hljs-comment"><span class="hljs-comment">/* * Don't bind network interface on Samsung GT-B3730, it is handled by * a separate module. */</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (dev_desc-&gt;idVendor == cpu_to_le16(SAMSUNG_VENDOR_ID) &amp;&amp;
    dev_desc-&gt;idProduct == cpu_to_le16(SAMSUNG_PRODUCT_GT_B3730) &amp;&amp;
    iface_desc-&gt;bInterfaceClass != USB_CLASS_CDC_DATA)
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> -ENODEV;


    <span class="hljs-preprocessor"><span class="hljs-comment">#if 1 </span><span class="hljs-comment"><span class="hljs-comment">//Added by Sky </span></span></span>
    <span class="hljs-comment"><span class="hljs-comment">//Quectel UC20's interface 4 can be used as USB Network device </span></span>
    <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (serial-&gt;dev-&gt;descriptor.idVendor == cpu_to_le16(<span class="hljs-number"><span class="hljs-number">0x05C6</span></span>) &amp;&amp; serial-&gt;dev-&gt;descriptor.idProduct == cpu_to_le16(<span class="hljs-number"><span class="hljs-number">0x9003</span></span>)  \
         &amp;&amp; serial-&gt;interface-&gt;cur_altsetting-&gt;desc.bInterfaceNumber &gt;= <span class="hljs-number"><span class="hljs-number">4</span></span>)   
    <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> -ENODEV; 
    <span class="hljs-comment"><span class="hljs-comment">//Quectel EC20's interface 4 can be used as USB Network device </span></span>
    <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (serial-&gt;dev-&gt;descriptor.idVendor == cpu_to_le16(<span class="hljs-number"><span class="hljs-number">0x05C6</span></span>) &amp;&amp; serial-&gt;dev-&gt;descriptor.idProduct == cpu_to_le16(<span class="hljs-number"><span class="hljs-number">0x9215</span></span>)  \
        &amp;&amp; serial-&gt;interface-&gt;cur_altsetting-&gt;desc.bInterfaceNumber &gt;= <span class="hljs-number"><span class="hljs-number">4</span></span>)   
        <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> -ENODEV; 
        <span class="hljs-comment"><span class="hljs-comment">//Quectel EC21&amp;EC25&amp;EC20 R2.0's interface 4 can be used as USB Network device </span></span>
    <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (serial-&gt;dev-&gt;descriptor.idVendor == cpu_to_le16(<span class="hljs-number"><span class="hljs-number">0x2C7C</span></span>)   \
        &amp;&amp; serial-&gt;interface-&gt;cur_altsetting-&gt;desc.bInterfaceNumber &gt;= <span class="hljs-number"><span class="hljs-number">4</span></span>)   
        <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> -ENODEV; 
    <span class="hljs-preprocessor"><span class="hljs-comment">#endif </span></span>


<span class="hljs-comment"><span class="hljs-comment">/* Store device id so we can use it during attach. */</span></span>
usb_set_serial_data(serial, (<span class="hljs-keyword">void</span> *)id);

<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-number"><span class="hljs-number">0</span></span>;

}

6 modify the kernel configuration, compile the kernel and brush in the new kernel

Add USB serial port GSM and CDMA driver options

Enable USB network support

Add driver code

//Step 5: Please add the following statements to file "[KERNEL]/drivers/net/usb/Makefile" ([KERNEL]/drivers/usb/net/Makefile if the kernel version is older than 2.6.22). 
obj-y += GobiNet.o 
GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o

7 quectel cm test

//Cross compile quertel cm 
/*quectel-CM will call busybox udhpc to obtain IP and NDS, and busybox udhpc will call script file /usr/share/udhcpc/default.script to set IP/DNS/Routing table for Linux board. You can download this tool's source code from https://busybox.net/. You should enable CONFIG_UDHCPC in busybox menuconfig,and copy the script file [BUSYBOX]/examples/udhcp/simple.script to your Linux board (renamed as /usr/share/udhcpc/default.script). */
quectel-CM –s ctnet & 
[01-01_00:26:45:355] Quectel_ConnectManager_SR01A01V10 
[01-01_00:26:45:356] ./quectel-CM profile = ctnet///, pincode = 
[01-01_00:26:45:357] Find qmichannel = /dev/qcqmi2 
[01-01_00:26:45:358] Find usbnet_adapter = eth2 
[01-01_00:26:45:368] Get clientWDS = 7 
[01-01_00:26:45:400] Get clientDMS = 8 
[01-01_00:26:45:432] Get clientNAS = 9 
[01-01_00:26:45:464] Get clientWDA = 10 
[01-01_00:26:45:496] requestBaseBandVersion EC20CQAR02A03E2G_BETA0914  1  [Sep 14 2015 13:51:27] 
[01-01_00:26:45:560] requestGetSIMStatus SIMStatus: SIM_READY 
[01-01_00:26:45:624] requestGetProfile ctnet///0 
[01-01_00:26:45:656] requestRegistrationState MCC: 460, MNC: 11, PS: Attached, DataCap: LTE 
[01-01_00:26:45:688] requestQueryDataCall ConnectionStatus: DISCONNECTED 
[01-01_00:26:45:720] requestRegistrationState MCC: 460, MNC: 11, PS: Attached, DataCap: LTE 
[01-01_00:26:45:752] requestQueryDataCall ConnectionStatus: DISCONNECTED 
[01-01_00:26:45:816] requestSetupDataCall WdsConnectionIPv4Handle: 0x43cc4478 
[01-01_00:26:45:912] requestQueryDataCall ConnectionStatus: CONNECTED 
[01-01_00:26:45:937] udhcpc (v1.20.2) started 
[01-01_00:26:45:956] Sending discover... 
[01-01_00:26:45:960] Sending select for 10.172.27.151... 
[01-01_00:26:45:964] Lease of 10.172.27.151 obtained, lease time 7200 
[01-01_00:26:45:984] deleting routers 
route: SIOCDELRT: No such process 
[01-01_00:26:46:003] adding dns 61.132.163.68 
[01-01_00:26:46:003] adding dns 202.102.213.68

Note that UDHCPC is required here to check whether your busybox has this thing. If it doesn't exist, you need to transplant busybox again and enable CONFIG_UDHCPC options. You also need to configure a configuration file. Please check it.

Special note: many of them are about the modification of kernel source code and kernel configuration. Different versions have different writing methods. There are detailed instructions in the document. Please pay special attention when using.
#PS: please respect the original, don't spray if you don't like it

#PS: if you want to reprint, please indicate the source. I own all rights

If you have any questions, please leave a message. I will reply as soon as I see it

Topics: Linux hardware