跳到主要内容

Neardi Wi-Fi适配手册

1. 前言

模块芯片接口
FD7256SEA6x21QxSDIO
FD7155UEA6x21QxUSB
FD7352SSWT6652xSDIO
FD7352PSWT6652xPCIE
FD7257SSWT6621SSDIO

2. 驱动包

🔖 seekwave的驱动还在不断完善,目录结构也在不断变化,具体以拿到的最新驱动为准;

⭐ SWT6652x (2x2 Gen1)

# SWT6652_H25.43.4.1_F25.44.1.2/swt6652x 目录下
$ tree -L 2
.
├── drivers # BSP包中驱动源码
│ ├── seekwaveplatform_v20 # 总线层驱动包,如SDIO USB PCIE传输层
│ ├── skwbt # 蓝牙驱动程序
│ └── skwifi # 网络层驱动,主要用于注册wifi设备
├── firmware
│ ├── PCIE-Firmware # PCIE接口wifi模块固件
│ ├── SDIO-Firmware # SDIO接口wifi模块固件
│ ├── USB20-Firmware # USB20接口wifi模块固件
│ └── USB30-Firmware # USB30接口wifi模块固件
├── include # 驱动头文件
│ └── linux
├── Makefile # 外部编译的Makefile文件,
└── sdio.patch

⭐ SWT6621S (1x1 Gen2)

# SWT6621S_H25.34.7.1_F25.34.6.1/seekwave/swt6621s 目录下
$ tree -L 2
.
├── drivers # BSP包中驱动源码
│ ├── Makefile # 外部编译的Makefile文件
│ ├── seekwaveplatform_lite # 总线层驱动,比如SDIO USB PCIE传输层
│ ├── swt6621s_wifi # 网络层驱动,主要用于注册wifi设备
│ └── swtbt4l # 蓝牙驱动程序
├── firmware # WiFi运行时固件,第一步就需要把固件发送给wifi芯片
│ ├── SDIO-Firmware # 用于传输接口为SDIO的wifi模块
│ └── USB-Firmware # 传输接口为USB的wifi模块
├── include # 驱动头文件
│ └── linux
└── Makefile # 外部编译的Makefile文件

⭐ EA6x21Qx (1x1 Gen1)

# EA6x21Qx_H25.35.2.1_F25.35.2.2_MP_In 目录下
$ tree -L 2
.
├── kernel
│ ├── drivers # wifi驱动
│ └── include # 驱动头文件
├── lib
│ ├── SDIO-Firmware # WiFi运行时固件,第一步就需要把固件发送给wifi芯片
│ └── USB-Firmware
└── Readme.txt

3. 基于RK平台

3.1 添加驱动

🔖 这里以swt6621s为例,其它型号的只是目录名称不同整体流程是相同的;​

⭐ 进入到xxx\SWT6621S_H25.34.7.1_F25.34.6.1\seekwave\swt6621s\driver目录;导航到 swt6621s 驱动目录

⭐ 将seekwaveplatform_lite目录完整的拷贝到你的SDK目录下的drivers/misc目录中,以我的环境为例;拷贝 seekwaveplatform_lite 至 drivers/misc

⭐ 修改drivers/misc下的MakefileKconfig文件;编辑 drivers/misc/Makefile编辑 drivers/misc/Kconfig

⭐ 将swt6621s_wifi目录完整的拷贝到kernel-6.1/drivers/net/wireless/rockchip_wlan目录下,并修改此目录下的MakefileKconfig文件;复制后 rockchip_wlan 目录结构编辑 rockchip_wlan/Makefile编辑 rockchip_wlan/Kconfig

⭐ 添加bt的驱动程序将swtbt4l拷贝到drivers/bluetooth目录下,修改MakefileKconfig文件;拷贝 swtbt4l 至 drivers/bluetooth编辑 drivers/bluetooth/Makefile编辑 drivers/bluetooth/Kconfig

⭐ 将头文件skw_platform_data.h拷贝到include/linux/platform_data下;拷贝 skw_platform_data.h 至 include/linux/platform_data

3.2 打开编译选项

🔖 下面的配置添加到当前使用的内核配置config文件中;

🔖 不同接口的wifi模块需在menuconfig中切换,之后重新编译生成对应接口的驱动;在 menuconfig 中切换接口

SWT6652x编译选项配置(sdio)

CONFIG_WLAN_VENDOR_SWT6652=m
CONFIG_SEEKWAVE_BSP_DRIVERS_V20=y
CONFIG_SEEKWAVE_PLD_RELEASE=y
CONFIG_SKW_SDIOHAL=m
CONFIG_SKW_BT=m

SWT6621s编译选项配置(sdio)

CONFIG_SEEKWAVE_BSP_DRIVERS=y
CONFIG_SEEKWAVE_PLD_RELEASE=y
CONFIG_SKW_SDIOHAL=m
CONFIG_WLAN_VENDOR_SEEKWAVE=m
CONFIG_SKW_BT=m
CONFIG_WLAN_VENDOR_SWT6621S=m

EA6x21Qx编译选项配置 (sdio)

CONFIG_SEEKWAVE_BSP_DRIVERS=y
CONFIG_SEEKWAVE_PLD_RELEASE=y
CONFIG_SKW_SDIOHAL=m
CONFIG_WLAN_VENDOR_SEEKWAVE=m
CONFIG_SKW_BT=m

3.3 编译生成ko

🔖 ​完成上面的步骤之后重新编译内核,即可生成驱动模块;

⭐ SWT6652x

# 接口层驱动,初始化wifi模块以及建立通信链路
xx/kernel/drivers/misc/seekwaveplatform_v20/skw_sdio_v20.ko
# 网络层驱动,用于注册创建wifi设备
xx/kernel/drivers/net/wireless/rockchip_wlan/skwifi/swt6652_wifi.ko
# 蓝牙驱动
xx/kernel/drivers/bluetooth/skwbt/skwbt.ko

⭐ SWT6621s

# 接口层驱动,初始化wifi模块以及建立通信链路
xx/kernel/drivers/misc/seekwaveplatform_lite/skw_sdio_lite.ko
# 网络层驱动,用于注册创建wifi设备
xx/kernel/drivers/net/wireless/rockchip_wlan/swt6621s_wifi/swt6621s_wifi.ko
# 蓝牙驱动
xx/kernel/drivers/bluetooth/skwbt/skwbt.ko

⭐ EA6x21Qx

# 接口层驱动,初始化wifi模块以及建立通信链路
xx/kernel/drivers/misc/seekwaveplatform/skw_sdio.ko
# 网络层驱动,用于注册创建wifi设备
xx/kernel/drivers/net/wireless/rockchip_wlan/seekwave/skw.ko
# 蓝牙驱动
xx/kernel/drivers/bluetooth/skwbt/skwbt.ko

3.4 设备树配置

🔖 配置仅作为参考,具体配置要根据不同的平台以及不同内核版本修改;

sdio接口设备树配置(仅控制器配置):

&{/} {
/* 时序控制 */
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
/* 时钟来源,我们的wifi模块内部有晶振,此项配置可以删除 */
//clocks = <&hym8563>;
//clock-names = "ext_clock";
pinctrl-names = "default";
pinctrl-0 = <&wifi_wake_up>;
/*
* On the module itself this is one of these (depending
* on the actual card populated):
* - SDIO_RESET_L_WL_REG_ON
* - PDN (power down when low)
*/
post-power-on-delay-ms = <200>;
/* 这里为必配项,对应wifi模块的CHIP_EN */
reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
};
};
/* sdio总线接口配置 */
&sdio {
/* sdio总线传输时钟配置 */
max-frequency = <200000000>;
supports-sdio;
//no-mmc;
bus-width = <4>;
disable-wp;
cap-sd-highspeed;
cap-sdio-irq;
keep-power-in-suspend;
mmc-pwrseq = <&sdio_pwrseq>;
non-removable;
pinctrl-names = "default";
pinctrl-0 = <&sdiom0_pins>;
sd-uhs-sdr104;
status = "okay";
};

PCIE接口设备树配置(仅控制器配置):

&pcie0 {
num-lanes = <1>;
vpcie3v3-supply = <&vcc3v3_pcie>;
pinctrl-names = "default";
pinctrl-0 = <&pcie_clkreqnb_cpm>;
/* PCIE ReSet GPIO 必须配置 */
ep-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
status = "okay";
};

⭐ 用于SeekWave驱动匹配设备树配置(不管什么接口都要添加此配置):

/* */
&{/} {
/* seekwave platform */
seekwave_boot: seekwave_boot {
compatible = "seekwave,sv6160";
dma_type = <1>;
status = "okay";
/* seekwave 功率文件配置, 后面会有详细对应 */
seekwave_nv_name = "SEEKWAVE_NV_SWT6652_SHARE.bin";
};
};

3.5 芯片固件(固件以及蓝牙配置文件)

🔖 这部分固件由wifi驱动通过对应的硬件接口发送给wifi芯片;

🔖 默认放在rootfs中的/lib/firmware目录下,加载驱动前要拷贝到这个目录下;

🔖 NV_BIN是通道的参数文件(共享/独立),RF_BIN是wifi模块的功率配置文件;

DRAM固件IRAM固件NVBIN配置RF_BIN配置bluetooth
SWT6652x(SDIO)SWT6652_DRAM_SDIO.binSWT6652_IRAM_SDIO.binSEEKWAVE_NV_SWT6652_SHARE.binEA6316_SEEKWAVE_R00006.binsv6316.nvbin
SWT6652x(PCIE)SWT6652_DRAM_PCIE.binSWT6652_IRAM_PCIE.binSEEKWAVE_NV_SWT6652_SHARE.binEA6316_SEEKWAVE_R08006.binsv6316.nvbin
SWT6652x(USB)SWT6652_DRAM_USB.binSWT6652_IRAM_USB.binSEEKWAVE_NV_SWT6652_SHARE.binEA6316_SEEKWAVE_R04006.binsv6316.nvbin

3.6 加载驱动

🔖 加载顺序: 接口层驱动 --> 网络层驱动 --> 蓝牙驱动;

🔖 加载驱动之前要先检查对应硬件接口状态是否有识别到设备;

⭐ 查看总线是否已经枚举到设备,分别以SDIOPCIEUSB为例:SDIO 总线枚举示例USB 总线枚举示例

待补充pcie的图片

PCIE 总线枚举示例

⭐ 加载驱动这里以SWT6652x为例,正常驱动加载之后生成wlanx设备节点:加载日志与 wlanx 设备 1加载日志与 wlanx 设备 2加载日志与 wlanx 设备 3加载日志与 wlanx 设备 4加载日志与 wlanx 设备 5

4. 常用工具

4.1 连接

⭐ 方式1:使用NetworkManager自带的管理工具进行连接;

# 使用NetworkManager提供的接口进行网络连接
# 查看NetworkManager服务状态,是否接管网络设置
nmcli networking | nmcli n
# nmcli更为具体的使用方法,这里就不再赘述在https://zhuanlan.zhihu.com/p/395236748
# 扫描wifi
nmcli dev wifi
# 扫描结果
IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS>
22:1F:54:52:A1:41 CMCC-PXJJ Infra 2 130 Mbit/s 100
# 连接wifi
sudo nmcli dev wifi connect xxxx password xxxx
# 之后查看就已经连接上WiFi了,而且ip地址已经获取了
Device 'wlan0' successfully activated with xxxx
# 这个命令前提是NetworkManager可以接管网络,而且wpa_supplicant服务要提前启动
# 查看获取到的ip地址
ip addr show wlan0 | ip a s wlan0 | ifconfig

⭐ 方式2:使用wpa_supplicant工具进行连接,此方式更通用;

# 使用wpa_supplicant方式连接
# 首先需要启动wpa_supplicant服务,很多厂商都是放在/etc/wpa_supplicant.conf中
cat /etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant #默认不建议修改!
ap_scan=1
update_config=1 #这个配置使wpa_cli命令配置的热点保存到conf文件里面(wpa_cli
save_config)
#AP配置项
network={
ssid="DoorNet-A" # Wi-Fi名字
psk="********-a" # Wi-Fi密码
key_mgmt=WPA-PSK # 加密配置,不加密则改为:key_mgmt=NONE
}
# 启动服务
wpa_supplicant -i wlan0 -D nl80211 -c /etc/wpa_supplicant.conf
# 扫描wifi
wpa_cli -i wlan0 scan
wpa_cli -i wlan0 scan_result
# 进入交互模式或者直接输入命令连接wifi
# 交互模式 wpa_cli -i wlan0
wpa_cli -i $STA_iface add_network $index ssid "\"$ssid\""
wpa_cli -i $STA_iface set_network $index ssid "\"$ssid\""
wpa_cli -i $STA_iface set_network $index psk "\"$psk\""
wpa_cli -i $STA_iface enable_network $index

⭐ 方式3:使用NetworkManager提供的图形化界面进行连接

# nmtui界面连接
# 前提可以使用NetworkManager服务
nutui --> Activate a connection --> select wifi --> passwd --> connect

4.2 AP功能

⚠️ 开启AX模式需要hostapd工具版本大于等于2.10

⭐ 使用iw命令在wlan0上虚拟出一个接口用于AP(也可以不做)

# 使用iw命令创建一个新的接口,用于station和ap同时使用
iw dev wlan0 set type station
iw dev wlan0 interface add ap0 type __ap

⭐ 创建完成之后配合hostapd以及dhcpd命令进行wifi热点的创建

# hostpad在2.10版本才支持ax模式AP热点的创建,其主要是创建一个软件模拟的AP模式,因为大多数嵌入式wifi模块并不支持物理AP,在支持物理AP的wifi模块上安装驱动之后会自动创建一个AP接口用于AP
apt install hostapd
# dhcpd是下发ip地址的工具,相似功能的还有udhcpd但是并不好用
apt install isc-dhcp-server
# rfkill工具,本例中用来解锁无线设备
apt install rfkill
# 开启防火墙net转发,用于共享网络,修改成需要共享的网络接口
bash -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
iptables -t nat -A POSTROUTING -o wlan0/eth0/ethx -j MASQUERADE
# 关闭NetworkManager对网卡的控制, 这里根据你生成的动态修改
nmcli d disconnect wlan0
# 启动dhcpd和hostapd,保存hostapd的日志
# hostapd的热点配置文件可以找fae或者测试索取
nohup hostapd xxx.conf > xxx.log 2>&1 &
dhcpd ap0
# dhcpd配置方法,打开/etc/dhcp/dhcpd.conf,添加如下内容
subnet 192.168.0.0 netmask 255.255.255.0
{
range 192.168.0.2 192.168.0.10;
option routers 192.168.0.1;
option domain-name-servers 192.168.0.1,114.114.114.114,8.8.8.8; # DNS
}
# 查看服务启动情况
ps -ef | head -n1 && ps -ef | egrep "dhcpd|hostapd"

4.3 蓝牙功能

⭐ 使用bluez协议包提供的工具进行连接,如果没有可以手动交叉编译;

# 首先需要安装bluez这个工具,这个工具是蓝牙的协议栈,没有这个工具无法正常使用蓝牙
# 启动bluetoothctl
sudo bluetoothctl
# 使能蓝牙
power on
# 设置蓝牙可以被发现
discoverable on
# 设置可以被配对
pairable on
# 扫描周围蓝牙设备
scan on
# 看到想要连接的就可以停止扫描了
scan off
# 然后配对
pair xx:xx:xx:xx:xx:xx
# 连接蓝牙设备需要安装pulseaudio-module-bluetooth软件包,并启动pulseaudio服务
sudo apt -y install pulseaudio-module-bluetooth
pulseaudio --start
# 再次进入bluetoothctl界面
sudo bluetoothctl
# 查看已经配对的设备
paired-devices
# 使用已经配对的蓝牙地址进行连接
connect xx:xx:xx:xx:xx:xx
# 如果提示连接成功就可以了
# 这种方法可以进行连接配对,但是无法进行调试

5. 常见问题

5.1 无法枚举到设备

💁‍♂️ 先寻求硬件帮助,检查外围电路是否正常,时序是否满足;

💁‍♂️ 检查wifi模块的供电是否使能,供电能力是否足够;

💁‍♂️ 检查chip_en的默认状态(cpu复位后此gpio的状态),如果默认状态为高则需要在sdio扫描设备之前将此gpio设置为低,一般建议在uboot中拉低此gpio;检查 chip_en 默认状态

5.2 驱动加载失败

💁‍♂️ 检查所需固件是否均正确放置在rootfs中;

💁‍♂️ 查看驱动具体失败位置,咨询FAE;​