ZYBO移植MT7601驱动实现WiFi热点

STA模式无线网卡驱动编译

内核配置

首先输入CROSS_COMPILE=arm-linux-gnueabihf- make zynq_zybo_config

注意
配置内核命令是make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
不要写错为make menuconfig,否则编译出来的内核文件不能用!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>Networking support 
--- Wireless
<*> cfg80211 - wireless configuration API
[ ] nl80211 testmode command
[ ] enable developer warnings
[ ] cfg80211 certification onus
[*] enable powersave by default
[ ] use statically compiled regulatory rules database
[*] cfg80211 wireless extensions compatibility
<*> Generic IEEE 802.11 Networking Stack (mac80211)
[*] Minstrel
[*] Minstrel 802.11n support

> Device Drivers > Network device support
--- Wireless LAN
[*] MediaTek devices
<M> MediaTek MT7601U (USB) support
[*] Ralink devices
<*> Ralink driver support --->
<*> Ralink rt27xx/rt28xx/rt30xx (USB) support

编译内核

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j2

生成uimage文件ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make UIMAGE_LOADADDR=0x8000 uImage

生成设备树 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make zynq-zybo.dtb

编译模块

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make modules

编译出來的mt7601u.ko文件在drivers/net/wireless/mediatek/mt7601u下面

把mt7601u.ko复制到开发板备用。在开发板上启动linux,执行

insmod mt7601u.ko

在我的开发板上加载成功后显示这些信息

1
2
3
4
usb 1-1: reset high-speed USB device number 2 using ci_hdrc                     
mt7601u 1-1:1.0: ASIC revision: 76010001 MAC revision: 76010500
mt7601u 1-1:1.0: EEPROM ver:0c fae:00
usbcore: registered new interface driver mt7601u

执行ifconfig -a命令会看到wlan0设备

移植wireless tools工具

编译步骤
  1. 进入wireless_tools.29目录
  2. 修改Makefile

vim Makefile

  1. 修改位置如下:
1
2
3
CC = arm-linux-gnueabihf-gcc
AR = arm-linux-gnueabihf-ar
RANLIB=arm-linux-gnueabihf-ranlib

Note:

  1. 确认 ~/.bashrc添加了一下内容
    export PATH=$PATH:/opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/
    export CROSS_COMPILE=arm-linux-gnueabihf-
  2. 否则执行 source /opt/Xilinx/Vivado/2017.4/settings64.sh

  1. 输入make开始编译

  2. 将生成的工具ifrename, iwconfig, iwevent, iwgetid, iwlist, iwpriv, iwspy可执行文件拷贝到根文件系统目录/bin目录

  3. iwlib.so、libiw.so.29动态库文件放在开发板/lib文件夹
  4. 在开发板终端输入iwlist等命令查看是否移植成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@Zybo:~# iwlist                                                             
Usage: iwlist [interface] scanning [essid NNN] [last]
[interface] frequency
[interface] channel
[interface] bitrate
[interface] rate
[interface] encryption
[interface] keys
[interface] power
[interface] txpower
[interface] retry
[interface] ap
[interface] accesspoints
[interface] peers
[interface] event
[interface] auth
[interface] wpakeys
[interface] genie
[interface] modulation

系统测试

下面我们来验证MT7601驱动加载正常。

  1. 加载驱动
    如果当时选择拷贝.ko文件,需要insmod /…/mt7601u.ko;
    如果编译内核时选择了<*> MediaTek MT7601U (USB) support,你开机就自动加载了驱动模块。

  2. 插入无线网卡,输入ifconfig wlan0 up

输入ifconfig指令,可以看到waln0:

1
2
3
4
5
6
7
8
wlan0     Link encap:Ethernet  HWaddr 00:0C:0B:00:0F:52                         
inet addr:192.168.1.12 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::20c:bff:fe00:f52%lo/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:58 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:504 (504.0 B) TX bytes:14776 (14.4 KiB)
  1. 使用wireless tools工具扫描、连接热点
    常用的指令有两个:
    • 扫描附近的热点信息:iwlist 无线网卡名称 scanning
      扫描结果类似下面这样:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      root@linaro-developer:~# iwlist wlan0 scanning                                                                           
      wlx000c0b000f52 Scan completed :
      Cell 01 - Address: 3A:69:6C:05:C3:D4
      Channel:1
      Frequency:2.412 GHz (Channel 1)
      Quality=27/70 Signal level=-83 dBm
      Encryption key:off
      ESSID:"HUST_WIRELESS"
      Bit Rates:11 Mb/s
      Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
      36 Mb/s; 48 Mb/s; 54 Mb/s
      Mode:Master
      Extra:tsf=000000021d90b4ab
      Extra: Last beacon: 1640ms ago
      IE: Unknown: 000D485553545F574952454C455353
      IE: Unknown: 010196
      IE: Unknown: 030101
      IE: Unknown: 050400010000
      IE: Unknown: 0706434E20010D1B
      IE: Unknown: 2A0100
      IE: Unknown: 2F0100
      IE: Unknown: 32088C9298A4B0C8606C
      IE: Unknown: 2D1AAD1917FFFFFF0000000000000000000000000000000
      IE: Unknown: 3D160108040000000000000000000000000000000000000
      IE: Unknown: 7F080000000000000040
      IE: Unknown: DD090010180201001C0000
      IE: Unknown: DD07001AA96B8B4567
      IE: Unknown: DD180050F20201018F000353280027A4000042435E00620
  • 连接热点:iwconfig 无线网卡名称 essid "wifi名称"(没有密码)或者
    iwconfig 无线网卡名称 essid "wifi名称" key s:1234-5678-90(假设密码1234567890,每四位一组)
    e.g.连接一个没有密码的wifi,名称D24G
    1
    2
    3
    4
    5
    6
    7
    root@Zybo:~# iwconfig wlan0 essid "D24G"                                        
    root@Zybo:~# wlan0: authenticate with 2a:b2:1a:50:5b:ba
    wlan0: send auth to 2a:b2:1a:50:5b:ba (try 1/3)
    wlan0: authenticated
    wlan0: associate with 2a:b2:1a:50:5b:ba (try 1/3)
    wlan0: RX AssocResp from 2a:b2:1a:50:5b:ba (capab=0x421 status=0 aid=2)
    wlan0: associated

这时候连接成功也上不了网,需要分配IP和配置DNS服务器

1
2
3
udhcpd wlan0 
vim /etc/resolv.conf
添加:nameserver 8.8.8.8

ping一下测试是否可以连接外网:

1
2
3
4
5
root@Zybo:~# ping qq.com                                                        
PING qq.com (182.254.74.167): 56 data bytes
64 bytes from 182.254.74.167: seq=0 ttl=46 time=37.261 ms
64 bytes from 182.254.74.167: seq=1 ttl=46 time=50.413 ms
64 bytes from 182.254.74.167: seq=2 ttl=46 time=35.170 ms

编译好的结果在下面:

https://github.com/fangzr/Zybo_Cross_Compile_Result

AP模式无线网卡驱动编译

下载源码

交叉编译

make LINUX_SRC=/.../linux-digilent ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

编译成功后驱动在mt7601u-ap/os/linux/mt7601Uap.ko

编译成功后驱动在mt7601u-AP/OS/LINUX/mt7601Uap.ko,再在/下建立WIFI/RT2870AP文件夹,把RT2870AP.txt文件复制到此文件夹内。

1
2
mkdir -p /etc/wifi/RT2870AP
cp -v RT2870AP.txt /etc/wifi/RT2870AP/

若出现编译错误,如:

1
2
/home/.../xilinx/driver/wifi/mt7601u-ap/os/linux/../../ap/ap_data.c:5213:30:error: passing argument 2 of ‘hex_dump’ from incompatible pointer type [-Werror=incompatible-pointer-types]
hex_dump("DataFrameHeader", pHeader, 36);

则需要修改的linux-XLNX主根目录下的Makefile文件,在817行处修改

1
2
3
4
5
6

816 # enforce correct pointer usage
817 KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
修改为
816 # enforce correct pointer usage
817 KBUILD_CFLAGS += $(call cc-option,-Wno-error=incompatible-pointer-types)

在我这里,编译驱动并且加载成功了,但是后面启动无线适配器时却工作不正常,即开启AP模式后,使用iwconfig查看时,生成了很多个接口,从ra0 - ra15,essid是HT_AP0,HT_AP1 …… ..然而在手机wifi连接界面上只看到了HT_AP0,连接会显示失败。后面我在这个博客看到了解决办法,我遇到的问题是驱动没有成功读取配置文件,这时候驱动就会使用默认的配置。这时可以修改mt7601u-AP / OS / LINUX / rt_linux.c

1
2
3
4
5
6
7
8
9
10
11
12
int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen)
{
DBGPRINT(RT_DEBUG_ERROR, ("add: %p %p\n", osfd->f_op, osfd->f_op->read));
/* The object must have a read method */
if (osfd->f_op /*&& osfd->f_op->read*/) {
//return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
return vfs_read(osfd, pDataPtr, readLen, &osfd->f_pos);
} else {
DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
return -1;
}
}

修改保存,重新编译。在启动开发板之前,需要在UBOOT界面修改bootargs参数,比如我的开发板bootargs参数加上coherent_pool = 2M
否则驱动加载会出错:rt2870: probe of 1-1:1.0 failed with error -1

加载成功后使用的iwconfig命令可以查看到以下信息。

1
2
3
4
5
6
7
8
9
10
[root@zybo:/home]#iwconfig                                                     
lo no wireless extensions.

sit0 no wireless extensions.

eth0 no wireless extensions.

ra0 IEEE 802.11bgn ESSID:"test"
Mode:Master Channel:11 Access Point: 28:F3:66:71:88:81
Bit Rate=72 Mb/s

使用手机连接成功,AP热点名是在test。

  • 注意:目前仅仅是实现了手机和开发板的局域网通信,由于在AP模式下没有配置DNS和IP转发规则,所以并不能访问外部网路。