跳转至

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_busnumwlan_regonwlan_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)选项并启用。这个选项将会把需要打包进入 rootfsko ,固件打包进入 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_busnumwlan_regonwlan_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-FiSTA 模式

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 地址

wifi_if

可以使用 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 进行连接

wifi_ap

常见问题

编译问题

找不到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包下面配置正确的路径,保持和启动脚本一致.