Linux Driver Porting and Testing for Quectel EC20 4G Module

Note: Please indicate the source when reprinting, all rights reserved by the author.Note: This is based on my own understanding,if it conflicts with your principles and ideas, please forgive me and do not criticize.

Environment Description

  None

Introduction

  None

EC20 Driver Porting and Testing

Introduction to EC20

  The EC20 is a fully compatible 4G module and provides detailed driver porting materials (source code + documentation). I simply followed the documentation, made some modifications, and established a usable environment.

Preparation for EC20 Driver Porting
  1. 1. First, you will receive a documentation file from the manufacturer and unzip it (similar to Quectel_GobiNetSR01A02V16.zip).
  2. 2. You will find a user manual PDF to open (similar to Quectel_WCDMA&LTE_Linux_USB_Driver_User_Guide_V1.6.pdf).
  3. 3. There is also a Readme.txt that tells you which parts of the above PDF to read. It may include the following:
About GobiNet driver, please refer to the chapter 3.2, 3.4, 5.4, 6
About ConnectManager, please refer to the chapter 5.4
  1. 4. Follow the instructions in the PDF as follows.
Porting the EC20 Linux Driver
  1. 1. Add PID & VID (for those unfamiliar, it is recommended to look up information to understand that this can be simply understood as the unique identifier of this device).[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 

  Here, only { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */ is needed; the others are irrelevant and can be omitted. option_ids[] is a USB serial device’s PID and VID table.

  1. 2. Comment out conflicting VID and PID devices (I guess the existence of the same VID and PID is historical).[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 it seems only the EC20 has conflicts here.

  1. 3. Add zero packet handling (this is related to bulk transfer in the 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, the PDF also contains information for Linux Kernel Version older than 2.6.35; please check according to your kernel version.

  1. 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
};
  1. 5. If you want to use GobiNet or QMI WWAN, you need to prevent the fourth interface from being registered 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;

    /* Never bind to the CD-Rom emulation interface    */
    if (iface_desc->bInterfaceClass == 0x08)
        return -ENODEV;

    /*
     * 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.
     */
    if (is_blacklisted(
        iface_desc->bInterfaceNumber,
        OPTION_BLACKLIST_RESERVED_IF,
        (const struct option_blacklist_info *) id->driver_info))
        return -ENODEV;
    /*
     * Don't bind network interface on Samsung GT-B3730, it is handled by
     * a separate module.
     */
    if (dev_desc->idVendor == cpu_to_le16(SAMSUNG_VENDOR_ID) &&
        dev_desc->idProduct == cpu_to_le16(SAMSUNG_PRODUCT_GT_B3730) &&
        iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
        return -ENODEV;


        #if 1  //Added by Sky 
        //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 EC21&&EC25&&EC20 R2.0'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 


    /* Store device id so we can use it during attach. */
    usb_set_serial_data(serial, (void *)id);

    return 0;
}
  1. 6. Modify the kernel configuration, compile the kernel, and flash the new kernel.  Add USB serial 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 
  1. 7. Testing with quectel-CM
//Cross-compile quectel-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 14201513: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, UDHCPC is required here; check if your busybox has this feature. If it does not exist, you need to re-port busybox and enable the CONFIG_UDHCPC option. You also need to configure a configuration file, and be sure to check.

  Special reminder, many modifications regarding the kernel source code and kernel configuration vary by version, and the documentation contains detailed instructions. Please pay special attention when using.

Postscript

  None

References

  • • None

Donations, subscriptions, favorites, throwing bananas, coins, please follow the public account.

Note: Please respect originality, do not criticize if you dislike.Note: Please indicate the source when reprinting, all rights reserved by the author.Note: If you have questions, please leave a message, and I will reply as soon as I see it.

Leave a Comment