今日在笔记本电脑ThinkBook 14 IML接入TP-LINK的TL-WDN7200H AC 1900双频高增益无线USB网卡,支持2.4GHz 600Mbps+5GHz 1300Mbps。
Windows10是免安装驱动直接可以支持的。但在CentOS Linux 8系统却遇到了麻烦,并无相关驱动支持,无法使用。
查看当前内核版本:
[root@centos ~]# uname -aLinux centos 4.18.0-147.6.el8.x86_64 #1 SMP Tue Oct 15 15:19:32 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
注意:要记住版本号4.18.0,稍后编译时修改代码要用。
寻思想通过自行编译驱动来解决,先要找到芯片厂商型号。
列出USB:
[root@centos ~]# lsusbBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 001 Device 005: ID 5986:2113 Acer, Inc Bus 001 Device 004: ID 27c6:55a4 Bus 001 Device 003: ID 18f8:1286 [Maxxter] Bus 001 Device 002: ID 2357:0106 TP-Link Bus 001 Device 006: ID 8087:0aaa Intel Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
看到Bus 001 Device 002: ID 2357:0106 TP-Link,提取ID 2357:0106,查找信息得知是无线USB网卡芯片厂商是realtek,型号是8814au。
在github找到Realtek 8814AU USB WiFi driver,下载编译。
注意:要找到这个版本rtl8814au v4.3.21_17997.20160531,不要找最新版本。
编译出现第一个错误:
/tmp/rtl8814au/os_dep/linux/os_intfs.c:914:22: error: initialization of ‘u16 (*)(struct net_device *, struct sk_buff *, struct net_device *, u16 (*)(struct net_device *, struct sk_buff *, struct net_device *))’ {aka ‘short unsigned int (*)(struct net_device *, struct sk_buff *, struct net_device *, short unsigned int (*)(struct net_device *, struct sk_buff *, struct net_device *))’} from incompatible pointer type ‘u16 (*)(struct net_device *, struct sk_buff *, void *, u16 (*)(struct net_device *, struct sk_buff *, struct net_device *))’ {aka ‘short unsigned int (*)(struct net_device *, struct sk_buff *, void *, short unsigned int (*)(struct net_device *, struct sk_buff *, struct net_device *))’} [-Werror=incompatible-pointer-types] .ndo_select_queue = rtw_select_queue, ^~~~~~~~~~~~~~~~/tmp/rtl8814au/os_dep/linux/os_intfs.c:914:22: note: (near initialization for ‘rtw_netdev_ops.ndo_select_queue’)cc1: some warnings being treated as errorsmake[2]: *** [scripts/Makefile.build:313: /tmp/rtl8814au/os_dep/linux/os_intfs.o] Error 1make[1]: *** [Makefile:1547: _module_/tmp/rtl8814au] Error 2make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.6.el8.x86_64'make: *** [Makefile:1699: modules] Error 2
打开rtl8814au目录下os_dep/linux/os_intfs.c文件,定位到rtw_select_queue函数:
static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) , void *accel_priv#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) , select_queue_fallback_t fallback#endif
#endif)
改成如下即可:
static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) , struct net_device *sb_dev #else , void *accel_priv #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) & LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) , select_queue_fallback_t fallback #endif#endif)
继续编译发现第二个错误:
/tmp/rtl8814au/os_dep/linux/rtw_android.c: In function ‘rtw_android_priv_cmd’:/tmp/rtl8814au/os_dep/linux/rtw_android.c:615:62: error: macro "access_ok" passed 3 arguments, but takes just 2 if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){ ^/tmp/rtl8814au/os_dep/linux/rtw_android.c:615:7: error: ‘access_ok’ undeclared (first use in this function) if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){ ^~~~~~~~~/tmp/rtl8814au/os_dep/linux/rtw_android.c:615:7: note: each undeclared identifier is reported only once for each function it appears inmake[2]: *** [scripts/Makefile.build:313: /tmp/rtl8814au/os_dep/linux/rtw_android.o] Error 1make[1]: *** [Makefile:1547: _module_/tmp/rtl8814au] Error 2make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.6.el8.x86_64'make: *** [Makefile:1699: modules] Error 2
打开rtl8814au目录下os_dep/linux/rtw_android.c文件,定位到rtw_android_priv_cmd函数:
if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){
改成如下即可:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))if (!access_ok(priv_cmd.buf, priv_cmd.total_len)) {#elseif (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) {#endif
继续编译正常通过了!
最后可看到已经生成8814au.ko:
LD [M] /tmp/rtl8814au/8814au.o Building modules, stage 2. MODPOST 1 modules CC /tmp/rtl8814au/8814au.mod.o LD [M] /tmp/rtl8814au/8814au.komake[1]: Leaving directory '/usr/src/kernels/4.18.0-147.6.el8.x86_64'
安装后使用加载模块:
modprobe 8814au
cat /proc/kmsg可看到:
<4>[19967.549960] RTL871X: module init start<4>[19967.549961] RTL871X: rtl8814au v4.3.21_17997.20160531<4>[19967.671171] RTL871X: rtw_ndev_init(wlan0) if1 mac_addr=08:1f:71:24:64:8a<6>[19967.671505] usbcore: registered new interface driver rtl8814au<4>[19967.671507] RTL871X: module init ret=0<6>[19967.682791] rtl8814au 1-3:1.0 wlp0s20f0u3: renamed from wlan0<6>[19967.697724] IPv6: ADDRCONF(NETDEV_UP): wlp0s20f0u3: link is not ready<6>[19968.104292] IPv6: ADDRCONF(NETDEV_UP): wlp0s20f0u3: link is not ready<6>[19968.106996] IPv6: ADDRCONF(NETDEV_UP): wlp0s20f0u3: link is not ready<6>[19968.121708] IPv6: ADDRCONF(NETDEV_UP): wlp0s20f0u3: link is not ready<4>[19971.176837] RTL871X: nolinked power save enter<6>[19971.191472] IPv6: ADDRCONF(NETDEV_UP): wlp0s20f0u3: link is not ready<4>[19971.617442] RTL871X: nolinked power save leave<4>[19974.653364] RTL871X: rtw_set_802_11_connect(wlp0s20f0u3) fw_state=0x00000008<4>[19974.859910] RTL871X: start auth<4>[19974.862100] RTL871X: auth success, start assoc<4>[19974.880289] RTL871X: rtw_cfg80211_indicate_connect(wlp0s20f0u3) BSS not found !!<4>[19974.880316] RTL871X: assoc success<4>[19975.010392] RTL871X: recv eapol packet<4>[19975.010619] RTL871X: send eapol packet<4>[19975.013448] RTL871X: recv eapol packet<4>[19975.013527] RTL871X: send eapol packet<4>[19975.013596] RTL871X: set pairwise key camid:4, addr:74:05:a5:01:23:45, kid:0, type:AES<6>[19975.013730] IPv6: ADDRCONF(NETDEV_CHANGE): wlp0s20f0u3: link becomes ready<4>[19975.014452] RTL871X: set group key camid:5, addr:74:05:a5:01:23:45, kid:2, type:AES
已经可以正常连接到WIFI上网了!
注:本文为Toyo Lau原创,未经许可不得在任何平台转载。如需转载,与作者联系~。或可以直接技术交流群:734638086。关注微信公众号:技术训练营(微信ID:TechBootcamp),获取更多资讯~
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。