188 lines
5.0 KiB
Markdown
188 lines
5.0 KiB
Markdown
# Отключение RRM-сканирования на OpenWrt
|
||
|
||
## Проблема
|
||
|
||
На Wi‑Fi uplink периодически возникали провалы связи примерно на 6.5 секунд.
|
||
|
||
Диагностика показала следующую цепочку:
|
||
|
||
1. Точка доступа отправляет клиенту 802.11k / RRM Beacon Measurement Request.
|
||
2. `wpa_supplicant` получает этот management frame.
|
||
3. `wpa_supplicant` запускает полный scan 2.4 GHz через `NL80211_CMD_TRIGGER_SCAN`.
|
||
4. Во время scan uplink практически перестаёт передавать пользовательский трафик.
|
||
5. В результате появляются потери пакетов и скачки latency.
|
||
|
||
На MT7981 это проявлялось как:
|
||
|
||
```text
|
||
event 33 -> примерно 6.5 сек -> event 34
|
||
```
|
||
|
||
где `event 33` соответствует запуску scan, а `event 34` — завершению scan.
|
||
|
||
## Рабочее решение
|
||
|
||
Для `wpa_supplicant` используется:
|
||
|
||
```ini
|
||
driver_param=no_rrm=1
|
||
```
|
||
|
||
Важно: параметр должен присутствовать **в момент создания STA-интерфейса**. Установка его уже после запуска через control interface проблему не устраняла.
|
||
|
||
В используемой версии OpenWrt конфигурация STA генерируется через:
|
||
|
||
```text
|
||
/usr/share/ucode/wifi/supplicant.uc
|
||
```
|
||
|
||
### Изменения
|
||
|
||
В функции:
|
||
|
||
```ucode
|
||
export function generate(config_list, data, interface)
|
||
```
|
||
|
||
после:
|
||
|
||
```ucode
|
||
interface.config.country = data.config.country_code;
|
||
interface.config.beacon_int = data.config.beacon_int;
|
||
```
|
||
|
||
добавлено:
|
||
|
||
```ucode
|
||
interface.config.driver_param = "no_rrm=1";
|
||
```
|
||
|
||
Также строка:
|
||
|
||
```ucode
|
||
append_vars(interface.config, [ 'country', 'beacon_int', 'freq_list' ]);
|
||
```
|
||
|
||
заменена на:
|
||
|
||
```ucode
|
||
append_vars(interface.config, [ 'country', 'beacon_int', 'freq_list', 'driver_param' ]);
|
||
```
|
||
|
||
Итоговый участок:
|
||
|
||
```ucode
|
||
interface.config.country = data.config.country_code;
|
||
interface.config.beacon_int = data.config.beacon_int;
|
||
interface.config.driver_param = "no_rrm=1";
|
||
|
||
if (!data.config.scan_list)
|
||
data.config.scan_list = wiphy_frequencies(data.phy, data.config.band, data.config.radio);
|
||
|
||
if (data.config.scan_list)
|
||
interface.config.freq_list = join(" ", data.config.scan_list);
|
||
|
||
append_vars(interface.config, [ 'country', 'beacon_int', 'freq_list', 'driver_param' ]);
|
||
```
|
||
|
||
## Применение
|
||
|
||
После изменения файла:
|
||
|
||
```bash
|
||
wifi down radio0
|
||
sleep 2
|
||
wifi up radio0
|
||
```
|
||
|
||
Проверить сгенерированный конфиг:
|
||
|
||
```bash
|
||
grep driver_param /var/run/wpa-supplicant-phy0-sta0.conf
|
||
```
|
||
|
||
Ожидаемый результат:
|
||
|
||
```text
|
||
driver_param=no_rrm=1
|
||
```
|
||
|
||
Также можно проверить runtime:
|
||
|
||
```bash
|
||
ubus call wpa_supplicant.phy0-sta0 control '{"command":"GET driver_param"}'
|
||
```
|
||
|
||
Ожидаемый результат:
|
||
|
||
```json
|
||
{
|
||
"result": "no_rrm=1"
|
||
}
|
||
```
|
||
|
||
## Проверка результата
|
||
|
||
Для контроля:
|
||
|
||
```bash
|
||
iw event -t
|
||
```
|
||
|
||
и параллельно:
|
||
|
||
```bash
|
||
ping 192.168.0.1
|
||
```
|
||
|
||
После применения `no_rrm=1` проблемные длительные RRM-сканы и связанные с ними потери пакетов исчезли.
|
||
|
||
## Резервная копия и патч
|
||
|
||
Перед изменением рекомендуется сохранить оригинал:
|
||
|
||
```bash
|
||
cp /usr/share/ucode/wifi/supplicant.uc /usr/share/ucode/wifi/supplicant.uc.bak
|
||
```
|
||
|
||
Для создания patch нужен пакет:
|
||
|
||
```bash
|
||
apk add diffutils
|
||
```
|
||
|
||
Создать patch:
|
||
|
||
```bash
|
||
diff -u /usr/share/ucode/wifi/supplicant.uc.bak /usr/share/ucode/wifi/supplicant.uc > /root/no-rrm.patch
|
||
```
|
||
|
||
Посмотреть patch:
|
||
|
||
```bash
|
||
cat /root/no-rrm.patch
|
||
```
|
||
|
||
## После обновления OpenWrt
|
||
|
||
Обновление OpenWrt или пакетов Wi‑Fi может перезаписать:
|
||
|
||
```text
|
||
/usr/share/ucode/wifi/supplicant.uc
|
||
```
|
||
|
||
После обновления проверить:
|
||
|
||
```bash
|
||
grep driver_param /var/run/wpa-supplicant-phy0-sta0.conf
|
||
```
|
||
|
||
После обновления применить патч если изменения пропали:
|
||
|
||
```bash
|
||
patch -p0 < /root/no-rrm.patch
|
||
```
|
||
Если параметр исчез, повторно применить изменение вручную либо использовать сохранённый patch.
|
||
|
||
> Примечание: patch, созданный для одной версии `supplicant.uc`, может не примениться автоматически после существенного обновления OpenWrt. В таком случае лучше повторить две небольшие правки вручную.
|