В ходе настройки Orange Pi Zero Plus 2 H3 обнаружил, что есть конкретные проблемы с Wi-Fi. В зависимости от используемого дистрибутива Linux имеем либо негрузящайся драйвер, либо работают только первые 11 каналов Wi-Fi, а учитывая, что моих сетей там нет, это проблема, которую пришлось решать. Решение я нашёл и ниже я его вам покажу и расскажу как с этой проблемой бороться.
Итак, хотелось мне запустить эту плату именно в Armbin, но именно этот дистрибутив славился тем, что данная плата в нём Wi-Fi не поддерживала. Но мы не ищем лёгких путей и из-за какого-то там чортова драйвера менять дистрибутив для меня просто унижение. Если драйвер есть и он в принципе работает, то и в Armbian он у меня заработает. Вызов принят!
Получаем проблему
Итак, первым делом накатываем Armbian. На официальной стрaнице образа для данной платы я не нашёл, но зато нашёл где эти сборки выкладываются. В общем качаем отсюда https://fi.mirror.armbian.de/archive/orangepizeroplus2-h3/archive/. Я использовал версию bullseye. Пробовал jammy, но там ровно тоже самое.
Альтернативные драйвера
Они существуют и возможно работают.
- https://github.com/antoineco/broadcom-wl
- http://linuxwireless.sipsolutions.net/en/users/Drivers/b43/
Проблема одна — их надо качать, а сети нет. Можно конечно скачать код на другом компьютере, залить на карточку и попытаться собрать на плате, но слишком много возни и вероятно потребуется докачивать зависимости.
Анализируем ошибки
В итоге имеем условно работающий Wi-Fi из каробки с куцым списком доступных сетей и ошибки в логах при загрузке фирмвари данного драйвера.
Ошибки выглядят так
% dmesg | grep brcm
brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.xunlong,orangepi-zero-plus2-h3.bin failed with error -2
brcmfmac mmc1:0001:1: Falling back to sysfs fallback for: brcm/brcmfmac43430-sdio.xunlong,orangepi-zero-plus2-h3.bin
brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.xunlong,orangepi-zero-plus2-h3.txt failed with error -2
brcmfmac mmc1:0001:1: Falling back to sysfs fallback for: brcm/brcmfmac43430-sdio.xunlong,orangepi-zero-plus2-h3.txt
brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: Mar 30 2016 11:30:56 version 7.45.77.h8.4 FWID 01-ee8a6268
Как видно оно пытается загрузить какую-то фирмварь и не может найти нужных файлов. Придётся таки разбираться, что такое firmware и как оно грузится
Linux и firmware
В общем, как выяснилось, для всяких проприетарных драйверов типа Broadcom-а у нас есть бинарные файлы (та самая firmware), которые и подгружаются родным линуксовым драйвером, чтобы всё работало как надо. Но кроме бинарника у нас есть некий конфиг, который есть ни что иное как набор переменных, которые заливаются в NVRAM драйвера.
Что не так в нашем случае
Для нашего случая всё выглядит вот так.
% ls -la /lib/firmware/brcm/*43430*
...
/lib/firmware/brcm/brcmfmac43430-sdio.bin # <=== бинарник фирмвари
/lib/firmware/brcm/brcmfmac43430-sdio.txt # <=== конфиг
Но как видно из ошибки, драйвер пытается загрузить firmware из файла с суффиксом вендора устройства, то есть /lib/firmware/brcm/brcmfmac43430-sdio.xunlong,orangepi-zero-plus2-h3.bin
вместо /lib/firmware/brcm/brcmfmac43430-sdio.bin
. Поэтому я решил просто создать нужные симлинки.
Забегая вперёд должен отметить, что это оказалось необязательно, а эта ошибка это скорее предупреждение. Походу драйвер таки находит фирмварь и по существующим именам. Но что сделано, то сделано и как минимум убираются сообщения об ошибках при загрузке.
После исправления имеем такую картину.
% ls -la /lib/firmware/brcm/*43430*
...
/lib/firmware/brcm/brcmfmac43430-sdio.bin # <=== бинарник фирмвари
/lib/firmware/brcm/brcmfmac43430-sdio.txt # <=== конфиг
/lib/firmware/brcm/brcmfmac43430-sdio.xunlong,orangepi-zero-plus2-h3.bin -> /lib/firmware/brcm/brcmfmac43430-sdio.bin
/lib/firmware/brcm/brcmfmac43430-sdio.xunlong,orangepi-zero-plus2-h3.txt -> /lib/firmware/brcm/brcmfmac43430-sdio.txt
Теперь при загрузке видим следующее
% dmesg | grep brcm
brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1 # <== стало норм
brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1 # <== стало норм
brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: Mar 30 2016 11:30:56 version 7.45.77.h8.4 FWID 01-ee8a6268
Задаём код региона
Несмотря на успешную загрузку фирмвари, нас осталась ошибка как раз насчёт ограничения каналов и фирмварь ругается на какой-то clm_blob
. Это как оказалось ещё один бинарник с региональными настройками для данного драйвера. И с этими самыми настройками полная чехарда. В разное время за это дело отвечали следующие подсистемы.
CRDA (central regulatory domain agent)
С этим связаны рекоммендации поправить регион в /etc/default/crda
, но нифига не работает, так как эта тема устарела с версии ядра 4.15
cfg80211
Есть так же рекоммендации передать регион драйверу Linux cfg80211, но это тоже устарело и сегодня каждый драйвер должен сам уметь разбираться с такими делами.
echo "options cfg80211 ieee80211_regdom=US" > /etc/modprobe.d/cfg80211.conf
clm_blob
Это по факту кусок базы данных, типа той, что использовалась в CRDA, но специфичный для данного драйвера. Как оказалось и этот метод устарел и вся информация уже должна содержаться в недрах драйвера. К слову я таки нашёл этот бинарь от Raspberry PI и подсунул для загрузки, но работать лучше не стало.
И что таки делать?
В итоге пришлось лезть в конфиг фирмвари и уже там я обнаружил подозрительную переменную ccode=ALL
, поменяв значение которой, после перезагрузки я получил полный список Wi-Fi сетей.
#AP6212_NVRAM_V1.0_20140603
# 2.4 GHz, 20 MHz BW mode
# The following parameter values are just placeholders, need to be updated.
.....
xtalfreq=26000
nocrc=1
ag0=255
aa2g=1
ccode=ALL # <===== вот тут меняем ALL на RU
extpagain2g=0
........
Но тут есть проблема — при обновлении пакета с фирмварями этот файл будет перезаписываться.
Всё чудесатее и чудесатее
Гугля по теме обнаружил ссылки на исходники с такими комментариями
/* In some cases the EFI-var stored nvram contains "ccode=ALL" or
* "ccode=XV" to specify "worldwide" compatible settings. ccode=ALL is
* not understood by the firmware and some of the firmware files in
* linux-firmware support only 2.4 GHz and not 5 GHz when ccode=XV.
*/
Так, что видимо стоит попробовать вместо RU использовать XV. Возможно даже появится диапазон 5ГГц.
Я сдаюсь
Кроме всего прочего искал способ прописать ccode в драйвер через /proc или /sys.
Декомпилировал devicetree в надежде найти там способ перезаписать значения NVRAM.
Все тщетно. Походу эти фирмвари и драйвера для Broadcom писались через жопу, на скорую руку и всё, что нам остаётся это грязно патчить через подмену значения в этом текстовом конфиге.
Итого
Как оказалось в принципе по минимуму достаточно поменять ccode=ALL
на ccode=RU
в конфиге фирмвари драйвера.
И видимо в автозагрузку придётся добавить скрипт для замены ccode в нужном файле.
Комментарии