Files
ols-ucentral-schema/renderer/wifi/phy.uc
John Crispin 0a77e9cd13 add EHT detection to phy.uc
Signed-off-by: John Crispin <john@phrozen.org>
2023-10-01 07:38:51 +02:00

171 lines
4.3 KiB
Ucode

let fs = require('fs');
let uci = require("uci");
let cursor = uci ? uci.cursor() : null;
let nl = require("nl80211");
let def = nl.const;
function freq2channel(freq) {
if (freq == 2484)
return 14;
else if (freq < 2484)
return (freq - 2407) / 5;
else if (freq >= 4910 && freq <= 4980)
return (freq - 4000) / 5;
else if(freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6)
return (freq - 56160) / 2160;
else if (freq >= 5955 && freq <= 7115)
return (freq - 5950) / 5;
else
return (freq - 5000) / 5;
}
function phy_get(wdev) {
let res = nl.request(def.NL80211_CMD_GET_WIPHY, def.NLM_F_DUMP, { split_wiphy_dump: true });
if (res === false)
warn("Unable to lookup phys: " + nl.error() + "\n");
return res;
}
let paths = {};
function add_path(path, phy, index) {
if (!phy)
return;
phy = fs.basename(phy);
paths[phy] = path;
if (index)
paths[phy] += '+' + index;
}
function lookup_paths() {
let wireless = cursor.get_all('wireless');
for (let k, section in wireless) {
if (section['.type'] != 'wifi-device' || !section.path)
continue;
let phys = fs.glob(sprintf('/sys/devices/%s/ieee80211/phy*', section.path));
if (!length(phys))
phys = fs.glob(sprintf('/sys/devices/platform/%s/ieee80211/phy*', section.path));
if (!length(phys))
continue;
sort(phys);
let index = 0;
for (let phy in phys)
add_path(section.path, phy, index++);
}
}
function get_hwmon(phy) {
let hwmon = fs.glob(sprintf('/sys/class/ieee80211/%s/hwmon*/temp*_input', phy));
if (!hwmon)
return 0;
let file = fs.open(hwmon[0], 'r');
if (!file)
return 0;
let temp = +file.read('all');
file.close();
return temp;
}
function lookup_phys() {
lookup_paths();
let phys = phy_get();
let ret = {};
for (let phy in phys) {
let phyname = 'phy' + phy.wiphy;
let path = paths[phyname];
if (!path)
continue;
let p = {};
let temp = get_hwmon('phy' + phy.wiphy);
if (temp)
p.temperature = temp / 1000;
p.tx_ant = phy.wiphy_antenna_tx;
p.rx_ant = phy.wiphy_antenna_rx;
p.tx_ant_avail = phy.wiphy_antenna_avail_tx;
p.rx_ant_avail = phy.wiphy_antenna_avail_rx;
p.frequencies = [];
p.channels = [];
p.dfs_channels = [];
p.htmode = [];
p.band = [];
for (let band in phy.wiphy_bands) {
for (let freq in band?.freqs) {
if (freq.disabled)
continue;
push(p.frequencies, freq.freq);
push(p.channels, freq2channel(freq.freq));
if (freq.radar)
push(p.dfs_channels, freq2channel(freq.freq));
if (freq.freq >= 6000)
push(p.band, '6G');
else if (freq.freq <= 2484)
push(p.band, '2G');
else if (freq.freq >= 5160 && freq.freq <= 5885)
push(p.band, '5G');
}
if (band?.ht_capa) {
p.ht_capa = band.ht_capa;
push(p.htmode, 'HT20');
if (band.ht_capa & 0x2)
push(p.htmode, 'HT40');
}
if (band?.vht_capa) {
p.vht_capa = band.vht_capa;
push(p.htmode, 'VHT20', 'VHT40', 'VHT80');
let chwidth = (band?.vht_capa >> 2) & 0x3;
switch(chwidth) {
case 2:
push(p.htmode, 'VHT80+80');
/* fall through */
case 1:
push(p.htmode, 'VHT160');
}
}
for (let iftype in band?.iftype_data) {
if (iftype.iftypes?.ap) {
p.he_phy_capa = iftype?.he_cap_phy;
p.he_mac_capa = iftype?.he_cap_mac;
push(p.htmode, 'HE20');
let chwidth = (iftype?.he_cap_phy[0] || 0) & 0xff;
if (chwidth & 0x2 || chwidth & 0x4)
push(p.htmode, 'HE40');
if (chwidth & 0x4)
push(p.htmode, 'HE80');
if (chwidth & 0x8 || chwidth & 0x10)
push(p.htmode, 'HE160');
if (chwidth & 0x10)
push(p.htmode, 'HE80+80');
if (iftype.eht_cap_phy) {
p.eht_phy_capa = iftype?.eht_cap_phy;
p.eht_mac_capa = iftype?.eht_cap_mac;
push(p.htmode, 'EHT20');
if (chwidth & 0x2 || chwidth & 0x4)
push(p.htmode, 'EHT40');
if (chwidth & 0x4)
push(p.htmode, 'EHT80');
if (chwidth & 0x8 || chwidth & 0x10)
push(p.htmode, 'EHT160');
if (chwidth & 0x10)
push(p.htmode, 'EHT80+80');
if ('6G' in p.band)
push(p.htmode, 'EHT320');
}
}
}
}
p.band = uniq(p.band);
if (!length(p.dfs_channels))
delete p.dfs_channels;
ret[path] = p;
}
return ret;
}
return lookup_phys();