🐤 Sync 2026-10-27 12:12:04

This commit is contained in:
github-actions[bot] committed 2026-10-27 12:12:04 +08:00
1 parent 8b63d5d4a9
commit e646593c56
30 files changed
+1281 -416

No files matched your search

@@ -62,7 +62,12 @@ function mergeUniqueValues(...lists) {
return merged;
}
let runtimeIfnames = Object.create(null);
function getQcaFallbackIfname(device, section) {
if (Object.prototype.hasOwnProperty.call(runtimeIfnames, section))
return runtimeIfnames[section];
if (/^ath\d+$/.test(String(section || '')))
return section;
@@ -252,13 +257,14 @@ function loadIwinfoResolver(force) {
if (!force && cachedIwinfoResolver != null)
return Promise.resolve(cachedIwinfoResolver);
const configuredDevices = getIwinfoDevicesFromConfig();
const deviceRequest = configuredDevices != null
? Promise.resolve(configuredDevices)
: L.resolveDefault(callIwinfoDevices(), []);
cachedIwinfoResolverPromise = deviceRequest.then((devices) => {
cachedIwinfoResolver = buildIwinfoResolver(devices, configuredDevices != null);
cachedIwinfoResolverPromise = network.getWifiRuntimeIfnames().then((names) => {
runtimeIfnames = names;
const configuredDevices = getIwinfoDevicesFromConfig();
return (configuredDevices != null ? Promise.resolve(configuredDevices)
: L.resolveDefault(callIwinfoDevices(), [])).then((devices) =>
buildIwinfoResolver(devices, configuredDevices != null));
}).then((resolver) => {
cachedIwinfoResolver = resolver;
cachedIwinfoResolverPromise = null;
return cachedIwinfoResolver;
}).catch(() => {
@@ -444,6 +450,9 @@ function isNetworkDisplayUp(radioNet) {
}
function getRadioDisplayName(radioDev) {
const info = cachedIwinfoInfoMap?.[radioDev.getName()];
if (info?.hardware?.name)
return info.hardware.name + (info.hwmodes_text ? ' 802.11' + info.hwmodes_text : '');
const name = radioDev.getI18n().replace(/ Wireless Controller .+$/, '');
const hwtype = uci.get('wireless', radioDev.getName(), 'type');
const hwmode = uci.get('wireless', radioDev.getName(), 'hwmode') || '';
@@ -608,7 +617,9 @@ function getDisplayEncryption(radioNet) {
function getDisplayBSSID(radioNet) {
// A radio MAC may differ from the BSSID of an individual virtual AP.
const target = cachedIwinfoResolver?.aliasMap[radioNet.getName()];
const candidates = [
cachedIwinfoInfoMap?.[target]?.bssid,
radioNet.getActiveBSSID(),
radioNet.getBSSID(),
uci.get('wireless', radioNet.getName(), 'macaddr')
@@ -1408,7 +1419,7 @@ function getDisplaySignalValue(radioNet, hwtype, is_assoc) {
if (hwtype == 'mt_dbdc' && radioNet.getMode() == 'ap')
return is_assoc ? getDisplayTxPower(radioNet) : null;
if (isQcaWifiHwtype(hwtype) && radioNet.getMode() == 'ap' && is_assoc)
return getDisplayTxPower(radioNet) ?? 30;
return getDisplayTxPower(radioNet);
return radioNet.getSignal();
}
@@ -1748,7 +1759,9 @@ var CBIWifiFrequencyValue = form.Value.extend({
const chval = +cfg_channel;
const allow_auto = (hwtype == 'mt_dbdc' || isQcaWifiHwtype(hwtype) ||
cfg_channel == 'auto' || L.hasSystemFeature('hostapd', 'acs'));
const configOnly = isConfigWifiDeviceDisabled(device_section) ||
const queryDevice = isQcaWifiHwtype(hwtype)
? cachedIwinfoResolver?.aliasMap[device_section] : device_section;
const configOnly = !queryDevice || isConfigWifiDeviceDisabled(device_section) ||
(isQcaWifiHwtype(hwtype) && areQcaRuntimeProbesSuspended());
const configDevice = configOnly
? network.getWifiDevicesFromConfig().find((device) => device.getName() == device_section)
@@ -1756,8 +1769,8 @@ var CBIWifiFrequencyValue = form.Value.extend({
return Promise.all([
configOnly ? configDevice : network.getWifiDevice(device_section),
configOnly ? [] : this.callFrequencyList(device_section),
configOnly ? {} : this.callDeviceInfo(device_section),
configOnly ? [] : this.callFrequencyList(queryDevice),
configOnly ? {} : this.callDeviceInfo(queryDevice),
configOnly ? {} : L.resolveDefault(this.callWirelessStatus(), {}),
!configOnly && isQcaWifiHwtype(hwtype) ? L.resolveDefault(fs.exec_direct('/usr/sbin/iw', [ 'dev' ]), '') : '',
!configOnly && isQcaWifiHwtype(hwtype) ? L.resolveDefault(fs.exec_direct('/usr/sbin/iw', [ 'phy' ]), '') : '',
@@ -1851,6 +1864,12 @@ var CBIWifiFrequencyValue = form.Value.extend({
if (!htmode_values.length)
htmode_values = L.toArray(devinfo.htmodes);
// Config-only WifiDevice instances default to b/g, even for a 5 GHz radio.
if (isQcaWifiHwtype(hwtype) && Array.isArray(devinfo.hwmodes))
hwmode_values = devinfo.hwmodes;
if (isQcaWifiHwtype(hwtype) && Array.isArray(devinfo.htmodes))
htmode_values = devinfo.htmodes;
if (!hwmode_values.length) {
if (/^11be/.test(hwval) || /^EHT/.test(htval))
hwmode_values = [ 'be' ];
@@ -1904,7 +1923,8 @@ var CBIWifiFrequencyValue = form.Value.extend({
const qca_ht320 = (!!(htmodelist.EHT320 || /^HT320$/.test(htval)) && qca_max_width >= 320);
this.modes = [
'', 'Legacy', { available: false },
'', hwtype == 'qcawifi' ? (hwmodelist.a ? 'A' : 'B/G') : 'Legacy',
{ available: hwtype == 'qcawifi' && (hwmodelist.a || hwmodelist.b || hwmodelist.g) },
'n', 'N', { available: qca_has_n },
'ac', 'AC', { available: qca_has_ac },
'ax', 'AX', { available: qca_has_ax },
@@ -1939,13 +1959,20 @@ var CBIWifiFrequencyValue = form.Value.extend({
]
};
if (hwtype == 'qcawifi')
for (let i = 0; i < this.htmodes.ac.length; i += 3)
this.htmodes.ac[i] = this.htmodes.ac[i].replace(/^HT/, 'VHT');
this.bands = {
'': [
'2g', '2.4 GHz', { available: has_band_channels('2g') },
'5g', '5 GHz', { available: has_band_channels('5g') },
'6g', '6 GHz', { available: has_band_channels('6g') }
],
'n': [ '2g', '2.4 GHz', { available: has_band_channels('2g') } ],
'n': [
'2g', '2.4 GHz', { available: has_band_channels('2g') },
'5g', '5 GHz', { available: hwtype == 'qcawifi' && has_band_channels('5g') }
],
'ac': [ '5g', '5 GHz', { available: has_band_channels('5g') } ],
'ax': [
'2g', '2.4 GHz', { available: has_band_channels('2g') },
@@ -2406,10 +2433,9 @@ var CBIWifiFrequencyValue = form.Value.extend({
const qcaBand = (hwtype == 'qcawificfg80211') ? getQcaBandCode(band) : null;
if (hwtype == 'qcawifi') {
if (mode == 'ac')
hwmode = '11ac';
else if (mode == 'n')
hwmode = '11ng';
// QCA10 netifd uses the band in hwmode and HT/VHT in htmode.
hwmode = band == '5g' ? '11a' : '11g';
setValue('htmode', mode == 'ac' ? htmode.replace(/^HT/, 'VHT') : (htmode || null));
}
else if (hwtype == 'qcawificfg80211') {
switch (mode) {
@@ -2469,7 +2495,9 @@ var CBIWifiTxPowerValue = form.ListValue.extend({
return form.ListValue.prototype.load.apply(this, [section_id]);
}
return this.callTxPowerList(section_id).then(L.bind(function(pwrlist) {
const queryDevice = isQcaWifiHwtype(hwtype)
? cachedIwinfoResolver?.aliasMap[device_section] : section_id;
return (queryDevice ? this.callTxPowerList(queryDevice) : Promise.resolve([])).then(L.bind(function(pwrlist) {
this.powerval = this.wifiNetwork ? getDisplayTxPower(this.wifiNetwork) : null;
this.poweroff = this.wifiNetwork ? this.wifiNetwork.getTXPowerOffset() : null;
@@ -2673,10 +2701,12 @@ return view.extend({
callSystemBoard()
]).then((data) => {
this.boardinfo = data[4] || {};
/* MTK capability rates need iwinfo and the PHY MCS/NSS map.
* Populate them before the first render, not the next poll. */
/* Config-only radios need their runtime iwinfo before the first render,
* including QCA VAP names and MTK PHY capability rates. */
if (!this.checkAnonymousSections() &&
uci.sections('wireless', 'wifi-device').some(radio => radio.type == 'mt_dbdc'))
uci.sections('wireless', 'wifi-device').some(radio =>
radio.type == 'mt_dbdc' ||
(isQcaWifiHwtype(radio.type) && !areQcaRuntimeProbesSuspended())))
return loadIwinfoInfoMap(false).then(() => data);
return data;
});
@@ -3314,6 +3344,15 @@ return view.extend({
o.depends('mode', 'ap-wds');
o.default = o.enabled;
if (hwtype == 'qcawifi' &&
cachedIwinfoInfoMap?.[radioNet.getWifiDeviceName()]?.hwmodes?.includes('ac')) {
o = ss.taboption('advanced', form.Flag, 'vhtmubfer', _('MU-MIMO'));
o.depends('mode', 'ap');
o.depends('mode', 'ap-wds');
o.default = o.disabled;
o.rmempty = false;
}
o = ss.taboption('advanced', form.Flag, 'doth', '802.11h');
o.depends('mode', 'ap');
o.depends('mode', 'ap-wds');