MT7628移植移远EC20驱动实现4G上网功能(绝大多数使用openwrt的设备通用)

您所在的位置:网站首页 移远eg95多少钱 MT7628移植移远EC20驱动实现4G上网功能(绝大多数使用openwrt的设备通用)

MT7628移植移远EC20驱动实现4G上网功能(绝大多数使用openwrt的设备通用)

2024-01-13 23:11| 来源: 网络整理| 查看: 265

我的上一篇文章中完成对MT7628固件的编译,本文是在固件编译通过的基础上移植EC20驱动的,固件编译问题请参考上文。

在讲解之前先介绍移远的EC20模块,该模块是目前较为成熟的4G模块,可向安装了Windows、Linux等设备的机器提供4G上网服务,移远同类产品中还有AG35模块,这个模块我之前在AM4378上移植过,当时花费了好多时间才移植成功,其实移远产品做得也不错,同类的模块移植方法基本是一样的。

废话不多说,下面开始讲述EC20驱动在MT7628上的移植过程。

 

第一步:

修改源码(注意:固件必须要先编译过一轮,否则没有build_dir目录)。此步骤必须细心修改,并认真核对。以下路径中的源文件均需要修改才能使用:

/home/user/openwrt-sdk/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/drivers/usb/serial/option.c

//大概在532行,添加如下代码 ...... static const struct usb_device_id option_ids[] = { #if 1 //Added by Quectel { 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 */ #endif { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, ...... //大概在1390行,插入以下代码 ...... #ifdef CONFIG_PM .suspend = usb_wwan_suspend, .resume = usb_wwan_resume, #if 1 //Added by Quectel .reset_resume = usb_wwan_resume, #endif #endif ...... //在大约1459行,插入以下代码 ...... 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 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&EC20 R2.0&EG91&EG95&EG06&EP06&EM06&BG96'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); ......

/home/user/openwrt-sdk/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/drivers/usb/serial/qcserial.c

//大概在81行,注释以下代码 //{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

/home/user/openwrt-sdk/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/drivers/net/usb/qmi_wwan.c

//大概在617行,注释以下代码 //{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ //在大概436行,插入以下代码 ...... static const struct 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/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 */ #endif ...... //在文件的开头处插入如下代码 ...... #include #include #if 1 //Added by Quectel #include 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 #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; } /* very simplistic detection of IPv4 or IPv6 headers */ static bool possibly_iphdr(const char *data) { return (data[0] & 0xd0) == 0x40; } #endif #endif ...... //在大概395行,插入如下代码 ...... #if 1 //Added by Quectel if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) { dev_info(&intf->dev, "Quectel EC25&EC21&EC20 R2.0&EG91&EG95&EG06&EP06&EM06&BG96 work on RawIP mode\n"); dev->net->flags |= IFF_NOARP; #if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,9,1 )) /* 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 */ } #endif 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 ...... //在大约504行,插入如下代码 ...... static const struct driver_info qmi_wwan_info = { .description = "WWAN/QMI device", .flags = FLAG_WWAN, .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, .rx_fixup = qmi_wwan_rx_fixup, #if 1 //Added by Quectel .tx_fixup = qmi_wwan_tx_fixup, #endif ......

/home/lusy/openwrt-sdk/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/drivers/usb/serial/usb_wwan.c

//大概在460行,插入如下代码 ...... 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) { 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 return urb; ......

 

第二步:

修改配置,在内核中添加一些选项来支持EC20。这里参考了别人的博客,网址如下:https://blog.csdn.net/hunzhangzui9837/article/details/85916965

#make menuconfig

Kernel modules->USB Support

照着图片配置就行。。。

Network->

将以下选项编译进内核,但是我在我的make menuconfig中找不到wwan,先不管它,有就勾上。

wwan

chat

ppp

uqmi

Utilities->

将以下选项编译进内核,同样没找到comgt-ncm,不管它

comgt

comgt-ncm

usb-modeswitch

Luci->

1.Collections

luci

3.Applications

luci-app-multiwan

luci-app-qos

6.Protocols

luci-proto-3g

luci-proto-ppp

全都配置完了,开始编译

#make V=s

没有问题,全部编译成功。

 

第三步:

将编译好的固件烧入开发板。固件在/home/user/openwrt-sdk/bin/ramips路径下,名称为openwrt-ramips-mt7628-mt7628-squashfs-sysupgrade.bin。

启动开发板,先用

#ifconfig

查看一下当前ip地址,然后将ip地址复制到浏览器打开,即可通过LuCI登录板子进行配置。

选择如上图所示进入固件更新页面,进入如下页面

在这个页面更新固件就可以了。

更新完成后,就可以将EC20通过USB插入开发板了,如果你的驱动移植成功,将会看到如下log:

#cd /dev

查看一下是否有这几个文件。

 

第四步:

怎么通过4G模块上网。先进入LuCI页面。

如上图,进入接口配置。这里需要添加一个接口,下图已经添加好了,我下面教大家怎么添加。

点击Add new interface,名字自己起一个,选DHCP,选wwan0,如下图所示。

完成后记得修改一下这个接口的防火墙,如下图。

保存退出,最好板子也重启一下。

再次进入板子,输入

#ifconfig

就能看到你新加的接口了,4G网络正常的话这个接口应能获取到IP地址。

#ping www.baidu.com

PING www.baidu.com (183.232.231.172): 56 data bytes 64 bytes from 183.232.231.172: seq=0 ttl=53 time=131.616 ms 64 bytes from 183.232.231.172: seq=1 ttl=53 time=107.725 ms 64 bytes from 183.232.231.172: seq=2 ttl=53 time=112.723 ms 64 bytes from 183.232.231.172: seq=3 ttl=53 time=113.865 ms

OK,大功告成!

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3