买了个 TL-WN725N v1 的无线网卡,据它自己说是支持 AP 模式的,Linux 3.7.x 驱动正常,使用的 rtlwifi:rtl8192cu。使用 iw list 命令查看网卡的确是支持 AP 模式的,由于配置 hostapd 测试了一下,客户端也可以看到 AP 了,但连接上后就自动断开,iPad 直接就连接不上。。。
通过查找、分析,最后定位问题在驱动程序上,下面是修复补丁,将rtlwifi编译成独立的模块替换系统中原有的模块即可。
From 59fb30735cbe7eb4f69b13a056947efcc4bfeab0 Mon Sep 17 00:00:00 2001
From: Heiher
Date: Tue, 19 Feb 2013 22:51:22 +0800
Subject: [PATCH] rtlwifi: Fix AP mode.
---
Makefile | 25 ++++++++++++++-----------
core.c | 26 ++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/Makefile b/Makefile
index 97935c5..544d22b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_RTLWIFI) += rtlwifi.o
+obj-m += rtlwifi.o
rtlwifi-objs := \
base.o \
cam.o \
@@ -11,18 +11,21 @@ rtlwifi-objs := \
rtl8192c_common-objs += \
-ifneq ($(CONFIG_PCI),)
rtlwifi-objs += pci.o
-endif
-
-ifneq ($(CONFIG_USB),)
rtlwifi-objs += usb.o
-endif
-obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/
-obj-$(CONFIG_RTL8192CE) += rtl8192ce/
-obj-$(CONFIG_RTL8192CU) += rtl8192cu/
-obj-$(CONFIG_RTL8192SE) += rtl8192se/
-obj-$(CONFIG_RTL8192DE) += rtl8192de/
+#obj-m += rtl8192c/
+#obj-m += rtl8192ce/
+#obj-m += rtl8192cu/
+#obj-m += rtl8192se/
+#obj-m += rtl8192de/
ccflags-y += -D__CHECK_ENDIAN__
+
+KVERSION = $(shell uname -r)
+
+all:
+ make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
+clean:
+ make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
+
diff --git a/core.c b/core.c
index a7c0e52..6e40070 100644
--- a/core.c
+++ b/core.c
@@ -574,6 +574,27 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw,
return 0;
}
+static void _rtl_update_beacon(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, struct ieee80211_vif *vif)
+{
+ struct sk_buff *skb;
+ struct ieee80211_tx_control control;
+
+ control.sta = sta;
+ skb = ieee80211_beacon_get(hw, vif);
+ rtl_op_tx(hw, &control, skb);
+}
+
+static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ bool set)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ _rtl_update_beacon(hw, sta, rtlpriv->mac80211.vif);
+
+ return 0;
+}
+
static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf, u32 changed)
@@ -591,6 +612,10 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
if ((changed & BSS_CHANGED_BEACON) ||
(changed & BSS_CHANGED_BEACON_ENABLED &&
bss_conf->enable_beacon)) {
+ rcu_read_lock();
+ sta = get_sta(hw, vif, bss_conf->bssid);
+ _rtl_update_beacon(hw, sta, vif);
+ rcu_read_unlock();
if (mac->beacon_enabled == 0) {
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
"BSS_CHANGED_BEACON_ENABLED\n");
@@ -1183,6 +1208,7 @@ const struct ieee80211_ops rtl_ops = {
.configure_filter = rtl_op_configure_filter,
.sta_add = rtl_op_sta_add,
.sta_remove = rtl_op_sta_remove,
+ .set_tim = rtl_op_set_tim,
.set_key = rtl_op_set_key,
.conf_tx = rtl_op_conf_tx,
.bss_info_changed = rtl_op_bss_info_changed,
--
1.8.1.3
cd linux-3.7
cd drivers/net/wirless/rtlwifi/
patch -Np1 -i ~/rtlwifi-Fix-AP-mode.patch
make
# Test
sudo rmmod rtl8129cu
sudo rmmod rtlwifi
sudo insmod ./rtlwifi.ko
sudo insmod rtl8192cu.ko
Over!
高亮用的哪个插件?
WP-Syntax
能否讲解一下
update_beacon和update_beacon两个函数的作用及修复的原理?
谢谢!
我也不懂。。。
更新beacon帧,客户端通过这个来判断AP是不是存在。AP是要定时发送这个帧的,但是rtlwifi貌似没实现这个
能否详细解释一下?
就是说。。AP需要定时发送beacon帧,告诉大家“我还活着”并且更新Station的信息。。。貌似rtlwifi驱动连上了就没管这玩意儿了然后Station就会认为AP挂了。。
了解了,好久没用这个网卡了,您有用吗?现在官方的驱动支持如何?
我用的跟您的一模一样的型号的网卡、、官方驱动貌似也不能解决问题、、
这个Patch确实有效。不过我把它移植到ARM开发板上做了一定的修改、、
哦,当时好像也是参考别人的一个相关邮件做的,没仔细研究,后来就忘记了,您测试下来稳定不?
还算稳定。。运行了几天没发现什么问题
可以提交到upstream啊。