之前买了一个MiniPC和一张Qualcomm Atheros QCA988x芯片的mini PCI-E网卡。打算用来实现家里的802.11ac 环境。

但网卡一直只能工作在802.11n模式下,无法实现802.11ac。翻来覆去的找了很多资料,终于在昨天攻克了难关(其实答案很简单,就是英语水平不过关,明明答案已经摆在眼前,就是没有留意到。自我鄙视一下)。原来Atheros的EEPROM有锁区限制,如果我们所在地区与它的EEPROM地区不在同一个地区的话,802.11ac是被禁用的。

怎么查看网卡是否支持802.11ac呢?我们可以使用iw list命令,其中有一段显示5GHz频道的信息,如:

(什么?你在系统中找不到ath的无线网卡?这说明你的kernel太旧或编译时没有加入支持ath网卡的驱动和模块。怎么破?自己编译kernel吧)

Frequencies:
* 5180 MHz [36] (23.0 dBm)
* 5200 MHz [40] (23.0 dBm)
* 5220 MHz [44] (23.0 dBm)
* 5240 MHz [48] (23.0 dBm)
* 5260 MHz [52] (23.0 dBm) (radar detection)
DFS state: usable (for 87672 sec)
* 5280 MHz [56] (23.0 dBm) (radar detection)
DFS state: usable (for 87672 sec)
* 5300 MHz [60] (23.0 dBm) (radar detection)
DFS state: usable (for 87672 sec)
* 5320 MHz [64] (23.0 dBm) (radar detection)
DFS state: usable (for 87672 sec)
* 5500 MHz [100] (disabled)
* 5520 MHz [104] (disabled)
* 5540 MHz [108] (disabled)
* 5560 MHz [112] (disabled)
* 5580 MHz [116] (disabled)
* 5600 MHz [120] (disabled)
* 5620 MHz [124] (disabled)
* 5640 MHz [128] (disabled)
* 5660 MHz [132] (disabled)
* 5680 MHz [136] (disabled)
* 5700 MHz [140] (disabled)
* 5720 MHz [144] (disabled)
* 5745 MHz [149] (30.0 dBm)
* 5765 MHz [153] (30.0 dBm)
* 5785 MHz [157] (30.0 dBm)
* 5805 MHz [161] (30.0 dBm)
* 5825 MHz [165] (30.0 dBm)

不同的网卡支持的频道不一样,但如果你的网卡并没有显示出这些5GHz频道的话,就说明你的网卡不支持802.11ac了,你可以死心了。

但如果你在频道后看到(disabled),或(passive scanning)或(no IBSS)字样的话,不好意思,这个频道你也用不了。如果所有频道都用不了的话,那么就说明你的网卡被锁区了。怎么破?重新编译ath网卡的驱动,避开网卡的驱动程序检查EEPROM中的区域就可以了。

说了这么久,到头来就是重新编译kernel的问题了。

(1) 到https://www.kernel.org/下载最新的稳定版。并解压到Linux服务器中,(比如/usr/local/src)

(2) 进入解压后的kernle 源代码目录中的drivers/net/wireless/ath子目录。

(3) vi regd.c  (编辑regd.c这个文件,就是为了让网卡驱动禁用检查EEPROM区域)

(A) 在文件第一行添加一行“#define ATH_USER_REGD 1

(B) 在文件中找出如下四个函数的定义部分,并在函数中添加如下红色行。

(a)   ath_reg_apply_beaconing_flags

ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
struct ath_regulatory *reg,
enum nl80211_reg_initiator initiator)
{
enum ieee80211_band band;
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
unsigned int i;

#ifdef ATH_USER_REGD
        return;
#endif

for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!wiphy->bands[band])
continue;
sband = wiphy->bands[band];
for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
__ath_reg_apply_beaconing_flags(wiphy, reg,
initiator, ch);
}
}
}

################################################################

(b)  ath_reg_apply_ir_flags

ath_reg_apply_ir_flags(struct wiphy *wiphy,
struct ath_regulatory *reg,
enum nl80211_reg_initiator initiator)
{
struct ieee80211_supported_band *sband;

#ifdef ATH_USER_REGD
        return;
#endif

sband = wiphy->bands[IEEE80211_BAND_2GHZ];
if (!sband)
return;

switch(initiator) {
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
ath_force_clear_no_ir_freq(wiphy, 2467);
ath_force_clear_no_ir_freq(wiphy, 2472);
break;
case NL80211_REGDOM_SET_BY_USER:
if (!ath_reg_dyn_country_user_allow(reg))
break;
ath_force_clear_no_ir_freq(wiphy, 2467);
ath_force_clear_no_ir_freq(wiphy, 2472);
break;
default:
ath_force_no_ir_freq(wiphy, 2467);
ath_force_no_ir_freq(wiphy, 2472);
}
}

(c)  static void ath_reg_apply_radar_flags

static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
unsigned int i;

#ifdef ATH_USER_REGD
        return;
#endif

if (!wiphy->bands[IEEE80211_BAND_5GHZ])
return;

sband = wiphy->bands[IEEE80211_BAND_5GHZ];

for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
if (!ath_is_radar_freq(ch->center_freq))
continue;
/* We always enable radar detection/DFS on this
* frequency range. Additionally we also apply on
* this frequency range:
* – If STA mode does not yet have DFS supports disable
*   active scanning
* – If adhoc mode does not support DFS yet then
*   disable adhoc in the frequency.
* – If AP mode does not yet support radar detection/DFS
*   do not allow AP mode
*/
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
ch->flags |= IEEE80211_CHAN_RADAR |
IEEE80211_CHAN_NO_IR;
}
}

################################################################

(d)  ath_regd_init_wiphy

ath_regd_init_wiphy(struct ath_regulatory *reg,
struct wiphy *wiphy,
void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request))
{
const struct ieee80211_regdomain *regd;

#ifdef ATH_USER_REGD
        return 0;
#endif

wiphy->reg_notifier = reg_notifier;
wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
REGULATORY_CUSTOM_REG;

if (ath_is_world_regd(reg)) {
/*
* Anything applied here (prior to wiphy registration) gets
* saved on the wiphy orig_* parameters
*/
regd = ath_world_regdomain(reg);
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_FOLLOW_POWER;
} else {
/*
* This gets applied in the case of the absence of CRDA,
* it’s our own custom world regulatory domain, similar to
* cfg80211’s but we enable passive scanning.
*/
regd = ath_default_world_regdomain();
}

wiphy_apply_custom_regulatory(wiphy, regd);
ath_reg_apply_radar_flags(wiphy);
ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
return 0;
}

##########################################################

下面就开始编译kernel (若编译过程中出错,说明你的系统环境区少了一些必须的软件,请通过yum下载安装吧。具体请google,不在这文章中详说了):

重新回到kernel源代码的根目录

make clean

make mrproper

cp /boot/config-`uname -r`.`uname -m` ./.config

make oldconfig

cat .config |grep ATH10K  (确保CONFIG_ATH10K和CONFIG_ATH10K_PCI是等于m。

make

make modules_install

make install

成功后,在/boot/grub/grub.conf 下就多了一个启动项(tital)。

重启电脑进入新的kernel。

这时,你应该可以在系统中找到无线网卡(通常是wlan0)了。如果你以为到这里就大功告成的话,对不起,你才完成了一半。

Qualcomm Atheros的网卡,不但需要驱动程序,还需要加载Firmware。那要什么Firmware呢?我们可以通过如下命令查看当前kernel将会加载什么Firmware。

# modinfo ath10k_pci | grep firmware

(下面是我的系统中看到的结果)

firmware:       ath10k/QCA9377/hw1.0/board.bin
firmware:       ath10k/QCA9377/hw1.0/firmware-5.bin
firmware:       ath10k/QCA6174/hw3.0/board-2.bin
firmware:       ath10k/QCA6174/hw3.0/board.bin
firmware:       ath10k/QCA6174/hw3.0/firmware-5.bin
firmware:       ath10k/QCA6174/hw3.0/firmware-4.bin
firmware:       ath10k/QCA6174/hw2.1/board-2.bin
firmware:       ath10k/QCA6174/hw2.1/board.bin
firmware:       ath10k/QCA6174/hw2.1/firmware-5.bin
firmware:       ath10k/QCA6174/hw2.1/firmware-4.bin
firmware:       ath10k/QCA988X/hw2.0/board-2.bin
firmware:       ath10k/QCA988X/hw2.0/board.bin
firmware:       ath10k/QCA988X/hw2.0/firmware-5.bin
firmware:       ath10k/QCA988X/hw2.0/firmware-4.bin
firmware:       ath10k/QCA988X/hw2.0/firmware-3.bin
firmware:       ath10k/QCA988X/hw2.0/firmware-2.bin
firmware:       ath10k/QCA988X/hw2.0/firmware.bin   

由于我的网卡是QCA988X版本,所以我所关系的就是最后几行。怎么知道我的网卡的信号?可以通过如下命令:

# dmesg |grep ath10k_pci

其中有一句“ath10k_pci 0000:01:00.0: qca988x hw2.0 target 0x4100016c chip_id 0x043022ff sub 11ad:6614” 可以确认我的网卡的型号。

由于不同的kernel需要不同的firmware,因此请以“modinfo ath10k_pci | grep firmware”命令中看到的firmware版本为准。

board-2.bin和board.bin 两者选其一。

firmware.bin ~ firmware-5.bin 六者选其一 (我选的是最新的firmware-5.bin)。

我们可以从https://github.com/kvalo/ath10k-firmware下载我们需要的firmware。

在里面,我找到了board.bin和最新的firmware-5.bin_10.2.4.70.31-2。

把这两个文件上传的服务器的/lib/firmware/ath10k/QCA988X/hw2.0/下,并把firmware-5.bin_10.2.4.70.31-2改名为firmware-5.bin。

重启服务器。

检查服务器是否有正常加载firmware。

# dmesg |grep ath10k_pci

如果看到如下两行,就说明board.bin和firmware-5.bin已经成功加载了。

ath10k_pci 0000:01:00.0: firmware ver 10.2.4.70.31-2 api 5 features no-p2p,raw-mode,mfp crc32 fee9a3e8

ath10k_pci 0000:01:00.0: board_file api 1 bmi_id N/A crc32 bebc7c08

由于我一直没有找到board-2.bin,而且系统会从上往下找firmware加载,所以它会先找board-2.bin,并出现如下错误。不够也没有关系,因为我们有board.bin。

ath10k_pci 0000:01:00.0: Direct firmware load for ath10k/QCA988X/hw2.0/board-2.bin failed with error -2

到此,ath10k网卡总算是安装好了。我们再检查5GHz的频道是否有可用的。

# iw list

这次,之前有(passive scanning)或(no IBSS)的频道都变成可用的了。

我们就可以在hostapd中使用这些频道。

下面是我的hostpad.conf配置,你可以参考一下

driver=nl80211
hw_mode=a
channel=0
interface=wlan0
ctrl_interface=/var/run/hostapd
disassoc_low_ack=1
preamble=1
auth_algs=1
wpa=2
ssid=xxxxxx
bridge=WIFI
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
wpa_passphrase=xxxxxxxx
wmm_enabled=1
ignore_broadcast_ssid=0

ieee80211n=1
ht_capab=[HT20][HT40+]
ieee80211ac=1
vht_oper_chwidth=1
vht_oper_centr_freq_seg0_idx=42
vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]

wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0

tx_queue_data3_aifs=7
tx_queue_data3_cwmin=15
tx_queue_data3_cwmax=1023
tx_queue_data3_burst=0
tx_queue_data2_aifs=3
tx_queue_data2_cwmin=15
tx_queue_data2_cwmax=63
tx_queue_data2_burst=0
tx_queue_data1_aifs=1
tx_queue_data1_cwmin=7
tx_queue_data1_cwmax=15
tx_queue_data1_burst=3.0
tx_queue_data0_aifs=1
tx_queue_data0_cwmin=3
tx_queue_data0_cwmax=7
tx_queue_data0_burst=1.5

logger_syslog=127
logger_syslog_level=2
logger_stdout=127
logger_stdout_level=2

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Post Navigation