(五)、QCA9531添加EC20 4G上网支持修改驱动配置

1、上几章完成了QCA9531的基础上网工作,这里我们继续扩展一下,支持4G上网功能。

最常用的模块就是EC20 移远的CAT4模块,我们需要将EC20挂载到QCA9531的USB口,即我们需要购买一个原生的EC20直接可以给EC20供电并且引出USB接口的模块即可(网上很多是直接带AP功能的,不要购买那种),这里我们直接购买的是野火的一个模块,如图所示。

2、记得第一章里面去掉对应电容(否则此模块无法上电开启),插上EC20后即可正常供电,可见灯亮起,说明供电正常。查看原理图,红色LED为EC20供电电源,蓝色LED为EC20 LED-WWAN引脚。

查看EC20手册 LED-WWAN 为网络指示灯(蓝色)

 3、网上参考了很多教程,发现都是以移远官方给的

《Quectel_QConnectManager_Linux_User_Guide_V1.0.pdf》

《Quectel_WCDMALTE_Linux_USB_Driver_User_Guide_V1.7.pdf》

这两个文档上的操作来进行修改的,由于版权原因,我就不放出来,有兴趣的同学可以下载看一下,其中 QConnectManager 为移远通信提供的网卡拨号工具,支持 QMI、 MBIM 协议拨号和 AT+QNETDEVCTL拨号。这里我们就使用这个官方提供的拨号工具来实现4G上网,编译这个拨号程序到OpenWRT中即可以实现上网。

除了这两个还必须包含移远提供的QCM linux包才可以,有大神已经做好了包,还包含了DNS设置,不然需要手动修改makefile 和 Config.in文件(后续有机会可以编译移远提供的最新驱动包,这里先用现成的驱动包),链接如下,本着尊重原作者的原则,大家自己去花积分下载。

https://download.csdn.net/download/jianzhizuo/10749215

下载完成后先保存这个文件  quectel_cm.7z 

①、为了识别到移远模块,我们要添加模块的 VID和PID 信息(USB的每个供应商的VID是唯一的,PID由供应商自行决定。 主机通过VID和PID来识别不同设备)

openwrt 目录下进入目录 build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.243/drivers/usb/serial:

cd build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.243/drivers/usb/serial

打开 option.c 文件

gedit option.c 

可以看到已添加了PID VID 实际上猜测我手上这个EC20对应为EC20 R20 之前测试的时候发现PID VID 编号为 2C7C, 0125,故这个文件我们就 不用修改  了。

从 《Quectel_WCDMALTE_Linux_USB_Driver_User_Guide_V1.7.pdf》这个文档中也可以看到EC20 R20的USB  ID号确实如此。

②、 根据USB协议的要求,需要增加批量传输时 处理零包的机制 。为什么要零包处理?

        与短数据包一样,零长度数据包也用于 传输完成 。假设您想要发送 2048 字节的批量数据。第一个数据包 = 1024 字节 第二个数据包 = 1024 字节。现在的问题是,两者都等于最大数据包大小。设备不会知道传输已完成。然后您发送一个零长度数据包。 第三个数据包 = 0 字节,这将使传输完成,然后设备可以开始处理数据。零长度数据包也用于状态阶段的控制传输,以通知成功完成。

在openwrt目录下进入 build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.243/drivers/usb/serial/ 目录并编辑 usb_wwan.c 文件

cd build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.243/drivers/usb/serial/
gedit usb_wwan.c

 在 usb_wwan_setup_urb 结构体中插入如下代码

	#if 1 //Added by Quectelfor 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;
		if (desc->idVendor == cpu_to_le16(0x1286) && desc->idProduct == cpu_to_le16(0x4e3d))
		{
	    		urb->transfer_flags |= URB_ZERO_PACKET;
		}
    	}
	#endif

如图所示

③、当 MCU 进入挂起/睡眠状态时,某些 USB 主控制器/USB 集线器会断电或重置模式,并且当 MCU 退出挂起/睡眠模式时,它们无法恢复 USB 设备; 相反,他们将进行复位恢复操作。 需要进行修改。

cd build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.243/drivers/usb/serial/
gedit option.c 

option_1port_device 结构体中插入如下代码:

#if 1 //Added by Quectel
        .reset_resume      = usb_wwan_resume,
#endif

如图所示位置:

④、 如果使用ucxx/ec2x/egxx/EP06/EM06/BG96/AG35,并要求GobiNet或QMI WWAN(Qualcomm GobiNet 是用于 Qualcomm Gobi 移动宽带解决方案的 USB 无线网卡的 Linux 驱动程序,而 QMI 是一种用于在 Qualcomm 移动设备之间进行通信的协议。),请添加以下语句,以防止这些模块接口4被用作USB串行设备。

cd build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.243/drivers/usb/serial/
gedit option.c

在 函数 option_probe 中添加如下代码:

#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->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
                return -ENODEV;
#endif

位置如下: 

⑤ 、添加QMI WWAN的驱动,添加VID和PID

cd build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.243/drivers/net/usb/
gedit qmi_wwan.c

结构体 usb_device_id products[] 上添加

#if 1 //Added by Quectel
        #ifndef QMI_FIXED_INTF
        /* map QMI/wwan function by a fixed interface number */
        #define QMI_FIXED_INTF(vend, prod, num) \
        .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
        USB_DEVICE_ID_MATCH_INT_INFO, \
        .idVendor = vend, \
        .idProduct = prod, \
        .bInterfaceClass = 0xff, \
        .bInterfaceSubClass = 0xff, \
        .bInterfaceProtocol = 0xff, \
        .driver_info = (unsigned long)&qmi_wwan_force_int##num,
        #endif
        { 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

添加位置如图所示:

 继续在这个文件中添加对 Raw IP Mode (原始 IP 接口允许客户端程序通过除 TCP 和 UDP 之外的任何 IP Internet 协议发送和接收任意 IP 数据报。)的支持,需要添加一个函数如下:

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;
};

请放置到文件最前面  否则报错!!! 

 位置如图所示:

修改 qmi_wwan_bind函数 ,插入如下代码:

#if 1 //Added by Quectel
        if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
                dev_info(&intf->dev, "Quectel EC25&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

如图所示:

两个结构体  qmi_wwan_info 和 qmi_wwan_info_quirk_dtr 添加如下代码:

#if 1 //Added by Quectel
        .tx_fixup       = qmi_wwan_tx_fixup,
#endif

 

保存,至此所有需要修改的文件准备完毕。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值