文章目录
0.前言
本文记录在linux 4.14
版本内核上面增加UC20/EC2x/EGxx/EP06/EM06/BG96/AG35
的QMI WWAN
驱动支持,
并且最终通过使用quectel-CM
程序完成拨号上网的工作。
- 参考文档:Quectel_WCDMA<E_Linux_USB_Driver_User_Guide_V1.7.pdf
- 连接管理工具:quectel-cm-1.1.34.zip
1.增加USB Serial驱动
1.1.增加VID和PID
文件:[KERNEL]/drivers/usb/serial/option.c
在数组option_ids
的结束项({ } /* Terminating entry */
)之前插入如下内容
{ USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
{ USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
{ USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25/EC20 R2.0 */
{ 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, 0x0296) }, /* Quectel BG96 */
插入效果如下图所示:
1.2.删除重复的定义(EC20需要,其余跳过即可)
对于EC20模块,如果内核源文件中存在以下文件和语句,请删除它们,因为它们会与EC20的USB驱动程序发生冲突。
1.2.1.冲突点1
文件:[KERNEL]/drivers/usb/serial/qcserial.c
需要删除的语句如下:
{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
删除效果如下图所示:
1.2.2.冲突点2
文件:[KERNEL]/drivers/net/usb/qmi_wwan.c
需要删除的语句如下:
{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
删除效果如下图所示:
1.3. 增加零包机制
根据USB协议的要求,客户需要添加在批量输出传输过程中处理零数据包的机制
[KERNEL]/drivers/usb/serial/usb_wwan.c
需要在函数usb_wwan_setup_urb
中的return urb
前添加如下语句:
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;
}
代码添加效果如下图所示:
1.4.增加Reset Resume
部分USB主机控制器/USB集线器在MCU进入suspend/sleep模式时会断电或复位,
MCU退出suspend/sleep模式后无法恢复USB设备。请添加以下语句以启用重置-恢复过程。
文件:[KERNEL]/drivers/usb/serial/option.c
在变量option_1port_device
中添加如下代码:
.reset_resume = usb_wwan_resume,
添加效果如下图所示:
1.5.支持GobiNet/QMI WWAN
如果客户正在使用UCxx/EC2x/EGxx/EP06/EM06/BG96/AG35,
并且需要GobiNet或QMI WWAN,请添加以下声明,以防止这些模块的接口4被用作USB串行设备。
文件:[KERNEL]/drivers/usb/serial/option.c
在函数option_probe
的usb_set_serial_data(serial, (void *)id);
语句前添加如下代码:
//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->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
代码添加示意图如下所示:
1.6.内核配置
使用命令make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
,进行内核配置操作。
内核配置项如下所示:
[*] Device Drivers ->
[*] USB Support ->
[*] USB Serial Converter support ->
[*] USB driver for GSM and CMDA modems
配置效果如下图所示:
2.增加QMI WWAN驱动
当Quectel模块被附加到QMI WWAN驱动程序时,驱动程序将创建一个网络设备和一个QMI通道。
网络设备命名为wwanX
,QMI通道命名为/dev/cdc- wdmx
。网络设备用于数据传输,QMI通道用于QMI消息交互。
2.1.添加VID和PID
文件:[KERNEL]/drivers/net/usb/qmi_wwan.c
在变量products
的末尾项({ }
)之前,添加如下内容:
{ QMI_FIXED_INTF(0x05C6, 0x9003, 4) }, /* Quectel UC20 */
{ QMI_FIXED_INTF(0x2C7C, 0x0125, 4) }, /* Quectel EC25/EC20 R2.0 */
{ 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 */
添加效果如下图所示:
2.2.添加 Raw IP Mode 支持
EC25/EC21/EC20 R2.0/EG91/EG95/EG06/EP06/EM06/BG96只支持原始IP模式(IP包不封装在以太网帧中)。
因此,当数据包发送到Quectel模块时,必须剥离以太网报头,当数据包从Quectel模块接收时,必须添加以太网报头。
文件:[KERNEL]/drivers/net/usb/qmi_wwan.c
2.2.1.步骤1
在文件中添加如下函数:
#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;
}
添加效果如下图所示,注意不要漏掉头文件:
2.2.2.步骤2
在函数qmi_wwan_bind
中的err:
标号上面添加如下代码:
if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
dev_info(&intf->dev, "Quectel EC25&EC21&EC20R2.0&EG91&EG95&EG06&EP06&EM06&BG96 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);
}
添加效果如下图所示:
2.2.3.步骤三
在变量qmi_wwan_info
和变量qmi_wwan_info_quirk_dtr
, 分别加入如下代码:
.tx_fixup = qmi_wwan_tx_fixup,
添加效果如下图所示:
2.3.内核配置
使用命令make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
,进行内核配置操作。
内核配置项如下所示:
[*] Device Drivers →
-*- Network device support →
USB Network Adapters →
{*} Multi-purpose USB Networking Framework
<*> QMI WWAN driver for Qualcomm MSM based 3G and LTE modems
配置效果如下图所示:
3.移植quectel-CM
没啥好说的,直接指定交叉编译工具链之后编译即可,命令如下:
make CROSS_COMPILE=arm-linux-gnueabihf-
4.测试
quectel-CM &