Ubuntu 下小度 Wifi 的 64 位驱动

我们已经知道,小度Wifi 使用的芯片是 MT7601U,网上能够找到的对应驱动的源代码包名为 D-PO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2,有的下载链接里没有那个减号。

这个源代码要想能够编译成功,要针对几个问题进行修订(共涉及 4 个文件):
1、增加小度 Wifi 的识别;
2、对 64 位系统兼容。

首先是增加小度 Wifi 的识别。这个需要对 common/rtusb_dev_id.c 进行改动,在 {USB_DEVICE(0x148f,0x7601)}, /* MT 6370 */ 这一行下新增以下三行代码:
{USB_DEVICE(0x2955,0x0001)}, /* XiaoDu Wifi */
{USB_DEVICE(0x2955,0x1001)}, /* XiaoDu Wifi */
{USB_DEVICE(0x148f,0x760b)}, /* 360 Wifi */
能看出来,支持的小度 Wifi 有两个版本,最后一行是对 360 Wifi 进行支持的(未测试)。

对 common/mlme.c 作一个小修订,找到 MlmeResetRalinkCounters 函数,把原来的 (UINT32)&pAd->RalinkCounters.OneSecEnd – (UINT32)&pAd->RalinkCounters.OneSecStart) 语句修改为 (UINT32)(&pAd->RalinkCounters.OneSecEnd – &pAd->RalinkCounters.OneSecStart) 即可,这是一个指针差的计算,原来的前强转后相减,在 32 位系统上问题不大,在 64 位系统上则会产生错误。

接下来要修改 include/os/rt_linux.h,主要涉及到对数据包的数据结构进行访问的几个操作宏,把:
#define GET_OS_PKT_DATATAIL(_pkt) \
(RTPKT_TO_OSPKT(_pkt)->tail)
#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \
((RTPKT_TO_OSPKT(_pkt))->tail) = (PUCHAR)((_start) + (_len))
改为
#define GET_OS_PKT_DATATAIL(_pkt) \
(skb_tail_pointer(RTPKT_TO_OSPKT(_pkt)))
#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \
(skb_set_tail_pointer(RTPKT_TO_OSPKT(_pkt), \
(int)((_start) – GET_OS_PKT_DATAPTR(_pkt)) + (_len)))
,再把:
#define GET_OS_PKT_END(_pkt) \
(RTPKT_TO_OSPKT(_pkt)->end)
改为
#define GET_OS_PKT_END(_pkt) \
(skb_end_pointer(RTPKT_TO_OSPKT(_pkt)))
,即可。

最后修改 os/linux/rt_linux.c。定位到函数 duplicate_pkt,把其中的两处 skb->tail 改为 GET_OS_PKT_DATATAIL(skb)。定位到函数 ClonePacket,把:
pClonedPkt->dev = pRxPkt->dev;
pClonedPkt->data = pData;
pClonedPkt->len = DataSize;
pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
改为
SET_OS_PKT_NETDEV(pClonedPkt, pRxPkt->dev);
SET_OS_PKT_DATAPTR(pClonedPkt, pData);
SET_OS_PKT_LEN(pClonedPkt, DataSize);
SET_OS_PKT_DATATAIL(pClonedPkt, pData, DataSize);
。定位到函数 wlan_802_11_to_802_3_packet,把:
pOSPkt->dev = pNetDev;
pOSPkt->data = pData;
pOSPkt->len = DataSize;
pOSPkt->tail = pOSPkt->data + pOSPkt->len;
改为
SET_OS_PKT_NETDEV(pOSPkt, pNetDev);
SET_OS_PKT_DATAPTR(pOSPkt, pData);
SET_OS_PKT_LEN(pOSPkt, DataSize);
SET_OS_PKT_DATATAIL(pOSPkt, pData, DataSize);
。定位到函数 RtmpOsSetPacket,把:
pOSPkt->dev = pNetDev;
pOSPkt->data = pData;
pOSPkt->len = DataSize;
pOSPkt->tail = pOSPkt->data + pOSPkt->len;
改为
SET_OS_PKT_NETDEV(pOSPkt, pNetDev);
SET_OS_PKT_DATAPTR(pOSPkt, pData);
SET_OS_PKT_LEN(pOSPkt, DataSize);
SET_OS_PKT_DATATAIL(pOSPkt, pData, DataSize);
。定位到函数 send_monitor_packets,把:
skb_put(pOSPkt, (pData – pOSPkt->data));
skb_pull(pOSPkt, (pData – pOSPkt->data));
改为
skb_put(pOSPkt, (pData – GET_OS_PKT_DATAPTR(pOSPkt)));
skb_pull(pOSPkt, (pData – GET_OS_PKT_DATAPTR(pOSPkt)));
。定位到函数 __RtmpOSFSInfoChange,把:
pOSFSInfo->fsuid = current_fsuid();
pOSFSInfo->fsgid = current_fsgid();
改为
pOSFSInfo->fsuid = current_fsuid().val;
pOSFSInfo->fsgid = current_fsgid().val;
。至此,所有修改完毕。

正常 make,sudo make install,然后再 sudo modprobe mt7601Usta 即可。

试用的感觉,这个驱动的效率应该很低。难道是我没有生成 release 的版本?

2条评论


  1. 你好
    我照着你说的改了一遍,但是不能编绎通过
    能发一份可编绎通过的64位小度wifi驱动给我吗?
    万分感谢!

    回复

    1. 我找找看,找到了就给你发一份。

      回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注