From: Felix Fietkau Date: Tue, 11 Jun 2024 15:29:22 +0000 (+0200) Subject: wifi-scripts: rewrite wifi detect code in ucode X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=4a3ed518b2d07ea3194d06d35fe0da77826a1c3a;p=openwrt%2Fstaging%2Fxback.git wifi-scripts: rewrite wifi detect code in ucode Rely entirely on /etc/board.json instead of screen scraping iw cli output Signed-off-by: Felix Fietkau --- diff --git a/package/network/config/wifi-scripts/files/lib/wifi/mac80211.sh b/package/network/config/wifi-scripts/files/lib/wifi/mac80211.sh deleted file mode 100644 index e24a2a634e..0000000000 --- a/package/network/config/wifi-scripts/files/lib/wifi/mac80211.sh +++ /dev/null @@ -1,217 +0,0 @@ -#!/bin/sh - -append DRIVERS "mac80211" - -check_mac80211_device() { - local device="$1" - local path="$2" - local macaddr="$3" - - [ -n "$found" ] && return 0 - - phy_path= - config_get phy "$device" phy - json_select wlan - [ -n "$phy" ] && case "$phy" in - phy*) - [ -d /sys/class/ieee80211/$phy ] && \ - phy_path="$(iwinfo nl80211 path "$dev")" - ;; - *) - if json_is_a "$phy" object; then - json_select "$phy" - json_get_var phy_path path - json_select .. - elif json_is_a "${phy%.*}" object; then - json_select "${phy%.*}" - json_get_var phy_path path - json_select .. - phy_path="$phy_path+${phy##*.}" - fi - ;; - esac - json_select .. - [ -n "$phy_path" ] || config_get phy_path "$device" path - [ -n "$path" -a "$phy_path" = "$path" ] && { - found=1 - return 0 - } - - config_get dev_macaddr "$device" macaddr - - [ -n "$macaddr" -a "$dev_macaddr" = "$macaddr" ] && found=1 - - return 0 -} - - -__get_band_defaults() { - local phy="$1" - - ( iw phy "$phy" info; echo ) | awk ' -BEGIN { - bands = "" -} - -($1 == "Band" || $1 == "") && band { - if (channel) { - mode="NOHT" - if (ht) mode="HT20" - if (vht && band != "1:") mode="VHT80" - if (he) mode="HE80" - if (he && band == "1:") mode="HE20" - sub("\\[", "", channel) - sub("\\]", "", channel) - bands = bands band channel ":" mode " " - } - band="" -} - -$1 == "Band" { - band = $2 - channel = "" - vht = "" - ht = "" - he = "" -} - -$0 ~ "Capabilities:" { - ht=1 -} - -$0 ~ "VHT Capabilities" { - vht=1 -} - -$0 ~ "HE Iftypes" { - he=1 -} - -$1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel { - channel = $4 -} - -END { - print bands -}' -} - -get_band_defaults() { - local phy="$1" - - for c in $(__get_band_defaults "$phy"); do - local band="${c%%:*}" - c="${c#*:}" - local chan="${c%%:*}" - c="${c#*:}" - local mode="${c%%:*}" - - case "$band" in - 1) band=2g;; - 2) band=5g;; - 3) band=60g;; - 4) band=6g;; - *) band="";; - esac - - [ -n "$band" ] || continue - [ -n "$mode_band" -a "$band" = "6g" ] && return - - mode_band="$band" - channel="$chan" - htmode="$mode" - done -} - -check_devidx() { - case "$1" in - radio[0-9]*) - local idx="${1#radio}" - [ "$devidx" -ge "${1#radio}" ] && devidx=$((idx + 1)) - ;; - esac -} - -check_board_phy() { - local name="$2" - - json_select "$name" - json_get_var phy_path path - json_select .. - - if [ "$path" = "$phy_path" ]; then - board_dev="$name" - elif [ "${path%+*}" = "$phy_path" ]; then - fallback_board_dev="$name.${path#*+}" - fi -} - -detect_mac80211() { - devidx=0 - config_load wireless - config_foreach check_devidx wifi-device - - json_load_file /etc/board.json - - for _dev in /sys/class/ieee80211/*; do - [ -e "$_dev" ] || continue - - dev="${_dev##*/}" - - mode_band="" - channel="" - htmode="" - ht_capab="" - - get_band_defaults "$dev" - - path="$(iwinfo nl80211 path "$dev")" - macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)" - - # work around phy rename related race condition - [ -n "$path" -o -n "$macaddr" ] || continue - - board_dev= - fallback_board_dev= - json_for_each_item check_board_phy wlan - [ -n "$board_dev" ] || board_dev="$fallback_board_dev" - [ -n "$board_dev" ] && dev="$board_dev" - - found= - config_foreach check_mac80211_device wifi-device "$path" "$macaddr" - [ -n "$found" ] && continue - - name="radio${devidx}" - devidx=$(($devidx + 1)) - case "$dev" in - phy*) - if [ -n "$path" ]; then - dev_id="set wireless.${name}.path='$path'" - else - dev_id="set wireless.${name}.macaddr='$macaddr'" - fi - ;; - *) - dev_id="set wireless.${name}.phy='$dev'" - ;; - esac - - uci -q batch <<-EOF - set wireless.${name}=wifi-device - set wireless.${name}.type=mac80211 - ${dev_id} - set wireless.${name}.channel=${channel} - set wireless.${name}.band=${mode_band} - set wireless.${name}.htmode=$htmode - set wireless.${name}.disabled=1 - - set wireless.default_${name}=wifi-iface - set wireless.default_${name}.device=${name} - set wireless.default_${name}.network=lan - set wireless.default_${name}.mode=ap - set wireless.default_${name}.ssid=OpenWrt - set wireless.default_${name}.encryption=none -EOF - uci -q commit wireless - done -} diff --git a/package/network/config/wifi-scripts/files/lib/wifi/mac80211.uc b/package/network/config/wifi-scripts/files/lib/wifi/mac80211.uc new file mode 100644 index 0000000000..8f25a791b3 --- /dev/null +++ b/package/network/config/wifi-scripts/files/lib/wifi/mac80211.uc @@ -0,0 +1,94 @@ +#!/usr/bin/env ucode +import { readfile } from "fs"; +import * as uci from 'uci'; + +const bands_order = [ "6G", "5G", "2G" ]; +const htmode_order = [ "HE", "VHT", "HT" ]; + +let board = json(readfile("/etc/board.json")); +if (!board.wlan) + exit(0); + +let idx = 0; +let commit; + +let config = uci.cursor().get_all("wireless") ?? {}; + +function radio_exists(path, macaddr, phy) { + for (let name, s in config) { + if (s[".type"] != "wifi-device") + continue; + if (s.macaddr & lc(s.macaddr) == lc(macaddr)) + return true; + if (s.phy == phy) + return true; + if (!s.path || !path) + continue; + if (substr(s.path, -length(path)) == path) + return true; + } +} + +for (let phy_name, phy in board.wlan) { + let info = phy.info; + if (!info || !length(info.bands)) + continue; + + while (config[`radio${idx}`]) + idx++; + let name = "radio" + idx++; + + let s = "wireless." + name; + let si = "wireless.default_" + name; + + let band_name = filter(bands_order, (b) => info.bands[b])[0]; + if (!band_name) + continue; + + let band = info.bands[band_name]; + let channel = band.default_channel ?? "auto"; + + let width = band.max_width; + if (band_name == "2G") + width = 20; + else if (width > 80) + width = 80; + + let htmode = filter(htmode_order, (m) => band[lc(m)])[0]; + if (htmode) + htmode += width; + else + htmode = "NOHT"; + + if (!phy.path) + continue; + + let macaddr = trim(readfile(`/sys/class/ieee80211/${phy_name}/macaddress`)); + if (radio_exists(phy.path, macaddr, phy_name)) + continue; + + let id = `phy='${phy_name}'`; + if (match(phy_name, /^phy[0-9]/)) + id = `path='${phy.path}'`; + + print(`set ${s}=wifi-device +set ${s}.type='mac80211' +set ${s}.${id} +set ${s}.band='${lc(band_name)}' +set ${s}.channel='${channel}' +set ${s}.htmode='${htmode}' +set ${s}.disabled='1' + +set ${si}=wifi-iface +set ${si}.device='${name}' +set ${si}.network='lan' +set ${si}.mode='ap' +set ${si}.ssid='OpenWrt' +set ${si}.encryption='none' + +`); + commit = true; +} + +if (commit) + print("commit wireless\n"); diff --git a/package/network/config/wifi-scripts/files/sbin/wifi b/package/network/config/wifi-scripts/files/sbin/wifi index 27cbad3781..f937dba7e6 100755 --- a/package/network/config/wifi-scripts/files/sbin/wifi +++ b/package/network/config/wifi-scripts/files/sbin/wifi @@ -178,6 +178,7 @@ wifi_config() { [ -e /tmp/.config_pending ] && return ucode /usr/share/hostap/wifi-detect.uc [ ! -f /etc/config/wireless ] && touch /etc/config/wireless + ucode /lib/wifi/mac80211.uc | uci -q batch for driver in $DRIVERS; do ( if eval "type detect_$driver" 2>/dev/null >/dev/null; then