樹莓派CM4 wifi頻繁斷開連線

王樓小子發表於2021-12-22

CM4核心板上自帶的wifi模組連線上華為/小米的路由器5G熱點以後,會頻繁斷開連線,斷開連線前使用 iw dev 檢視wifi資訊如下:

phy#0
        Unnamed/non-netdev interface
                wdev 0x2
                addr de:a6:32:fe:d2:**
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 6
                wdev 0x1
                addr dc:a6:32:fe:d2:**
                ssid HUAWEI-***_HiLink_5G
                type managed
                channel 153 (5765 MHz), width: 80 MHz, center1: 5775 MHz
                txpower 31.00 dBm

使用 iw event 命令監控原因,在斷開連線時看到如下資訊:

  wlan0 (phy #0): scan finished: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 5540 5560 5580 5600 5620 5640 5660 5680 5700 5720 5745 5765 5785 5805 5825, ""
  wlan0 (phy #0): connected to 24:da:33:4c:11:22
  phy #0: regulatory domain change: set to CN by a country IE request on phy0  //wifi連線上時的log

wlan0 (phy #0): disconnected (local request) reason: 3: Deauthenticated because sending station is leaving (or has left) the IBSS or ESS //過了一會wifi斷開連線時的log
wlan0 (phy #0): scan started
wlan0 (phy #0): scan finished: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467 2472 5745 5765 5785 5805 5825, ""
wlan0 (phy #0): connected to 24:da:33:4c:11:22

斷開連線後會重新連線上,這時再用 iw dev 檢視wifi資訊如下:

phy#0
        Unnamed/non-netdev interface
                wdev 0x2
                addr de:a6:32:fe:d2:**
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 6
                wdev 0x1
                addr dc:a6:32:fe:d2:**
                ssid HUAWEI-**_HiLink_5G
                type managed
                channel 153 (5765 MHz), width: 40 MHz, center1: 5755 MHz
                txpower 31.00 dBm

這時會發線wifi模組工作再40MHz通道寬度上,這是為什麼呢?通過 iw event 的資訊來看,可以點也只有“phy #0: regulatory domain change: set to CN by a country IE request on phy0”這句話了,因為在wpa_supplicant的配置檔案中我設定了 country=US ,但是通過 iw reg get 檢視發現國家碼確實被改成CN了。為什麼國家碼會被改成CN呢?

通過查閱資料得到,如果路由器本身使能了 ieee80211d=1 ,那麼wifi模組的驅動會通過country IE 重新獲取國家碼,那麼中國這邊獲取的國家碼為CN,然後就把國家碼設定到wifi模組上了。這一切也都很正常,但是問題在於樹莓派核心板上wifi模組在國家碼設定為CN的時候,不支援80MHz通道寬度和36、40、44、48等5G通道,所以會斷開重新連線AP,因為我們wifi連線工具wpa_supplicant的配置檔案設定的國家碼為US,所以wifi模組連線上AP以後如果還是工作在80MHz通道寬度,會又重複上面斷開連線的情況。如果wifi模組連線上AP以後工作在40MHz通道寬度(如上面所示),那麼可以穩定工作在40MHZ通道寬度,不會再斷開連線。

至於為什麼有時候斷開連線又重新連線在80MHz,有時候斷開連線後重新連線在40MHz,可能是重新連線時wpa_cli 執行了reconfigure命令,原因暫不追究,我們來想辦法避免重複斷開連線的情況。

解決方法1:

國家碼做成可配置,不同的區域設定不同的國家碼。

即在wpa_supplicant的配置檔案里加上 country=CN 。

優點:

在中國使用的話,國家碼設為CN以後,對於149~165通道的5G AP來說,wifi模組連線上以後工作在40MHz通道寬度上,穩定,不會掉線。

缺點:

不能支援36~48通道的5G AP,由於36~48通道在很多年之前在中國已經開放了,越來越多的路由器是支援36~48通道的,缺點很明顯。令外如果有些AP不支援40MHz通道寬度的話(只支援5G AP 只支援80MHz通道寬度,比如rackrouter v1),也是連線不上的。

解決方法2:

更改wifi驅動,通過模組引數可設定強制wifi模組只工作在US國家碼下。

修改 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 檔案, 如下:

1. 新增模組引數 regulatory_domain_force_us:

static int regulatory_domain_force_us = 0; 
module_param(regulatory_domain_force_us, int, S_IRUGO);
MODULE_PARM_DESC(regulatory_domain_force_us, "force set regulatory domain to US.");

2. 修改 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *req) 函式:

 1 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
 2                     struct regulatory_request *req)
 3 {
 4     struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 5     struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
 6     struct brcmf_pub *drvr = cfg->pub;
 7     struct brcmf_fil_country_le ccreq;
 8     char *alpha2;
 9     s32 err; 
10     int i;
11     char reg_code[3] = "US";
12 
13     err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
14     if (err) {
15         bphy_err(drvr, "Country code iovar returned err = %d\n", err);
16         return;
17     }    
18 
19     /* The country code gets set to "00" by default at boot - substitute
20      * any saved ccode from the nvram file unless there is a valid code
21      * already set.
22      */
23     if (regulatory_domain_force_us)
24         alpha2 = reg_code;
25     else 
26         alpha2 = req->alpha2;
27     
28     if (alpha2[0] == '0' && alpha2[1] == '0') {
29         extern char saved_ccode[2];
30 
31         if ((isupper(ccreq.country_abbrev[0]) &&
32              isupper(ccreq.country_abbrev[1])) ||
33             !saved_ccode[0])
34             return;
35         alpha2 = saved_ccode;
36         pr_debug("brcmfmac: substituting saved ccode %c%c\n",

第11,23,24,25,26為新增的內容,重新編譯驅動並替換原有驅動。並在系統裡新增/etc/modprobe.d/brcmfmac.conf檔案,內容如下:

options brcmfmac regulatory_domain_force_us=1

這樣在wifi驅動brcmfmac.ko載入的時候會自動傳入模組引數 regulatory_domain_force_us=1,強制指定國家碼為US。可通過 cat /sys/module/brcmfmac/parameters/regulatory_domain_force_us 檢視 regulatory_domain_force_us 的值。

優點:

wifi模組既能支援36~48通道的AP,又能解決wifi模組工作在80MHz通道寬度頻繁掉線的問題。

 

相關文章