ラズパイで6GHz帯WiFiを使ってみた（クライアント編）

2022年9月から日本でも6GHz帯が無線LANで使用することが許可されました。Netgear A8000を使って、ラズパイで6GHz対応のクライアントを作ってみました（English version article is [here](https://dev.to/wataniguchi/how-to-build-a-6ghz-wifi-client-with-a-raspberry-pi-and-netgear-a8000-47ok)）
接続先のアクセスポイントは[「ラズパイで6GHz帯WiFiを使ってみた（ルータモードアクセスポイント編）」](https://qiita.com/wataniguchi/items/380cd315226f6cce2cc1)、または[「ラズパイで6GHz帯WiFiを使ってみた（ブリッジモードアクセスポイント編）」](https://qiita.com/wataniguchi/items/313aeecba00e2b28554d)で作ります。

# まとめ - これだけやればできる

- A8000がUSB接続時に返すベンダーID・製品IDが標準mt7921uドライバに認識されるようにする
- Linux無線規制データベースを最新化して日本での6GHz帯使用許可を反映する
- MediaTek WiFiアダプタ用のファームウェアを最新化する
- WPA Supplicantをv2.10へ差し替える

# 前提

- Raspberry Pi OSはBullseye（kernel 6.1）を利用しています
- ラズパイの内蔵WiFiのインターフェース名がwlan0、A8000のインターフェース名がwlan1であるとします

# A8000がUSB接続時に返すベンダーID・製品IDが標準mt7921uドライバに認識されるようにする

[解説ページ](https://github.com/morrownr/USB-WiFi/blob/main/home/USB_WiFi_Adapters_that_are_supported_with_Linux_in-kernel_drivers.md)のA8000に関する記述に従い、`/etc/udev/rules.d/90-usb-0846:9060-mt7921u.rules`を作成します。

```
ACTION=="add", \
	SUBSYSTEM=="usb", \
	ENV{ID_VENDOR_ID}=="0846", \
	ENV{ID_MODEL_ID}=="9060", \
	RUN+="/usr/sbin/modprobe mt7921u", \
	RUN+="/bin/sh -c 'echo 0846 9060 > /sys/bus/usb/drivers/mt7921u/new_id'"
```

ブート時にA8000が自動認識され、従来の2.4GHz帯、5GHz帯の利用が可能となります。


# Linux無線規制データベースを最新化して日本での6GHz帯使用許可を反映する

Bullseyeで`iw reg get`すると、無線規制データベース（Wireless Regulatory Database）に日本での6GHz帯使用許可が反映されていないことがわかります。
`wireless-regdb`パッケージの日付が、許可日より前の2022年4月ですので当然です。

```
~ $ iw reg get
global
country JP: DFS-JP
	(2402 - 2482 @ 40), (N/A, 20), (N/A)
	(2474 - 2494 @ 20), (N/A, 20), (N/A), NO-OFDM
	(4910 - 4990 @ 40), (N/A, 23), (N/A)
	(5170 - 5250 @ 80), (N/A, 20), (N/A), AUTO-BW
	(5250 - 5330 @ 80), (N/A, 20), (0 ms), DFS, AUTO-BW
	(5490 - 5710 @ 160), (N/A, 23), (0 ms), DFS
	(57000 - 66000 @ 2160), (N/A, 10), (N/A)
~ $ apt list --installed | grep regdb
wireless-regdb/stable,now 2022.04.08-2~deb11u1 all [installed]
```

[無線規制データベースの配布サイト](https://mirrors.edge.kernel.org/pub/software/network/wireless-regdb/)から本稿執筆当時で最新の配布ファイルを取得し、最新のデータベースバイナリファイルを```/lib/crda```へ配置します。

```
xzcat wireless-regdb-2023.05.03.tar.xz | tar -xvf -
cd wireless-regdb-2023.05.03/
sudo mv /lib/crda/regulatory.bin /lib/crda/regulatory.bin.orig
sudo cp regulatory.bin /lib/crda
```

ブートするとエラーメッセージが出力されますが、データベース入れ替え前から出力されているものであり、新しいデータベースは問題なく認識されます。

```
[    6.043125] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    6.080025] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[    6.092479] cfg80211: loaded regulatory.db is malformed or signature is missing/invalid
```

再度`iw reg get`して、日本での6GHz帯使用許可が反映されていることを確認します。

```
~ $ iw reg get
global
country JP: DFS-JP
	(2402 - 2482 @ 40), (N/A, 20), (N/A)
	(2474 - 2494 @ 20), (N/A, 20), (N/A), NO-OFDM
	(4910 - 4990 @ 40), (N/A, 23), (N/A)
	(5170 - 5250 @ 80), (N/A, 20), (N/A), AUTO-BW
	(5250 - 5330 @ 80), (N/A, 20), (0 ms), DFS, AUTO-BW
	(5490 - 5730 @ 160), (N/A, 23), (0 ms), DFS
	(5925 - 6425 @ 160), (N/A, 23), (N/A), NO-OUTDOOR
	(57000 - 66000 @ 2160), (N/A, 10), (N/A)
```

# MediaTek WiFiアダプタ用のファームウェアを最新化する

ファームウェアというとデバイスのEEPROMに焼き込んであると想像しがちですが、MediaTekチップを使ったWiFiアダプタへはOSからファームウェアをロードします。
Bullseyeには元々MediaTek用のファームウェアが含まれていますが、[解説ページ](https://github.com/morrownr/USB-WiFi/blob/main/home/How_to_Install_Firmware_for_Mediatek_based_USB_WiFi_adapters.md)の記述に従い、念のため最新化しておきます。
Bullseyeで`ethtool -i wlan1`すると、ファームウェアのバージョンが`____010000-20220908211021`であることがわかります。

```
~ $ ethtool -i wlan1
driver: mt7921u
version: 6.1.21-v8+
firmware-version: ____010000-20220908211021
expansion-rom-version: 
bus-info: 1-1.4:1.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
```

[Linux用MediaTekファームウェアの配布サイト](https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/mediatek)からMT7921用のファイルをダウンロードして、```/lib/firmware/mediatek```へ配置します。
```
sudo mv /lib/firmware/mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin /lib/firmware/mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin.orig
sudo mv /lib/firmware/mediatek/WIFI_RAM_CODE_MT7961_1.bin /lib/firmware/mediatek/WIFI_RAM_CODE_MT7961_1.bin.orig
sudo cp WIFI_MT7961_patch_mcu_1_2_hdr.bin /lib/firmware/mediatek
sudo cp WIFI_RAM_CODE_MT7961_1.bin /lib/firmware/mediatek
```


再び`ethtool -i wlan1`すると、ファームウェアのバージョンが`____010000-20230526130958`に変わったことがわかります。

```
~ $ ethtool -i wlan1
driver: mt7921u
version: 6.1.21-v8+
firmware-version: ____010000-20230526130958
expansion-rom-version: 
bus-info: 1-1.4:1.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
```

# WPA Supplicantをv2.10へ差し替える

[WiFi 6EはWPA Supplicant v2.9では完全にサポートされていない](https://medium.com/@barry_wu.me/how-to-connect-wi-fi-6e-ap-over-the-6-ghz-band-with-ubuntu-21-04-2a0b4f071ac2)ので、本稿執筆当時で最新であるv2.10への差し替えを行います。
[「ラズパイで6GHz帯WiFiを使ってみた（ルータモードアクセスポイント編）」](https://qiita.com/wataniguchi/items/380cd315226f6cce2cc1#hostapdを導入してv210へ差し替える)・[「ラズパイで6GHz帯WiFiを使ってみた（ブリッジモードアクセスポイント編）」](https://qiita.com/wataniguchi/items/313aeecba00e2b28554d#hostapdを導入してv210へ差し替える)ではhostapdをv2.10へ差し替えます。WPA Supplicantとhostapdの両方が含まれた`hostap_2_10.tar.gz`を[配布サイト](https://w1.fi/cgit/hostap/)からダウンロードします。
以下は手順です。なお、`wpa_supplicant`が稼働中に差し替えをしようとすると、`Text file busy`になってしまいます。ローカルコンソールで作業する等の方法で対処しましょう。

```
tar -xzvf hostap_2_10.tar.gz
cd hostap_2_10/wpa_supplicant
cp defconfig .config
make
sudo mv /usr/sbin/wpa_supplicant /usr/sbin/wpa_supplicant_2_9
sudo cp wpa_supplicant /usr/sbin
sudo mv /usr/sbin/wpa_cli /usr/sbin/wpa_cli_2_9
sudo cp wpa_cli /usr/sbin
```

# wlan1（A8000）が別のネットワークへ接続されるようにする

wlan0（ラズパイ内蔵WiFi）とwlan1（A8000）が別のネットワークへ接続されるよう、WPA Supplicantの設定ファイルを変更します。

```
cd /etc/wpa_supplicant
sudo mv wpa_supplicant.conf wpa_supplicant-wlan0.conf
```

`wpa_supplicant-wlan1.conf`を新規作成します。`ssid=`と`sae_password=`の部分は適当に変更して下さい。

```wpa_supplicant-wlan1.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
pmf=2
sae_pwe=1

network={
    scan_ssid=1
	ssid="foo-ax"
	key_mgmt=SAE
	proto=RSN
	ieee80211w=2
    sae_password="foobar"
	pairwise=CCMP
	group=CCMP
}
```

もし、wlan0を無効化して6GHz帯のみの通信としたい場合には、`sudo iwconfig wlan0 txpower off`します。
（解説記事は[こちら](https://qiita.com/hayate242/items/4f3d07d63a5b9577cb55)）

# 完了

`iwconfig`すると、6GHz帯でアクセスポイントへ接続されていることがわかります。お疲れ様でした。
```
~ $ iwconfig
lo        no wireless extensions.

wlan0     IEEE 802.11  ESSID:off/any  
          Mode:Managed  Access Point: Not-Associated   
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:on
          
wlan1     IEEE 802.11  ESSID:"foo-ax"  
          Mode:Managed  Frequency:6.235 GHz  Access Point: 94:18:65:xx:xx:xx   
          Bit Rate=286.7 Mb/s   Tx-Power=3 dBm   
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:on
          Link Quality=70/70  Signal level=-31 dBm  
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0
```