Wi-Fi
本文将介绍 Allwinner 平台上的Tina Wi-Fi 软件框架,Wi-Fi驱动移植,与如何使用 Wi-Fi。
Tina Wi-Fi 软件结构
-
wifimanger
: 主要用于STATION模式,提供Wi-Fi连接扫描等功能。 -
softap manager
:提供启动AP的功能。 -
smartlink
: 对于NoInput
的设备,通过借助第三方设备(如手机)实现透传配网的功能,包括softap/soundwave/xconfig/airkiss/
等多种配网方式。 -
wpa_supplicant
: 开源的无线网络配置工具,主要用来支持WEP,WPA/WPA2和WAPI无线协议和加密认证的,实际上的工作内容是通过socket
与驱动交互上报数据给用户。 -
hostapd
: 是一个用户态用于AP和认证服务器的守护进程。 -
monitor
: Wi-Fi处于混杂设备监听模式的处理应用。
Wi-Fi 驱动
当前开发板板载的是 XradioTech 所设计的 XR829 Wi-Fi 模组。在 Tina Linux SDK 中已经内置了 XR829 的驱动并已经启用,在这里我们假定并没有启用本 Wi-Fi 模组,简单说明如何配置驱动。
从原理图中我们可以查到 IO 的对应关系:
SDC1_CLK | SDC1_CMD | SDC1_D0 | SDC1_D1 | SDC1_D2 | SDC1_D3 | CLK_FANOUT0 | WL_REG_ON | WL_WAKE_AP |
---|---|---|---|---|---|---|---|---|
PG0 | PG1 | PG2 | PG3 | PG4 | PG5 | PG6 | PH15 | PG7 |
要说明的是 WL_REG_ON
在原理图中叫做 WL_PMU_EN_SOC
设备树的配置
我们首先找到 SDC1
并启用它,设置 status = "okay"
&sdc1 {
bus-width = <4>; # SDIO 总线,4Bit
no-mmc; # 声明不是一个 MMC 设备
no-sd; # 声明不是一个 SD 设备
cap-sd-highspeed; # 高速模式
/*sd-uhs-sdr12*/
/*sd-uhs-sdr25*/
/*sd-uhs-sdr50;*/
/*sd-uhs-ddr50;*/
/*sd-uhs-sdr104*/
/*sunxi-power-save-mode;*/
sunxi-dis-signal-vol-sw; # 关闭 IO 电压修改
cap-sdio-irq; # 捕获中断
keep-power-in-suspend; # 保持持续供电
ignore-pm-notify; # 无视提醒
max-frequency = <50000000>; # 最大时钟
ctl-spec-caps = <0x8>;
status = "okay"; # 启用节点
};
然后找到 wlan0
节点,配置 wlan_busnum
、 wlan_regon
、wlan_hostwake
。另外也要配置一下供电。
wlan: wlan@0 {
compatible = "allwinner,sunxi-wlan"; # 选择sunxi-wlan 驱动
pinctrl-0 = <&wlan_pins_a>; # 32K 时钟输出脚绑定
pinctrl-names = "default"; # 命名输出脚 default
clock-names = "32k-fanout0"; # 命名时钟
clocks = <&clk_fanout0>; # 选择时钟源
wlan_busnum = <0x1>; # 设置使用的 SDIO 总线号,这里是 SDC1 所有
wlan_power_num = <1>; # PMU 使用的电源号,没有 PMU 此处注释
wlan_power1 = "axp2101-dcdc1"; # PMU 使用的电源名称,没有 PMU 此处注释
wlan_io_regulator = "axp2101-dcdc1"; # PMU 使用的电源名称,没有 PMU 此处注释
wlan_power_voltage = <3300000>; # 设置 Wi-Fi模块主电源 输出电压,没有 PMU 此处注释
wlan_io_voltage = <3300000>; # 设置 IO 电压,没有 PMU 此处注释
wlan_regon = <&pio PH 15 1 0x1 0x2 0>; # 配置启用 Wi-Fi 模块脚,上面的WL_REG_ON
wlan_hostwake = <&pio PG 7 14 0x1 0x2 0>; # 配置 Wi-Fi 模块唤醒主控脚,上面的WL_WAKE_AP
chip_en; # 启用模块
power_en; # 启用 Wi-Fi 电源
status = "okay"; # 启用这个节点
wakeup-source; # 这个节点是外部休眠唤醒源
};
Kernel 的配置
首先我们进入 make kernel_menuconfig
配置界面,在 Device Drivers > Network device support > Wireless LAN
找到 <M> XR829 WLAN support --->
选项,并启用为模块<M>
。
Tina Linux 的配置
然后进入 make menuconfig
找到 Kernel modules > Wireless Drivers
中的 <*> kmod-net-xr829-40M............................... xr829 support (staging)
选项并启用。这个选项将会把需要打包进入 rootfs
的 ko
,固件打包进入 rootfs
此时也可以去检查一下 Firmware
目录中的固件有没有被成功勾选。
最后,还需要勾选一下 Wi-Fi 的用户接口,方便测试 Wi-Fi。找到 Allwinner > Wireless
勾选 <*> wifimanager............................................. Tina wifimanager --->
Wi-Fi 模组移植
Wi-Fi模组工作的条件,需要硬件满足以下几个条件:
-
供电:一般有两路供电,其中 VCC-Wi-Fi 为主电源,VCCIO-Wi-Fi 为 IO 上拉电源。
-
使能:要能正常工作,需要 WL-REG-ON 给高电平。
-
SDIO:与SOC的通信有通过 USB,SDIO 等,这里以 SDIO 为例,其中 SDIO 0~3 为SDIO 的 4 条数据线。
-
唤醒主控:当系统休眠时,Wi-Fi 模组可通过 WL-WAKE-AP 通过中断的方式唤醒主控,有些模组也通过该引脚来作为主控接收数据的中断。
-
24/26/30/40/60MHz 时钟信号,依照 Wi-Fi 芯片而定
-
32.768KHz信号:根据模组而定,有些模组可以内部生成,有些需要外部单独输入该信号。
下面示例一款新模组移植到 Tina 平台的步骤。
选取了一块开发板,将 XR829 WI-FI 模块拆除,更换为了 RTL8723DS Wi-Fi 模块。商品名称:6223A-SRD
。
硬件修改
由于是 RTL8723DS,所以需要按照原理图里的说明修改跳线电阻,图示为 8723BS 的跳线电阻配置,需要安装 F
区域的电阻,摘除 B、C、E、G
区域的电阻。
根据原理图可知,我们只需要安装 RW27、RW28
两颗电阻,可以查看点位图获取它们的位置
如下图,焊接 10K
电阻即可。
内核驱动移植配置
首先,我们需要获得驱动程序,一般可以找厂家获得,也可以在 Github
Gitee
上找到。
检查 platform
文件夹内是否有 platform_ARM_SUNxI_sdio.c
这个接口源码。
如果没有,需要适配到 Tina 平台。主要修改的地方是调用Tina平台提供的上下电,扫卡函数,SDIO
驱动等等。工作量较大建议请专业人士进行移植。
然后将驱动文件复制进 kernel/linux-4.9/drivers/net/wireless
文件夹内
编辑 kernel/linux-4.9/drivers/net/wireless/rtl8723ds/Makefile
找到 Platform Related
设置区域,将其他选项全部关闭,只保留 CONFIG_PLATFORM_ARM_SUNxI = y
是开启的。
同时找到 Interface
区域,只启用 CONFIG_SDIO_HCI
接下来编辑 kernel/linux-4.9/drivers/net/wireless/Kconfig
,增加引索
source "drivers/net/wireless/rtl8723ds/Kconfig"
再打开 kernel/linux-4.9/drivers/net/wireless/rtl8723ds/Kconfig
查看对应的 config
符号,可以看到是 RTL8723DS
就可以在 kernel/linux-4.9/drivers/net/wireless/Makefile
里增加编译文件夹
obj-$(CONFIG_RTL8723DS) += rtl8723ds/
配置完成,就可以在 make kernel_menuconfig
里找到这个选项了,将其编译为模块。
Tina 适配
上面完成了内核驱动方面的配置,接下来是配置 Tina Linux 侧。由于部分 Wi-Fi 驱动需要文件系统挂载提供固件,所以需要在 Tina Linux 配置完成打包上面编译的驱动模块与固件,同时也要配置自动加载驱动的脚本才能使系统正常运行。
在这之前,我们先检查一下是否提供了 RTL8723DS 的固件,可以在 make menuconfig
s搜索是否有 8723DS 的固件存在。
可以看到,Tina Linux 提供了 RTL8723DS 的固件,名叫 r8723ds-firmware
可以进行下一步了。
修改 openwrt/target/v853/v853-vision/modules.mk
文件,增加 RTL8723DS 这个 kmod 选项。注意,DEPENDS
里包含的固件名称就是上面查找得到的名称。
define KernelPackage/net-rtl8723ds
SUBMENU:=$(WIRELESS_MENU)
TITLE:=RTL8723DS support (staging)
DEPENDS:= +r8723ds-firmware +@IPV6 +@USES_REALTEK
FILES:=$(LINUX_DIR)/drivers/net/wireless/rtl8723ds/8723ds.ko
AUTOLOAD:=$(call AutoProbe,8723ds)
endef
define KernelPackage/net-rtl8723ds/description
Kernel modules for RealTek RTL8723DS support
endef
$(eval $(call KernelPackage,net-rtl8723ds))
现在 make menuconfig
进入 Tina Linux 的配置界面,就可以在 Kernel modules > Wireless Drivers
中找到 <*> kmod-net-rtl8723ds........................... RTL8723DS support (staging)
,勾选他。
最后,还需要启用自动加载驱动的功能,位于 openwrt/target/v853/v853-vision/busybox-init-base-files/etc/init.d/rc.modules
,别忘了注释不需要的驱动。
insmod /lib/modules/4.9.191/8723ds.ko
设备树适配
与上文相同,注意启用 SDC1
节点与 wlan0
节点,配置wlan_busnum
、wlan_regon
、wlan_hostwake
。由于这里使用的是同款开发板所以不做再次说明,这里直接使用上面的设备树。
wlan: wlan@0 {
compatible = "allwinner,sunxi-wlan";
pinctrl-0 = <&wlan_pins_a>;
pinctrl-names = "default";
clock-names = "32k-fanout0";
clocks = <&clk_fanout0>;
wlan_busnum = <0x1>;
wlan_power_num = <1>;
wlan_power1 = "axp2101-dcdc1";
wlan_io_regulator = "axp2101-dcdc1";
wlan_power_voltage = <3300000>;
wlan_io_voltage = <3300000>;
wlan_regon = <&pio PH 15 1 0x1 0x2 0>;
wlan_hostwake = <&pio PG 7 14 0x1 0x2 0>;
chip_en;
power_en;
status = "okay";
wakeup-source;
};
测试移植的驱动
编译,打包。在编译的过程中可以看到编译了 RTL8723DS 相关驱动。
下载固件到开发板上,可以在开机的时候看到 LOG 输出
使用 ifconfig -a
命令可以看到 RTL8723DS 的两个 WLAN 都找到了
Wi-Fi 的使用
Wi-Fi 工作的几种模式
目前Tina平台上的Wi-Fi一般可处于3种工作模式,分别是 STA,AP,MONITOR。
- STATION:连接无线网络的终端,大部分无线网卡默认都处于该模式,也是常用的一种模式。
- AP:无线接入点,常称热点,比如路由器功能。
- MONITOR:也称为混杂设备监听模式,所有数据包无过滤传输到主机。
Wi-Fi 扫描网络与连接网络
Tina 提供了一套简易方便的 Wi-Fi 测试套件:wifi
,使用 wifi
命令可以设置 Wi-Fi 的工作模式,扫描网络,连接网络等等。它的使用方法可以通过运行 wifi -h
了解。这里首先介绍如何使用 wifi
扫描网络:
(1)设置 Wi-Fi
为 STA
模式
root@TinaLinux:/# wifi -o sta
(2)扫描当前网络环境的 Wi-Fi 站点
root@TinaLinux:/# wifi -s
(3)连接Wi-Fi(SSID:awol,密码 12345678)
root@TinaLinux:/# wifi -c awol 12345678
(4)连接网络后输入 ifconfig
即可查看当前 ip 地址
可以使用 ping
命令测试 网络连接
root@TinaLinux:/# ping www.baidu.com
它会输出以下内容
PING 202.108.22.5 (202.108.22.5): 56 data bytes
64 bytes from 202.108.22.5: seq=0 ttl=49 time=48.734 ms
64 bytes from 202.108.22.5: seq=1 ttl=49 time=48.624 ms
64 bytes from 202.108.22.5: seq=2 ttl=49 time=58.370 ms
64 bytes from 202.108.22.5: seq=3 ttl=49 time=69.119 ms
64 bytes from 202.108.22.5: seq=4 ttl=49 time=49.635 ms
(5)关闭Wi-Fi
root@TinaLinux:/# wifi -f
Wi-Fi 建立热点
(1)创建热点,SSID v853 密码 12345678
root@TinaLinux:/# wifi -o ap v853 12345678
(2)然后就可以扫描到 Wi-Fi 了,输入密码 12345678 进行连接
常见问题
编译问题
找不到wowlan变量
1.现象:
drivers/net/wireless/xr829/umac/main.c:870:17: error: 'struct wiphy' has no member named 'wowlan'
if ((hw->wiphy->wowlan->flags || hw->wiphy->wowlan->n_patterns)
2.原因:
wowlan成员变量受CONFIG_PM控制,没有打开导致的.休眠唤醒的依赖。
3.解决方案:
在内核配置
-Power management options --->
Device power management core functionality
找不到xxx.ko
1.现象:
sunxi_wlan_get_bus_index...xradio_core.ko undefined!
2.原因:
缺少配置misc。
3.解决方案:
在内核配置
m kernel_menuconfig-->
Device drivers-->
Misc devices-->
Allwinner rfkill driver
mmc_xxx undefined
1.现象:
drivers/built-in.o: In function scan_device_store':
lichee/linux-4.9/drivers/misc/sunxi-rf/sunxi-wlan.c:309: undefined reference tosunxi_mmc_rescan_card'
lichee/linux-4.9/drivers/misc/sunxi-rf/sunxi-wlan.c:309:(.text+0x5fc40): relocation truncated to fit:
R_AARCH64_CALL26 against undefined symbol `sunxi_mmc_rescan_card'
2.原因:
没有配置mmc。
3.解决方案
Device Drivers --->
<*> MMC/SD/SDIO card support --->
<*> Allwinner sunxi SD/MMC Host Controller support
缺少依赖库
1.现象:
Package kmod-net-xr829 is missing dependencies for the following libraries:
cfg80211.ko
mmc_core.ko
sunxi-wlan.ko
2.原因:
依赖库需要编译进内核,不能以模块方式编译进去。
3.解决方案。
在内核配置如下模块时,配置成y
CONFIG_RFKILL =y
CONFIG_CFG80211=y
CONFIG_MMC=y
CONFIG_MAC80211=y
驱动加载问题
博通模组联网时提示:No such device.
1.现象:
root@TinaLinux:/# wifi_add_network_test ssid passwd 1
*********************************
***Start wifi connect ap test!***
*********************************
wpa_suppplicant not running!
Cannot create "/data/misc/wifi/entropy.bin": No such file or directory
Wi-Fi entropy file was not created
ifconfig: SIOCGIFFLAGS: No such device
event_label 0x0
wifi on failed!
wifi on failed event 0xf001
2.原因:
firmware选择不匹配,导致驱动加载时下载失败.
- lsmod查看驱动已经正常加载
- dmesg 查看加载log发现:
[ 22.336336] dhdsdio_download_code_file: Open firmware file failed /lib/firmware/fw_bcm43438a1.bin
[ 22.346331] _dhdsdio_download_firmware: dongle image file download failed
表示firmware固件缺失(这里表示缺失fw_bcm43438a1.bin)
最后发现是在配置firmware时选择了ap6212,正常应该用ap6212a
3.解决方案
tina配置正确的firmware
firmware --->
└─> <*> ap6212a-firmware............................... Broadcom AP6212A firmware
XR829模组ifconfig显示:No such device
1.现象:
ifconfig: SIOCGIFFLAGS: No such device
2.原因:
firmware选择不匹配。
- lsmod查看驱动已经正常加载。
- dmesg 查看加载log发现:
[ 195.966066] [XRADIO_ERR] xradio_load_firmware: Wait for wakeup:device is not responding.
XR829换了40M晶振。
3.解决方案
tina配置选择40M晶振的firmware
firmware --->
[*] xr829 with 40M sdd
XR829 can't open /etc/wifi/xr_wifi.conf, failed
1.现象:
lsmod驱动没有正常加载。
2.原因:
- dmesg查看log:
[ 6.802331] [XRADIO_ERR] can't open /etc/wifi/xr_wifi.conf, failed(-30)
[ 6.802338] [XRADIO_ERR] Access_file failed, path:/etc/wifi/xr_wifi.conf!
[ 6.914044] sunxi-mmc sdc1: no vqmmc,Check if there is regulator
[ 7.028376] [XRADIO_ERR] xradio_load_firmware: Wait_for_wakeup: can't read control register.
busnum配置错误,原理图上使用的是sdc0.
3.解决方案
board.dts中配置wlan时
busnum = 0;
驱动加载问题总结
配置问题
1.内核驱动,Tina modules, Tina firmware三者必须正确对应同一个模组。
2.注意common下的modules.mk的编写。
3.Sdio的配置一定要根据原理图选择对应busnum。
可能导致:
1.扫卡失败。
2.下载firmware失败。
最终导致驱动加载失败。
供电问题
检查VCC_WIFI和VCC_IO_WIFI两路电。
不同模组对供电时序有一定要求,比如RTL8723ds需要两路电同时供电,针对有AXP的方案,一定要注意供电的配置,
特别是enable的时间。
1.硬件方面:主要排查两路电的供电方案,是否是同一路供电,若是分开供电,要考虑两路供电的时序,
例如DCDC1--->VCC_WIFI,LDOA--->VCC_IO_WIFI,那么DCDC1和LDOA的时序就得考虑。
2.软件方面主要是sysconfig.fex或者boart.dts的配置,分开供电的是否需要单独配置。
如:R818硬件设计是两路电分开供电。
可能导致:
1.扫卡失败。
2.下载firmware失败。
3.sdio_clk没有时钟。
4.32k竞争不起振。
最终导致驱动加载失败。
sdio问题
1.sdio busnum配置错误.
2.驱动WL-REG-ON的方式不对.例如:
XR819模块出现
[SBUS_ERR] sdio probe timeout!
[XRADIO_ERR] sbus_sdio_init_failed
这个问题主要是sdio扫卡失败,跟sdio上电时序有关,可在drivers/net/wireless/xradio/wlan/platform.c中
xradio_wlan_power函数sunxi_wlan_set_power(on)后面加上一段延时。
RLT8723ds需要先高-低-高的方式.
可能导致:
1.扫卡失败。
2.下载firmware失败。
3.sdio_clk没有时钟。
4.32k晶振不起振。
5.WL-REG-ON无法正常被拉高。
最终导致驱动加载失败。
起wlan0网卡问题
RTL8723DS ifconfig wlan0 up: No such device
1.现象:
ifconfig: SIOCGIFFLAGS: No such device
2.原因:
- lsmod查看驱动已经正常加载。
- dmesg查看log未发现异常。
- 排查sdio_clk, regon_on,32k,都正常。
- 两路供电都正常配置。
- 对比其他平台硬件发现,供电方式不一样,两路电采用了分开供电,咨询RTL需要同时上电。
3.解决方案
硬件更改,VCC_WIFI/VCC_IO_WIFI用同一路电供电。
RTL8723DS 无法自启动wlan0
1.现象:
启动脚本/etc/init.d/wpa_supplicant中会自启动wlan0
但是每次启动启动都自启动失败,然后手动ifconfig wlan0 up正常。
2.原因:
AP-WAKE_BT引脚被接了上拉电阻,进入测试模式了。
3.解决方案
硬件摘除上拉电阻。
起wlan0网卡问题总结
wlan0启动失败问题目前遇到的都是与硬件相关的,如果不能自加载一般采用ifconfig wlan0 up先手动加载看看打印提示。同时让硬件帮忙check一下供电和一些io的上下拉电阻。
supplicant服务问题
找不到wpa_suplicant.conf文件
1.现象:
起supplicant失败
- ps发现没有supplicant进程.
- 于是手动执行wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B
提示:
Failed to open config file '/etc/wpa_supplicant.conf', error: No such file or directory
Failed to read or parse configuration '/etc/wpa_supplicant.conf'.
2.原因:
路径错误。
3.解决方案
tina正常的路径一般在/etc/wifi/wpa_supplicant.conf
在wifimanage包下面配置正确的路径,保持和启动脚本一致.