ath12.4-cs1: update to latest SDK

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2024-12-09 08:35:44 +01:00
parent ed7e047514
commit e4b535f6cb
2614 changed files with 16622 additions and 648867 deletions

View File

@@ -270,7 +270,7 @@ define Package/wpad/Default
CATEGORY:=Network
SUBMENU:=WirelessAPD
TITLE:=IEEE 802.1x Auth/Supplicant (QCA)
DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus
DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus $(CORE_DEPENDS)
EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE))
USERID:=network=101:network=101
URL:=http://hostap.epitest.fi/
@@ -720,23 +720,24 @@ define Install/supplicant
$(INSTALL_DIR) $(1)/usr/sbin
endef
EXTERNAL_FILE_DIR:=$(CURDIR)/files
#EXTERNAL_FILE_DIR:=$(CURDIR)/files-qca
define Package/hostapd-common/install
$(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d
$(INSTALL_DATA) $(EXTERNAL_FILE_DIR)/hostapd.sh $(1)/lib/netifd/hostapd.sh
$(INSTALL_BIN) $(EXTERNAL_FILE_DIR)/wpad.init $(1)/etc/init.d/wpad
$(INSTALL_BIN) $(EXTERNAL_FILE_DIR)/wps-hotplug.sh $(1)/etc/rc.button/wps
$(INSTALL_DATA) $(EXTERNAL_FILE_DIR)/wpad_acl.json $(1)/usr/share/acl.d
$(INSTALL_DATA) $(EXTERNAL_FILE_DIR)/wpad.json $(1)/etc/capabilities
$(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh
$(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad
$(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps
$(INSTALL_DATA) ./files/wpad_acl.json $(1)/usr/share/acl.d
$(INSTALL_DATA) ./files/wpad.json $(1)/etc/capabilities
$(INSTALL_DIR) $(1)/usr/share/hostap/
$(INSTALL_DATA) $(EXTERNAL_FILE_DIR)/*.uc $(1)/usr/share/hostap/
$(INSTALL_DATA) ./files/*.uc $(1)/usr/share/hostap/
$(INSTALL_BIN) ./files/mpskd $(1)/usr/share/hostap/
$(INSTALL_BIN) ./files/mpskd.init $(1)/etc/init.d/mpskd
endef
define Package/hostapd/install
$(call Install/hostapd,$(1))
$(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd $(1)/usr/sbin/
endef
Package/hostapd-basic/install = $(Package/hostapd/install)
Package/hostapd-basic-openssl/install = $(Package/hostapd/install)
Package/hostapd-basic-wolfssl/install = $(Package/hostapd/install)

View File

@@ -0,0 +1,156 @@
#!/usr/bin/ucode
'use strict';
import * as iwinfo from 'iwinfo';
function print_assoclist(stations) {
for (let mac, station in stations) {
printf(`${station.mac} ${station.signal} dBm / ${station.noise} dBm (SNR ${station.snr}) ${station.inactive_time} ms ago\n`);
for (let k in [ 'rx', 'tx' ]) {
let bitrate = station[k];
let flags = join(', ', bitrate.flags);
printf(`\t${uc(k)}: ${bitrate.bitrate} MBit/s`);
if (length(bitrate.flags))
printf(', %s', flags);
printf('%10d Pkts.\n', bitrate.packets);
}
printf(`\texpected throughput: ${station.expected_throughput}\n\n`);
}
}
function print_countrylist(list) {
for (let k, v in list.countries)
printf(`${k == list.active ? '*' : ' '} ${k} "${v}"\n`);
}
function print_freqlist(channels) {
for (let channel in channels) {
printf(`${channel.active ? '*' : ' '} ${channel.freq} GHz (Band: ${channel.band} GHz, Channel ${channel.channel})`);
if (length(channel.flags))
printf(` [${join(', ', channel.flags)}]`);
printf('\n');
}
}
function print_htmodelist(htmode) {
printf('%s\n', join(' ', htmode));
}
function print_info(list) {
let padding = ' ';
for (let bss in list) {
printf(`${bss.iface} ESSID: "${bss.ssid}"\n`);
printf(`${padding}Access Point: ${bss.mac}\n`);
printf(`${padding}Mode: ${bss.mode} Channel: ${bss.channel} (${bss.freq} GHz) HT Mode: ${bss.htmode}\n`);
printf(`${padding}Center Channel 1: ${bss.center_freq1} 2: ${bss.center_freq2}\n`);
printf(`${padding}Tx-Power: ${bss.txpower} dBm Link Quality: ${bss.quality}/70\n`);
printf(`${padding}Signal: ${bss.signal} Noise: ${bss.noise}\n`);
printf(`${padding}Bit Rate: ${bss.bitrate ?? 'unknown'} MBit/s\n`);
printf(`${padding}Encryption: ${bss.encryption}\n`);
printf(`${padding}Type: nl80211 HW Mode(s): 802.11${bss.hwmode}\n`);
printf(`${padding}Hardware: ${bss.hw_type} [${bss.hw_id}]\n`);
printf(`${padding}TX power offset: ${bss.power_offset}\n`);
printf(`${padding}Channel offset: ${bss.channel_offset}\n`);
printf(`${padding}Supports VAPs: ${bss.vaps} PHY name: ${bss.phy}\n`);
if (bss.owe_transition_ifname)
printf(`${padding}OWE partner: ${bss.owe_transition_ifname}\n`);
printf('\n');
}
return 0;
}
function print_scan(cells) {
let idx = 1;
for (let cell in cells) {
printf('Cell %02d - Address: %s\n', idx++, cell.bssid);
printf('\t Mode: %s Frequency: %s GHz Band: %s GHz Channel: %d\n', cell.mode, cell.frequency, cell.band, cell.channel);
printf('\t Signal: %d dBm Quality: %2d/70\n', cell.dbm, cell.quality);
if (!length(cell.crypto.key_mgmt))
printf('\t Encryption: NONE\n');
else
printf('\t Encryption: %s (%s)\n', join(' / ', cell.crypto.key_mgmt), join(' / ', cell.crypto.pair));
if (cell.ht) {
printf('\t HT Operation:\n');
printf('\t\tPrimary Channel: %d\n', cell.ht.primary_channel);
printf('\t\tSecondary Channel Offset: %s\n', cell.ht.secondary_chan_off);
printf('\t\tChannel Width: %s\n', cell.ht.chan_width);
}
if (cell.vht) {
printf('\t VHT Operation:\n');
printf('\t\tCenter Frequency 1: %d\n', cell.vht.center_chan_1);
printf('\t\tCenter Frequency 2: %s\n', cell.vht.center_chan_2);
printf('\t\tChannel Width: %s\n', cell.vht.chan_width);
}
printf('\n');
}
}
function print_txpowerlist(list) {
for (let power in list)
printf('%s %2d dbm (%4d mW)\n', power.active ? '*' : ' ', power.dbm, power.mw);
}
let pretty = true;
if (ARGV[0] == '-j') {
pretty = false;
shift(ARGV);
}
if (!length(ARGV)) {
let info = iwinfo.info();
if (pretty)
print_info(info);
else
printf('%.J\n', info);
return 0;
}
const commands = {
assoclist: [ iwinfo.assoclist, print_assoclist ],
countrylist: [ iwinfo.countrylist, print_countrylist ],
freqlist: [ iwinfo.freqlist, print_freqlist ],
htmodelist: [ iwinfo.htmodelist, print_htmodelist ],
info: [ iwinfo.info, print_info ],
scan: [ iwinfo.scan, print_scan ],
txpowerlist: [ iwinfo.txpowerlist, print_txpowerlist ],
};
if (length(ARGV) == 2 && iwinfo.ifaces[ARGV[0]])
for (let cmd, cb in commands)
if (substr(cmd, 0, length(ARGV[1])) == ARGV[1]) {
let ret = cb[0](ARGV[0]);
if (pretty)
cb[1](ret);
else
printf('%.J\n', ret);
return 0;
}
switch(ARGV[0]) {
case 'phy':
printf('%.J\n', iwinfo.phys);
return 0;
case 'iface':
printf('%.J\n', iwinfo.ifaces);
return 0;
}
printf('Usage:\n' +
'\tiwinfo <device> info\n' +
'\tiwinfo <device> scan\n' +
'\tiwinfo <device> txpowerlist\n' +
'\tiwinfo <device> freqlist\n' +
'\tiwinfo <device> assoclist\n' +
'\tiwinfo <device> countrylist\n' +
'\tiwinfo <device> htmodelist\n' +
'\tiwinfo <backend> phyname <section>\n');

View File

@@ -0,0 +1,249 @@
{
"00": "World",
"AD": "Andorra",
"AE": "United Arab Emirates",
"AF": "Afghanistan",
"AG": "Antigua and Barbuda",
"AI": "Anguilla",
"AL": "Albania",
"AM": "Armenia",
"AN": "Netherlands Antilles",
"AO": "Angola",
"AQ": "Antarctica",
"AR": "Argentina",
"AS": "American Samoa",
"AT": "Austria",
"AU": "Australia",
"AW": "Aruba",
"AX": "Aland Islands",
"AZ": "Azerbaijan",
"BA": "Bosnia and Herzegovina",
"BB": "Barbados",
"BD": "Bangladesh",
"BE": "Belgium",
"BF": "Burkina Faso",
"BG": "Bulgaria",
"BH": "Bahrain",
"BI": "Burundi",
"BJ": "Benin",
"BL": "Saint Barthelemy",
"BM": "Bermuda",
"BN": "Brunei Darussalam",
"BO": "Bolivia",
"BR": "Brazil",
"BS": "Bahamas",
"BT": "Bhutan",
"BV": "Bouvet Island",
"BW": "Botswana",
"BY": "Belarus",
"BZ": "Belize",
"CA": "Canada",
"CC": "Cocos (Keeling) Islands",
"CD": "Congo",
"CF": "Central African Republic",
"CG": "Congo",
"CH": "Switzerland",
"CI": "Cote d'Ivoire",
"CK": "Cook Islands",
"CL": "Chile",
"CM": "Cameroon",
"CN": "China",
"CO": "Colombia",
"CR": "Costa Rica",
"CU": "Cuba",
"CV": "Cape Verde",
"CX": "Christmas Island",
"CY": "Cyprus",
"CZ": "Czech Republic",
"DE": "Germany",
"DJ": "Djibouti",
"DK": "Denmark",
"DM": "Dominica",
"DO": "Dominican Republic",
"DZ": "Algeria",
"EC": "Ecuador",
"EE": "Estonia",
"EG": "Egypt",
"EH": "Western Sahara",
"ER": "Eritrea",
"ES": "Spain",
"ET": "Ethiopia",
"FI": "Finland",
"FJ": "Fiji",
"FK": "Falkland Islands",
"FM": "Micronesia",
"FO": "Faroe Islands",
"FR": "France",
"GA": "Gabon",
"GB": "United Kingdom",
"GD": "Grenada",
"GE": "Georgia",
"GF": "French Guiana",
"GG": "Guernsey",
"GH": "Ghana",
"GI": "Gibraltar",
"GL": "Greenland",
"GM": "Gambia",
"GN": "Guinea",
"GP": "Guadeloupe",
"GQ": "Equatorial Guinea",
"GR": "Greece",
"GS": "South Georgia",
"GT": "Guatemala",
"GU": "Guam",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HK": "Hong Kong",
"HM": "Heard and McDonald Islands",
"HN": "Honduras",
"HR": "Croatia",
"HT": "Haiti",
"HU": "Hungary",
"ID": "Indonesia",
"IE": "Ireland",
"IL": "Israel",
"IM": "Isle of Man",
"IN": "India",
"IO": "Chagos Islands",
"IQ": "Iraq",
"IR": "Iran",
"IS": "Iceland",
"IT": "Italy",
"JE": "Jersey",
"JM": "Jamaica",
"JO": "Jordan",
"JP": "Japan",
"KE": "Kenya",
"KG": "Kyrgyzstan",
"KH": "Cambodia",
"KI": "Kiribati",
"KM": "Comoros",
"KN": "Saint Kitts and Nevis",
"KP": "North Korea",
"KR": "South Korea",
"KW": "Kuwait",
"KY": "Cayman Islands",
"KZ": "Kazakhstan",
"LA": "Laos",
"LB": "Lebanon",
"LC": "Saint Lucia",
"LI": "Liechtenstein",
"LK": "Sri Lanka",
"LR": "Liberia",
"LS": "Lesotho",
"LT": "Lithuania",
"LU": "Luxembourg",
"LV": "Latvia",
"LY": "Libyan Arab Jamahiriya",
"MA": "Morocco",
"MC": "Monaco",
"MD": "Moldova",
"ME": "Montenegro",
"MF": "Saint Martin (French part)",
"MG": "Madagascar",
"MH": "Marshall Islands",
"MK": "Macedonia",
"ML": "Mali",
"MM": "Myanmar",
"MN": "Mongolia",
"MO": "Macao",
"MP": "Northern Mariana Islands",
"MQ": "Martinique",
"MR": "Mauritania",
"MS": "Montserrat",
"MT": "Malta",
"MU": "Mauritius",
"MV": "Maldives",
"MW": "Malawi",
"MX": "Mexico",
"MY": "Malaysia",
"MZ": "Mozambique",
"NA": "Namibia",
"NC": "New Caledonia",
"NE": "Niger",
"NF": "Norfolk Island",
"NG": "Nigeria",
"NI": "Nicaragua",
"NL": "Netherlands",
"NO": "Norway",
"NP": "Nepal",
"NR": "Nauru",
"NU": "Niue",
"NZ": "New Zealand",
"OM": "Oman",
"PA": "Panama",
"PE": "Peru",
"PF": "French Polynesia",
"PG": "Papua New Guinea",
"PH": "Philippines",
"PK": "Pakistan",
"PL": "Poland",
"PM": "Saint Pierre and Miquelon",
"PN": "Pitcairn",
"PR": "Puerto Rico",
"PS": "Palestinian Territory",
"PT": "Portugal",
"PW": "Palau",
"PY": "Paraguay",
"QA": "Qatar",
"RE": "Reunion",
"RO": "Romania",
"RS": "Serbia",
"RU": "Russian Federation",
"RW": "Rwanda",
"SA": "Saudi Arabia",
"SB": "Solomon Islands",
"SC": "Seychelles",
"SD": "Sudan",
"SE": "Sweden",
"SG": "Singapore",
"SH": "St. Helena and Dependencies",
"SI": "Slovenia",
"SJ": "Svalbard and Jan Mayen",
"SK": "Slovakia",
"SL": "Sierra Leone",
"SM": "San Marino",
"SN": "Senegal",
"SO": "Somalia",
"SR": "Suriname",
"ST": "Sao Tome and Principe",
"SV": "El Salvador",
"SY": "Syrian Arab Republic",
"SZ": "Swaziland",
"TC": "Turks and Caicos Islands",
"TD": "Chad",
"TF": "French Southern Territories",
"TG": "Togo",
"TH": "Thailand",
"TJ": "Tajikistan",
"TK": "Tokelau",
"TL": "Timor-Leste",
"TM": "Turkmenistan",
"TN": "Tunisia",
"TO": "Tonga",
"TR": "Turkey",
"TT": "Trinidad and Tobago",
"TV": "Tuvalu",
"TW": "Taiwan",
"TZ": "Tanzania",
"UA": "Ukraine",
"UG": "Uganda",
"UM": "U.S. Minor Outlying Islands",
"US": "United States",
"UY": "Uruguay",
"UZ": "Uzbekistan",
"VA": "Vatican City State",
"VC": "St. Vincent and Grenadines",
"VE": "Venezuela",
"VG": "Virgin Islands, British",
"VI": "Virgin Islands, U.S.",
"VN": "Viet Nam",
"VU": "Vanuatu",
"WF": "Wallis and Futuna",
"WS": "Samoa",
"YE": "Yemen",
"YT": "Mayotte",
"ZA": "South Africa",
"ZM": "Zambia",
"ZW": "Zimbabwe"
}

View File

@@ -0,0 +1,606 @@
'use strict';
import * as nl80211 from 'nl80211';
import * as libubus from 'ubus';
import { readfile, stat } from "fs";
let wifi_devices = json(readfile('/usr/share/wifi_devices.json'));
let countries = json(readfile('/usr/share/iso3166.json'));
let board_data = json(readfile('/etc/board.json'));
export let phys = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, nl80211.const.NLM_F_DUMP, { split_wiphy_dump: true });
let interfaces = nl80211.request(nl80211.const.NL80211_CMD_GET_INTERFACE, nl80211.const.NLM_F_DUMP);
let ubus = libubus.connect();
let wireless_status = ubus.call('network.wireless', 'status');
function find_phy(wiphy) {
for (let k, phy in phys)
if (phy.wiphy == wiphy)
return phy;
return null;
}
function get_noise(iface) {
for (let phy in phys) {
let channels = nl80211.request(nl80211.const.NL80211_CMD_GET_SURVEY, nl80211.const.NLM_F_DUMP, { dev: iface.ifname });
for (let k, channel in channels)
if (channel.survey_info.frequency == iface.wiphy_freq)
return channel.survey_info.noise;
}
return -100;
}
function get_country(iface) {
let reg = nl80211.request(nl80211.const.NL80211_CMD_GET_REG, 0, { dev: iface.ifname });
return reg.reg_alpha2 ?? '';
}
function get_max_power(iface) {
let phy = find_phy(iface.wiphy);
for (let k, band in phy.wiphy_bands)
if (band)
for (let freq in band.freqs)
if (freq.freq == iface.wiphy_freq)
return freq.max_tx_power;;
return 0;
}
function get_hardware_id(iface) {
let hw = {
type: 'nl80211',
id: 'Generic MAC80211',
power_offset: 0,
channel_offset: 0,
};
let path = `/sys/class/ieee80211/phy${iface.wiphy}/device/`;
if (stat(path) + 'vendor') {
let data = [];
for (let lookup in [ 'vendor', 'device', 'subsystem_vendor', 'subsystem_device' ])
push(data, trim(readfile(path + lookup), '\n'));
for (let device in wifi_devices.pci) {
let match = 0;
for (let i = 0; i < 4; i++)
if (lc(data[i]) == lc(device[i]))
match++;
if (match == 4) {
hw.type = `${data[0]}:${data[1]} ${data[2]}:${data[3]}`;
hw.power_offset = device[4];
hw.channel_offset = device[5];
hw.id = `${device[6]} ${device[7]}`;
}
}
}
let compatible = trim(readfile(`/sys/class/net/${iface.ifname}/device/of_node/compatible`), '\n');
if (compatible && wifi_devices.compatible[compatible]) {
hw.id = wifi_devices.compatible[compatible][0] + ' ' + wifi_devices.compatible[compatible][1];
hw.compatible = compatible;
hw.type = 'embedded';
}
return hw;
}
const iftypes = [
'Unknown', 'Ad-Hoc', 'Client', 'Master', 'Master (VLAN)',
'WDS', 'Monitor', 'Mesh Point', 'P2P Client', 'P2P Go',
];
export let ifaces = {};
for (let k, v in interfaces) {
let iface = ifaces[v.ifname] = v;
iface.mode = iftypes[iface.iftype] ?? 'unknonw',
iface.noise = get_noise(iface);
iface.country = get_country(iface);
iface.max_power = get_max_power(iface);
iface.assoclist = nl80211.request(nl80211.const.NL80211_CMD_GET_STATION, nl80211.const.NLM_F_DUMP, { dev: v.ifname }) ?? [];
iface.hardware = get_hardware_id(iface);
iface.bss_info = ubus.call('hostapd', 'bss_info', { iface: v.ifname });
if (!iface.bss_info)
iface.bss_info = ubus.call('wpa_supplicant', 'bss_info', { iface: v.ifname });
}
for (let radio, data in wireless_status)
for (let k, v in data.interfaces) {
if (!v.ifname || !ifaces[v.ifname])
continue;
ifaces[v.ifname].ssid = v.config.ssid;
ifaces[v.ifname].radio = data.config;
let bss_info = ifaces[v.ifname].bss_info;
let owe_transition_ifname = bss_info?.owe_transition_ifname;
if (v.config.owe_transition && ifaces[owe_transition_ifname]) {
ifaces[v.ifname].owe_transition_ifname = owe_transition_ifname;
ifaces[owe_transition_ifname].ssid = v.config.ssid;
ifaces[owe_transition_ifname].radio = data.config;
ifaces[owe_transition_ifname].owe_transition_ifname = v.ifname
}
}
function format_channel(freq) {
if (freq < 1000)
return 0;
if (freq == 2484)
return 14;
if (freq == 5935)
return 2;
if (freq < 2484)
return (freq - 2407) / 5;
if (freq >= 4910 && freq <= 4980)
return (freq - 4000) / 5;
if (freq < 5950)
return (freq - 5000) / 5;
if (freq <= 45000)
return (freq - 5950) / 5;
if (freq >= 58320 && freq <= 70200)
return (freq - 56160) / 2160;
return 'unknown';
}
function format_band(freq) {
if (freq == 5935)
return '6';
if (freq < 2484)
return '2.4';
if (freq < 5950)
return '5';
if (freq <= 45000)
return '6';
return '60';
}
function format_frequency(freq) {
if (!freq)
return 'unknown';
freq = '' + freq;
return substr(freq, 0, 1) + '.' + substr(freq, 1);
}
function format_rate(rate) {
if (!rate)
return 'unknown';
return '' + (rate / 10) + '.' + (rate % 10);
}
function format_mgmt_key(key) {
switch(+key) {
case 1:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
return '802.1x';
case 2:
return 'WPA PSK';
case 4:
return 'FT PSK';
case 6:
return 'WPA PSK2';
case 8:
return 'SAE';
case 18:
return 'OWE';
}
return null;
}
function assoc_flags(data) {
const assoc_mhz = {
width_40: 40,
width_80: 80,
width_80p80: '80+80',
width_160: 160,
width_320: 320,
width_10: 10,
width_5: 5
};
let mhz = 'unknown';
for (let k, v in assoc_mhz)
if (data[k])
mhz = v;
const assoc_flags = {
mcs: {
mcs: 'MCS',
},
vht_mcs: {
vht_mcs: 'VHT-MCS',
vht_nss: 'VHT-NSS',
},
he_mcs: {
he_mcs: 'HE-MCS',
he_nss: 'HE-NSS',
he_gi: 'HE-GI',
he_dcm: 'HE-DCM',
},
eht_mcs: {
eht_mcs: 'EHT-MCS',
eht_nss: 'EHT-NSS',
eht_gi: 'EHT-GI',
},
};
let flags = [];
for (let k, v in assoc_flags) {
if (!data[k])
continue;
let first = 0;
for (let name, flag in v) {
if (data[name] == null)
continue;
push(flags, `${flag} ${data[name]}`);
if (!first++)
push(flags, `${mhz}MHz`);
}
}
return flags;
}
function dbm2mw(dbm) {
const LOG10_MAGIC = 1.25892541179;
let res = 1.0;
let ip = dbm / 10;
let fp = dbm % 10;
for (let k = 0; k < ip; k++)
res *= 10;
for (let k = 0; k < fp; k++)
res *= 1.25892541179;
return int(res);
}
function dbm2quality(dbm) {
let quality = dbm;
if (quality < -110)
quality = -110;
else if (quality > -40)
quality = -40;
quality += 110;
return quality;
}
function hwmodelist(name) {
const mode = { 'HT*': 'n', 'VHT*': 'ac', 'HE*': 'ax' };
let iface = ifaces[name];
let phy = board_data.wlan?.['phy' + iface.wiphy];
if (!phy)
return '';
let htmodes = phy.info.bands[uc(iface.radio.band)].modes;
let list = [];
if (iface.radio.band == '2g' && 'NOHT' in htmodes)
push(list, 'g/b');
for (let k, v in mode)
for (let htmode in htmodes)
if (wildcard(htmode, k))
push(list, v);
return join('/', reverse(uniq(list)));
}
export function assoclist(dev) {
let stations = ifaces[dev].assoclist;
let ret = {};
for (let station in stations) {
let sta = {
mac: uc(station.mac),
signal: station.sta_info.signal_avg,
noise: ifaces[dev].noise,
snr: station.sta_info.signal_avg - ifaces[dev].noise,
inactive_time: station.sta_info.inactive_time,
rx: {
bitrate: format_rate(station.sta_info.rx_bitrate.bitrate),
bitrate_raw: station.sta_info.rx_bitrate.bitrate,
packets: station.sta_info.rx_packets,
flags: assoc_flags(station.sta_info.rx_bitrate),
},
tx: {
bitrate: format_rate(station.sta_info.tx_bitrate.bitrate),
bitrate_raw: station.sta_info.tx_bitrate.bitrate,
packets: station.sta_info.tx_packets,
flags: assoc_flags(station.sta_info.tx_bitrate),
},
expected_throughput: station.sta_info.expected_throughput ?? 'unknown',
};
ret[sta.mac] = sta;
}
return ret;
};
export function freqlist(name) {
const freq_flags = {
no_10mhz: 'NO_10MHZ',
no_20mhz: 'NO_20MHZ',
no_ht40_minus: 'NO_HT40-',
no_ht40_plus: 'NO_HT40+',
no_80mhz: 'NO_80MHZ',
no_160mhz: 'NO_160MHZ',
indoor_only: 'INDOOR_ONLY',
no_ir: 'NO_IR',
no_he: 'NO_HE',
};
let iface = ifaces[name];
let phy = find_phy(iface.wiphy);
let channels = [];
for (let k, band in phy.wiphy_bands) {
if (!band)
continue;
let band_name = format_band(band.freqs[0].freq);
for (let freq in band.freqs) {
if (freq.disabled)
continue;
let channel = {
freq: format_frequency(freq.freq),
band: band_name,
channel: format_channel(freq.freq),
flags: [],
active: iface.wiphy_freq == freq.freq,
};
for (let k, v in freq_flags)
if (freq[k])
push(channel.flags, v);
push(channels, channel);
}
}
return channels;
};
export function info(name) {
let order = [];
for (let iface, data in ifaces)
push(order, iface);
let list = [];
for (let iface in sort(order)) {
if (name && iface != name)
continue;
let data = ifaces[iface];
let dev = {
iface,
ssid: data.ssid,
mac: data.mac,
mode: data.mode,
channel: format_channel(data.wiphy_freq),
freq: format_frequency(data.wiphy_freq),
htmode: data.radio.htmode,
center_freq1: format_channel(data.center_freq1) || 'unknown',
center_freq2: format_channel(data.center_freq2) || 'unknown',
txpower: data.wiphy_tx_power_level / 100,
noise: data.noise,
signal: 0,
bitrate: 0,
encryption: 'unknown',
hwmode: hwmodelist(iface),
phy: 'phy' + data.wiphy,
vaps: 'no',
hw_type: data.hardware.type,
hw_id: data.hardware.id,
power_offset: data.hardware.power_offset || 'none',
channel_offset: data.hardware.channel_offset || 'none',
};
let phy = find_phy(data.wiphy);
for (let limit in phy.interface_combinations[0]?.limits)
if (limit.types?.ap && limit.max > 1)
dev.vaps = 'yes';
if (data.bss_info) {
if (data.bss_info.wpa_key_mgmt && data.bss_info.wpa_pairwise)
dev.encryption = `${replace(data.bss_info.wpa_key_mgmt, ' ', ' / ')} (${data.bss_info.wpa_pairwise})`;
else if (data.owe_transition_ifname)
dev.encryption = 'none (OWE transition)';
else
dev.encryption = 'none';
}
let stations = assoclist(iface);
for (let k, station in stations) {
dev.signal += station.signal;
dev.bitrate += station.tx.bitrate_raw;
}
dev.signal /= length(data.assoclist) || 1;
dev.bitrate /= length(data.assoclist) || 1;
dev.bitrate = format_rate(dev.bitrate);
dev.quality = dbm2quality(dev.signal);
if (data.owe_transition_ifname)
dev.owe_transition_ifname = data.owe_transition_ifname;
push(list, dev);
}
return list;
};
export function htmodelist(name) {
let iface = ifaces[name];
let phy = board_data.wlan?.['phy' + iface.wiphy];
if (!phy)
return [];
return filter(phy.info.bands[uc(iface.radio.band)].modes, (v) => v != 'NOHT');
};
export function txpowerlist(name) {
let iface = ifaces[name];
let max_power = iface.max_power / 100;
let match = iface.wiphy_tx_power_level / 100;
let list = [];
for (let power = 0; power <= max_power; power++) {
let txpower = {
dbm: power,
mw: dbm2mw(power),
active: power == match,
};
push(list, txpower);
}
return list;
};
export function countrylist(dev) {
let iface = ifaces[dev];
let list = {
active: iface.country,
countries,
};
return list;
};
export function scan(dev) {
const rsn_cipher = [ 'NONE', 'WEP-40', 'TKIP', 'WRAP', 'CCMP', 'WEP-104', 'AES-OCB', 'CKIP', 'GCMP', 'GCMP-256', 'CCMP-256' ];
const ht_chan_offset = [ 'no secondary', 'above', '[reserved]', 'below' ];
const vht_chan_width = [ '20 or 40 MHz', '80 MHz', '80+80 MHz', '160 MHz' ];
const ht_chan_width = [ '20 MHz', '40 MHz or higher' ];
const SCAN_FLAG_AP = (1<<2);
let params = {
dev,
scan_flags: SCAN_FLAG_AP,
scan_ssids: [ '' ],
};
let res = nl80211.request(nl80211.const.NL80211_CMD_TRIGGER_SCAN, 0, params);
if (res === false) {
printf("Unable to trigger scan: " + nl80211.error() + "\n");
exit(1);
}
res = nl80211.waitfor([
nl80211.const.NL80211_CMD_NEW_SCAN_RESULTS,
nl80211.const.NL80211_CMD_SCAN_ABORTED
], 5000);
if (!res) {
printf("Netlink error while awaiting scan results: " + nl80211.error() + "\n");
exit(1);
} else if (res.cmd == nl80211.const.NL80211_CMD_SCAN_ABORTED) {
printf("Scan aborted by kernel\n");
exit(1);
}
let scan = nl80211.request(nl80211.const.NL80211_CMD_GET_SCAN, nl80211.const.NLM_F_DUMP, { dev });
let cells = [];
for (let k, bss in scan) {
bss = bss.bss;
let cell = {
bssid: uc(bss.bssid),
frequency: format_frequency(bss.frequency),
band: format_band(bss.frequency),
channel: format_channel(bss.frequency),
dbm: bss.signal_mbm / 100,
};
if (bss.capability & (1 << 1))
cell.mode = 'Ad-Hoc';
else if (bss.capability & (1 << 0))
cell.mode = 'Master';
else
cell.mode = 'Mesh Point';
cell.quality = dbm2quality(cell.dbm);
for (let ie in bss.information_elements)
switch(ie.type) {
case 0:
case 114:
cell.ssid = ie.data;
break;
case 7:
cell.country = substr(ie.data, 0, 2);
break;
case 48:
cell.crypto = {
group: rsn_cipher[+ord(ie.data, 5)] ?? '',
pair: [],
key_mgmt: [],
};
let offset = 6;
let count = +ord(ie.data, offset);
offset += 2;
for (let i = 0; i < count; i++) {
let key = rsn_cipher[+ord(ie.data, offset + 3)];
if (key)
push(cell.crypto.pair, key);
offset += 4;
}
count = +ord(ie.data, offset);
offset += 2;
for (let i = 0; i < count; i++) {
let key = format_mgmt_key(ord(ie.data, offset + 3));
if (key)
push(cell.crypto.key_mgmt, key);
offset += 4;
}
break;
case 61:
cell.ht = {
primary_channel: ord(ie.data, 0),
secondary_chan_off: ht_chan_offset[ord(ie.data, 1) & 0x3],
chan_width: ht_chan_width[(ord(ie.data, 1) & 0x4) >> 2],
};
break;
case 192:
cell.vht = {
chan_width: vht_chan_width[ord(ie.data, 0)],
center_chan_1: ord(ie.data, 1),
center_chan_2: ord(ie.data, 2),
};
break;
};
push(cells, cell);
}
return cells;
};

View File

@@ -0,0 +1,258 @@
{
"pci": [
[ "0x0777", "0x11ac", "0x0777", "0xe7f9", 0, 0, "Ubiquiti", "LiteBeam, 5AC" ],
[ "0xffff", "0xffff", "0xffff", "0xb102", 0, 0, "Ubiquiti", "PowerStation2, (18V)" ],
[ "0xffff", "0xffff", "0xffff", "0xb202", 0, 0, "Ubiquiti", "PowerStation2, (16D)" ],
[ "0xffff", "0xffff", "0xffff", "0xb302", 0, 0, "Ubiquiti", "PowerStation2, (EXT)" ],
[ "0xffff", "0xffff", "0xffff", "0xb105", 0, 0, "Ubiquiti", "PowerStation5, (22V)" ],
[ "0xffff", "0xffff", "0xffff", "0xb305", 0, 0, "Ubiquiti", "PowerStation5, (EXT)" ],
[ "0xffff", "0xffff", "0xffff", "0xc302", 0, 0, "Ubiquiti", "PicoStation2" ],
[ "0xffff", "0xffff", "0xffff", "0xc3a2", 10, 0, "Ubiquiti", "PicoStation2, HP" ],
[ "0xffff", "0xffff", "0xffff", "0xa105", 0, 0, "Ubiquiti", "WispStation5" ],
[ "0xffff", "0xffff", "0xffff", "0xa002", 10, 0, "Ubiquiti", "LiteStation2" ],
[ "0xffff", "0xffff", "0xffff", "0xa005", 5, 0, "Ubiquiti", "LiteStation5" ],
[ "0xffff", "0xffff", "0xffff", "0xc002", 10, 0, "Ubiquiti", "NanoStation2" ],
[ "0xffff", "0xffff", "0xffff", "0xc005", 5, 0, "Ubiquiti", "NanoStation5" ],
[ "0xffff", "0xffff", "0xffff", "0xc102", 10, 0, "Ubiquiti", "NanoStation, Loco2" ],
[ "0xffff", "0xffff", "0xffff", "0xc105", 5, 0, "Ubiquiti", "NanoStation, Loco5" ],
[ "0xffff", "0xffff", "0xffff", "0xc202", 10, 0, "Ubiquiti", "Bullet2" ],
[ "0xffff", "0xffff", "0xffff", "0xc205", 5, 0, "Ubiquiti", "Bullet5" ],
[ "0x168c", "0xffff", "0x0777", "0xe002", 6, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe003", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe006", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe009", 6, 0, "Ubiquiti", "NanoStation, Loco, M9" ],
[ "0x168c", "0xffff", "0x0777", "0xe012", 10, 0, "Ubiquiti", "NanoStation, M2" ],
[ "0x168c", "0xffff", "0x0777", "0xe035", 3, 0, "Ubiquiti", "NanoStation, M3" ],
[ "0x168c", "0xffff", "0x0777", "0xe0a2", 2, 0, "Ubiquiti", "NanoStation, Loco, M2" ],
[ "0x168c", "0xffff", "0x0777", "0xe0a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe102", 6, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe105", 5, 0, "Ubiquiti", "Rocket, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe112", 10, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe115", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1a3", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1a5", 5, 0, "Ubiquiti", "PowerBridge, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe1b2", 10, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1b3", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1b5", 5, 0, "Ubiquiti", "Rocket, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe1b6", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1b9", 6, 0, "Ubiquiti", "Rocket, M9" ],
[ "0x168c", "0xffff", "0x0777", "0xe1c2", 10, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1c3", 3, 0, "Ubiquiti", "Rocket, M3" ],
[ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "Rocket, M5, GPS" ],
[ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1d2", 10, 0, "Ubiquiti", "Rocket, M2, Titanium" ],
[ "0x168c", "0xffff", "0x0777", "0xe1d3", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1d5", 5, 0, "Ubiquiti", "airOS, XM/XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe1d9", 6, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1e3", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe1e5", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ],
[ "0x168c", "0xffff", "0x0777", "0xe205", 6, 0, "Ubiquiti", "Bullet, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe212", 1, 0, "Ubiquiti", "AirGrid, M2" ],
[ "0x168c", "0xffff", "0x0777", "0xe215", 1, 0, "Ubiquiti", "AirGrid, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe232", 2, 0, "Ubiquiti", "NanoBridge, M2" ],
[ "0x168c", "0xffff", "0x0777", "0xe233", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe235", 1, 0, "Ubiquiti", "NanoBridge, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe239", 6, 0, "Ubiquiti", "NanoBridge, M9" ],
[ "0x168c", "0xffff", "0x0777", "0xe242", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ],
[ "0x168c", "0xffff", "0x0777", "0xe243", 3, 0, "Ubiquiti", "NanoBridge, M3" ],
[ "0x168c", "0xffff", "0x0777", "0xe245", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ],
[ "0x168c", "0xffff", "0x0777", "0xe252", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ],
[ "0x168c", "0xffff", "0x0777", "0xe255", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ],
[ "0x168c", "0xffff", "0x0777", "0xe2a3", 3, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe2a5", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe2b2", 10, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe2b5", 1, 0, "Ubiquiti", "NanoBridge, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe2b9", 6, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe2c2", 10, 0, "Ubiquiti", "NanoBeam, M2, Int" ],
[ "0x168c", "0xffff", "0x0777", "0xe2c3", 6, 0, "Ubiquiti", "Bullet, M2, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe2c4", 6, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe2d2", 12, 0, "Ubiquiti", "Bullet, M2, Titanium, HP" ],
[ "0x168c", "0xffff", "0x0777", "0xe2d4", 6, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe2d5", 6, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe2e5", 4, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2"],
[ "0x168c", "0xffff", "0x0777", "0xe305", 6, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe345", 6, 0, "Ubiquiti", "WispStation, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe3a5", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe3b5", 6, 0, "Ubiquiti", "airOS, XM/XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe3e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 300" ],
[ "0x168c", "0xffff", "0x0777", "0xe402", 10, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe405", 1, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe4a2", 1, 0, "Ubiquiti", "AirRouter" ],
[ "0x168c", "0xffff", "0x0777", "0xe4a5", 1, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe4b2", 9, 0, "Ubiquiti", "AirRouter, HP" ],
[ "0x168c", "0xffff", "0x0777", "0xe4d5", 5, 0, "Ubiquiti", "Rocket, M5, Titanium" ],
[ "0x168c", "0xffff", "0x0777", "0xe4e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400" ],
[ "0x168c", "0xffff", "0x0777", "0xe5e5", 4, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe6a2", 1, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe6b2", 1, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe6b5", 5, 0, "Ubiquiti", "Rocket, M5, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe6c2", 6, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe6e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400, ISO" ],
[ "0x168c", "0xffff", "0x0777", "0xe7f8", 2, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe805", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0xffff", "0x0777", "0xe812", 6, 0, "Ubiquiti", "NanoBeam, M2, 13" ],
[ "0x168c", "0xffff", "0x0777", "0xe815", 4, 0, "Ubiquiti", "NanoBeam, M5, 16" ],
[ "0x168c", "0xffff", "0x0777", "0xe825", 4, 0, "Ubiquiti", "NanoBeam, M5, 19" ],
[ "0x168c", "0xffff", "0x0777", "0xe835", 6, 0, "Ubiquiti", "AirGrid, M5, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe845", 1, 0, "Ubiquiti", "NanoStation, Loco, M5, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe855", 5, 0, "Ubiquiti", "NanoStation, M5, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe865", 6, 0, "Ubiquiti", "LiteBeam, M5" ],
[ "0x168c", "0xffff", "0x0777", "0xe866", 6, 0, "Ubiquiti", "NanoStation, M2, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe867", 2, 0, "Ubiquiti", "NanoStation, Loco, M2, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe868", 7, 0, "Ubiquiti", "Rocket, M2, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe869", 2, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe875", 4, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe879", 2, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe885", 4, 0, "Ubiquiti", "PowerBeam, M5, 620, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe895", 4, 0, "Ubiquiti", "airOS, XW" ],
[ "0x168c", "0xffff", "0x0777", "0xe8a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5"],
[ "0x168c", "0xffff", "0x0777", "0xe8b5", 5, 0, "Ubiquiti", "airOS, XM" ],
[ "0x168c", "0x001b", "0x0777", "0x3002", 10, 0, "Ubiquiti", "XR2" ],
[ "0x168c", "0x001b", "0x7777", "0x3002", 10, 0, "Ubiquiti", "XR2" ],
[ "0x168c", "0x001b", "0x0777", "0x3b02", 10, 0, "Ubiquiti", "XR2.3" ],
[ "0x168c", "0x001b", "0x0777", "0x3c02", 10, 0, "Ubiquiti", "XR2.6" ],
[ "0x168c", "0x001b", "0x0777", "0x3b03", 10, 0, "Ubiquiti", "XR3-2.8" ],
[ "0x168c", "0x001b", "0x0777", "0x3c03", 10, 0, "Ubiquiti", "XR3-3.6" ],
[ "0x168c", "0x001b", "0x0777", "0x3003", 10, 0, "Ubiquiti", "XR3" ],
[ "0x168c", "0x001b", "0x0777", "0x3004", 10, 0, "Ubiquiti", "XR4" ],
[ "0x168c", "0x001b", "0x0777", "0x3005", 10, 0, "Ubiquiti", "XR5" ],
[ "0x168c", "0x001b", "0x7777", "0x3005", 10, 0, "Ubiquiti", "XR5" ],
[ "0x168c", "0x001b", "0x0777", "0x3007", 10, 0, "Ubiquiti", "XR7" ],
[ "0x168c", "0x001b", "0x0777", "0x3009", 10, -1520, "Ubiquiti", "XR9" ],
[ "0x168c", "0x001b", "0x168c", "0x2063", 0, 0, "Atheros", "AR5413" ],
[ "0x168c", "0x0013", "0x168c", "0x1042", 1, 0, "Ubiquiti", "SRC" ],
[ "0x168c", "0x0013", "0x0777", "0x2041", 10, 0, "Ubiquiti", "SR2" ],
[ "0x168c", "0x0013", "0x0777", "0x2004", 6, 0, "Ubiquiti", "SR4" ],
[ "0x168c", "0x0013", "0x7777", "0x2004", 6, 0, "Ubiquiti", "SR4" ],
[ "0x168c", "0x0013", "0x0777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ],
[ "0x168c", "0x0013", "0x7777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ],
[ "0x168c", "0x0013", "0x168c", "0x2042", 7, 0, "Ubiquiti", "SR5" ],
[ "0x168c", "0x0013", "0x7777", "0x2009", 12, -1500, "Ubiquiti", "SR9" ],
[ "0x168c", "0x0027", "0x168c", "0x2082", 7, 0, "Ubiquiti", "SR71A" ],
[ "0x168c", "0x0027", "0x0777", "0x4082", 7, 0, "Ubiquiti", "SR71" ],
[ "0x168c", "0x0029", "0x0777", "0x4005", 7, 0, "Ubiquiti", "SR71-15" ],
[ "0x168c", "0x002a", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2" ],
[ "0x168c", "0x002a", "0x0777", "0xe012", 12, 0, "Ubiquiti", "NanoStation, M2" ],
[ "0x168c", "0x002a", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ],
[ "0x168c", "0x002a", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ],
[ "0x168c", "0x002a", "0x0777", "0xe805", 5, 0, "Ubiquiti", "Bullet, M5" ],
[ "0x168c", "0x002a", "0x0777", "0xe345", 0, 0, "Ubiquiti", "WispStation, M5" ],
[ "0x168c", "0x0029", "0x168c", "0xa094", 0, 0, "Atheros", "AR9220" ],
[ "0x168c", "0x0029", "0x168c", "0xa095", 0, 0, "Atheros", "AR9223" ],
[ "0x168c", "0x002a", "0x168c", "0xa093", 0, 0, "Atheros", "AR9280" ],
[ "0x168c", "0x002b", "0x168c", "0xa091", 0, 0, "Atheros", "AR9285" ],
[ "0x168c", "0x002d", "0x168c", "0x209a", 0, 0, "Atheros", "AR9287" ],
[ "0x168c", "0x002e", "0x1a3b", "0x1121", 0, 0, "Atheros", "AR9287" ],
[ "0x168c", "0x002e", "0x0777", "0xe0a2", 8, 0, "Ubiquiti", "NanoStation, Loco, M2, (XM)" ],
[ "0x168c", "0x002e", "0x168c", "0x30a4", 0, 0, "Atheros", "AR9287" ],
[ "0x168c", "0x002e", "0x168c", "0xa199", 0, 0, "Atheros", "AR9287" ],
[ "0x168c", "0x0030", "0x168c", "0x3112", 0, 0, "Atheros", "AR9380" ],
[ "0x168c", "0x0030", "0x168c", "0x3114", 0, 0, "Atheros", "AR9390" ],
[ "0x168c", "0x0033", "0x168c", "0xa120", 0, 0, "Atheros", "AR9580" ],
[ "0x168c", "0x0033", "0x168c", "0xa136", 0, 0, "Atheros", "AR9580" ],
[ "0x168c", "0x0033", "0x168c", "0x3123", 0, 0, "Atheros", "AR9590" ],
[ "0x168c", "0x0033", "0x19b6", "0xd014", 0, 0, "MikroTik", "R11e-5HnD" ],
[ "0x168c", "0x0033", "0x19b6", "0xd057", 0, 0, "MikroTik", "R11e-5HnDr2" ],
[ "0x168c", "0x0033", "0x19b6", "0xd016", 0, 0, "MikroTik", "R11e-2HPnD" ],
[ "0x168c", "0x0034", "0x17aa", "0x3214", 0, 0, "Atheros", "AR9462" ],
[ "0x168c", "0x003c", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9880" ],
[ "0x168c", "0x003c", "0x168c", "0x3223", 0, 0, "Qualcomm, Atheros", "QCA9880" ],
[ "0x168c", "0x003c", "0x1a56", "0x1420", 0, 0, "Qualcomm, Atheros", "QCA9862" ],
[ "0x168c", "0x003c", "0x19b6", "0xd03c", 0, 0, "Mikrotik", "R11e-5HacT" ],
[ "0x168c", "0x003c", "0x19b6", "0xd075", 0, 0, "Mikrotik", "R11e-5HacD" ],
[ "0x168c", "0x003e", "0x168c", "0x3361", 0, 0, "Qualcomm, Atheros", "QCA6174" ],
[ "0x168c", "0x0040", "0x168c", "0x0002", 0, 0, "Qualcomm, Atheros", "QCA9990" ],
[ "0x168c", "0x0046", "0x168c", "0xcafe", 0, 0, "Qualcomm, Atheros", "QCA9984" ],
[ "0x168c", "0x0050", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9887" ],
[ "0x168c", "0x0056", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9886" ],
[ "0x17cb", "0x1104", "0x17cb", "0x1104", 0, 0, "Qualcomm, Atheros", "QCN6024/9024/9074" ],
[ "0x1814", "0x3051", "0x1814", "0x0007", 0, 0, "Ralink", "Rt3051" ],
[ "0x1814", "0x3052", "0x1814", "0x0008", 0, 0, "Ralink", "Rt3052" ],
[ "0x1814", "0x3350", "0x1814", "0x000b", 0, 0, "Ralink", "Rt3350" ],
[ "0x1814", "0x3662", "0x1814", "0x000d", 0, 0, "Ralink", "Rt3662" ],
[ "0x11ab", "0x2a55", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8864" ],
[ "0x02df", "0x9135", "0x0000", "0x0000", 0, 0, "Marvell", "88W8887" ],
[ "0x11ab", "0x2b40", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8964" ],
[ "0x02df", "0x9141", "0x0000", "0x0000", 0, 0, "Marvell", "88W8997" ],
[ "0x14c3", "0x0608", "0x14c3", "0x0608", 0, 0, "AMD", "RZ608" ],
[ "0x14c3", "0x7603", "0x14c3", "0x7603", 0, 0, "MediaTek", "MT7603E" ],
[ "0x14c3", "0x7610", "0x14c3", "0x7610", 0, 0, "MediaTek", "MT7610E" ],
[ "0x14c3", "0x7612", "0x14c3", "0x7612", 0, 0, "MediaTek", "MT7612E" ],
[ "0x14c3", "0x7663", "0x14c3", "0x7663", 0, 0, "MediaTek", "MT7613BE" ],
[ "0x14c3", "0x7615", "0x7615", "0x14c3", 0, 0, "MediaTek", "MT7615E" ],
[ "0x14c3", "0x7628", "0x14c3", "0x0004", 0, 0, "MediaTek", "MT76x8" ],
[ "0x14c3", "0x7650", "0x14c3", "0x7650", 0, 0, "MediaTek", "MT7610E" ],
[ "0x14c3", "0x7662", "0x14c3", "0x7662", 0, 0, "MediaTek", "MT76x2E" ],
[ "0x14c3", "0x7915", "0x14c3", "0x7915", 0, 0, "MediaTek", "MT7915E" ],
[ "0x14c3", "0x7906", "0x14c3", "0x7906", 0, 0, "MediaTek", "MT7916AN" ],
[ "0x14c3", "0x7990", "0x14C3", "0x6639", 0, 0, "MediaTek", "MT7996E" ],
[ "0x14e4", "0xaa52", "0x14e4", "0xaa52", 0, 0, "Broadcom", "BCM43602" ],
[ "0x02d0", "0xa9a6", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ],
[ "0x02d0", "0x4345", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ],
[ "0x1ae9", "0x0310", "0x1ae9", "0x0000", 0, 0, "Wilocity", "Wil6210" ],
[ "0x0000", "0x0000", "0x148f", "0x7601", 0, 0, "MediaTek", "MT7601U" ],
[ "0x0000", "0x0000", "0x0e8d", "0x7961", 0, 0, "MediaTek", "MT7921AU" ],
[ "0x0000", "0x0000", "0x0b05", "0x1833", 0, 0, "ASUS", "USB-AC54" ],
[ "0x0000", "0x0000", "0x0b05", "0x17eb", 0, 0, "ASUS", "USB-AC55" ],
[ "0x0000", "0x0000", "0x0b05", "0x180b", 0, 0, "ASUS", "USB-N53, B1" ],
[ "0x0000", "0x0000", "0x0e8d", "0x7612", 0, 0, "Aukey", "USBAC1200" ],
[ "0x0000", "0x0000", "0x057c", "0x8503", 0, 0, "AVM", "FRITZ!WLAN, AC860" ],
[ "0x0000", "0x0000", "0x7392", "0xb711", 0, 0, "Edimax", "EW-7722UAC" ],
[ "0x0000", "0x0000", "0x0e8d", "0x7632", 0, 0, "High, Cloud", "HC-M7662BU1" ],
[ "0x0000", "0x0000", "0x2c4e", "0x0103", 0, 0, "Mercury", "UD13" ],
[ "0x0000", "0x0000", "0x0846", "0x9053", 0, 0, "Netgear", "A6210" ],
[ "0x0000", "0x0000", "0x045e", "0x02e6", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ],
[ "0x0000", "0x0000", "0x045e", "0x02fe", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ],
[ "0x0000", "0x0000", "0x148f", "0x7610", 0, 0, "MediaTek", "MT7610U" ],
[ "0x0000", "0x0000", "0x13b1", "0x003e", 0, 0, "Linksys", "AE6000" ],
[ "0x0000", "0x0000", "0x0e8d", "0x7610", 0, 0, "Sabrent", "NTWLAC" ],
[ "0x0000", "0x0000", "0x7392", "0xa711", 0, 0, "Edimax", "7711MAC" ],
[ "0x0000", "0x0000", "0x148f", "0x761a", 0, 0, "TP-Link", "TL-WDN5200" ],
[ "0x0000", "0x0000", "0x0b05", "0x17d1", 0, 0, "ASUS", "USB-AC51" ],
[ "0x0000", "0x0000", "0x0b05", "0x17db", 0, 0, "ASUS", "USB-AC50" ],
[ "0x0000", "0x0000", "0x0df6", "0x0075", 0, 0, "Sitecom", "WLA-3100" ],
[ "0x0000", "0x0000", "0x2019", "0xab31", 0, 0, "Planex", "GW-450D" ],
[ "0x0000", "0x0000", "0x2001", "0x3d02", 0, 0, "D-Link", "DWA-171, rev, B1" ],
[ "0x0000", "0x0000", "0x0586", "0x3425", 0, 0, "Zyxel", "NWD6505" ],
[ "0x0000", "0x0000", "0x07b8", "0x7610", 0, 0, "AboCom", "AU7212" ],
[ "0x0000", "0x0000", "0x04bb", "0x0951", 0, 0, "I-O, DATA", "WN-AC433UK" ],
[ "0x0000", "0x0000", "0x057c", "0x8502", 0, 0, "AVM", "FRITZ!WLAN, AC430" ],
[ "0x0000", "0x0000", "0x293c", "0x5702", 0, 0, "Comcast", "Xfinity, KXW02AAA" ],
[ "0x0000", "0x0000", "0x20f4", "0x806b", 0, 0, "TRENDnet", "TEW-806UBH" ],
[ "0x0000", "0x0000", "0x7392", "0xc711", 0, 0, "Devolo", "WiFi, Stick, ac" ],
[ "0x0000", "0x0000", "0x0df6", "0x0079", 0, 0, "Sitecom", "WL-356" ],
[ "0x0000", "0x0000", "0x2357", "0x0123", 0, 0, "TP-Link", "T2UHP, US, v1" ],
[ "0x0000", "0x0000", "0x2357", "0x010b", 0, 0, "TP-Link", "T2UHP, UN, v1" ],
[ "0x0000", "0x0000", "0x2357", "0x0105", 0, 0, "TP-Link", "Archer, T1U" ],
[ "0x0000", "0x0000", "0x0e8d", "0x7630", 0, 0, "MediaTek", "MT7630U" ],
[ "0x0000", "0x0000", "0x0e8d", "0x7650", 0, 0, "MediaTek", "MT7650U" ],
[ "0x0000", "0x0000", "0x0e8d", "0x7663", 0, 0, "MediaTek", "MT7663U" ],
[ "0x0000", "0x0000", "0x043e", "0x310c", 0, 0, "LG", "LGSBWAC02" ],
[ "0x0000", "0x0000", "0x0bda", "0x8176", 0, 0, "Realtek", "RTL8188CU" ],
[ "0x0000", "0x0000", "0x0bda", "0xf179", 0, 0, "Realtek", "RTL8188FTV" ]
],
"compatible": {
"qca,ar9130-wmac": [ "Atheros", "AR9130" ],
"qca,ar9330-wmac": [ "Atheros", "AR9330" ],
"qca,ar9340-wmac": [ "Atheros", "AR9340" ],
"qca,qca9530-wmac": [ "Qualcomm Atheros", "QCA9530" ],
"qca,qca9550-wmac": [ "Qualcomm Atheros", "QCA9550" ],
"qca,qca9560-wmac": [ "Qualcomm Atheros", "QCA9560" ],
"qcom,ipq4019-wifi": [ "Qualcomm Atheros", "IPQ4019" ],
"qcom,ipq6018-wifi": [ "Qualcomm Atheros", "IPQ6018" ],
"qcom,ipq8074-wifi": [ "Qualcomm Atheros", "IPQ8074" ],
"mediatek,mt7622-wmac": [ "MediaTek", "MT7622" ],
"mediatek,mt7628-wmac": [ "MediaTek", "MT7628" ],
"mediatek,mt7981-wmac": [ "MediaTek", "MT7981" ],
"mediatek,mt7986-wmac": [ "MediaTek", "MT7986" ],
"ralink,rt2880-wmac": [ "Ralink", "Rt2880" ],
"ralink,rt3050-wmac": [ "Ralink", "Rt3050" ],
"ralink,rt3352-wmac": [ "Ralink", "Rt3352" ],
"ralink,rt3883-wmac": [ "Ralink", "Rt3883" ],
"ralink,rt5350-wmac": [ "Ralink", "Rt5350" ],
"ralink,rt7620-wmac": [ "MediaTek", "MT7620" ]
}
}

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env ucode
'use strict';
let fs = require("fs");
let ubus = require('ubus').connect();
let gps_info = ubus.call('gps', 'info');
let latitude = gps_info.latitude ?? 0;
let longitude = gps_info.longitude ?? 0;
// afc-location.json file content
let afc_location = {};
afc_location.location_type = "ellipse";
afc_location.location = longitude + ":" + latitude ;
afc_location.height = gps_info.elevation ?? 0;
afc_location.height_type = "AMSL";
afc_location.major_axis = gps_info.major_axis ?? 0;
afc_location.minor_axis = gps_info.minor_axis ?? 0;
afc_location.orientation = gps_info.major_orientation ?? 0;
afc_location.vertical_tolerance = gps_info.vdop ?? 0;
let afc_location_json = fs.open("/etc/ucentral/afc-location.json", "w");
afc_location_json.write(afc_location);
afc_location_json.close();

View File

@@ -1,132 +0,0 @@
#!/usr/bin/env ucode
'use strict';
import { basename } from "fs";
let uclient = require("uclient");
let uloop = require("uloop");
let libubus = require("ubus");
let opts = {};
let reqs = [];
const usage_message = `Usage: ${basename(sourcepath())} <options>
Options:
-u <url>: AFC server URL (required)
-c <path>: AFC server CA certificate
`;
function usage() {
warn(usage_message);
exit(1);
}
while (substr(ARGV[0], 0, 1) == "-") {
let opt = substr(shift(ARGV), 1);
switch (opt) {
case 'u':
opts.url = shift(ARGV);
break;
case 'c':
opts.cert = shift(ARGV);
if (!opts.cert)
usage();
break;
default:
usage();
}
}
if (!opts.url)
usage();
function request_done(cb, error)
{
if (!cb.req)
return;
if (error)
delete cb.data;
cb.req.reply({ data: cb.data }, error);
delete cb.req;
delete cb.client;
}
const cb_proto = {
data_read: function(cb) {
let cur;
while (length(cur = this.read()) > 0)
cb.data += cur;
},
data_eof: function(cb) {
request_done(cb, 0);
},
error: function(cb, code) {
request_done(cb, libubus.STATUS_UNKNOWN_ERROR);
},
};
function handle_request(req)
{
let cb = proto({ data: "" }, cb_proto);
let cl = uclient.new(opts.url, null, cb);
if (!cl.ssl_init({ verify: !!opts.cert, ca_files: [ opts.cert ] })) {
warn(`Failed to initialize SSL\n`);
return false;
}
if (!cl.connect()) {
warn(`Failed to connect\n`);
return false;
}
let meta = {
headers: {
"Content-Type": "application/json",
},
post_data: req.args.data
};
if (!cl.request("POST", meta)) {
warn(`Failed to send request\n`);
return false;
}
cb.client = cl;
cb.req = req;
return true;
}
function add_ubus(ubus) {
return ubus.publish("afc", {
request: {
call: function(req) {
if (!req.args.data)
return libubus.STATUS_INVALID_ARGUMENT;
let ret = handle_request(req);
if (!ret)
return libubus.STATUS_UNKNOWN_ERROR;
req.defer();
},
args: {
data: "",
},
},
});
}
uloop.init();
let ubus = libubus.connect();
if (!add_ubus(ubus)) {
warn("Failed to publish ubus object\n");
exit(1);
}
uloop.run();
uloop.done();

View File

@@ -1,318 +0,0 @@
import * as nl80211 from "nl80211";
import * as rtnl from "rtnl";
import { readfile, glob, basename, readlink } from "fs";
const iftypes = {
ap: nl80211.const.NL80211_IFTYPE_AP,
mesh: nl80211.const.NL80211_IFTYPE_MESH_POINT,
sta: nl80211.const.NL80211_IFTYPE_STATION,
adhoc: nl80211.const.NL80211_IFTYPE_ADHOC,
monitor: nl80211.const.NL80211_IFTYPE_MONITOR,
};
function wdev_remove(name)
{
nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name });
}
function __phy_is_fullmac(phyidx)
{
let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx });
return !data.software_iftypes.ap_vlan;
}
function phy_is_fullmac(phy)
{
let phyidx = int(trim(readfile(`/sys/class/ieee80211/${phy}/index`)));
return __phy_is_fullmac(phyidx);
}
function find_reusable_wdev(phyidx)
{
if (!__phy_is_fullmac(phyidx))
return null;
let data = nl80211.request(
nl80211.const.NL80211_CMD_GET_INTERFACE,
nl80211.const.NLM_F_DUMP,
{ wiphy: phyidx });
for (let res in data)
if (trim(readfile(`/sys/class/net/${res.ifname}/operstate`)) == "down")
return res.ifname;
return null;
}
function wdev_create(phy, name, data)
{
let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`));
wdev_remove(name);
if (!iftypes[data.mode])
return `Invalid mode: ${data.mode}`;
let req = {
wiphy: phyidx,
ifname: name,
iftype: iftypes[data.mode],
};
if (data["4addr"])
req["4addr"] = data["4addr"];
if (data.macaddr)
req.mac = data.macaddr;
nl80211.error();
let reuse_ifname = find_reusable_wdev(phyidx);
if (reuse_ifname &&
(reuse_ifname == name ||
rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false))
nl80211.request(
nl80211.const.NL80211_CMD_SET_INTERFACE, 0, {
wiphy: phyidx,
dev: name,
iftype: iftypes[data.mode],
});
else
nl80211.request(
nl80211.const.NL80211_CMD_NEW_INTERFACE,
nl80211.const.NLM_F_CREATE,
req);
let error = nl80211.error();
if (error)
return error;
if (data.powersave != null) {
nl80211.request(nl80211.const.NL80211_CMD_SET_POWER_SAVE, 0,
{ dev: name, ps_state: data.powersave ? 1 : 0});
}
return null;
}
function phy_sysfs_file(phy, name)
{
return trim(readfile(`/sys/class/ieee80211/${phy}/${name}`));
}
function macaddr_split(str)
{
return map(split(str, ":"), (val) => hex(val));
}
function macaddr_join(addr)
{
return join(":", map(addr, (val) => sprintf("%02x", val)));
}
function wdev_macaddr(wdev)
{
return trim(readfile(`/sys/class/net/${wdev}/address`));
}
const phy_proto = {
macaddr_init: function(used, options) {
this.macaddr_options = options ?? {};
this.macaddr_list = {};
if (type(used) == "object")
for (let addr in used)
this.macaddr_list[addr] = used[addr];
else
for (let addr in used)
this.macaddr_list[addr] = -1;
this.for_each_wdev((wdev) => {
let macaddr = wdev_macaddr(wdev);
this.macaddr_list[macaddr] ??= -1;
});
return this.macaddr_list;
},
macaddr_generate: function(data) {
let phy = this.name;
let idx = int(data.id ?? 0);
let mbssid = int(data.mbssid ?? 0) > 0;
let num_global = int(data.num_global ?? 1);
let use_global = !mbssid && idx < num_global;
let base_addr = phy_sysfs_file(phy, "macaddress");
if (!base_addr)
return null;
if (!idx && !mbssid)
return base_addr;
let base_mask = phy_sysfs_file(phy, "address_mask");
if (!base_mask)
return null;
if (base_mask == "00:00:00:00:00:00" && idx >= num_global) {
let addrs = split(phy_sysfs_file(phy, "addresses"), "\n");
if (idx < length(addrs))
return addrs[idx];
base_mask = "ff:ff:ff:ff:ff:ff";
}
let addr = macaddr_split(base_addr);
let mask = macaddr_split(base_mask);
let type;
if (mbssid)
type = "b5";
else if (use_global)
type = "add";
else if (mask[0] > 0)
type = "b1";
else if (mask[5] < 0xff)
type = "b5";
else
type = "add";
switch (type) {
case "b1":
if (!(addr[0] & 2))
idx--;
addr[0] |= 2;
addr[0] ^= idx << 2;
break;
case "b5":
if (mbssid)
addr[0] |= 2;
addr[5] ^= idx;
break;
default:
for (let i = 5; i > 0; i--) {
addr[i] += idx;
if (addr[i] < 256)
break;
addr[i] %= 256;
}
break;
}
return macaddr_join(addr);
},
macaddr_next: function(val) {
let data = this.macaddr_options ?? {};
let list = this.macaddr_list;
for (let i = 0; i < 32; i++) {
data.id = i;
let mac = this.macaddr_generate(data);
if (!mac)
return null;
if (list[mac] != null)
continue;
list[mac] = val != null ? val : -1;
return mac;
}
},
for_each_wdev: function(cb) {
let wdevs = glob(`/sys/class/ieee80211/${this.name}/device/net/*`);
wdevs = map(wdevs, (arg) => basename(arg));
for (let wdev in wdevs) {
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != this.name)
continue;
cb(wdev);
}
}
};
function phy_open(phy)
{
let phyidx = readfile(`/sys/class/ieee80211/${phy}/index`);
if (!phyidx)
return null;
return proto({
name: phy,
idx: int(phyidx)
}, phy_proto);
}
const vlist_proto = {
update: function(values, arg) {
let data = this.data;
let cb = this.cb;
let seq = { };
let new_data = {};
let old_data = {};
this.data = new_data;
if (type(values) == "object") {
for (let key in values) {
old_data[key] = data[key];
new_data[key] = values[key];
delete data[key];
}
} else {
for (let val in values) {
let cur_key = val[0];
let cur_obj = val[1];
old_data[cur_key] = data[cur_key];
new_data[cur_key] = val[1];
delete data[cur_key];
}
}
for (let key in data) {
cb(null, data[key], arg);
delete data[key];
}
for (let key in new_data)
cb(new_data[key], old_data[key], arg);
}
};
function is_equal(val1, val2) {
let t1 = type(val1);
if (t1 != type(val2))
return false;
if (t1 == "array") {
if (length(val1) != length(val2))
return false;
for (let i = 0; i < length(val1); i++)
if (!is_equal(val1[i], val2[i]))
return false;
return true;
} else if (t1 == "object") {
for (let key in val1)
if (!is_equal(val1[key], val2[key]))
return false;
for (let key in val2)
if (val1[key] == null)
return false;
return true;
} else {
return val1 == val2;
}
}
function vlist_new(cb) {
return proto({
cb: cb,
data: {}
}, vlist_proto);
}
export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac, phy_open };

View File

@@ -1,2 +0,0 @@
#!/bin/sh
[ "$1" = bound ] && echo "$serverid"

View File

@@ -1,404 +0,0 @@
# Example hostapd build time configuration
#
# This file lists the configuration options that are used when building the
# hostapd binary. All lines starting with # are ignored. Configuration option
# lines must be commented out complete, if they are not to be included, i.e.,
# just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cass, these lines should use += in order not
# to override previous values of the variables.
# Driver interface for Host AP driver
#CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
CONFIG_DRIVER_WIRED=y
# Driver interface for drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
#LIBS += -L$<path to libnl library files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
#LIBS_p += -L/usr/local/lib
#LIBS_c += -L/usr/local/lib
# Driver interface for no driver (e.g., RADIUS server only)
#CONFIG_DRIVER_NONE=y
# IEEE 802.11F/IAPP
#CONFIG_IAPP=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
# IEEE 802.11w (management frame protection)
#CONFIG_IEEE80211W=y
# Support Operating Channel Validation
CONFIG_OCV=y
# Integrated EAP server
#CONFIG_EAP=y
# EAP Re-authentication Protocol (ERP) in integrated EAP server
#CONFIG_ERP=y
# EAP-MD5 for the integrated EAP server
#CONFIG_EAP_MD5=y
# EAP-TLS for the integrated EAP server
#CONFIG_EAP_TLS=y
# EAP-MSCHAPv2 for the integrated EAP server
#CONFIG_EAP_MSCHAPV2=y
# EAP-PEAP for the integrated EAP server
#CONFIG_EAP_PEAP=y
# EAP-GTC for the integrated EAP server
#CONFIG_EAP_GTC=y
# EAP-TTLS for the integrated EAP server
#CONFIG_EAP_TTLS=y
# EAP-SIM for the integrated EAP server
#CONFIG_EAP_SIM=y
# EAP-AKA for the integrated EAP server
#CONFIG_EAP_AKA=y
# EAP-AKA' for the integrated EAP server
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# EAP-PAX for the integrated EAP server
#CONFIG_EAP_PAX=y
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd for the integrated EAP server (secure authentication with a password)
#CONFIG_EAP_PWD=y
# EAP-SAKE for the integrated EAP server
#CONFIG_EAP_SAKE=y
# EAP-GPSK for the integrated EAP server
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-FAST for the integrated EAP server
#CONFIG_EAP_FAST=y
# EAP-TEAP for the integrated EAP server
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# Wi-Fi Protected Setup (WPS)
#CONFIG_WPS=y
# Enable UPnP support for external WPS Registrars
#CONFIG_WPS_UPNP=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# Trusted Network Connect (EAP-TNC)
#CONFIG_EAP_TNC=y
# EAP-EKE for the integrated EAP server
#CONFIG_EAP_EKE=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
#CONFIG_PKCS12=y
# RADIUS authentication server. This provides access to the integrated EAP
# server from external hosts using RADIUS.
#CONFIG_RADIUS_SERVER=y
# Build IPv6 support for RADIUS operations
#CONFIG_IPV6=y
# IEEE Std 802.11r-2008 (Fast BSS Transition)
CONFIG_IEEE80211R=y
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211)
#CONFIG_DRIVER_RADIUS_ACL=y
# IEEE 802.11n (High Throughput) support
CONFIG_IEEE80211N=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
#CONFIG_WNM=y
# IEEE 802.11ac (Very High Throughput) support
CONFIG_IEEE80211AC=y
# IEEE 802.11ax HE support
# Note: This is experimental and work in progress. The definitions are still
# subject to change and this should not be expected to interoperate with the
# final IEEE 802.11ax version.
#CONFIG_IEEE80211AX=y
# Remove debugging code that is printing out debug messages to stdout.
# This can be used to reduce the size of the hostapd considerably if debugging
# code is not needed.
#CONFIG_NO_STDOUT_DEBUG=y
# Add support for writing debug log to a file: -f /tmp/hostapd.log
# Disabled by default.
#CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Remove support for RADIUS accounting
CONFIG_NO_ACCOUNTING=y
# Remove support for RADIUS
CONFIG_NO_RADIUS=y
# Remove support for VLANs
#CONFIG_NO_VLAN=y
# Enable support for fully dynamic VLANs. This enables hostapd to
# automatically create bridge and VLAN interfaces if necessary.
#CONFIG_FULL_DYNAMIC_VLAN=y
# Use netlink-based kernel API for VLAN operations instead of ioctl()
# Note: This requires libnl 3.1 or newer.
#CONFIG_VLAN_NETLINK=y
# Remove support for dumping internal state through control interface commands
# This can be used to reduce binary size at the cost of disabling a debugging
# option.
CONFIG_NO_DUMP_STATE=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# For BSD, comment out these.
#LIBS += -lexecinfo
#LIBS_p += -lexecinfo
#LIBS_c += -lexecinfo
# Use libbfd to get more details for developer debugging
# This enables use of libbfd to get more detailed symbols for the backtraces
# generated by CONFIG_WPA_TRACE=y.
#CONFIG_WPA_TRACE_BFD=y
# For BSD, comment out these.
#LIBS += -lbfd -liberty -lz
#LIBS_p += -lbfd -liberty -lz
#LIBS_c += -lbfd -liberty -lz
# hostapd depends on strong random number generation being available from the
# operating system. os_get_random() function is used to fetch random data when
# needed, e.g., for key generation. On Linux and BSD systems, this works by
# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
# properly initialized before hostapd is started. This is important especially
# on embedded devices that do not have a hardware random number generator and
# may by default start up with minimal entropy available for random number
# generation.
#
# As a safety net, hostapd is by default trying to internally collect
# additional entropy for generating random data to mix in with the data
# fetched from the OS. This by itself is not considered to be very strong, but
# it may help in cases where the system pool is not initialized properly.
# However, it is very strongly recommended that the system pool is initialized
# with enough entropy either by using hardware assisted random number
# generator or by storing state over device reboots.
#
# hostapd can be configured to maintain its own entropy store over restarts to
# enhance random number generation. This is not perfect, but it is much more
# secure than using the same sequence of random numbers after every reboot.
# This can be enabled with -e<entropy file> command line option. The specified
# file needs to be readable and writable by hostapd.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal hostapd random pool can be disabled.
# This will save some in binary size and CPU use. However, this should only be
# considered for builds that are known to be used on devices that meet the
# requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used.
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms.
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
#CONFIG_INTERNAL_LIBTOMMATH=y
#ifndef CONFIG_INTERNAL_LIBTOMMATH
#LTM_PATH=/usr/src/libtommath-0.39
#CFLAGS += -I$(LTM_PATH)
#LIBS += -L$(LTM_PATH)
#LIBS_p += -L$(LTM_PATH)
#endif
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks.
#CONFIG_INTERWORKING=y
# Hotspot 2.0
#CONFIG_HS20=y
# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file
#CONFIG_SQLITE=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# Testing options
# This can be used to enable some testing options (see also the example
# configuration file) that are really useful only for testing clients that
# connect to this hostapd. These options allow, for example, to drop a
# certain percentage of probe requests or auth/(re)assoc frames.
#
#CONFIG_TESTING_OPTIONS=y
# Automatic Channel Selection
# This will allow hostapd to pick the channel automatically when channel is set
# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# You can customize the ACS survey algorithm with the hostapd.conf variable
# acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#
#CONFIG_ACS=y
# Multiband Operation support
# These extentions facilitate efficient use of multiple frequency bands
# available to the AP and the devices that may associate with it.
#CONFIG_MBO=y
# Client Taxonomy
# Has the AP retain the Probe Request and (Re)Association Request frames from
# a client, from which a signature can be produced which can identify the model
# of client device like "Nexus 6P" or "iPhone 5s".
#CONFIG_TAXONOMY=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Include internal line edit mode in hostapd_cli. This can be used to provide
# limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Airtime policy support
CONFIG_AIRTIME_POLICY=y
# Proxy ARP support
#CONFIG_PROXYARP=y
# Override default value for the wpa_disable_eapol_key_retries configuration
# parameter. See that parameter in hostapd.conf for more details.
#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
#CONFIG_CTRL_IFACE_MIB=y

View File

@@ -1,404 +0,0 @@
# Example hostapd build time configuration
#
# This file lists the configuration options that are used when building the
# hostapd binary. All lines starting with # are ignored. Configuration option
# lines must be commented out complete, if they are not to be included, i.e.,
# just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cass, these lines should use += in order not
# to override previous values of the variables.
# Driver interface for Host AP driver
#CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
CONFIG_DRIVER_WIRED=y
# Driver interface for Prism54 driver
#CONFIG_DRIVER_PRISM54=y
# Driver interface for drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for no driver (e.g., RADIUS server only)
#CONFIG_DRIVER_NONE=y
# IEEE 802.11F/IAPP
CONFIG_IAPP=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
CONFIG_PEERKEY=y
# IEEE 802.11w (management frame protection)
CONFIG_IEEE80211W=y
# Support Operating Channel Validation
#CONFIG_OCV=y
# Integrated EAP server
CONFIG_EAP=y
# EAP Re-authentication Protocol (ERP) in integrated EAP server
CONFIG_ERP=y
# EAP-MD5 for the integrated EAP server
CONFIG_EAP_MD5=y
# EAP-TLS for the integrated EAP server
CONFIG_EAP_TLS=y
# EAP-MSCHAPv2 for the integrated EAP server
CONFIG_EAP_MSCHAPV2=y
# EAP-PEAP for the integrated EAP server
CONFIG_EAP_PEAP=y
# EAP-GTC for the integrated EAP server
CONFIG_EAP_GTC=y
# EAP-TTLS for the integrated EAP server
CONFIG_EAP_TTLS=y
# EAP-SIM for the integrated EAP server
#CONFIG_EAP_SIM=y
# EAP-AKA for the integrated EAP server
#CONFIG_EAP_AKA=y
# EAP-AKA' for the integrated EAP server
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# EAP-PAX for the integrated EAP server
#CONFIG_EAP_PAX=y
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd for the integrated EAP server (secure authentication with a password)
#CONFIG_EAP_PWD=y
# EAP-SAKE for the integrated EAP server
#CONFIG_EAP_SAKE=y
# EAP-GPSK for the integrated EAP server
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-FAST for the integrated EAP server
CONFIG_EAP_FAST=y
# EAP-TEAP for the integrated EAP server
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# Wi-Fi Protected Setup (WPS)
CONFIG_WPS=y
CONFIG_WPS2=y
# Enable UPnP support for external WPS Registrars
#CONFIG_WPS_UPNP=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# Trusted Network Connect (EAP-TNC)
#CONFIG_EAP_TNC=y
# EAP-EKE for the integrated EAP server
#CONFIG_EAP_EKE=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
# RADIUS authentication server. This provides access to the integrated EAP
# server from external hosts using RADIUS.
CONFIG_RADIUS_SERVER=y
# Build IPv6 support for RADIUS operations
CONFIG_IPV6=y
# IEEE Std 802.11r-2008 (Fast BSS Transition)
CONFIG_IEEE80211R=y
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211)
#CONFIG_DRIVER_RADIUS_ACL=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
CONFIG_WNM=y
# IEEE 802.11n (High Throughput) support
CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support
CONFIG_IEEE80211AC=y
# IEEE 802.11ax HE support
# Note: This is experimental and work in progress. The definitions are still
# subject to change and this should not be expected to interoperate with the
# final IEEE 802.11ax version.
CONFIG_IEEE80211AX=y
# IEEE 802.11be (EHT Throughput) support
CONFIG_IEEE80211BE=y
# Remove debugging code that is printing out debug messages to stdout.
# This can be used to reduce the size of the hostapd considerably if debugging
# code is not needed.
#CONFIG_NO_STDOUT_DEBUG=y
# Add support for writing debug log to a file: -f /tmp/hostapd.log
# Disabled by default.
CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Remove support for RADIUS accounting
#CONFIG_NO_ACCOUNTING=y
# Remove support for RADIUS
#CONFIG_NO_RADIUS=y
# Remove support for VLANs
#CONFIG_NO_VLAN=y
# Enable support for fully dynamic VLANs. This enables hostapd to
# automatically create bridge and VLAN interfaces if necessary.
CONFIG_FULL_DYNAMIC_VLAN=y
# Use netlink-based kernel API for VLAN operations instead of ioctl()
# Note: This requires libnl 3.1 or newer.
#CONFIG_VLAN_NETLINK=y
# Remove support for dumping internal state through control interface commands
# This can be used to reduce binary size at the cost of disabling a debugging
# option.
CONFIG_NO_DUMP_STATE=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# hostapd depends on strong random number generation being available from the
# operating system. os_get_random() function is used to fetch random data when
# needed, e.g., for key generation. On Linux and BSD systems, this works by
# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
# properly initialized before hostapd is started. This is important especially
# on embedded devices that do not have a hardware random number generator and
# may by default start up with minimal entropy available for random number
# generation.
#
# As a safety net, hostapd is by default trying to internally collect
# additional entropy for generating random data to mix in with the data
# fetched from the OS. This by itself is not considered to be very strong, but
# it may help in cases where the system pool is not initialized properly.
# However, it is very strongly recommended that the system pool is initialized
# with enough entropy either by using hardware assisted random number
# generator or by storing state over device reboots.
#
# hostapd can be configured to maintain its own entropy store over restarts to
# enhance random number generation. This is not perfect, but it is much more
# secure than using the same sequence of random numbers after every reboot.
# This can be enabled with -e<entropy file> command line option. The specified
# file needs to be readable and writable by hostapd.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal hostapd random pool can be disabled.
# This will save some in binary size and CPU use. However, this should only be
# considered for builds that are known to be used on devices that meet the
# requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used.
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms.
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
CONFIG_INTERNAL_LIBTOMMATH=y
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks.
CONFIG_INTERWORKING=y
# Hotspot 2.0
CONFIG_HS20=y
# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file
#CONFIG_SQLITE=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# Testing options
# This can be used to enable some testing options (see also the example
# configuration file) that are really useful only for testing clients that
# connect to this hostapd. These options allow, for example, to drop a
# certain percentage of probe requests or auth/(re)assoc frames.
#
#CONFIG_TESTING_OPTIONS=y
# Automatic Channel Selection
# This will allow hostapd to pick the channel automatically when channel is set
# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# You can customize the ACS survey algorithm with the hostapd.conf variable
# acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#
CONFIG_ACS=y
# Multiband Operation support
# These extentions facilitate efficient use of multiple frequency bands
# available to the AP and the devices that may associate with it.
CONFIG_MBO=y
# Client Taxonomy
# Has the AP retain the Probe Request and (Re)Association Request frames from
# a client, from which a signature can be produced which can identify the model
# of client device like "Nexus 6P" or "iPhone 5s".
CONFIG_TAXONOMY=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Include internal line edit mode in hostapd_cli. This can be used to provide
# limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Airtime policy support
CONFIG_AIRTIME_POLICY=y
# Proxy ARP support
CONFIG_PROXYARP=y
# Override default value for the wpa_disable_eapol_key_retries configuration
# parameter. See that parameter in hostapd.conf for more details.
#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
CONFIG_CTRL_IFACE_MIB=y
# CONFIG_INTERNAL_AES=y
# NEED_AES_DEC=y
CONFIG_P2P_MANAGER=y
CONFIG_LIBNL32=y
CONFIG_LIBNL3_ROUTE=y
CONFIG_RX_PROBE_REQ_EVENT=y
CONFIG_SAE=y
CONFIG_OWE=y
CONFIG_SUITEB192=y
CONFIG_SUITEB=y
NEED_DH_GROUPS_ALL=y
CONFIG_FILS=y
CONFIG_DPP=y
CONFIG_DPP2=y
CONFIG_DPP3=y

View File

@@ -1,407 +0,0 @@
# Example hostapd build time configuration
#
# This file lists the configuration options that are used when building the
# hostapd binary. All lines starting with # are ignored. Configuration option
# lines must be commented out complete, if they are not to be included, i.e.,
# just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cass, these lines should use += in order not
# to override previous values of the variables.
# Driver interface for Host AP driver
#CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
CONFIG_DRIVER_WIRED=y
# Driver interface for drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
#LIBS += -L$<path to libnl library files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
#LIBS_p += -L/usr/local/lib
#LIBS_c += -L/usr/local/lib
# Driver interface for no driver (e.g., RADIUS server only)
#CONFIG_DRIVER_NONE=y
# IEEE 802.11F/IAPP
CONFIG_IAPP=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
# IEEE 802.11w (management frame protection)
#CONFIG_IEEE80211W=y
# Support Operating Channel Validation
CONFIG_OCV=y
# Integrated EAP server
CONFIG_EAP=y
# EAP Re-authentication Protocol (ERP) in integrated EAP server
CONFIG_ERP=y
# EAP-MD5 for the integrated EAP server
CONFIG_EAP_MD5=y
# EAP-TLS for the integrated EAP server
CONFIG_EAP_TLS=y
# EAP-MSCHAPv2 for the integrated EAP server
CONFIG_EAP_MSCHAPV2=y
# EAP-PEAP for the integrated EAP server
CONFIG_EAP_PEAP=y
# EAP-GTC for the integrated EAP server
CONFIG_EAP_GTC=y
# EAP-TTLS for the integrated EAP server
CONFIG_EAP_TTLS=y
# EAP-SIM for the integrated EAP server
#CONFIG_EAP_SIM=y
# EAP-AKA for the integrated EAP server
#CONFIG_EAP_AKA=y
# EAP-AKA' for the integrated EAP server
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# EAP-PAX for the integrated EAP server
#CONFIG_EAP_PAX=y
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd for the integrated EAP server (secure authentication with a password)
#CONFIG_EAP_PWD=y
# EAP-SAKE for the integrated EAP server
#CONFIG_EAP_SAKE=y
# EAP-GPSK for the integrated EAP server
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-FAST for the integrated EAP server
CONFIG_EAP_FAST=y
# EAP-TEAP for the integrated EAP server
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# Wi-Fi Protected Setup (WPS)
CONFIG_WPS=y
# Enable UPnP support for external WPS Registrars
#CONFIG_WPS_UPNP=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# Trusted Network Connect (EAP-TNC)
#CONFIG_EAP_TNC=y
# EAP-EKE for the integrated EAP server
#CONFIG_EAP_EKE=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
# RADIUS authentication server. This provides access to the integrated EAP
# server from external hosts using RADIUS.
CONFIG_RADIUS_SERVER=y
# Build IPv6 support for RADIUS operations
CONFIG_IPV6=y
# IEEE Std 802.11r-2008 (Fast BSS Transition)
CONFIG_IEEE80211R=y
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211)
#CONFIG_DRIVER_RADIUS_ACL=y
# IEEE 802.11n (High Throughput) support
CONFIG_IEEE80211N=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
CONFIG_WNM=y
# IEEE 802.11ac (Very High Throughput) support
CONFIG_IEEE80211AC=y
# IEEE 802.11ax HE support
# Note: This is experimental and work in progress. The definitions are still
# subject to change and this should not be expected to interoperate with the
# final IEEE 802.11ax version.
CONFIG_IEEE80211AX=y
# IEEE 802.11be (EHT Throughput) support
CONFIG_IEEE80211BE=y
# Remove debugging code that is printing out debug messages to stdout.
# This can be used to reduce the size of the hostapd considerably if debugging
# code is not needed.
#CONFIG_NO_STDOUT_DEBUG=y
# Add support for writing debug log to a file: -f /tmp/hostapd.log
# Disabled by default.
CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Remove support for RADIUS accounting
#CONFIG_NO_ACCOUNTING=y
# Remove support for RADIUS
#CONFIG_NO_RADIUS=y
# Remove support for VLANs
#CONFIG_NO_VLAN=y
# Enable support for fully dynamic VLANs. This enables hostapd to
# automatically create bridge and VLAN interfaces if necessary.
CONFIG_FULL_DYNAMIC_VLAN=y
# Use netlink-based kernel API for VLAN operations instead of ioctl()
# Note: This requires libnl 3.1 or newer.
#CONFIG_VLAN_NETLINK=y
# Remove support for dumping internal state through control interface commands
# This can be used to reduce binary size at the cost of disabling a debugging
# option.
CONFIG_NO_DUMP_STATE=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# For BSD, comment out these.
#LIBS += -lexecinfo
#LIBS_p += -lexecinfo
#LIBS_c += -lexecinfo
# Use libbfd to get more details for developer debugging
# This enables use of libbfd to get more detailed symbols for the backtraces
# generated by CONFIG_WPA_TRACE=y.
#CONFIG_WPA_TRACE_BFD=y
# For BSD, comment out these.
#LIBS += -lbfd -liberty -lz
#LIBS_p += -lbfd -liberty -lz
#LIBS_c += -lbfd -liberty -lz
# hostapd depends on strong random number generation being available from the
# operating system. os_get_random() function is used to fetch random data when
# needed, e.g., for key generation. On Linux and BSD systems, this works by
# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
# properly initialized before hostapd is started. This is important especially
# on embedded devices that do not have a hardware random number generator and
# may by default start up with minimal entropy available for random number
# generation.
#
# As a safety net, hostapd is by default trying to internally collect
# additional entropy for generating random data to mix in with the data
# fetched from the OS. This by itself is not considered to be very strong, but
# it may help in cases where the system pool is not initialized properly.
# However, it is very strongly recommended that the system pool is initialized
# with enough entropy either by using hardware assisted random number
# generator or by storing state over device reboots.
#
# hostapd can be configured to maintain its own entropy store over restarts to
# enhance random number generation. This is not perfect, but it is much more
# secure than using the same sequence of random numbers after every reboot.
# This can be enabled with -e<entropy file> command line option. The specified
# file needs to be readable and writable by hostapd.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal hostapd random pool can be disabled.
# This will save some in binary size and CPU use. However, this should only be
# considered for builds that are known to be used on devices that meet the
# requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used.
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms.
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
CONFIG_INTERNAL_LIBTOMMATH=y
#ifndef CONFIG_INTERNAL_LIBTOMMATH
#LTM_PATH=/usr/src/libtommath-0.39
#CFLAGS += -I$(LTM_PATH)
#LIBS += -L$(LTM_PATH)
#LIBS_p += -L$(LTM_PATH)
#endif
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks.
CONFIG_INTERWORKING=y
# Hotspot 2.0
CONFIG_HS20=y
# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file
#CONFIG_SQLITE=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# Testing options
# This can be used to enable some testing options (see also the example
# configuration file) that are really useful only for testing clients that
# connect to this hostapd. These options allow, for example, to drop a
# certain percentage of probe requests or auth/(re)assoc frames.
#
#CONFIG_TESTING_OPTIONS=y
# Automatic Channel Selection
# This will allow hostapd to pick the channel automatically when channel is set
# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# You can customize the ACS survey algorithm with the hostapd.conf variable
# acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#
#CONFIG_ACS=y
# Multiband Operation support
# These extentions facilitate efficient use of multiple frequency bands
# available to the AP and the devices that may associate with it.
CONFIG_MBO=y
# Client Taxonomy
# Has the AP retain the Probe Request and (Re)Association Request frames from
# a client, from which a signature can be produced which can identify the model
# of client device like "Nexus 6P" or "iPhone 5s".
CONFIG_TAXONOMY=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Include internal line edit mode in hostapd_cli. This can be used to provide
# limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Airtime policy support
CONFIG_AIRTIME_POLICY=y
# Proxy ARP support
CONFIG_PROXYARP=y
# Override default value for the wpa_disable_eapol_key_retries configuration
# parameter. See that parameter in hostapd.conf for more details.
#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
CONFIG_CTRL_IFACE_MIB=y

View File

@@ -1,404 +0,0 @@
# Example hostapd build time configuration
#
# This file lists the configuration options that are used when building the
# hostapd binary. All lines starting with # are ignored. Configuration option
# lines must be commented out complete, if they are not to be included, i.e.,
# just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cass, these lines should use += in order not
# to override previous values of the variables.
# Driver interface for Host AP driver
#CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
CONFIG_DRIVER_WIRED=y
# Driver interface for drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
#LIBS += -L$<path to libnl library files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
#LIBS_p += -L/usr/local/lib
#LIBS_c += -L/usr/local/lib
# Driver interface for no driver (e.g., RADIUS server only)
#CONFIG_DRIVER_NONE=y
# IEEE 802.11F/IAPP
#CONFIG_IAPP=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
# IEEE 802.11w (management frame protection)
#CONFIG_IEEE80211W=y
# Support Operating Channel Validation
#CONFIG_OCV=y
# Integrated EAP server
#CONFIG_EAP=y
# EAP Re-authentication Protocol (ERP) in integrated EAP server
#CONFIG_ERP=y
# EAP-MD5 for the integrated EAP server
#CONFIG_EAP_MD5=y
# EAP-TLS for the integrated EAP server
#CONFIG_EAP_TLS=y
# EAP-MSCHAPv2 for the integrated EAP server
#CONFIG_EAP_MSCHAPV2=y
# EAP-PEAP for the integrated EAP server
#CONFIG_EAP_PEAP=y
# EAP-GTC for the integrated EAP server
#CONFIG_EAP_GTC=y
# EAP-TTLS for the integrated EAP server
#CONFIG_EAP_TTLS=y
# EAP-SIM for the integrated EAP server
#CONFIG_EAP_SIM=y
# EAP-AKA for the integrated EAP server
#CONFIG_EAP_AKA=y
# EAP-AKA' for the integrated EAP server
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# EAP-PAX for the integrated EAP server
#CONFIG_EAP_PAX=y
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd for the integrated EAP server (secure authentication with a password)
#CONFIG_EAP_PWD=y
# EAP-SAKE for the integrated EAP server
#CONFIG_EAP_SAKE=y
# EAP-GPSK for the integrated EAP server
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-FAST for the integrated EAP server
#CONFIG_EAP_FAST=y
# EAP-TEAP for the integrated EAP server
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# Wi-Fi Protected Setup (WPS)
#CONFIG_WPS=y
# Enable UPnP support for external WPS Registrars
#CONFIG_WPS_UPNP=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# Trusted Network Connect (EAP-TNC)
#CONFIG_EAP_TNC=y
# EAP-EKE for the integrated EAP server
#CONFIG_EAP_EKE=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
#CONFIG_PKCS12=y
# RADIUS authentication server. This provides access to the integrated EAP
# server from external hosts using RADIUS.
#CONFIG_RADIUS_SERVER=y
# Build IPv6 support for RADIUS operations
#CONFIG_IPV6=y
# IEEE Std 802.11r-2008 (Fast BSS Transition)
#CONFIG_IEEE80211R=y
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211)
#CONFIG_DRIVER_RADIUS_ACL=y
# IEEE 802.11n (High Throughput) support
CONFIG_IEEE80211N=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
#CONFIG_WNM=y
# IEEE 802.11ac (Very High Throughput) support
CONFIG_IEEE80211AC=y
# IEEE 802.11ax HE support
# Note: This is experimental and work in progress. The definitions are still
# subject to change and this should not be expected to interoperate with the
# final IEEE 802.11ax version.
#CONFIG_IEEE80211AX=y
# Remove debugging code that is printing out debug messages to stdout.
# This can be used to reduce the size of the hostapd considerably if debugging
# code is not needed.
#CONFIG_NO_STDOUT_DEBUG=y
# Add support for writing debug log to a file: -f /tmp/hostapd.log
# Disabled by default.
#CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Remove support for RADIUS accounting
CONFIG_NO_ACCOUNTING=y
# Remove support for RADIUS
CONFIG_NO_RADIUS=y
# Remove support for VLANs
#CONFIG_NO_VLAN=y
# Enable support for fully dynamic VLANs. This enables hostapd to
# automatically create bridge and VLAN interfaces if necessary.
#CONFIG_FULL_DYNAMIC_VLAN=y
# Use netlink-based kernel API for VLAN operations instead of ioctl()
# Note: This requires libnl 3.1 or newer.
#CONFIG_VLAN_NETLINK=y
# Remove support for dumping internal state through control interface commands
# This can be used to reduce binary size at the cost of disabling a debugging
# option.
CONFIG_NO_DUMP_STATE=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# For BSD, comment out these.
#LIBS += -lexecinfo
#LIBS_p += -lexecinfo
#LIBS_c += -lexecinfo
# Use libbfd to get more details for developer debugging
# This enables use of libbfd to get more detailed symbols for the backtraces
# generated by CONFIG_WPA_TRACE=y.
#CONFIG_WPA_TRACE_BFD=y
# For BSD, comment out these.
#LIBS += -lbfd -liberty -lz
#LIBS_p += -lbfd -liberty -lz
#LIBS_c += -lbfd -liberty -lz
# hostapd depends on strong random number generation being available from the
# operating system. os_get_random() function is used to fetch random data when
# needed, e.g., for key generation. On Linux and BSD systems, this works by
# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
# properly initialized before hostapd is started. This is important especially
# on embedded devices that do not have a hardware random number generator and
# may by default start up with minimal entropy available for random number
# generation.
#
# As a safety net, hostapd is by default trying to internally collect
# additional entropy for generating random data to mix in with the data
# fetched from the OS. This by itself is not considered to be very strong, but
# it may help in cases where the system pool is not initialized properly.
# However, it is very strongly recommended that the system pool is initialized
# with enough entropy either by using hardware assisted random number
# generator or by storing state over device reboots.
#
# hostapd can be configured to maintain its own entropy store over restarts to
# enhance random number generation. This is not perfect, but it is much more
# secure than using the same sequence of random numbers after every reboot.
# This can be enabled with -e<entropy file> command line option. The specified
# file needs to be readable and writable by hostapd.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal hostapd random pool can be disabled.
# This will save some in binary size and CPU use. However, this should only be
# considered for builds that are known to be used on devices that meet the
# requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used.
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms.
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
#CONFIG_INTERNAL_LIBTOMMATH=y
#ifndef CONFIG_INTERNAL_LIBTOMMATH
#LTM_PATH=/usr/src/libtommath-0.39
#CFLAGS += -I$(LTM_PATH)
#LIBS += -L$(LTM_PATH)
#LIBS_p += -L$(LTM_PATH)
#endif
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks.
#CONFIG_INTERWORKING=y
# Hotspot 2.0
#CONFIG_HS20=y
# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file
#CONFIG_SQLITE=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# Testing options
# This can be used to enable some testing options (see also the example
# configuration file) that are really useful only for testing clients that
# connect to this hostapd. These options allow, for example, to drop a
# certain percentage of probe requests or auth/(re)assoc frames.
#
#CONFIG_TESTING_OPTIONS=y
# Automatic Channel Selection
# This will allow hostapd to pick the channel automatically when channel is set
# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# You can customize the ACS survey algorithm with the hostapd.conf variable
# acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#
#CONFIG_ACS=y
# Multiband Operation support
# These extentions facilitate efficient use of multiple frequency bands
# available to the AP and the devices that may associate with it.
#CONFIG_MBO=y
# Client Taxonomy
# Has the AP retain the Probe Request and (Re)Association Request frames from
# a client, from which a signature can be produced which can identify the model
# of client device like "Nexus 6P" or "iPhone 5s".
#CONFIG_TAXONOMY=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Include internal line edit mode in hostapd_cli. This can be used to provide
# limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Airtime policy support
#CONFIG_AIRTIME_POLICY=y
# Proxy ARP support
#CONFIG_PROXYARP=y
# Override default value for the wpa_disable_eapol_key_retries configuration
# parameter. See that parameter in hostapd.conf for more details.
#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
#CONFIG_CTRL_IFACE_MIB=y

File diff suppressed because it is too large Load Diff

View File

@@ -1,928 +0,0 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open } from "common";
let ubus = libubus.connect(null, 60);
hostapd.data.config = {};
hostapd.data.pending_config = {};
hostapd.data.file_fields = {
vlan_file: true,
wpa_psk_file: true,
accept_mac_file: true,
deny_mac_file: true,
eap_user_file: true,
ca_cert: true,
server_cert: true,
server_cert2: true,
private_key: true,
private_key2: true,
dh_file: true,
eap_sim_db: true,
};
function iface_remove(cfg)
{
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
return;
for (let bss in cfg.bss)
wdev_remove(bss.ifname);
}
function iface_gen_config(phy, config, start_disabled)
{
let str = `data:
${join("\n", config.radio.data)}
channel=${config.radio.channel}
`;
for (let i = 0; i < length(config.bss); i++) {
let bss = config.bss[i];
let type = i > 0 ? "bss" : "interface";
let nasid = bss.nasid ?? replace(bss.bssid, ":", "");
str += `
${type}=${bss.ifname}
bssid=${bss.bssid}
${join("\n", bss.data)}
nas_identifier=${nasid}
`;
if (start_disabled)
str += `
start_disabled=1
`;
}
return str;
}
function iface_freq_info(iface, config, params)
{
let freq = params.frequency;
if (!freq)
return null;
let sec_offset = params.sec_chan_offset;
if (sec_offset != -1 && sec_offset != 1)
sec_offset = 0;
let width = 0;
for (let line in config.radio.data) {
if (!sec_offset && match(line, /^ht_capab=.*HT40/)) {
sec_offset = null; // auto-detect
continue;
}
let val = match(line, /^(vht_oper_chwidth|he_oper_chwidth)=(\d+)/);
if (!val)
continue;
val = int(val[2]);
if (val > width)
width = val;
}
if (freq < 4000)
width = 0;
return hostapd.freq_info(freq, sec_offset, width);
}
function iface_add(phy, config, phy_status)
{
let config_inline = iface_gen_config(phy, config, !!phy_status);
let bss = config.bss[0];
let ret = hostapd.add_iface(`bss_config=${phy}:${config_inline}`);
if (ret < 0)
return false;
if (!phy_status)
return true;
let iface = hostapd.interfaces[phy];
if (!iface)
return false;
let freq_info = iface_freq_info(iface, config, phy_status);
return iface.start(freq_info) >= 0;
}
function iface_config_macaddr_list(config)
{
let macaddr_list = {};
for (let i = 0; i < length(config.bss); i++) {
let bss = config.bss[i];
if (!bss.default_macaddr)
macaddr_list[bss.bssid] = i;
}
return macaddr_list;
}
function iface_update_supplicant_macaddr(phy, config)
{
let macaddr_list = [];
for (let i = 0; i < length(config.bss); i++)
push(macaddr_list, config.bss[i].bssid);
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
}
function __iface_pending_next(pending, state, ret, data)
{
let config = pending.config;
let phydev = pending.phydev;
let phy = pending.phy;
let bss = config.bss[0];
if (pending.defer)
pending.defer.abort();
delete pending.defer;
switch (state) {
case "init":
let macaddr_list = [];
for (let i = 0; i < length(config.bss); i++)
push(macaddr_list, config.bss[i].bssid);
pending.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
return "create_bss";
case "create_bss":
let err = wdev_create(phy, bss.ifname, { mode: "ap" });
if (err) {
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
return null;
}
pending.call("wpa_supplicant", "phy_status", { phy: phy });
return "check_phy";
case "check_phy":
let phy_status = data;
if (phy_status && phy_status.state == "COMPLETED") {
if (iface_add(phy, config, phy_status))
return "done";
hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
}
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
return "wpas_stopped";
case "wpas_stopped":
if (!iface_add(phy, config))
hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
return null;
case "done":
default:
delete hostapd.data.pending_config[phy];
break;
}
}
function iface_pending_next(ret, data)
{
let pending = true;
let cfg = this;
while (pending) {
this.next_state = __iface_pending_next(cfg, this.next_state, ret, data);
if (!this.next_state) {
__iface_pending_next(cfg, "done");
return;
}
pending = !this.defer;
}
}
function iface_pending_abort()
{
this.next_state = "done";
this.next();
}
function iface_pending_ubus_call(obj, method, arg)
{
let ubus = hostapd.data.ubus;
let pending = this;
this.defer = ubus.defer(obj, method, arg, (ret, data) => { delete pending.defer; pending.next(ret, data) });
}
const iface_pending_proto = {
next: iface_pending_next,
call: iface_pending_ubus_call,
abort: iface_pending_abort,
};
function iface_pending_init(phydev, config)
{
let phy = phydev.name;
let pending = proto({
next_state: "init",
phydev: phydev,
phy: phy,
config: config,
next: iface_pending_next,
}, iface_pending_proto);
hostapd.data.pending_config[phy] = pending;
pending.next();
}
function iface_restart(phydev, config, old_config)
{
let phy = phydev.name;
let pending = hostapd.data.pending_config[phy];
if (pending)
pending.abort();
hostapd.remove_iface(phy);
iface_remove(old_config);
iface_remove(config);
if (!config.bss || !config.bss[0]) {
hostapd.printf(`No bss for phy ${phy}`);
return;
}
phydev.macaddr_init(iface_config_macaddr_list(config));
for (let i = 0; i < length(config.bss); i++) {
let bss = config.bss[i];
if (bss.default_macaddr)
bss.bssid = phydev.macaddr_next();
}
iface_pending_init(phydev, config);
}
function array_to_obj(arr, key, start)
{
let obj = {};
start ??= 0;
for (let i = start; i < length(arr); i++) {
let cur = arr[i];
obj[cur[key]] = cur;
}
return obj;
}
function find_array_idx(arr, key, val)
{
for (let i = 0; i < length(arr); i++)
if (arr[i][key] == val)
return i;
return -1;
}
function bss_reload_psk(bss, config, old_config)
{
if (is_equal(old_config.hash.wpa_psk_file, config.hash.wpa_psk_file))
return;
old_config.hash.wpa_psk_file = config.hash.wpa_psk_file;
if (!is_equal(old_config, config))
return;
let ret = bss.ctrl("RELOAD_WPA_PSK");
ret ??= "failed";
hostapd.printf(`Reload WPA PSK file for bss ${config.ifname}: ${ret}`);
}
function remove_file_fields(config)
{
return filter(config, (line) => !hostapd.data.file_fields[split(line, "=")[0]]);
}
function bss_remove_file_fields(config)
{
let new_cfg = {};
for (let key in config)
new_cfg[key] = config[key];
new_cfg.data = remove_file_fields(new_cfg.data);
new_cfg.hash = {};
for (let key in config.hash)
new_cfg.hash[key] = config.hash[key];
delete new_cfg.hash.wpa_psk_file;
delete new_cfg.hash.vlan_file;
return new_cfg;
}
function bss_config_hash(config)
{
return hostapd.sha1(remove_file_fields(config) + "");
}
function bss_find_existing(config, prev_config, prev_hash)
{
let hash = bss_config_hash(config.data);
for (let i = 0; i < length(prev_config.bss); i++) {
if (!prev_hash[i] || hash != prev_hash[i])
continue;
prev_hash[i] = null;
return i;
}
return -1;
}
function get_config_bss(config, idx)
{
if (!config.bss[idx]) {
hostapd.printf(`Invalid bss index ${idx}`);
return null;
}
let ifname = config.bss[idx].ifname;
if (!ifname)
hostapd.printf(`Could not find bss ${config.bss[idx].ifname}`);
return hostapd.bss[ifname];
}
function iface_reload_config(phydev, config, old_config)
{
let phy = phydev.name;
if (!old_config || !is_equal(old_config.radio, config.radio))
return false;
if (is_equal(old_config.bss, config.bss))
return true;
if (hostapd.data.pending_config[phy])
return false;
if (!old_config.bss || !old_config.bss[0])
return false;
let iface = hostapd.interfaces[phy];
let iface_name = old_config.bss[0].ifname;
if (!iface) {
hostapd.printf(`Could not find previous interface ${iface_name}`);
return false;
}
let first_bss = hostapd.bss[iface_name];
if (!first_bss) {
hostapd.printf(`Could not find bss of previous interface ${iface_name}`);
return false;
}
let macaddr_list = iface_config_macaddr_list(config);
let bss_list = [];
let bss_list_cfg = [];
let prev_bss_hash = [];
for (let bss in old_config.bss) {
let hash = bss_config_hash(bss.data);
push(prev_bss_hash, bss_config_hash(bss.data));
}
// Step 1: find (possibly renamed) interfaces with the same config
// and store them in the new order (with gaps)
for (let i = 0; i < length(config.bss); i++) {
let prev;
// For fullmac devices, the first interface needs to be preserved,
// since it's treated as the master
if (!i && phy_is_fullmac(phy)) {
prev = 0;
prev_bss_hash[0] = null;
} else {
prev = bss_find_existing(config.bss[i], old_config, prev_bss_hash);
}
if (prev < 0)
continue;
let cur_config = config.bss[i];
let prev_config = old_config.bss[prev];
let prev_bss = get_config_bss(old_config, prev);
if (!prev_bss)
return false;
// try to preserve MAC address of this BSS by reassigning another
// BSS if necessary
if (cur_config.default_macaddr &&
!macaddr_list[prev_config.bssid]) {
macaddr_list[prev_config.bssid] = i;
cur_config.bssid = prev_config.bssid;
}
bss_list[i] = prev_bss;
bss_list_cfg[i] = old_config.bss[prev];
}
if (config.mbssid && !bss_list_cfg[0]) {
hostapd.printf("First BSS changed with MBSSID enabled");
return false;
}
// Step 2: if none were found, rename and preserve the first one
if (length(bss_list) == 0) {
// can't change the bssid of the first bss
if (config.bss[0].bssid != old_config.bss[0].bssid) {
if (!config.bss[0].default_macaddr) {
hostapd.printf(`BSSID of first interface changed: ${lc(old_config.bss[0].bssid)} -> ${lc(config.bss[0].bssid)}`);
return false;
}
config.bss[0].bssid = old_config.bss[0].bssid;
}
let prev_bss = get_config_bss(old_config, 0);
if (!prev_bss)
return false;
macaddr_list[config.bss[0].bssid] = 0;
bss_list[0] = prev_bss;
bss_list_cfg[0] = old_config.bss[0];
prev_bss_hash[0] = null;
}
// Step 3: delete all unused old interfaces
for (let i = 0; i < length(prev_bss_hash); i++) {
if (!prev_bss_hash[i])
continue;
let prev_bss = get_config_bss(old_config, i);
if (!prev_bss)
return false;
let ifname = old_config.bss[i].ifname;
hostapd.printf(`Remove bss '${ifname}' on phy '${phy}'`);
prev_bss.delete();
wdev_remove(ifname);
}
// Step 4: rename preserved interfaces, use temporary name on duplicates
let rename_list = [];
for (let i = 0; i < length(bss_list); i++) {
if (!bss_list[i])
continue;
let old_ifname = bss_list_cfg[i].ifname;
let new_ifname = config.bss[i].ifname;
if (old_ifname == new_ifname)
continue;
if (hostapd.bss[new_ifname]) {
new_ifname = "tmp_" + substr(hostapd.sha1(new_ifname), 0, 8);
push(rename_list, i);
}
hostapd.printf(`Rename bss ${old_ifname} to ${new_ifname}`);
if (!bss_list[i].rename(new_ifname)) {
hostapd.printf(`Failed to rename bss ${old_ifname} to ${new_ifname}`);
return false;
}
bss_list_cfg[i].ifname = new_ifname;
}
// Step 5: rename interfaces with temporary names
for (let i in rename_list) {
let new_ifname = config.bss[i].ifname;
if (!bss_list[i].rename(new_ifname)) {
hostapd.printf(`Failed to rename bss to ${new_ifname}`);
return false;
}
bss_list_cfg[i].ifname = new_ifname;
}
// Step 6: assign BSSID for newly created interfaces
let macaddr_data = {
num_global: config.num_global_macaddr ?? 1,
mbssid: config.mbssid ?? 0,
};
macaddr_list = phydev.macaddr_init(macaddr_list, macaddr_data);
for (let i = 0; i < length(config.bss); i++) {
if (bss_list[i])
continue;
let bsscfg = config.bss[i];
let mac_idx = macaddr_list[bsscfg.bssid];
if (mac_idx < 0)
macaddr_list[bsscfg.bssid] = i;
if (mac_idx == i)
continue;
// statically assigned bssid of the new interface is in conflict
// with the bssid of a reused interface. reassign the reused interface
if (!bsscfg.default_macaddr) {
// can't update bssid of the first BSS, need to restart
if (!mac_idx < 0)
return false;
bsscfg = config.bss[mac_idx];
}
let addr = phydev.macaddr_next(i);
if (!addr) {
hostapd.printf(`Failed to generate mac address for phy ${phy}`);
return false;
}
bsscfg.bssid = addr;
}
let config_inline = iface_gen_config(phy, config);
// Step 7: fill in the gaps with new interfaces
for (let i = 0; i < length(config.bss); i++) {
let ifname = config.bss[i].ifname;
let bss = bss_list[i];
if (bss)
continue;
hostapd.printf(`Add bss ${ifname} on phy ${phy}`);
bss_list[i] = iface.add_bss(config_inline, i);
if (!bss_list[i]) {
hostapd.printf(`Failed to add new bss ${ifname} on phy ${phy}`);
return false;
}
}
// Step 8: update interface bss order
if (!iface.set_bss_order(bss_list)) {
hostapd.printf(`Failed to update BSS order on phy '${phy}'`);
return false;
}
// Step 9: update config
for (let i = 0; i < length(config.bss); i++) {
if (!bss_list_cfg[i])
continue;
let ifname = config.bss[i].ifname;
let bss = bss_list[i];
if (is_equal(config.bss[i], bss_list_cfg[i]))
continue;
if (is_equal(bss_remove_file_fields(config.bss[i]),
bss_remove_file_fields(bss_list_cfg[i]))) {
hostapd.printf(`Update config data files for bss ${ifname}`);
if (bss.set_config(config_inline, i, true) < 0) {
hostapd.printf(`Could not update config data files for bss ${ifname}`);
return false;
} else {
bss.ctrl("RELOAD_WPA_PSK");
continue;
}
}
bss_reload_psk(bss, config.bss[i], bss_list_cfg[i]);
if (is_equal(config.bss[i], bss_list_cfg[i]))
continue;
hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`);
if (bss.set_config(config_inline, i) < 0) {
hostapd.printf(`Failed to set config for bss ${ifname}`);
return false;
}
}
return true;
}
function iface_set_config(phy, config)
{
let old_config = hostapd.data.config[phy];
hostapd.data.config[phy] = config;
if (!config) {
hostapd.remove_iface(phy);
return iface_remove(old_config);
}
let phydev = phy_open(phy);
if (!phydev) {
hostapd.printf(`Failed to open phy ${phy}`);
return false;
}
try {
let ret = iface_reload_config(phydev, config, old_config);
if (ret) {
iface_update_supplicant_macaddr(phy, config);
hostapd.printf(`Reloaded settings for phy ${phy}`);
return 0;
}
} catch (e) {
hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`);
}
hostapd.printf(`Restart interface for phy ${phy}`);
let ret = iface_restart(phydev, config, old_config);
return ret;
}
function config_add_bss(config, name)
{
let bss = {
ifname: name,
data: [],
hash: {}
};
push(config.bss, bss);
return bss;
}
function iface_load_config(filename)
{
let f = open(filename, "r");
if (!f)
return null;
let config = {
radio: {
data: []
},
bss: [],
orig_file: filename,
};
let bss;
let line;
while ((line = rtrim(f.read("line"), "\n")) != null) {
let val = split(line, "=", 2);
if (!val[0])
continue;
if (val[0] == "interface") {
bss = config_add_bss(config, val[1]);
break;
}
if (val[0] == "channel") {
config.radio.channel = val[1];
continue;
}
if (val[0] == "#num_global_macaddr" ||
val[0] == "mbssid")
config[val[0]] = int(val[1]);
push(config.radio.data, line);
}
while ((line = rtrim(f.read("line"), "\n")) != null) {
if (line == "#default_macaddr")
bss.default_macaddr = true;
let val = split(line, "=", 2);
if (!val[0])
continue;
if (val[0] == "bssid") {
bss.bssid = lc(val[1]);
continue;
}
if (val[0] == "nas_identifier")
bss.nasid = val[1];
if (val[0] == "bss") {
bss = config_add_bss(config, val[1]);
continue;
}
if (hostapd.data.file_fields[val[0]])
bss.hash[val[0]] = hostapd.sha1(readfile(val[1]));
push(bss.data, line);
}
f.close();
return config;
}
function ex_wrap(func) {
return (req) => {
try {
let ret = func(req);
return ret;
} catch(e) {
hostapd.printf(`Exception in ubus function: ${e}\n${e.stacktrace[0].context}`);
}
return libubus.STATUS_UNKNOWN_ERROR;
};
}
let main_obj = {
reload: {
args: {
phy: "",
},
call: ex_wrap(function(req) {
let phy_list = req.args.phy ? [ req.args.phy ] : keys(hostapd.data.config);
for (let phy_name in phy_list) {
let phy = hostapd.data.config[phy_name];
let config = iface_load_config(phy.orig_file);
iface_set_config(phy_name, config);
}
return 0;
})
},
apsta_state: {
args: {
phy: "",
up: true,
frequency: 0,
sec_chan_offset: 0,
csa: true,
csa_count: 0,
},
call: ex_wrap(function(req) {
if (req.args.up == null || !req.args.phy)
return libubus.STATUS_INVALID_ARGUMENT;
let phy = req.args.phy;
let config = hostapd.data.config[phy];
if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname)
return 0;
let iface = hostapd.interfaces[phy];
if (!iface)
return 0;
if (!req.args.up) {
iface.stop();
return 0;
}
if (!req.args.frequency)
return libubus.STATUS_INVALID_ARGUMENT;
let freq_info = iface_freq_info(iface, config, req.args);
if (!freq_info)
return libubus.STATUS_UNKNOWN_ERROR;
let ret;
if (req.args.csa) {
freq_info.csa_count = req.args.csa_count ?? 10;
ret = iface.switch_channel(freq_info);
} else {
ret = iface.start(freq_info);
}
if (!ret)
return libubus.STATUS_UNKNOWN_ERROR;
return 0;
})
},
config_get_macaddr_list: {
args: {
phy: ""
},
call: ex_wrap(function(req) {
let phy = req.args.phy;
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
let ret = {
macaddr: [],
};
let config = hostapd.data.config[phy];
if (!config)
return ret;
ret.macaddr = map(config.bss, (bss) => bss.bssid);
return ret;
})
},
config_set: {
args: {
phy: "",
config: "",
prev_config: "",
},
call: ex_wrap(function(req) {
let phy = req.args.phy;
let file = req.args.config;
let prev_file = req.args.prev_config;
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
if (prev_file && !hostapd.data.config[phy]) {
let config = iface_load_config(prev_file);
if (config)
config.radio.data = [];
hostapd.data.config[phy] = config;
}
let config = iface_load_config(file);
hostapd.printf(`Set new config for phy ${phy}: ${file}`);
iface_set_config(phy, config);
hostapd.data.auth_obj.notify("reload", { phy });
return {
pid: hostapd.getpid()
};
})
},
config_add: {
args: {
iface: "",
config: "",
},
call: ex_wrap(function(req) {
if (!req.args.iface || !req.args.config)
return libubus.STATUS_INVALID_ARGUMENT;
if (hostapd.add_iface(`bss_config=${req.args.iface}:${req.args.config}`) < 0)
return libubus.STATUS_INVALID_ARGUMENT;
return {
pid: hostapd.getpid()
};
})
},
config_remove: {
args: {
iface: ""
},
call: ex_wrap(function(req) {
if (!req.args.iface)
return libubus.STATUS_INVALID_ARGUMENT;
hostapd.remove_iface(req.args.iface);
return 0;
})
},
};
hostapd.data.ubus = ubus;
hostapd.data.obj = ubus.publish("hostapd", main_obj);
let auth_obj = {};
hostapd.data.auth_obj = ubus.publish("hostapd-auth", auth_obj);
function bss_event(type, name, data) {
let ubus = hostapd.data.ubus;
data ??= {};
data.name = name;
hostapd.data.obj.notify(`bss.${type}`, data, null, null, null, -1);
ubus.call("service", "event", { type: `hostapd.${name}.${type}`, data: {} });
}
return {
shutdown: function() {
for (let phy in hostapd.data.config)
iface_set_config(phy, null);
hostapd.ubus.disconnect();
},
afc_request: function(iface, data) {
let ret = ubus.call("afc", "request", { data });
if (type(ret) != "object")
return;
return ret.data;
},
bss_add: function(name, obj) {
bss_event("add", name);
},
bss_reload: function(name, obj, reconf) {
bss_event("reload", name, { reconf: reconf != 0 });
},
bss_remove: function(name, obj) {
bss_event("remove", name);
},
sta_auth: function(iface, sta) {
let msg = { iface, sta };
let ret = {};
let data_cb = (type, data) => {
ret = { ...ret, ...data };
};
hostapd.data.auth_obj.notify("sta_auth", msg, data_cb, null, null, 1000);
return ret;
},
sta_connected: function(iface, sta, data) {
let msg = { iface, sta, ...data };
let ret = {};
let data_cb = (type, data) => {
ret = { ...ret, ...data };
};
hostapd.data.auth_obj.notify("sta_connected", msg, data_cb, null, null, 1000);
return ret;
},
};

View File

@@ -1,28 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
extern int hostapd_main(int argc, char **argv);
extern int wpa_supplicant_main(int argc, char **argv);
int main(int argc, char **argv)
{
bool restart = false;
const char *prog = argv[0];
restart:
if (strstr(argv[0], "hostapd"))
return hostapd_main(argc, argv);
else if (strstr(argv[0], "wpa_supplicant"))
return wpa_supplicant_main(argc, argv);
if (!restart && argc > 1) {
argv++;
argc--;
restart = true;
goto restart;
}
fprintf(stderr, "Invalid command.\nUsage: %s wpa_supplicant|hostapd [<arguments>]\n", prog);
return 255;
}

View File

@@ -1,207 +0,0 @@
#!/usr/bin/env ucode
'use strict';
import { vlist_new, is_equal, wdev_create, wdev_remove, phy_open } from "/usr/share/hostap/common.uc";
import { readfile, writefile, basename, readlink, glob } from "fs";
let libubus = require("ubus");
let keep_devices = {};
let phy = shift(ARGV);
let command = shift(ARGV);
let phydev;
const mesh_params = [
"mesh_retry_timeout", "mesh_confirm_timeout", "mesh_holding_timeout", "mesh_max_peer_links",
"mesh_max_retries", "mesh_ttl", "mesh_element_ttl", "mesh_hwmp_max_preq_retries",
"mesh_path_refresh_time", "mesh_min_discovery_timeout", "mesh_hwmp_active_path_timeout",
"mesh_hwmp_preq_min_interval", "mesh_hwmp_net_diameter_traversal_time", "mesh_hwmp_rootmode",
"mesh_hwmp_rann_interval", "mesh_gate_announcements", "mesh_sync_offset_max_neighor",
"mesh_rssi_threshold", "mesh_hwmp_active_path_to_root_timeout", "mesh_hwmp_root_interval",
"mesh_hwmp_confirmation_interval", "mesh_awake_window", "mesh_plink_timeout",
"mesh_auto_open_plinks", "mesh_fwding", "mesh_power_mode"
];
function iface_stop(wdev)
{
if (keep_devices[wdev.ifname])
return;
wdev_remove(wdev.ifname);
}
function iface_start(wdev)
{
let ifname = wdev.ifname;
if (readfile(`/sys/class/net/${ifname}/ifindex`)) {
system([ "ip", "link", "set", "dev", ifname, "down" ]);
wdev_remove(ifname);
}
let wdev_config = {};
for (let key in wdev)
wdev_config[key] = wdev[key];
if (!wdev_config.macaddr && wdev.mode != "monitor")
wdev_config.macaddr = phydev.macaddr_next();
wdev_create(phy, ifname, wdev_config);
system([ "ip", "link", "set", "dev", ifname, "up" ]);
if (wdev.freq)
system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`);
if (wdev.mode == "adhoc") {
let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ];
if (wdev.bssid)
push(cmd, wdev.bssid);
for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ])
if (wdev[key])
push(cmd, key, wdev[key]);
system(cmd);
} else if (wdev.mode == "mesh") {
let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ];
for (let key in [ "mcast-rate", "beacon-interval" ])
if (wdev[key])
push(cmd, key, wdev[key]);
system(cmd);
cmd = ["iw", "dev", ifname, "set", "mesh_param" ];
let len = length(cmd);
for (let param in mesh_params)
if (wdev[param])
push(cmd, param, wdev[param]);
if (len == length(cmd))
return;
system(cmd);
}
}
function iface_cb(new_if, old_if)
{
if (old_if && new_if && is_equal(old_if, new_if))
return;
if (old_if)
iface_stop(old_if);
if (new_if)
iface_start(new_if);
}
function drop_inactive(config)
{
for (let key in config) {
if (!readfile(`/sys/class/net/${key}/ifindex`))
delete config[key];
}
}
function add_ifname(config)
{
for (let key in config)
config[key].ifname = key;
}
function delete_ifname(config)
{
for (let key in config)
delete config[key].ifname;
}
function add_existing(phy, config)
{
let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`);
wdevs = map(wdevs, (arg) => basename(arg));
for (let wdev in wdevs) {
if (config[wdev])
continue;
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy)
continue;
if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
config[wdev] = {};
}
}
function usage()
{
warn(`Usage: ${basename(sourcepath())} <phy> <command> [<arguments>]
Commands:
set_config <config> [<device]...] - set phy configuration
get_macaddr <id> - get phy MAC address for vif index <id>
`);
exit(1);
}
const commands = {
set_config: function(args) {
let statefile = `/var/run/wdev-${phy}.json`;
let new_config = shift(args);
for (let dev in ARGV)
keep_devices[dev] = true;
if (!new_config)
usage();
new_config = json(new_config);
if (!new_config) {
warn("Invalid configuration\n");
exit(1);
}
let old_config = readfile(statefile);
if (old_config)
old_config = json(old_config);
let config = vlist_new(iface_cb);
if (type(old_config) == "object")
config.data = old_config;
add_existing(phy, config.data);
add_ifname(config.data);
drop_inactive(config.data);
let ubus = libubus.connect();
let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
let macaddr_list = [];
if (type(data) == "object" && data.macaddr)
macaddr_list = data.macaddr;
ubus.disconnect();
phydev.macaddr_init(macaddr_list);
add_ifname(new_config);
config.update(new_config);
drop_inactive(config.data);
delete_ifname(config.data);
writefile(statefile, sprintf("%J", config.data));
},
get_macaddr: function(args) {
let data = {};
for (let arg in args) {
arg = split(arg, "=", 2);
data[arg[0]] = arg[1];
}
let macaddr = phydev.macaddr_generate(data);
if (!macaddr) {
warn(`Could not get MAC address for phy ${phy}\n`);
exit(1);
}
print(macaddr + "\n");
},
};
if (!phy || !command | !commands[command])
usage();
phydev = phy_open(phy);
if (!phydev) {
warn(`PHY ${phy} does not exist\n`);
exit(1);
}
commands[command](ARGV);

View File

@@ -1,625 +0,0 @@
# Example wpa_supplicant build time configuration
#
# This file lists the configuration options that are used when building the
# wpa_supplicant binary. All lines starting with # are ignored. Configuration
# option lines must be commented out complete, if they are not to be included,
# i.e., just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cases, these lines should use += in order not
# to override previous values of the variables.
# Uncomment following two lines and fix the paths if you have installed OpenSSL
# or GnuTLS in non-default location
#CFLAGS += -I/usr/local/openssl/include
#LIBS += -L/usr/local/openssl/lib
# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
# the kerberos files are not in the default include path. Following line can be
# used to fix build issues on such systems (krb5.h not found).
#CFLAGS += -I/usr/include/kerberos
# Driver interface for generic Linux wireless extensions
# Note: WEXT is deprecated in the current Linux kernel version and no new
# functionality is added to it. nl80211-based interface is the new
# replacement for WEXT and its use allows wpa_supplicant to properly control
# the driver to improve existing functionality like roaming and to support new
# functionality.
CONFIG_DRIVER_WEXT=y
# Driver interface for Linux drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
#LIBS += -L$<path to libnl library files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
#LIBS_p += -L/usr/local/lib
#LIBS_c += -L/usr/local/lib
# Driver interface for Windows NDIS
#CONFIG_DRIVER_NDIS=y
#CFLAGS += -I/usr/include/w32api/ddk
#LIBS += -L/usr/local/lib
# For native build using mingw
#CONFIG_NATIVE_WINDOWS=y
# Additional directories for cross-compilation on Linux host for mingw target
#CFLAGS += -I/opt/mingw/mingw32/include/ddk
#LIBS += -L/opt/mingw/mingw32/lib
#CC=mingw32-gcc
# By default, driver_ndis uses WinPcap for low-level operations. This can be
# replaced with the following option which replaces WinPcap calls with NDISUIO.
# However, this requires that WZC is disabled (net stop wzcsvc) before starting
# wpa_supplicant.
# CONFIG_USE_NDISUIO=y
# Driver interface for wired Ethernet drivers
CONFIG_DRIVER_WIRED=y
# Driver interface for MACsec capable Qualcomm Atheros drivers
#CONFIG_DRIVER_MACSEC_QCA=y
# Driver interface for Linux MACsec drivers
#CONFIG_DRIVER_MACSEC_LINUX=y
# Driver interface for the Broadcom RoboSwitch family
#CONFIG_DRIVER_ROBOSWITCH=y
# Driver interface for no driver (e.g., WPS ER only)
#CONFIG_DRIVER_NONE=y
# Solaris libraries
#LIBS += -lsocket -ldlpi -lnsl
#LIBS_c += -lsocket
# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
# MACsec is included)
#CONFIG_IEEE8021X_EAPOL=y
# EAP-MD5
#CONFIG_EAP_MD5=y
# EAP-MSCHAPv2
#CONFIG_EAP_MSCHAPV2=y
# EAP-TLS
#CONFIG_EAP_TLS=y
# EAL-PEAP
#CONFIG_EAP_PEAP=y
# EAP-TTLS
#CONFIG_EAP_TTLS=y
# EAP-FAST
#CONFIG_EAP_FAST=y
# EAP-TEAP
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# EAP-GTC
#CONFIG_EAP_GTC=y
# EAP-OTP
#CONFIG_EAP_OTP=y
# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
#CONFIG_EAP_SIM=y
# Enable SIM simulator (Milenage) for EAP-SIM
#CONFIG_SIM_SIMULATOR=y
# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd (secure authentication using only a password)
#CONFIG_EAP_PWD=y
# EAP-PAX
#CONFIG_EAP_PAX=y
# LEAP
#CONFIG_EAP_LEAP=y
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
#CONFIG_EAP_AKA=y
# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# Enable USIM simulator (Milenage) for EAP-AKA
#CONFIG_USIM_SIMULATOR=y
# EAP-SAKE
#CONFIG_EAP_SAKE=y
# EAP-GPSK
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-TNC and related Trusted Network Connect support (experimental)
#CONFIG_EAP_TNC=y
# Wi-Fi Protected Setup (WPS)
#CONFIG_WPS=y
# Enable WPS external registrar functionality
#CONFIG_WPS_ER=y
# Disable credentials for an open network by default when acting as a WPS
# registrar.
#CONFIG_WPS_REG_DISABLE_OPEN=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# EAP-EKE
#CONFIG_EAP_EKE=y
# MACsec
#CONFIG_MACSEC=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
#CONFIG_PKCS12=y
# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
# engine.
#CONFIG_SMARTCARD=y
# PC/SC interface for smartcards (USIM, GSM SIM)
# Enable this if EAP-SIM or EAP-AKA is included
#CONFIG_PCSC=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
CONFIG_HT_OVERRIDES=y
# Support VHT overrides (disable VHT, mask MCS rates, etc.)
CONFIG_VHT_OVERRIDES=y
# Development testing
#CONFIG_EAPOL_TEST=y
# Select control interface backend for external programs, e.g, wpa_cli:
# unix = UNIX domain sockets (default for Linux/*BSD)
# udp = UDP sockets using localhost (127.0.0.1)
# udp6 = UDP IPv6 sockets using localhost (::1)
# named_pipe = Windows Named Pipe (default for Windows)
# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
# y = use default (backwards compatibility)
# If this option is commented out, control interface is not included in the
# build.
CONFIG_CTRL_IFACE=y
# Include support for GNU Readline and History Libraries in wpa_cli.
# When building a wpa_cli binary for distribution, please note that these
# libraries are licensed under GPL and as such, BSD license may not apply for
# the resulting binary.
#CONFIG_READLINE=y
# Include internal line edit mode in wpa_cli. This can be used as a replacement
# for GNU Readline to provide limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Remove debugging code that is printing out debug message to stdout.
# This can be used to reduce the size of the wpa_supplicant considerably
# if debugging code is not needed. The size reduction can be around 35%
# (e.g., 90 kB).
#CONFIG_NO_STDOUT_DEBUG=y
# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
# 35-50 kB in code size.
#CONFIG_NO_WPA=y
# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
# This option can be used to reduce code size by removing support for
# converting ASCII passphrases into PSK. If this functionality is removed, the
# PSK can only be configured as the 64-octet hexstring (e.g., from
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
#CONFIG_SAE=y
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
# Select configuration backend:
# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
# path is given on command line, not here; this option is just used to
# select the backend that allows configuration files to be used)
# winreg = Windows registry (see win_example.reg for an example)
CONFIG_BACKEND=file
# Remove configuration write functionality (i.e., to allow the configuration
# file to be updated based on runtime configuration changes). The runtime
# configuration can still be changed, the changes are just not going to be
# persistent over restarts. This option can be used to reduce code size by
# about 3.5 kB.
CONFIG_NO_CONFIG_WRITE=y
# Remove support for configuration blobs to reduce code size by about 1.5 kB.
#CONFIG_NO_CONFIG_BLOBS=y
# Select program entry point implementation:
# main = UNIX/POSIX like main() function (default)
# main_winsvc = Windows service (read parameters from registry)
# main_none = Very basic example (development use only)
#CONFIG_MAIN=main
# Select wrapper for operating system and C library specific functions
# unix = UNIX/POSIX like systems (default)
# win32 = Windows systems
# none = Empty template
#CONFIG_OS=unix
# Select event loop implementation
# eloop = select() loop (default)
# eloop_win = Windows events and WaitForMultipleObject() loop
#CONFIG_ELOOP=eloop
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select layer 2 packet implementation
# linux = Linux packet socket (default)
# pcap = libpcap/libdnet/WinPcap
# freebsd = FreeBSD libpcap
# winpcap = WinPcap with receive thread
# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
# none = Empty template
#CONFIG_L2_PACKET=linux
# Disable Linux packet socket workaround applicable for station interface
# in a bridge for EAPOL frames. This should be uncommented only if the kernel
# is known to not have the regression issue in packet socket behavior with
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
# IEEE 802.11w (management frame protection), also known as PMF
# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
# Support Operating Channel Validation
CONFIG_OCV=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used. It should be noted that some existing TLS v1.0 -based
# implementation may not be compatible with TLS v1.1 message (ClientHello is
# sent prior to negotiating which version will be used)
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms. It should be
# noted that some existing TLS v1.0 -based implementation may not be compatible
# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
# will be used)
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
#CONFIG_INTERNAL_LIBTOMMATH=y
#ifndef CONFIG_INTERNAL_LIBTOMMATH
#LTM_PATH=/usr/src/libtommath-0.39
#CFLAGS += -I$(LTM_PATH)
#LIBS += -L$(LTM_PATH)
#LIBS_p += -L$(LTM_PATH)
#endif
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
# This is only for Windows builds and requires WMI-related header files and
# WbemUuid.Lib from Platform SDK even when building with MinGW.
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
#CONFIG_CTRL_IFACE_DBUS_INTRO=y
# Add support for loading EAP methods dynamically as shared libraries.
# When this option is enabled, each EAP method can be either included
# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
# be loaded in the beginning of the wpa_supplicant configuration file
# (see load_dynamic_eap parameter in the example file) before being used in
# the network blocks.
#
# Note that some shared parts of EAP methods are included in the main program
# and in order to be able to use dynamic EAP methods using these parts, the
# main program must have been build with the EAP method enabled (=y or =dyn).
# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
# unless at least one of them was included in the main build to force inclusion
# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
# in the main build to be able to load these methods dynamically.
#
# Please also note that using dynamic libraries will increase the total binary
# size. Thus, it may not be the best option for targets that have limited
# amount of memory/flash.
#CONFIG_DYNAMIC_EAP_METHODS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
CONFIG_IEEE80211R=y
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
#CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Set syslog facility for debug messages
CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Add support for writing debug log to Android logcat instead of standard
# output
#CONFIG_ANDROID_LOG=y
# Enable privilege separation (see README 'Privilege separation' for details)
#CONFIG_PRIVSEP=y
# Enable mitigation against certain attacks against TKIP by delaying Michael
# MIC error reports by a random amount of time between 0 and 60 seconds
#CONFIG_DELAYED_MIC_ERROR_REPORT=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# For BSD, uncomment these.
#LIBS += -lexecinfo
#LIBS_p += -lexecinfo
#LIBS_c += -lexecinfo
# Use libbfd to get more details for developer debugging
# This enables use of libbfd to get more detailed symbols for the backtraces
# generated by CONFIG_WPA_TRACE=y.
#CONFIG_WPA_TRACE_BFD=y
# For BSD, uncomment these.
#LIBS += -lbfd -liberty -lz
#LIBS_p += -lbfd -liberty -lz
#LIBS_c += -lbfd -liberty -lz
# wpa_supplicant depends on strong random number generation being available
# from the operating system. os_get_random() function is used to fetch random
# data when needed, e.g., for key generation. On Linux and BSD systems, this
# works by reading /dev/urandom. It should be noted that the OS entropy pool
# needs to be properly initialized before wpa_supplicant is started. This is
# important especially on embedded devices that do not have a hardware random
# number generator and may by default start up with minimal entropy available
# for random number generation.
#
# As a safety net, wpa_supplicant is by default trying to internally collect
# additional entropy for generating random data to mix in with the data fetched
# from the OS. This by itself is not considered to be very strong, but it may
# help in cases where the system pool is not initialized properly. However, it
# is very strongly recommended that the system pool is initialized with enough
# entropy either by using hardware assisted random number generator or by
# storing state over device reboots.
#
# wpa_supplicant can be configured to maintain its own entropy store over
# restarts to enhance random number generation. This is not perfect, but it is
# much more secure than using the same sequence of random numbers after every
# reboot. This can be enabled with -e<entropy file> command line option. The
# specified file needs to be readable and writable by wpa_supplicant.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal wpa_supplicant random pool can be
# disabled. This will save some in binary size and CPU use. However, this
# should only be considered for builds that are known to be used on devices
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
#CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
# (depends on CONFIG_IEEE80211N)
#CONFIG_IEEE80211AC=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
#CONFIG_WNM=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks (GAS/ANQP to learn more about the networks and network
# selection based on available credentials).
#CONFIG_INTERWORKING=y
# Hotspot 2.0
#CONFIG_HS20=y
# Enable interface matching in wpa_supplicant
#CONFIG_MATCH_IFACE=y
# Disable roaming in wpa_supplicant
#CONFIG_NO_ROAMING=y
# AP mode operations with wpa_supplicant
# This can be used for controlling AP mode operations with wpa_supplicant. It
# should be noted that this is mainly aimed at simple cases like
# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
# external RADIUS server can be supported with hostapd.
#CONFIG_AP=y
# P2P (Wi-Fi Direct)
# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
# more information on P2P operations.
#CONFIG_P2P=y
# Enable TDLS support
#CONFIG_TDLS=y
# Wi-Fi Display
# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
# Autoscan
# This can be used to enable automatic scan support in wpa_supplicant.
# See wpa_supplicant.conf for more information on autoscan usage.
#
# Enabling directly a module will enable autoscan support.
# For exponential module:
#CONFIG_AUTOSCAN_EXPONENTIAL=y
# For periodic module:
#CONFIG_AUTOSCAN_PERIODIC=y
# Password (and passphrase, etc.) backend for external storage
# These optional mechanisms can be used to add support for storing passwords
# and other secrets in external (to wpa_supplicant) location. This allows, for
# example, operating system specific key storage to be used
#
# External password backend for testing purposes (developer use)
#CONFIG_EXT_PASSWORD_TEST=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# OS X builds. This is only for building eapol_test.
#CONFIG_OSX=y
# Automatic Channel Selection
# This will allow wpa_supplicant to pick the channel automatically when channel
# is set to "0".
#
# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative
# to "channel=0". This would enable us to eventually add other ACS algorithms in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with
# a newly to create wpa_supplicant.conf variable acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#CONFIG_ACS=y
# Support Multi Band Operation
#CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Support RSN on IBSS networks
# This is needed to be able to use mode=1 network profile with proto=RSN and
# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
#CONFIG_IBSS_RSN=y
# External PMKSA cache control
# This can be used to enable control interface commands that allow the current
# PMKSA cache entries to be fetched and new entries to be added.
#CONFIG_PMKSA_CACHE_EXTERNAL=y
# Mesh Networking (IEEE 802.11s)
#CONFIG_MESH=y
# Background scanning modules
# These can be used to request wpa_supplicant to perform background scanning
# operations for roaming within an ESS (same SSID). See the bgscan parameter in
# the wpa_supplicant.conf file for more details.
# Periodic background scans based on signal strength
#CONFIG_BGSCAN_SIMPLE=y
# Learn channels used by the network and try to avoid bgscans on other
# channels (experimental)
#CONFIG_BGSCAN_LEARN=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Device Provisioning Protocol (DPP)
# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
# wpa_supplicant/README-DPP for details)
#CONFIG_DPP=y
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
#CONFIG_CTRL_IFACE_MIB=y

View File

@@ -1,599 +0,0 @@
# Example wpa_supplicant build time configuration
#
# This file lists the configuration options that are used when building the
# wpa_supplicant binary. All lines starting with # are ignored. Configuration
# option lines must be commented out complete, if they are not to be included,
# i.e., just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cases, these lines should use += in order not
# to override previous values of the variables.
# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
# the kerberos files are not in the default include path. Following line can be
# used to fix build issues on such systems (krb5.h not found).
#CFLAGS += -I/usr/include/kerberos
# Driver interface for generic Linux wireless extensions
# Note: WEXT is deprecated in the current Linux kernel version and no new
# functionality is added to it. nl80211-based interface is the new
# replacement for WEXT and its use allows wpa_supplicant to properly control
# the driver to improve existing functionality like roaming and to support new
# functionality.
CONFIG_DRIVER_WEXT=y
# Driver interface for Linux drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# For native build using mingw
#CONFIG_NATIVE_WINDOWS=y
# Additional directories for cross-compilation on Linux host for mingw target
#CFLAGS += -I/opt/mingw/mingw32/include/ddk
#LIBS += -L/opt/mingw/mingw32/lib
#CC=mingw32-gcc
# By default, driver_ndis uses WinPcap for low-level operations. This can be
# replaced with the following option which replaces WinPcap calls with NDISUIO.
# However, this requires that WZC is disabled (net stop wzcsvc) before starting
# wpa_supplicant.
# CONFIG_USE_NDISUIO=y
# Driver interface for wired Ethernet drivers
CONFIG_DRIVER_WIRED=y
# Driver interface for MACsec capable Qualcomm Atheros drivers
#CONFIG_DRIVER_MACSEC_QCA=y
# Driver interface for Linux MACsec drivers
#CONFIG_DRIVER_MACSEC_LINUX=y
# Driver interface for the Broadcom RoboSwitch family
#CONFIG_DRIVER_ROBOSWITCH=y
# Driver interface for no driver (e.g., WPS ER only)
#CONFIG_DRIVER_NONE=y
# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
# MACsec is included)
CONFIG_IEEE8021X_EAPOL=y
# EAP-MD5
CONFIG_EAP_MD5=y
# EAP-MSCHAPv2
CONFIG_EAP_MSCHAPV2=y
# EAP-TLS
CONFIG_EAP_TLS=y
# EAL-PEAP
CONFIG_EAP_PEAP=y
# EAP-TTLS
CONFIG_EAP_TTLS=y
# EAP-FAST
CONFIG_EAP_FAST=y
# EAP-TEAP
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# EAP-GTC
CONFIG_EAP_GTC=y
# EAP-OTP
CONFIG_EAP_OTP=y
# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
#CONFIG_EAP_SIM=y
# Enable SIM simulator (Milenage) for EAP-SIM
#CONFIG_SIM_SIMULATOR=y
# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd (secure authentication using only a password)
#CONFIG_EAP_PWD=y
# EAP-PAX
#CONFIG_EAP_PAX=y
# LEAP
CONFIG_EAP_LEAP=y
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
#CONFIG_EAP_AKA=y
# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# Enable USIM simulator (Milenage) for EAP-AKA
#CONFIG_USIM_SIMULATOR=y
# EAP-SAKE
#CONFIG_EAP_SAKE=y
# EAP-GPSK
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-TNC and related Trusted Network Connect support (experimental)
#CONFIG_EAP_TNC=y
# Wi-Fi Protected Setup (WPS)
CONFIG_WPS=y
# Enable WPS external registrar functionality
#CONFIG_WPS_ER=y
# Disable credentials for an open network by default when acting as a WPS
# registrar.
#CONFIG_WPS_REG_DISABLE_OPEN=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# EAP-EKE
#CONFIG_EAP_EKE=y
# MACsec
#CONFIG_MACSEC=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
# engine.
CONFIG_SMARTCARD=y
# PC/SC interface for smartcards (USIM, GSM SIM)
# Enable this if EAP-SIM or EAP-AKA is included
#CONFIG_PCSC=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
CONFIG_HT_OVERRIDES=y
# Support VHT overrides (disable VHT, mask MCS rates, etc.)
CONFIG_VHT_OVERRIDES=y
# Development testing
#CONFIG_EAPOL_TEST=y
# Select control interface backend for external programs, e.g, wpa_cli:
# unix = UNIX domain sockets (default for Linux/*BSD)
# udp = UDP sockets using localhost (127.0.0.1)
# udp6 = UDP IPv6 sockets using localhost (::1)
# named_pipe = Windows Named Pipe (default for Windows)
# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
# y = use default (backwards compatibility)
# If this option is commented out, control interface is not included in the
# build.
CONFIG_CTRL_IFACE=y
# Include support for GNU Readline and History Libraries in wpa_cli.
# When building a wpa_cli binary for distribution, please note that these
# libraries are licensed under GPL and as such, BSD license may not apply for
# the resulting binary.
#CONFIG_READLINE=y
# Include internal line edit mode in wpa_cli. This can be used as a replacement
# for GNU Readline to provide limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Remove debugging code that is printing out debug message to stdout.
# This can be used to reduce the size of the wpa_supplicant considerably
# if debugging code is not needed. The size reduction can be around 35%
# (e.g., 90 kB).
#CONFIG_NO_STDOUT_DEBUG=y
# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
# 35-50 kB in code size.
#CONFIG_NO_WPA=y
# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
# This option can be used to reduce code size by removing support for
# converting ASCII passphrases into PSK. If this functionality is removed, the
# PSK can only be configured as the 64-octet hexstring (e.g., from
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
# Select configuration backend:
# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
# path is given on command line, not here; this option is just used to
# select the backend that allows configuration files to be used)
# winreg = Windows registry (see win_example.reg for an example)
CONFIG_BACKEND=file
# Remove configuration write functionality (i.e., to allow the configuration
# file to be updated based on runtime configuration changes). The runtime
# configuration can still be changed, the changes are just not going to be
# persistent over restarts. This option can be used to reduce code size by
# about 3.5 kB.
#CONFIG_NO_CONFIG_WRITE=y
# Remove support for configuration blobs to reduce code size by about 1.5 kB.
#CONFIG_NO_CONFIG_BLOBS=y
# Select program entry point implementation:
# main = UNIX/POSIX like main() function (default)
# main_winsvc = Windows service (read parameters from registry)
# main_none = Very basic example (development use only)
#CONFIG_MAIN=main
# Select wrapper for operating system and C library specific functions
# unix = UNIX/POSIX like systems (default)
# win32 = Windows systems
# none = Empty template
#CONFIG_OS=unix
# Select event loop implementation
# eloop = select() loop (default)
# eloop_win = Windows events and WaitForMultipleObject() loop
#CONFIG_ELOOP=eloop
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select layer 2 packet implementation
# linux = Linux packet socket (default)
# pcap = libpcap/libdnet/WinPcap
# freebsd = FreeBSD libpcap
# winpcap = WinPcap with receive thread
# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
# none = Empty template
#CONFIG_L2_PACKET=linux
# Disable Linux packet socket workaround applicable for station interface
# in a bridge for EAPOL frames. This should be uncommented only if the kernel
# is known to not have the regression issue in packet socket behavior with
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
CONFIG_PEERKEY=y
# IEEE 802.11w (management frame protection), also known as PMF
# Driver support is also needed for IEEE 802.11w.
CONFIG_IEEE80211W=y
# Support Operating Channel Validation
CONFIG_OCV=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used. It should be noted that some existing TLS v1.0 -based
# implementation may not be compatible with TLS v1.1 message (ClientHello is
# sent prior to negotiating which version will be used)
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms. It should be
# noted that some existing TLS v1.0 -based implementation may not be compatible
# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
# will be used)
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
CONFIG_INTERNAL_LIBTOMMATH=y
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
# This is only for Windows builds and requires WMI-related header files and
# WbemUuid.Lib from Platform SDK even when building with MinGW.
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
#CONFIG_CTRL_IFACE_DBUS_INTRO=y
# Add support for loading EAP methods dynamically as shared libraries.
# When this option is enabled, each EAP method can be either included
# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
# be loaded in the beginning of the wpa_supplicant configuration file
# (see load_dynamic_eap parameter in the example file) before being used in
# the network blocks.
#
# Note that some shared parts of EAP methods are included in the main program
# and in order to be able to use dynamic EAP methods using these parts, the
# main program must have been build with the EAP method enabled (=y or =dyn).
# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
# unless at least one of them was included in the main build to force inclusion
# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
# in the main build to be able to load these methods dynamically.
#
# Please also note that using dynamic libraries will increase the total binary
# size. Thus, it may not be the best option for targets that have limited
# amount of memory/flash.
#CONFIG_DYNAMIC_EAP_METHODS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
CONFIG_IEEE80211R=y
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Set syslog facility for debug messages
CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Add support for writing debug log to Android logcat instead of standard
# output
#CONFIG_ANDROID_LOG=y
# Enable privilege separation (see README 'Privilege separation' for details)
#CONFIG_PRIVSEP=y
# Enable mitigation against certain attacks against TKIP by delaying Michael
# MIC error reports by a random amount of time between 0 and 60 seconds
#CONFIG_DELAYED_MIC_ERROR_REPORT=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# wpa_supplicant depends on strong random number generation being available
# from the operating system. os_get_random() function is used to fetch random
# data when needed, e.g., for key generation. On Linux and BSD systems, this
# works by reading /dev/urandom. It should be noted that the OS entropy pool
# needs to be properly initialized before wpa_supplicant is started. This is
# important especially on embedded devices that do not have a hardware random
# number generator and may by default start up with minimal entropy available
# for random number generation.
#
# As a safety net, wpa_supplicant is by default trying to internally collect
# additional entropy for generating random data to mix in with the data fetched
# from the OS. This by itself is not considered to be very strong, but it may
# help in cases where the system pool is not initialized properly. However, it
# is very strongly recommended that the system pool is initialized with enough
# entropy either by using hardware assisted random number generator or by
# storing state over device reboots.
#
# wpa_supplicant can be configured to maintain its own entropy store over
# restarts to enhance random number generation. This is not perfect, but it is
# much more secure than using the same sequence of random numbers after every
# reboot. This can be enabled with -e<entropy file> command line option. The
# specified file needs to be readable and writable by wpa_supplicant.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal wpa_supplicant random pool can be
# disabled. This will save some in binary size and CPU use. However, this
# should only be considered for builds that are known to be used on devices
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
# (depends on CONFIG_IEEE80211N)
CONFIG_IEEE80211AC=y
# IEEE 802.11ax (HE Throughput) support
CONFIG_IEEE80211AX=y
# IEEE 802.11be (EHT Throughput) support
CONFIG_IEEE80211BE=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
CONFIG_WNM=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks (GAS/ANQP to learn more about the networks and network
# selection based on available credentials).
CONFIG_INTERWORKING=y
# Hotspot 2.0
CONFIG_HS20=y
# Enable interface matching in wpa_supplicant
#CONFIG_MATCH_IFACE=y
# Disable roaming in wpa_supplicant
#CONFIG_NO_ROAMING=y
# AP mode operations with wpa_supplicant
# This can be used for controlling AP mode operations with wpa_supplicant. It
# should be noted that this is mainly aimed at simple cases like
# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
# external RADIUS server can be supported with hostapd.
CONFIG_AP=y
# P2P (Wi-Fi Direct)
# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
# more information on P2P operations.
#CONFIG_P2P=y
# Enable TDLS support
CONFIG_TDLS=y
# Wi-Fi Display
# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
# Autoscan
# This can be used to enable automatic scan support in wpa_supplicant.
# See wpa_supplicant.conf for more information on autoscan usage.
#
# Enabling directly a module will enable autoscan support.
# For exponential module:
#CONFIG_AUTOSCAN_EXPONENTIAL=y
# For periodic module:
#CONFIG_AUTOSCAN_PERIODIC=y
# Password (and passphrase, etc.) backend for external storage
# These optional mechanisms can be used to add support for storing passwords
# and other secrets in external (to wpa_supplicant) location. This allows, for
# example, operating system specific key storage to be used
#
# External password backend for testing purposes (developer use)
#CONFIG_EXT_PASSWORD_TEST=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# OS X builds. This is only for building eapol_test.
#CONFIG_OSX=y
# Automatic Channel Selection
# This will allow wpa_supplicant to pick the channel automatically when channel
# is set to "0".
#
# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative
# to "channel=0". This would enable us to eventually add other ACS algorithms in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with
# a newly to create wpa_supplicant.conf variable acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
CONFIG_ACS=y
# Support Multi Band Operation
CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Support RSN on IBSS networks
# This is needed to be able to use mode=1 network profile with proto=RSN and
# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
CONFIG_IBSS_RSN=y
# External PMKSA cache control
# This can be used to enable control interface commands that allow the current
# PMKSA cache entries to be fetched and new entries to be added.
#CONFIG_PMKSA_CACHE_EXTERNAL=y
# Mesh Networking (IEEE 802.11s)
CONFIG_MESH=y
# Background scanning modules
# These can be used to request wpa_supplicant to perform background scanning
# operations for roaming within an ESS (same SSID). See the bgscan parameter in
# the wpa_supplicant.conf file for more details.
# Periodic background scans based on signal strength
#CONFIG_BGSCAN_SIMPLE=y
# Learn channels used by the network and try to avoid bgscans on other
# channels (experimental)
#CONFIG_BGSCAN_LEARN=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Device Provisioning Protocol (DPP)
# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
# wpa_supplicant/README-DPP for details)
#CONFIG_DPP=y
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
CONFIG_CTRL_IFACE_MIB=y
NEED_80211_COMMON=y
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
CONFIG_SAE=y
CONFIG_LIBNL32=y
CONFIG_LIBNL3_ROUTE=y
CONFIG_LIBNL32=y
CONFIG_LIBNL3_ROUTE=y
CONFIG_BUILD_WPA_CLIENT_SO=y
NEED_DH_GROUPS_ALL=y
CONFIG_DPP=y
CONFIG_DPP2=y
CONFIG_DPP3=y

View File

@@ -1,631 +0,0 @@
# Example wpa_supplicant build time configuration
#
# This file lists the configuration options that are used when building the
# wpa_supplicant binary. All lines starting with # are ignored. Configuration
# option lines must be commented out complete, if they are not to be included,
# i.e., just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cases, these lines should use += in order not
# to override previous values of the variables.
# Uncomment following two lines and fix the paths if you have installed OpenSSL
# or GnuTLS in non-default location
#CFLAGS += -I/usr/local/openssl/include
#LIBS += -L/usr/local/openssl/lib
# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
# the kerberos files are not in the default include path. Following line can be
# used to fix build issues on such systems (krb5.h not found).
#CFLAGS += -I/usr/include/kerberos
# Driver interface for generic Linux wireless extensions
# Note: WEXT is deprecated in the current Linux kernel version and no new
# functionality is added to it. nl80211-based interface is the new
# replacement for WEXT and its use allows wpa_supplicant to properly control
# the driver to improve existing functionality like roaming and to support new
# functionality.
CONFIG_DRIVER_WEXT=y
# Driver interface for Linux drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
#LIBS += -L$<path to libnl library files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
#LIBS_p += -L/usr/local/lib
#LIBS_c += -L/usr/local/lib
# Driver interface for Windows NDIS
#CONFIG_DRIVER_NDIS=y
#CFLAGS += -I/usr/include/w32api/ddk
#LIBS += -L/usr/local/lib
# For native build using mingw
#CONFIG_NATIVE_WINDOWS=y
# Additional directories for cross-compilation on Linux host for mingw target
#CFLAGS += -I/opt/mingw/mingw32/include/ddk
#LIBS += -L/opt/mingw/mingw32/lib
#CC=mingw32-gcc
# By default, driver_ndis uses WinPcap for low-level operations. This can be
# replaced with the following option which replaces WinPcap calls with NDISUIO.
# However, this requires that WZC is disabled (net stop wzcsvc) before starting
# wpa_supplicant.
# CONFIG_USE_NDISUIO=y
# Driver interface for wired Ethernet drivers
CONFIG_DRIVER_WIRED=y
# Driver interface for MACsec capable Qualcomm Atheros drivers
#CONFIG_DRIVER_MACSEC_QCA=y
# Driver interface for Linux MACsec drivers
#CONFIG_DRIVER_MACSEC_LINUX=y
# Driver interface for the Broadcom RoboSwitch family
#CONFIG_DRIVER_ROBOSWITCH=y
# Driver interface for no driver (e.g., WPS ER only)
#CONFIG_DRIVER_NONE=y
# Solaris libraries
#LIBS += -lsocket -ldlpi -lnsl
#LIBS_c += -lsocket
# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
# MACsec is included)
CONFIG_IEEE8021X_EAPOL=y
# EAP-MD5
CONFIG_EAP_MD5=y
# EAP-MSCHAPv2
CONFIG_EAP_MSCHAPV2=y
# EAP-TLS
CONFIG_EAP_TLS=y
# EAL-PEAP
CONFIG_EAP_PEAP=y
# EAP-TTLS
CONFIG_EAP_TTLS=y
# EAP-FAST
CONFIG_EAP_FAST=y
# EAP-TEAP
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# EAP-GTC
CONFIG_EAP_GTC=y
# EAP-OTP
CONFIG_EAP_OTP=y
# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
#CONFIG_EAP_SIM=y
# Enable SIM simulator (Milenage) for EAP-SIM
#CONFIG_SIM_SIMULATOR=y
# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd (secure authentication using only a password)
#CONFIG_EAP_PWD=y
# EAP-PAX
#CONFIG_EAP_PAX=y
# LEAP
CONFIG_EAP_LEAP=y
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
#CONFIG_EAP_AKA=y
# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# Enable USIM simulator (Milenage) for EAP-AKA
#CONFIG_USIM_SIMULATOR=y
# EAP-SAKE
#CONFIG_EAP_SAKE=y
# EAP-GPSK
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-TNC and related Trusted Network Connect support (experimental)
#CONFIG_EAP_TNC=y
# Wi-Fi Protected Setup (WPS)
CONFIG_WPS=y
# Enable WPS external registrar functionality
#CONFIG_WPS_ER=y
# Disable credentials for an open network by default when acting as a WPS
# registrar.
#CONFIG_WPS_REG_DISABLE_OPEN=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# EAP-EKE
#CONFIG_EAP_EKE=y
# MACsec
#CONFIG_MACSEC=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
# engine.
CONFIG_SMARTCARD=y
# PC/SC interface for smartcards (USIM, GSM SIM)
# Enable this if EAP-SIM or EAP-AKA is included
#CONFIG_PCSC=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
CONFIG_HT_OVERRIDES=y
# Support VHT overrides (disable VHT, mask MCS rates, etc.)
CONFIG_VHT_OVERRIDES=y
# Development testing
#CONFIG_EAPOL_TEST=y
# Select control interface backend for external programs, e.g, wpa_cli:
# unix = UNIX domain sockets (default for Linux/*BSD)
# udp = UDP sockets using localhost (127.0.0.1)
# udp6 = UDP IPv6 sockets using localhost (::1)
# named_pipe = Windows Named Pipe (default for Windows)
# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
# y = use default (backwards compatibility)
# If this option is commented out, control interface is not included in the
# build.
CONFIG_CTRL_IFACE=y
# Include support for GNU Readline and History Libraries in wpa_cli.
# When building a wpa_cli binary for distribution, please note that these
# libraries are licensed under GPL and as such, BSD license may not apply for
# the resulting binary.
#CONFIG_READLINE=y
# Include internal line edit mode in wpa_cli. This can be used as a replacement
# for GNU Readline to provide limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Remove debugging code that is printing out debug message to stdout.
# This can be used to reduce the size of the wpa_supplicant considerably
# if debugging code is not needed. The size reduction can be around 35%
# (e.g., 90 kB).
#CONFIG_NO_STDOUT_DEBUG=y
# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
# 35-50 kB in code size.
#CONFIG_NO_WPA=y
# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
# This option can be used to reduce code size by removing support for
# converting ASCII passphrases into PSK. If this functionality is removed, the
# PSK can only be configured as the 64-octet hexstring (e.g., from
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
#CONFIG_SAE=y
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
# Select configuration backend:
# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
# path is given on command line, not here; this option is just used to
# select the backend that allows configuration files to be used)
# winreg = Windows registry (see win_example.reg for an example)
CONFIG_BACKEND=file
# Remove configuration write functionality (i.e., to allow the configuration
# file to be updated based on runtime configuration changes). The runtime
# configuration can still be changed, the changes are just not going to be
# persistent over restarts. This option can be used to reduce code size by
# about 3.5 kB.
#CONFIG_NO_CONFIG_WRITE=y
# Remove support for configuration blobs to reduce code size by about 1.5 kB.
#CONFIG_NO_CONFIG_BLOBS=y
# Select program entry point implementation:
# main = UNIX/POSIX like main() function (default)
# main_winsvc = Windows service (read parameters from registry)
# main_none = Very basic example (development use only)
#CONFIG_MAIN=main
# Select wrapper for operating system and C library specific functions
# unix = UNIX/POSIX like systems (default)
# win32 = Windows systems
# none = Empty template
#CONFIG_OS=unix
# Select event loop implementation
# eloop = select() loop (default)
# eloop_win = Windows events and WaitForMultipleObject() loop
#CONFIG_ELOOP=eloop
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select layer 2 packet implementation
# linux = Linux packet socket (default)
# pcap = libpcap/libdnet/WinPcap
# freebsd = FreeBSD libpcap
# winpcap = WinPcap with receive thread
# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
# none = Empty template
#CONFIG_L2_PACKET=linux
# Disable Linux packet socket workaround applicable for station interface
# in a bridge for EAPOL frames. This should be uncommented only if the kernel
# is known to not have the regression issue in packet socket behavior with
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
# IEEE 802.11w (management frame protection), also known as PMF
# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
# Support Operating Channel Validation
CONFIG_OCV=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used. It should be noted that some existing TLS v1.0 -based
# implementation may not be compatible with TLS v1.1 message (ClientHello is
# sent prior to negotiating which version will be used)
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms. It should be
# noted that some existing TLS v1.0 -based implementation may not be compatible
# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
# will be used)
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
CONFIG_INTERNAL_LIBTOMMATH=y
#ifndef CONFIG_INTERNAL_LIBTOMMATH
#LTM_PATH=/usr/src/libtommath-0.39
#CFLAGS += -I$(LTM_PATH)
#LIBS += -L$(LTM_PATH)
#LIBS_p += -L$(LTM_PATH)
#endif
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
# This is only for Windows builds and requires WMI-related header files and
# WbemUuid.Lib from Platform SDK even when building with MinGW.
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
#CONFIG_CTRL_IFACE_DBUS_INTRO=y
# Add support for loading EAP methods dynamically as shared libraries.
# When this option is enabled, each EAP method can be either included
# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
# be loaded in the beginning of the wpa_supplicant configuration file
# (see load_dynamic_eap parameter in the example file) before being used in
# the network blocks.
#
# Note that some shared parts of EAP methods are included in the main program
# and in order to be able to use dynamic EAP methods using these parts, the
# main program must have been build with the EAP method enabled (=y or =dyn).
# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
# unless at least one of them was included in the main build to force inclusion
# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
# in the main build to be able to load these methods dynamically.
#
# Please also note that using dynamic libraries will increase the total binary
# size. Thus, it may not be the best option for targets that have limited
# amount of memory/flash.
#CONFIG_DYNAMIC_EAP_METHODS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
CONFIG_IEEE80211R=y
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Set syslog facility for debug messages
CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Add support for writing debug log to Android logcat instead of standard
# output
#CONFIG_ANDROID_LOG=y
# Enable privilege separation (see README 'Privilege separation' for details)
#CONFIG_PRIVSEP=y
# Enable mitigation against certain attacks against TKIP by delaying Michael
# MIC error reports by a random amount of time between 0 and 60 seconds
#CONFIG_DELAYED_MIC_ERROR_REPORT=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# For BSD, uncomment these.
#LIBS += -lexecinfo
#LIBS_p += -lexecinfo
#LIBS_c += -lexecinfo
# Use libbfd to get more details for developer debugging
# This enables use of libbfd to get more detailed symbols for the backtraces
# generated by CONFIG_WPA_TRACE=y.
#CONFIG_WPA_TRACE_BFD=y
# For BSD, uncomment these.
#LIBS += -lbfd -liberty -lz
#LIBS_p += -lbfd -liberty -lz
#LIBS_c += -lbfd -liberty -lz
# wpa_supplicant depends on strong random number generation being available
# from the operating system. os_get_random() function is used to fetch random
# data when needed, e.g., for key generation. On Linux and BSD systems, this
# works by reading /dev/urandom. It should be noted that the OS entropy pool
# needs to be properly initialized before wpa_supplicant is started. This is
# important especially on embedded devices that do not have a hardware random
# number generator and may by default start up with minimal entropy available
# for random number generation.
#
# As a safety net, wpa_supplicant is by default trying to internally collect
# additional entropy for generating random data to mix in with the data fetched
# from the OS. This by itself is not considered to be very strong, but it may
# help in cases where the system pool is not initialized properly. However, it
# is very strongly recommended that the system pool is initialized with enough
# entropy either by using hardware assisted random number generator or by
# storing state over device reboots.
#
# wpa_supplicant can be configured to maintain its own entropy store over
# restarts to enhance random number generation. This is not perfect, but it is
# much more secure than using the same sequence of random numbers after every
# reboot. This can be enabled with -e<entropy file> command line option. The
# specified file needs to be readable and writable by wpa_supplicant.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal wpa_supplicant random pool can be
# disabled. This will save some in binary size and CPU use. However, this
# should only be considered for builds that are known to be used on devices
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
# (depends on CONFIG_IEEE80211N)
CONFIG_IEEE80211AC=y
# IEEE 802.11ax (HE Throughput) support
CONFIG_IEEE80211AX=y
# IEEE 802.11be (EHT Throughput) support
CONFIG_IEEE80211BE=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
CONFIG_WNM=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks (GAS/ANQP to learn more about the networks and network
# selection based on available credentials).
CONFIG_INTERWORKING=y
# Hotspot 2.0
CONFIG_HS20=y
# Enable interface matching in wpa_supplicant
#CONFIG_MATCH_IFACE=y
# Disable roaming in wpa_supplicant
#CONFIG_NO_ROAMING=y
# AP mode operations with wpa_supplicant
# This can be used for controlling AP mode operations with wpa_supplicant. It
# should be noted that this is mainly aimed at simple cases like
# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
# external RADIUS server can be supported with hostapd.
#CONFIG_AP=y
# P2P (Wi-Fi Direct)
# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
# more information on P2P operations.
#CONFIG_P2P=y
# Enable TDLS support
#CONFIG_TDLS=y
# Wi-Fi Display
# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
# Autoscan
# This can be used to enable automatic scan support in wpa_supplicant.
# See wpa_supplicant.conf for more information on autoscan usage.
#
# Enabling directly a module will enable autoscan support.
# For exponential module:
#CONFIG_AUTOSCAN_EXPONENTIAL=y
# For periodic module:
#CONFIG_AUTOSCAN_PERIODIC=y
# Password (and passphrase, etc.) backend for external storage
# These optional mechanisms can be used to add support for storing passwords
# and other secrets in external (to wpa_supplicant) location. This allows, for
# example, operating system specific key storage to be used
#
# External password backend for testing purposes (developer use)
#CONFIG_EXT_PASSWORD_TEST=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# OS X builds. This is only for building eapol_test.
#CONFIG_OSX=y
# Automatic Channel Selection
# This will allow wpa_supplicant to pick the channel automatically when channel
# is set to "0".
#
# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative
# to "channel=0". This would enable us to eventually add other ACS algorithms in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with
# a newly to create wpa_supplicant.conf variable acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#CONFIG_ACS=y
# Support Multi Band Operation
CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Support RSN on IBSS networks
# This is needed to be able to use mode=1 network profile with proto=RSN and
# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
CONFIG_IBSS_RSN=y
# External PMKSA cache control
# This can be used to enable control interface commands that allow the current
# PMKSA cache entries to be fetched and new entries to be added.
#CONFIG_PMKSA_CACHE_EXTERNAL=y
# Mesh Networking (IEEE 802.11s)
#CONFIG_MESH=y
# Background scanning modules
# These can be used to request wpa_supplicant to perform background scanning
# operations for roaming within an ESS (same SSID). See the bgscan parameter in
# the wpa_supplicant.conf file for more details.
# Periodic background scans based on signal strength
#CONFIG_BGSCAN_SIMPLE=y
# Learn channels used by the network and try to avoid bgscans on other
# channels (experimental)
#CONFIG_BGSCAN_LEARN=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Device Provisioning Protocol (DPP)
# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
# wpa_supplicant/README-DPP for details)
#CONFIG_DPP=y
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
CONFIG_CTRL_IFACE_MIB=y

View File

@@ -1,625 +0,0 @@
# Example wpa_supplicant build time configuration
#
# This file lists the configuration options that are used when building the
# wpa_supplicant binary. All lines starting with # are ignored. Configuration
# option lines must be commented out complete, if they are not to be included,
# i.e., just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cases, these lines should use += in order not
# to override previous values of the variables.
# Uncomment following two lines and fix the paths if you have installed OpenSSL
# or GnuTLS in non-default location
#CFLAGS += -I/usr/local/openssl/include
#LIBS += -L/usr/local/openssl/lib
# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
# the kerberos files are not in the default include path. Following line can be
# used to fix build issues on such systems (krb5.h not found).
#CFLAGS += -I/usr/include/kerberos
# Driver interface for generic Linux wireless extensions
# Note: WEXT is deprecated in the current Linux kernel version and no new
# functionality is added to it. nl80211-based interface is the new
# replacement for WEXT and its use allows wpa_supplicant to properly control
# the driver to improve existing functionality like roaming and to support new
# functionality.
CONFIG_DRIVER_WEXT=y
# Driver interface for Linux drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
#LIBS += -L$<path to libnl library files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
#LIBS_p += -L/usr/local/lib
#LIBS_c += -L/usr/local/lib
# Driver interface for Windows NDIS
#CONFIG_DRIVER_NDIS=y
#CFLAGS += -I/usr/include/w32api/ddk
#LIBS += -L/usr/local/lib
# For native build using mingw
#CONFIG_NATIVE_WINDOWS=y
# Additional directories for cross-compilation on Linux host for mingw target
#CFLAGS += -I/opt/mingw/mingw32/include/ddk
#LIBS += -L/opt/mingw/mingw32/lib
#CC=mingw32-gcc
# By default, driver_ndis uses WinPcap for low-level operations. This can be
# replaced with the following option which replaces WinPcap calls with NDISUIO.
# However, this requires that WZC is disabled (net stop wzcsvc) before starting
# wpa_supplicant.
# CONFIG_USE_NDISUIO=y
# Driver interface for wired Ethernet drivers
CONFIG_DRIVER_WIRED=y
# Driver interface for MACsec capable Qualcomm Atheros drivers
#CONFIG_DRIVER_MACSEC_QCA=y
# Driver interface for Linux MACsec drivers
#CONFIG_DRIVER_MACSEC_LINUX=y
# Driver interface for the Broadcom RoboSwitch family
#CONFIG_DRIVER_ROBOSWITCH=y
# Driver interface for no driver (e.g., WPS ER only)
#CONFIG_DRIVER_NONE=y
# Solaris libraries
#LIBS += -lsocket -ldlpi -lnsl
#LIBS_c += -lsocket
# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
# MACsec is included)
#CONFIG_IEEE8021X_EAPOL=y
# EAP-MD5
#CONFIG_EAP_MD5=y
# EAP-MSCHAPv2
#CONFIG_EAP_MSCHAPV2=y
# EAP-TLS
#CONFIG_EAP_TLS=y
# EAL-PEAP
#CONFIG_EAP_PEAP=y
# EAP-TTLS
#CONFIG_EAP_TTLS=y
# EAP-FAST
#CONFIG_EAP_FAST=y
# EAP-TEAP
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# EAP-GTC
#CONFIG_EAP_GTC=y
# EAP-OTP
#CONFIG_EAP_OTP=y
# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
#CONFIG_EAP_SIM=y
# Enable SIM simulator (Milenage) for EAP-SIM
#CONFIG_SIM_SIMULATOR=y
# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd (secure authentication using only a password)
#CONFIG_EAP_PWD=y
# EAP-PAX
#CONFIG_EAP_PAX=y
# LEAP
#CONFIG_EAP_LEAP=y
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
#CONFIG_EAP_AKA=y
# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# Enable USIM simulator (Milenage) for EAP-AKA
#CONFIG_USIM_SIMULATOR=y
# EAP-SAKE
#CONFIG_EAP_SAKE=y
# EAP-GPSK
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-TNC and related Trusted Network Connect support (experimental)
#CONFIG_EAP_TNC=y
# Wi-Fi Protected Setup (WPS)
#CONFIG_WPS=y
# Enable WPS external registrar functionality
#CONFIG_WPS_ER=y
# Disable credentials for an open network by default when acting as a WPS
# registrar.
#CONFIG_WPS_REG_DISABLE_OPEN=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# EAP-EKE
#CONFIG_EAP_EKE=y
# MACsec
#CONFIG_MACSEC=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
#CONFIG_PKCS12=y
# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
# engine.
#CONFIG_SMARTCARD=y
# PC/SC interface for smartcards (USIM, GSM SIM)
# Enable this if EAP-SIM or EAP-AKA is included
#CONFIG_PCSC=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
CONFIG_HT_OVERRIDES=y
# Support VHT overrides (disable VHT, mask MCS rates, etc.)
CONFIG_VHT_OVERRIDES=y
# Development testing
#CONFIG_EAPOL_TEST=y
# Select control interface backend for external programs, e.g, wpa_cli:
# unix = UNIX domain sockets (default for Linux/*BSD)
# udp = UDP sockets using localhost (127.0.0.1)
# udp6 = UDP IPv6 sockets using localhost (::1)
# named_pipe = Windows Named Pipe (default for Windows)
# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
# y = use default (backwards compatibility)
# If this option is commented out, control interface is not included in the
# build.
CONFIG_CTRL_IFACE=y
# Include support for GNU Readline and History Libraries in wpa_cli.
# When building a wpa_cli binary for distribution, please note that these
# libraries are licensed under GPL and as such, BSD license may not apply for
# the resulting binary.
#CONFIG_READLINE=y
# Include internal line edit mode in wpa_cli. This can be used as a replacement
# for GNU Readline to provide limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Remove debugging code that is printing out debug message to stdout.
# This can be used to reduce the size of the wpa_supplicant considerably
# if debugging code is not needed. The size reduction can be around 35%
# (e.g., 90 kB).
#CONFIG_NO_STDOUT_DEBUG=y
# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
# 35-50 kB in code size.
#CONFIG_NO_WPA=y
# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
# This option can be used to reduce code size by removing support for
# converting ASCII passphrases into PSK. If this functionality is removed, the
# PSK can only be configured as the 64-octet hexstring (e.g., from
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
#CONFIG_SAE=y
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
# Select configuration backend:
# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
# path is given on command line, not here; this option is just used to
# select the backend that allows configuration files to be used)
# winreg = Windows registry (see win_example.reg for an example)
CONFIG_BACKEND=file
# Remove configuration write functionality (i.e., to allow the configuration
# file to be updated based on runtime configuration changes). The runtime
# configuration can still be changed, the changes are just not going to be
# persistent over restarts. This option can be used to reduce code size by
# about 3.5 kB.
CONFIG_NO_CONFIG_WRITE=y
# Remove support for configuration blobs to reduce code size by about 1.5 kB.
#CONFIG_NO_CONFIG_BLOBS=y
# Select program entry point implementation:
# main = UNIX/POSIX like main() function (default)
# main_winsvc = Windows service (read parameters from registry)
# main_none = Very basic example (development use only)
#CONFIG_MAIN=main
# Select wrapper for operating system and C library specific functions
# unix = UNIX/POSIX like systems (default)
# win32 = Windows systems
# none = Empty template
#CONFIG_OS=unix
# Select event loop implementation
# eloop = select() loop (default)
# eloop_win = Windows events and WaitForMultipleObject() loop
#CONFIG_ELOOP=eloop
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select layer 2 packet implementation
# linux = Linux packet socket (default)
# pcap = libpcap/libdnet/WinPcap
# freebsd = FreeBSD libpcap
# winpcap = WinPcap with receive thread
# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
# none = Empty template
#CONFIG_L2_PACKET=linux
# Disable Linux packet socket workaround applicable for station interface
# in a bridge for EAPOL frames. This should be uncommented only if the kernel
# is known to not have the regression issue in packet socket behavior with
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
# IEEE 802.11w (management frame protection), also known as PMF
# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
# Support Operating Channel Validation
#CONFIG_OCV=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used. It should be noted that some existing TLS v1.0 -based
# implementation may not be compatible with TLS v1.1 message (ClientHello is
# sent prior to negotiating which version will be used)
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms. It should be
# noted that some existing TLS v1.0 -based implementation may not be compatible
# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
# will be used)
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
#CONFIG_INTERNAL_LIBTOMMATH=y
#ifndef CONFIG_INTERNAL_LIBTOMMATH
#LTM_PATH=/usr/src/libtommath-0.39
#CFLAGS += -I$(LTM_PATH)
#LIBS += -L$(LTM_PATH)
#LIBS_p += -L$(LTM_PATH)
#endif
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
# This is only for Windows builds and requires WMI-related header files and
# WbemUuid.Lib from Platform SDK even when building with MinGW.
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
#CONFIG_CTRL_IFACE_DBUS_INTRO=y
# Add support for loading EAP methods dynamically as shared libraries.
# When this option is enabled, each EAP method can be either included
# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
# be loaded in the beginning of the wpa_supplicant configuration file
# (see load_dynamic_eap parameter in the example file) before being used in
# the network blocks.
#
# Note that some shared parts of EAP methods are included in the main program
# and in order to be able to use dynamic EAP methods using these parts, the
# main program must have been build with the EAP method enabled (=y or =dyn).
# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
# unless at least one of them was included in the main build to force inclusion
# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
# in the main build to be able to load these methods dynamically.
#
# Please also note that using dynamic libraries will increase the total binary
# size. Thus, it may not be the best option for targets that have limited
# amount of memory/flash.
#CONFIG_DYNAMIC_EAP_METHODS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
#CONFIG_IEEE80211R=y
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
#CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Set syslog facility for debug messages
CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Add support for writing debug log to Android logcat instead of standard
# output
#CONFIG_ANDROID_LOG=y
# Enable privilege separation (see README 'Privilege separation' for details)
#CONFIG_PRIVSEP=y
# Enable mitigation against certain attacks against TKIP by delaying Michael
# MIC error reports by a random amount of time between 0 and 60 seconds
#CONFIG_DELAYED_MIC_ERROR_REPORT=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# For BSD, uncomment these.
#LIBS += -lexecinfo
#LIBS_p += -lexecinfo
#LIBS_c += -lexecinfo
# Use libbfd to get more details for developer debugging
# This enables use of libbfd to get more detailed symbols for the backtraces
# generated by CONFIG_WPA_TRACE=y.
#CONFIG_WPA_TRACE_BFD=y
# For BSD, uncomment these.
#LIBS += -lbfd -liberty -lz
#LIBS_p += -lbfd -liberty -lz
#LIBS_c += -lbfd -liberty -lz
# wpa_supplicant depends on strong random number generation being available
# from the operating system. os_get_random() function is used to fetch random
# data when needed, e.g., for key generation. On Linux and BSD systems, this
# works by reading /dev/urandom. It should be noted that the OS entropy pool
# needs to be properly initialized before wpa_supplicant is started. This is
# important especially on embedded devices that do not have a hardware random
# number generator and may by default start up with minimal entropy available
# for random number generation.
#
# As a safety net, wpa_supplicant is by default trying to internally collect
# additional entropy for generating random data to mix in with the data fetched
# from the OS. This by itself is not considered to be very strong, but it may
# help in cases where the system pool is not initialized properly. However, it
# is very strongly recommended that the system pool is initialized with enough
# entropy either by using hardware assisted random number generator or by
# storing state over device reboots.
#
# wpa_supplicant can be configured to maintain its own entropy store over
# restarts to enhance random number generation. This is not perfect, but it is
# much more secure than using the same sequence of random numbers after every
# reboot. This can be enabled with -e<entropy file> command line option. The
# specified file needs to be readable and writable by wpa_supplicant.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal wpa_supplicant random pool can be
# disabled. This will save some in binary size and CPU use. However, this
# should only be considered for builds that are known to be used on devices
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
#CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
# (depends on CONFIG_IEEE80211N)
#CONFIG_IEEE80211AC=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
#CONFIG_WNM=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks (GAS/ANQP to learn more about the networks and network
# selection based on available credentials).
#CONFIG_INTERWORKING=y
# Hotspot 2.0
#CONFIG_HS20=y
# Enable interface matching in wpa_supplicant
#CONFIG_MATCH_IFACE=y
# Disable roaming in wpa_supplicant
#CONFIG_NO_ROAMING=y
# AP mode operations with wpa_supplicant
# This can be used for controlling AP mode operations with wpa_supplicant. It
# should be noted that this is mainly aimed at simple cases like
# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
# external RADIUS server can be supported with hostapd.
#CONFIG_AP=y
# P2P (Wi-Fi Direct)
# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
# more information on P2P operations.
#CONFIG_P2P=y
# Enable TDLS support
#CONFIG_TDLS=y
# Wi-Fi Display
# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
# Autoscan
# This can be used to enable automatic scan support in wpa_supplicant.
# See wpa_supplicant.conf for more information on autoscan usage.
#
# Enabling directly a module will enable autoscan support.
# For exponential module:
#CONFIG_AUTOSCAN_EXPONENTIAL=y
# For periodic module:
#CONFIG_AUTOSCAN_PERIODIC=y
# Password (and passphrase, etc.) backend for external storage
# These optional mechanisms can be used to add support for storing passwords
# and other secrets in external (to wpa_supplicant) location. This allows, for
# example, operating system specific key storage to be used
#
# External password backend for testing purposes (developer use)
#CONFIG_EXT_PASSWORD_TEST=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# OS X builds. This is only for building eapol_test.
#CONFIG_OSX=y
# Automatic Channel Selection
# This will allow wpa_supplicant to pick the channel automatically when channel
# is set to "0".
#
# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative
# to "channel=0". This would enable us to eventually add other ACS algorithms in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with
# a newly to create wpa_supplicant.conf variable acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#CONFIG_ACS=y
# Support Multi Band Operation
#CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Support RSN on IBSS networks
# This is needed to be able to use mode=1 network profile with proto=RSN and
# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
#CONFIG_IBSS_RSN=y
# External PMKSA cache control
# This can be used to enable control interface commands that allow the current
# PMKSA cache entries to be fetched and new entries to be added.
#CONFIG_PMKSA_CACHE_EXTERNAL=y
# Mesh Networking (IEEE 802.11s)
#CONFIG_MESH=y
# Background scanning modules
# These can be used to request wpa_supplicant to perform background scanning
# operations for roaming within an ESS (same SSID). See the bgscan parameter in
# the wpa_supplicant.conf file for more details.
# Periodic background scans based on signal strength
#CONFIG_BGSCAN_SIMPLE=y
# Learn channels used by the network and try to avoid bgscans on other
# channels (experimental)
#CONFIG_BGSCAN_LEARN=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Device Provisioning Protocol (DPP)
# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
# wpa_supplicant/README-DPP for details)
#CONFIG_DPP=y
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
#CONFIG_CTRL_IFACE_MIB=y

View File

@@ -1,625 +0,0 @@
# Example wpa_supplicant build time configuration
#
# This file lists the configuration options that are used when building the
# wpa_supplicant binary. All lines starting with # are ignored. Configuration
# option lines must be commented out complete, if they are not to be included,
# i.e., just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cases, these lines should use += in order not
# to override previous values of the variables.
# Uncomment following two lines and fix the paths if you have installed OpenSSL
# or GnuTLS in non-default location
#CFLAGS += -I/usr/local/openssl/include
#LIBS += -L/usr/local/openssl/lib
# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
# the kerberos files are not in the default include path. Following line can be
# used to fix build issues on such systems (krb5.h not found).
#CFLAGS += -I/usr/include/kerberos
# Driver interface for generic Linux wireless extensions
# Note: WEXT is deprecated in the current Linux kernel version and no new
# functionality is added to it. nl80211-based interface is the new
# replacement for WEXT and its use allows wpa_supplicant to properly control
# the driver to improve existing functionality like roaming and to support new
# functionality.
CONFIG_DRIVER_WEXT=y
# Driver interface for Linux drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
# QCA vendor extensions to nl80211
#CONFIG_DRIVER_NL80211_QCA=y
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$<path to libnl include files>
#LIBS += -L$<path to libnl library files>
# Use libnl v2.0 (or 3.0) libraries.
#CONFIG_LIBNL20=y
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
#CONFIG_LIBNL32=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
#LIBS_p += -L/usr/local/lib
#LIBS_c += -L/usr/local/lib
# Driver interface for Windows NDIS
#CONFIG_DRIVER_NDIS=y
#CFLAGS += -I/usr/include/w32api/ddk
#LIBS += -L/usr/local/lib
# For native build using mingw
#CONFIG_NATIVE_WINDOWS=y
# Additional directories for cross-compilation on Linux host for mingw target
#CFLAGS += -I/opt/mingw/mingw32/include/ddk
#LIBS += -L/opt/mingw/mingw32/lib
#CC=mingw32-gcc
# By default, driver_ndis uses WinPcap for low-level operations. This can be
# replaced with the following option which replaces WinPcap calls with NDISUIO.
# However, this requires that WZC is disabled (net stop wzcsvc) before starting
# wpa_supplicant.
# CONFIG_USE_NDISUIO=y
# Driver interface for wired Ethernet drivers
CONFIG_DRIVER_WIRED=y
# Driver interface for MACsec capable Qualcomm Atheros drivers
#CONFIG_DRIVER_MACSEC_QCA=y
# Driver interface for Linux MACsec drivers
#CONFIG_DRIVER_MACSEC_LINUX=y
# Driver interface for the Broadcom RoboSwitch family
#CONFIG_DRIVER_ROBOSWITCH=y
# Driver interface for no driver (e.g., WPS ER only)
#CONFIG_DRIVER_NONE=y
# Solaris libraries
#LIBS += -lsocket -ldlpi -lnsl
#LIBS_c += -lsocket
# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
# MACsec is included)
CONFIG_IEEE8021X_EAPOL=y
# EAP-MD5
CONFIG_EAP_MD5=y
# EAP-MSCHAPv2
CONFIG_EAP_MSCHAPV2=y
# EAP-TLS
CONFIG_EAP_TLS=y
# EAL-PEAP
CONFIG_EAP_PEAP=y
# EAP-TTLS
CONFIG_EAP_TTLS=y
# EAP-FAST
CONFIG_EAP_FAST=y
# EAP-TEAP
# Note: The current EAP-TEAP implementation is experimental and should not be
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
# of conflicting statements and missing details and the implementation has
# vendor specific workarounds for those and as such, may not interoperate with
# any other implementation. This should not be used for anything else than
# experimentation and interoperability testing until those issues has been
# resolved.
#CONFIG_EAP_TEAP=y
# EAP-GTC
CONFIG_EAP_GTC=y
# EAP-OTP
CONFIG_EAP_OTP=y
# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used)
#CONFIG_EAP_SIM=y
# Enable SIM simulator (Milenage) for EAP-SIM
#CONFIG_SIM_SIMULATOR=y
# EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-pwd (secure authentication using only a password)
#CONFIG_EAP_PWD=y
# EAP-PAX
#CONFIG_EAP_PAX=y
# LEAP
CONFIG_EAP_LEAP=y
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
#CONFIG_EAP_AKA=y
# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# Enable USIM simulator (Milenage) for EAP-AKA
#CONFIG_USIM_SIMULATOR=y
# EAP-SAKE
#CONFIG_EAP_SAKE=y
# EAP-GPSK
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-TNC and related Trusted Network Connect support (experimental)
#CONFIG_EAP_TNC=y
# Wi-Fi Protected Setup (WPS)
CONFIG_WPS=y
# Enable WPS external registrar functionality
#CONFIG_WPS_ER=y
# Disable credentials for an open network by default when acting as a WPS
# registrar.
#CONFIG_WPS_REG_DISABLE_OPEN=y
# Enable WPS support with NFC config method
#CONFIG_WPS_NFC=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# EAP-EKE
#CONFIG_EAP_EKE=y
# MACsec
#CONFIG_MACSEC=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
# Smartcard support (i.e., private key on a smartcard), e.g., with openssl
# engine.
CONFIG_SMARTCARD=y
# PC/SC interface for smartcards (USIM, GSM SIM)
# Enable this if EAP-SIM or EAP-AKA is included
#CONFIG_PCSC=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
CONFIG_HT_OVERRIDES=y
# Support VHT overrides (disable VHT, mask MCS rates, etc.)
CONFIG_VHT_OVERRIDES=y
# Development testing
#CONFIG_EAPOL_TEST=y
# Select control interface backend for external programs, e.g, wpa_cli:
# unix = UNIX domain sockets (default for Linux/*BSD)
# udp = UDP sockets using localhost (127.0.0.1)
# udp6 = UDP IPv6 sockets using localhost (::1)
# named_pipe = Windows Named Pipe (default for Windows)
# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
# y = use default (backwards compatibility)
# If this option is commented out, control interface is not included in the
# build.
CONFIG_CTRL_IFACE=y
# Include support for GNU Readline and History Libraries in wpa_cli.
# When building a wpa_cli binary for distribution, please note that these
# libraries are licensed under GPL and as such, BSD license may not apply for
# the resulting binary.
#CONFIG_READLINE=y
# Include internal line edit mode in wpa_cli. This can be used as a replacement
# for GNU Readline to provide limited command line editing and history support.
#CONFIG_WPA_CLI_EDIT=y
# Remove debugging code that is printing out debug message to stdout.
# This can be used to reduce the size of the wpa_supplicant considerably
# if debugging code is not needed. The size reduction can be around 35%
# (e.g., 90 kB).
#CONFIG_NO_STDOUT_DEBUG=y
# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save
# 35-50 kB in code size.
#CONFIG_NO_WPA=y
# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
# This option can be used to reduce code size by removing support for
# converting ASCII passphrases into PSK. If this functionality is removed, the
# PSK can only be configured as the 64-octet hexstring (e.g., from
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
# Simultaneous Authentication of Equals (SAE), WPA3-Personal
#CONFIG_SAE=y
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
# Select configuration backend:
# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
# path is given on command line, not here; this option is just used to
# select the backend that allows configuration files to be used)
# winreg = Windows registry (see win_example.reg for an example)
CONFIG_BACKEND=file
# Remove configuration write functionality (i.e., to allow the configuration
# file to be updated based on runtime configuration changes). The runtime
# configuration can still be changed, the changes are just not going to be
# persistent over restarts. This option can be used to reduce code size by
# about 3.5 kB.
#CONFIG_NO_CONFIG_WRITE=y
# Remove support for configuration blobs to reduce code size by about 1.5 kB.
#CONFIG_NO_CONFIG_BLOBS=y
# Select program entry point implementation:
# main = UNIX/POSIX like main() function (default)
# main_winsvc = Windows service (read parameters from registry)
# main_none = Very basic example (development use only)
#CONFIG_MAIN=main
# Select wrapper for operating system and C library specific functions
# unix = UNIX/POSIX like systems (default)
# win32 = Windows systems
# none = Empty template
#CONFIG_OS=unix
# Select event loop implementation
# eloop = select() loop (default)
# eloop_win = Windows events and WaitForMultipleObject() loop
#CONFIG_ELOOP=eloop
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
# Should we use epoll instead of select? Select is used by default.
CONFIG_ELOOP_EPOLL=y
# Should we use kqueue instead of select? Select is used by default.
#CONFIG_ELOOP_KQUEUE=y
# Select layer 2 packet implementation
# linux = Linux packet socket (default)
# pcap = libpcap/libdnet/WinPcap
# freebsd = FreeBSD libpcap
# winpcap = WinPcap with receive thread
# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y)
# none = Empty template
#CONFIG_L2_PACKET=linux
# Disable Linux packet socket workaround applicable for station interface
# in a bridge for EAPOL frames. This should be uncommented only if the kernel
# is known to not have the regression issue in packet socket behavior with
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
# IEEE 802.11w (management frame protection), also known as PMF
# Driver support is also needed for IEEE 802.11w.
CONFIG_IEEE80211W=y
# Support Operating Channel Validation
#CONFIG_OCV=y
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
# internal = Internal TLSv1 implementation (experimental)
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
# none = Empty template
CONFIG_TLS=internal
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
# can be enabled to get a stronger construction of messages when block ciphers
# are used. It should be noted that some existing TLS v1.0 -based
# implementation may not be compatible with TLS v1.1 message (ClientHello is
# sent prior to negotiating which version will be used)
#CONFIG_TLSV11=y
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
# can be enabled to enable use of stronger crypto algorithms. It should be
# noted that some existing TLS v1.0 -based implementation may not be compatible
# with TLS v1.2 message (ClientHello is sent prior to negotiating which version
# will be used)
#CONFIG_TLSV12=y
# Select which ciphers to use by default with OpenSSL if the user does not
# specify them.
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
# If CONFIG_TLS=internal is used, additional library and include paths are
# needed for LibTomMath. Alternatively, an integrated, minimal version of
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
# and drawbacks of this option.
CONFIG_INTERNAL_LIBTOMMATH=y
#ifndef CONFIG_INTERNAL_LIBTOMMATH
#LTM_PATH=/usr/src/libtommath-0.39
#CFLAGS += -I$(LTM_PATH)
#LIBS += -L$(LTM_PATH)
#LIBS_p += -L$(LTM_PATH)
#endif
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
# can be configured to include faster routines for exptmod, sqr, and div to
# speed up DH and RSA calculation considerably
CONFIG_INTERNAL_LIBTOMMATH_FAST=y
# Include NDIS event processing through WMI into wpa_supplicant/wpasvc.
# This is only for Windows builds and requires WMI-related header files and
# WbemUuid.Lib from Platform SDK even when building with MinGW.
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
#CONFIG_CTRL_IFACE_DBUS_INTRO=y
# Add support for loading EAP methods dynamically as shared libraries.
# When this option is enabled, each EAP method can be either included
# statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).
# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to
# be loaded in the beginning of the wpa_supplicant configuration file
# (see load_dynamic_eap parameter in the example file) before being used in
# the network blocks.
#
# Note that some shared parts of EAP methods are included in the main program
# and in order to be able to use dynamic EAP methods using these parts, the
# main program must have been build with the EAP method enabled (=y or =dyn).
# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries
# unless at least one of them was included in the main build to force inclusion
# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included
# in the main build to be able to load these methods dynamically.
#
# Please also note that using dynamic libraries will increase the total binary
# size. Thus, it may not be the best option for targets that have limited
# amount of memory/flash.
#CONFIG_DYNAMIC_EAP_METHODS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
#CONFIG_IEEE80211R=y
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
#CONFIG_DEBUG_FILE=y
# Send debug messages to syslog instead of stdout
CONFIG_DEBUG_SYSLOG=y
# Set syslog facility for debug messages
CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# Add support for sending all debug messages (regardless of debug verbosity)
# to the Linux kernel tracing facility. This helps debug the entire stack by
# making it easy to record everything happening from the driver up into the
# same file, e.g., using trace-cmd.
#CONFIG_DEBUG_LINUX_TRACING=y
# Add support for writing debug log to Android logcat instead of standard
# output
#CONFIG_ANDROID_LOG=y
# Enable privilege separation (see README 'Privilege separation' for details)
#CONFIG_PRIVSEP=y
# Enable mitigation against certain attacks against TKIP by delaying Michael
# MIC error reports by a random amount of time between 0 and 60 seconds
#CONFIG_DELAYED_MIC_ERROR_REPORT=y
# Enable tracing code for developer debugging
# This tracks use of memory allocations and other registrations and reports
# incorrect use with a backtrace of call (or allocation) location.
#CONFIG_WPA_TRACE=y
# For BSD, uncomment these.
#LIBS += -lexecinfo
#LIBS_p += -lexecinfo
#LIBS_c += -lexecinfo
# Use libbfd to get more details for developer debugging
# This enables use of libbfd to get more detailed symbols for the backtraces
# generated by CONFIG_WPA_TRACE=y.
#CONFIG_WPA_TRACE_BFD=y
# For BSD, uncomment these.
#LIBS += -lbfd -liberty -lz
#LIBS_p += -lbfd -liberty -lz
#LIBS_c += -lbfd -liberty -lz
# wpa_supplicant depends on strong random number generation being available
# from the operating system. os_get_random() function is used to fetch random
# data when needed, e.g., for key generation. On Linux and BSD systems, this
# works by reading /dev/urandom. It should be noted that the OS entropy pool
# needs to be properly initialized before wpa_supplicant is started. This is
# important especially on embedded devices that do not have a hardware random
# number generator and may by default start up with minimal entropy available
# for random number generation.
#
# As a safety net, wpa_supplicant is by default trying to internally collect
# additional entropy for generating random data to mix in with the data fetched
# from the OS. This by itself is not considered to be very strong, but it may
# help in cases where the system pool is not initialized properly. However, it
# is very strongly recommended that the system pool is initialized with enough
# entropy either by using hardware assisted random number generator or by
# storing state over device reboots.
#
# wpa_supplicant can be configured to maintain its own entropy store over
# restarts to enhance random number generation. This is not perfect, but it is
# much more secure than using the same sequence of random numbers after every
# reboot. This can be enabled with -e<entropy file> command line option. The
# specified file needs to be readable and writable by wpa_supplicant.
#
# If the os_get_random() is known to provide strong random data (e.g., on
# Linux/BSD, the board in question is known to have reliable source of random
# data from /dev/urandom), the internal wpa_supplicant random pool can be
# disabled. This will save some in binary size and CPU use. However, this
# should only be considered for builds that are known to be used on devices
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
# Should we attempt to use the getrandom(2) call that provides more reliable
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
CONFIG_GETRANDOM=y
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
#CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
# (depends on CONFIG_IEEE80211N)
#CONFIG_IEEE80211AC=y
# Wireless Network Management (IEEE Std 802.11v-2011)
# Note: This is experimental and not complete implementation.
#CONFIG_WNM=y
# Interworking (IEEE 802.11u)
# This can be used to enable functionality to improve interworking with
# external networks (GAS/ANQP to learn more about the networks and network
# selection based on available credentials).
#CONFIG_INTERWORKING=y
# Hotspot 2.0
#CONFIG_HS20=y
# Enable interface matching in wpa_supplicant
#CONFIG_MATCH_IFACE=y
# Disable roaming in wpa_supplicant
#CONFIG_NO_ROAMING=y
# AP mode operations with wpa_supplicant
# This can be used for controlling AP mode operations with wpa_supplicant. It
# should be noted that this is mainly aimed at simple cases like
# WPA2-Personal while more complex configurations like WPA2-Enterprise with an
# external RADIUS server can be supported with hostapd.
CONFIG_AP=y
# P2P (Wi-Fi Direct)
# This can be used to enable P2P support in wpa_supplicant. See README-P2P for
# more information on P2P operations.
CONFIG_P2P=y
# Enable TDLS support
#CONFIG_TDLS=y
# Wi-Fi Display
# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
# Autoscan
# This can be used to enable automatic scan support in wpa_supplicant.
# See wpa_supplicant.conf for more information on autoscan usage.
#
# Enabling directly a module will enable autoscan support.
# For exponential module:
#CONFIG_AUTOSCAN_EXPONENTIAL=y
# For periodic module:
#CONFIG_AUTOSCAN_PERIODIC=y
# Password (and passphrase, etc.) backend for external storage
# These optional mechanisms can be used to add support for storing passwords
# and other secrets in external (to wpa_supplicant) location. This allows, for
# example, operating system specific key storage to be used
#
# External password backend for testing purposes (developer use)
#CONFIG_EXT_PASSWORD_TEST=y
# Enable Fast Session Transfer (FST)
#CONFIG_FST=y
# Enable CLI commands for FST testing
#CONFIG_FST_TEST=y
# OS X builds. This is only for building eapol_test.
#CONFIG_OSX=y
# Automatic Channel Selection
# This will allow wpa_supplicant to pick the channel automatically when channel
# is set to "0".
#
# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative
# to "channel=0". This would enable us to eventually add other ACS algorithms in
# similar way.
#
# Automatic selection is currently only done through initialization, later on
# we hope to do background checks to keep us moving to more ideal channels as
# time goes by. ACS is currently only supported through the nl80211 driver and
# your driver must have survey dump capability that is filled by the driver
# during scanning.
#
# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with
# a newly to create wpa_supplicant.conf variable acs_num_scans.
#
# Supported ACS drivers:
# * ath9k
# * ath5k
# * ath10k
#
# For more details refer to:
# http://wireless.kernel.org/en/users/Documentation/acs
#CONFIG_ACS=y
# Support Multi Band Operation
#CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
# Support RSN on IBSS networks
# This is needed to be able to use mode=1 network profile with proto=RSN and
# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
CONFIG_IBSS_RSN=y
# External PMKSA cache control
# This can be used to enable control interface commands that allow the current
# PMKSA cache entries to be fetched and new entries to be added.
#CONFIG_PMKSA_CACHE_EXTERNAL=y
# Mesh Networking (IEEE 802.11s)
#CONFIG_MESH=y
# Background scanning modules
# These can be used to request wpa_supplicant to perform background scanning
# operations for roaming within an ESS (same SSID). See the bgscan parameter in
# the wpa_supplicant.conf file for more details.
# Periodic background scans based on signal strength
#CONFIG_BGSCAN_SIMPLE=y
# Learn channels used by the network and try to avoid bgscans on other
# channels (experimental)
#CONFIG_BGSCAN_LEARN=y
# Opportunistic Wireless Encryption (OWE)
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
# Device Provisioning Protocol (DPP)
# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
# wpa_supplicant/README-DPP for details)
#CONFIG_DPP=y
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
CONFIG_UBUS=y
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
# leads to the MIB only being compiled in if
# CONFIG_CTRL_IFACE_MIB is enabled.
CONFIG_CTRL_IFACE_MIB=y

View File

@@ -1,330 +0,0 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_open } from "common";
let ubus = libubus.connect();
wpas.data.config = {};
wpas.data.iface_phy = {};
wpas.data.macaddr_list = {};
function iface_stop(iface)
{
let ifname = iface.config.iface;
if (!iface.running)
return;
delete wpas.data.iface_phy[ifname];
wpas.remove_iface(ifname);
wdev_remove(ifname);
iface.running = false;
}
function iface_start(phydev, iface, macaddr_list)
{
let phy = phydev.name;
if (iface.running)
return;
let ifname = iface.config.iface;
let wdev_config = {};
for (let field in iface.config)
wdev_config[field] = iface.config[field];
if (!wdev_config.macaddr)
wdev_config.macaddr = phydev.macaddr_next();
wpas.data.iface_phy[ifname] = phy;
wdev_remove(ifname);
let ret = wdev_create(phy, ifname, wdev_config);
if (ret)
wpas.printf(`Failed to create device ${ifname}: ${ret}`);
wpas.add_iface(iface.config);
iface.running = true;
}
function iface_cb(new_if, old_if)
{
if (old_if && new_if && is_equal(old_if.config, new_if.config)) {
new_if.running = old_if.running;
return;
}
if (new_if && old_if)
wpas.printf(`Update configuration for interface ${old_if.config.iface}`);
else if (old_if)
wpas.printf(`Remove interface ${old_if.config.iface}`);
if (old_if)
iface_stop(old_if);
}
function prepare_config(config)
{
config.config_data = readfile(config.config);
return { config: config };
}
function set_config(phy_name, config_list)
{
let phy = wpas.data.config[phy_name];
if (!phy) {
phy = vlist_new(iface_cb, false);
wpas.data.config[phy_name] = phy;
}
let values = [];
for (let config in config_list)
push(values, [ config.iface, prepare_config(config) ]);
phy.update(values);
}
function start_pending(phy_name)
{
let phy = wpas.data.config[phy_name];
let ubus = wpas.data.ubus;
if (!phy || !phy.data)
return;
let phydev = phy_open(phy_name);
if (!phydev) {
wpas.printf(`Could not open phy ${phy_name}`);
return;
}
let macaddr_list = wpas.data.macaddr_list[phy_name];
phydev.macaddr_init(macaddr_list);
for (let ifname in phy.data)
iface_start(phydev, phy.data[ifname]);
}
let main_obj = {
phy_set_state: {
args: {
phy: "",
stop: true,
},
call: function(req) {
if (!req.args.phy || req.args.stop == null)
return libubus.STATUS_INVALID_ARGUMENT;
let phy = wpas.data.config[req.args.phy];
if (!phy)
return libubus.STATUS_NOT_FOUND;
try {
if (req.args.stop) {
for (let ifname in phy.data)
iface_stop(phy.data[ifname]);
} else {
start_pending(req.args.phy);
}
} catch (e) {
wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`);
return libubus.STATUS_INVALID_ARGUMENT;
}
return 0;
}
},
phy_set_macaddr_list: {
args: {
phy: "",
macaddr: [],
},
call: function(req) {
let phy = req.args.phy;
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
wpas.data.macaddr_list[phy] = req.args.macaddr;
return 0;
}
},
phy_status: {
args: {
phy: ""
},
call: function(req) {
if (!req.args.phy)
return libubus.STATUS_INVALID_ARGUMENT;
let phy = wpas.data.config[req.args.phy];
if (!phy)
return libubus.STATUS_NOT_FOUND;
for (let ifname in phy.data) {
try {
let iface = wpas.interfaces[ifname];
if (!iface)
continue;
let status = iface.status();
if (!status)
continue;
if (status.state == "INTERFACE_DISABLED")
continue;
status.ifname = ifname;
return status;
} catch (e) {
continue;
}
}
return libubus.STATUS_NOT_FOUND;
}
},
config_set: {
args: {
phy: "",
config: [],
defer: true,
},
call: function(req) {
if (!req.args.phy)
return libubus.STATUS_INVALID_ARGUMENT;
wpas.printf(`Set new config for phy ${req.args.phy}`);
try {
if (req.args.config)
set_config(req.args.phy, req.args.config);
if (!req.args.defer)
start_pending(req.args.phy);
} catch (e) {
wpas.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`);
return libubus.STATUS_INVALID_ARGUMENT;
}
return {
pid: wpas.getpid()
};
}
},
config_add: {
args: {
driver: "",
iface: "",
bridge: "",
hostapd_ctrl: "",
ctrl: "",
config: "",
},
call: function(req) {
if (!req.args.iface || !req.args.config)
return libubus.STATUS_INVALID_ARGUMENT;
if (wpas.add_iface(req.args) < 0)
return libubus.STATUS_INVALID_ARGUMENT;
return {
pid: wpas.getpid()
};
}
},
config_remove: {
args: {
iface: ""
},
call: function(req) {
if (!req.args.iface)
return libubus.STATUS_INVALID_ARGUMENT;
wpas.remove_iface(req.args.iface);
return 0;
}
},
};
wpas.data.ubus = ubus;
wpas.data.obj = ubus.publish("wpa_supplicant", main_obj);
function iface_event(type, name, data) {
let ubus = wpas.data.ubus;
data ??= {};
data.name = name;
wpas.data.obj.notify(`iface.${type}`, data, null, null, null, -1);
ubus.call("service", "event", { type: `wpa_supplicant.${name}.${type}`, data: {} });
}
function iface_hostapd_notify(phy, ifname, iface, state)
{
let ubus = wpas.data.ubus;
let status = iface.status();
let msg = { phy: phy };
switch (state) {
case "DISCONNECTED":
case "AUTHENTICATING":
case "SCANNING":
msg.up = false;
break;
case "INTERFACE_DISABLED":
case "INACTIVE":
msg.up = true;
break;
case "COMPLETED":
msg.up = true;
msg.frequency = status.frequency;
msg.sec_chan_offset = status.sec_chan_offset;
break;
default:
return;
}
ubus.call("hostapd", "apsta_state", msg);
}
function iface_channel_switch(phy, ifname, iface, info)
{
let msg = {
phy: phy,
up: true,
csa: true,
csa_count: info.csa_count ? info.csa_count - 1 : 0,
frequency: info.frequency,
sec_chan_offset: info.sec_chan_offset,
};
ubus.call("hostapd", "apsta_state", msg);
}
return {
shutdown: function() {
for (let phy in wpas.data.config)
set_config(phy, []);
wpas.ubus.disconnect();
},
iface_add: function(name, obj) {
iface_event("add", name);
},
iface_remove: function(name, obj) {
iface_event("remove", name);
},
state: function(ifname, iface, state) {
let phy = wpas.data.iface_phy[ifname];
if (!phy) {
wpas.printf(`no PHY for ifname ${ifname}`);
return;
}
iface_hostapd_notify(phy, ifname, iface, state);
},
event: function(ifname, iface, ev, info) {
let phy = wpas.data.iface_phy[ifname];
if (!phy) {
wpas.printf(`no PHY for ifname ${ifname}`);
return;
}
if (ev == "CH_SWITCH_STARTED")
iface_channel_switch(phy, ifname, iface, info);
}
};

View File

@@ -1,43 +0,0 @@
#!/bin/sh /etc/rc.common
START=19
STOP=21
USE_PROCD=1
NAME=wpad
start_service() {
if [ -x "/usr/sbin/hostapd" ]; then
mkdir -p /var/run/hostapd
chown network:network /var/run/hostapd
procd_open_instance hostapd
procd_set_param command /usr/sbin/hostapd -s -g /var/run/hostapd/global
procd_set_param respawn 3600 1 0
procd_set_param limits core="unlimited"
[ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && {
procd_add_jail hostapd
procd_set_param capabilities /etc/capabilities/wpad.json
procd_set_param user network
procd_set_param group network
procd_set_param no_new_privs 1
}
procd_close_instance
fi
if [ -x "/usr/sbin/wpa_supplicant" ]; then
mkdir -p /var/run/wpa_supplicant
chown network:network /var/run/wpa_supplicant
procd_open_instance supplicant
procd_set_param command /usr/sbin/wpa_supplicant -n -s -g /var/run/wpa_supplicant/global
procd_set_param respawn 3600 1 0
procd_set_param limits core="unlimited"
[ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && {
procd_add_jail wpa_supplicant
procd_set_param capabilities /etc/capabilities/wpad.json
procd_set_param user network
procd_set_param group network
procd_set_param no_new_privs 1
}
procd_close_instance
fi
}

View File

@@ -1,22 +0,0 @@
{
"bounding": [
"CAP_NET_ADMIN",
"CAP_NET_RAW"
],
"effective": [
"CAP_NET_ADMIN",
"CAP_NET_RAW"
],
"ambient": [
"CAP_NET_ADMIN",
"CAP_NET_RAW"
],
"permitted": [
"CAP_NET_ADMIN",
"CAP_NET_RAW"
],
"inheritable": [
"CAP_NET_ADMIN",
"CAP_NET_RAW"
]
}

View File

@@ -1,10 +0,0 @@
{
"user": "network",
"access": {
"service": {
"methods": [ "event" ]
}
},
"publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*" ],
"send": [ "bss.*", "wps_credentials" ]
}

View File

@@ -1,69 +0,0 @@
#!/bin/sh
wps_catch_credentials() {
local iface ifaces ifc ifname ssid encryption key radio radios
local found=0
. /usr/share/libubox/jshn.sh
ubus -S -t 30 listen wps_credentials | while read creds; do
json_init
json_load "$creds"
json_select wps_credentials || continue
json_get_vars ifname ssid key encryption
local ifcname="$ifname"
json_init
json_load "$(ubus -S call network.wireless status)"
json_get_keys radios
for radio in $radios; do
json_select $radio
json_select interfaces
json_get_keys ifaces
for ifc in $ifaces; do
json_select $ifc
json_get_vars ifname
[ "$ifname" = "$ifcname" ] && {
ubus -S call uci set "{\"config\":\"wireless\", \"type\":\"wifi-iface\", \
\"match\": { \"device\": \"$radio\", \"encryption\": \"wps\" }, \
\"values\": { \"encryption\": \"$encryption\", \
\"ssid\": \"$ssid\", \
\"key\": \"$key\" } }"
ubus -S call uci commit '{"config": "wireless"}'
ubus -S call uci apply
}
json_select ..
done
json_select ..
json_select ..
done
done
}
if [ "$ACTION" = "released" ] && [ "$BUTTON" = "wps" ]; then
# If the button was pressed for 3 seconds or more, trigger WPS on
# wpa_supplicant only, no matter if hostapd is running or not. If
# was pressed for less than 3 seconds, try triggering on
# hostapd. If there is no hostapd instance to trigger it on or WPS
# is not enabled on them, trigger it on wpa_supplicant.
if [ "$SEEN" -lt 3 ] ; then
wps_done=0
ubusobjs="$( ubus -S list hostapd.* )"
for ubusobj in $ubusobjs; do
ubus -S call $ubusobj wps_start && wps_done=1
done
[ $wps_done = 0 ] || return 0
fi
wps_done=0
ubusobjs="$( ubus -S list wpa_supplicant.* )"
for ubusobj in $ubusobjs; do
ifname="$(echo $ubusobj | cut -d'.' -f2 )"
multi_ap=""
if [ -e "/var/run/wpa_supplicant-${ifname}.conf.is_multiap" ]; then
ubus -S call $ubusobj wps_start '{ "multi_ap": true }' && wps_done=1
else
ubus -S call $ubusobj wps_start && wps_done=1
fi
done
[ $wps_done = 0 ] || wps_catch_credentials &
fi
return 0

View File

@@ -1,6 +1,6 @@
import * as nl80211 from "nl80211";
import * as rtnl from "rtnl";
import { readfile, glob, basename, readlink } from "fs";
import { readfile, glob, basename, readlink, open } from "fs";
const iftypes = {
ap: nl80211.const.NL80211_IFTYPE_AP,
@@ -10,6 +10,36 @@ const iftypes = {
monitor: nl80211.const.NL80211_IFTYPE_MONITOR,
};
const mesh_params = {
mesh_retry_timeout: "retry_timeout",
mesh_confirm_timeout: "confirm_timeout",
mesh_holding_timeout: "holding_timeout",
mesh_max_peer_links: "max_peer_links",
mesh_max_retries: "max_retries",
mesh_ttl: "ttl",
mesh_element_ttl: "element_ttl",
mesh_auto_open_plinks: "auto_open_plinks",
mesh_hwmp_max_preq_retries: "hwmp_max_preq_retries",
mesh_path_refresh_time: "path_refresh_time",
mesh_min_discovery_timeout: "min_discovery_timeout",
mesh_hwmp_active_path_timeout: "hwmp_active_path_timeout",
mesh_hwmp_preq_min_interval: "hwmp_preq_min_interval",
mesh_hwmp_net_diameter_traversal_time: "hwmp_net_diam_trvs_time",
mesh_hwmp_rootmode: "hwmp_rootmode",
mesh_hwmp_rann_interval: "hwmp_rann_interval",
mesh_gate_announcements: "gate_announcements",
mesh_sync_offset_max_neighor: "sync_offset_max_neighbor",
mesh_rssi_threshold: "rssi_threshold",
mesh_hwmp_active_path_to_root_timeout: "hwmp_path_to_root_timeout",
mesh_hwmp_root_interval: "hwmp_root_interval",
mesh_hwmp_confirmation_interval: "hwmp_confirmation_interval",
mesh_awake_window: "awake_window",
mesh_plink_timeout: "plink_timeout",
mesh_fwding: "forwarding",
mesh_power_mode: "power_mode",
mesh_nolearn: "nolearn"
};
function wdev_remove(name)
{
nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name });
@@ -19,7 +49,7 @@ function __phy_is_fullmac(phyidx)
{
let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx });
return 0; //!data.software_iftypes.ap_vlan;
return !data.software_iftypes.monitor;
}
function phy_is_fullmac(phy)
@@ -44,6 +74,14 @@ function find_reusable_wdev(phyidx)
return null;
}
function wdev_set_radio_mask(name, mask)
{
nl80211.request(nl80211.const.NL80211_CMD_SET_INTERFACE, 0, {
dev: name,
vif_radio_mask: mask
});
}
function wdev_create(phy, name, data)
{
let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`));
@@ -63,24 +101,24 @@ function wdev_create(phy, name, data)
req["4addr"] = data["4addr"];
if (data.macaddr)
req.mac = data.macaddr;
if (data.radio != null && data.radio >= 0)
req.vif_radio_mask = 1 << data.radio;
nl80211.error();
let reuse_ifname = find_reusable_wdev(phyidx);
if (reuse_ifname &&
(reuse_ifname == name ||
rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false))
nl80211.request(
nl80211.const.NL80211_CMD_SET_INTERFACE, 0, {
wiphy: phyidx,
dev: name,
iftype: iftypes[data.mode],
});
else
rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false)) {
req.dev = req.ifname;
delete req.ifname;
nl80211.request(nl80211.const.NL80211_CMD_SET_INTERFACE, 0, req);
} else {
nl80211.request(
nl80211.const.NL80211_CMD_NEW_INTERFACE,
nl80211.const.NLM_F_CREATE,
req);
}
let error = nl80211.error();
if (error)
@@ -94,6 +132,31 @@ function wdev_create(phy, name, data)
return null;
}
function wdev_set_mesh_params(name, data)
{
let mesh_cfg = {};
for (let key in mesh_params) {
let val = data[key];
if (val == null)
continue;
mesh_cfg[mesh_params[key]] = int(val);
}
if (!length(mesh_cfg))
return null;
nl80211.request(nl80211.const.NL80211_CMD_SET_MESH_CONFIG, 0,
{ dev: name, mesh_params: mesh_cfg });
return nl80211.error();
}
function wdev_set_up(name, up)
{
rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: name, change: 1, flags: up ? 1 : 0 });
}
function phy_sysfs_file(phy, name)
{
return trim(readfile(`/sys/class/ieee80211/${phy}/${name}`));
@@ -135,7 +198,8 @@ const phy_proto = {
},
macaddr_generate: function(data) {
let phy = this.name;
let phy = this.phy;
let radio_idx = this.radio;
let idx = int(data.id ?? 0);
let mbssid = int(data.mbssid ?? 0) > 0;
let num_global = int(data.num_global ?? 1);
@@ -145,22 +209,30 @@ const phy_proto = {
if (!base_addr)
return null;
if (!idx && !mbssid)
return base_addr;
let base_mask = phy_sysfs_file(phy, "address_mask");
if (!base_mask)
return null;
if (base_mask == "00:00:00:00:00:00" && idx >= num_global) {
if (base_mask == "00:00:00:00:00:00" &&
(radio_idx > 0 || idx >= num_global)) {
let addrs = split(phy_sysfs_file(phy, "addresses"), "\n");
if (idx < length(addrs))
return addrs[idx];
if (radio_idx != null) {
if (radio_idx && radio_idx < length(addrs))
base_addr = addrs[radio_idx];
else
idx += radio_idx * 16;
} else {
if (idx < length(addrs))
return addrs[idx];
base_mask = "ff:ff:ff:ff:ff:ff";
base_mask = "ff:ff:ff:ff:ff:ff";
}
}
if (!idx && !mbssid)
return base_addr;
let addr = macaddr_split(base_addr);
let mask = macaddr_split(base_mask);
let type;
@@ -220,27 +292,55 @@ const phy_proto = {
}
},
wdev_add: function(name, data) {
let phydev = this;
wdev_create(this.phy, name, {
...data,
radio: this.radio,
});
},
for_each_wdev: function(cb) {
let wdevs = glob(`/sys/class/ieee80211/${this.name}/device/net/*`);
wdevs = map(wdevs, (arg) => basename(arg));
let wdevs = nl80211.request(
nl80211.const.NL80211_CMD_GET_INTERFACE,
nl80211.const.NLM_F_DUMP,
{ wiphy: this.idx }
);
let mac_wdev = {};
for (let wdev in wdevs) {
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != this.name)
if (wdev.iftype == nl80211.const.NL80211_IFTYPE_AP_VLAN)
continue;
if (this.radio != null && wdev.vif_radio_mask != null &&
!(wdev.vif_radio_mask & (1 << this.radio)))
continue;
mac_wdev[wdev.mac] = wdev;
}
for (let wdev in wdevs) {
if (!mac_wdev[wdev.mac])
continue;
cb(wdev);
cb(wdev.ifname);
}
}
};
function phy_open(phy)
function phy_open(phy, radio)
{
let phyidx = readfile(`/sys/class/ieee80211/${phy}/index`);
if (!phyidx)
return null;
let name = phy;
if (radio === "" || radio < 0)
radio = null;
if (radio != null)
name += "." + radio;
return proto({
name: phy,
idx: int(phyidx)
phy, name, radio,
idx: int(phyidx),
}, phy_proto);
}
@@ -310,9 +410,9 @@ function is_equal(val1, val2) {
function vlist_new(cb) {
return proto({
cb: cb,
data: {}
}, vlist_proto);
cb: cb,
data: {}
}, vlist_proto);
}
export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac, phy_open };
export { wdev_remove, wdev_create, wdev_set_mesh_params, wdev_set_radio_mask, wdev_set_up, is_equal, vlist_new, phy_is_fullmac, phy_open };

View File

@@ -24,12 +24,12 @@ hostapd_append_wep_key() {
[1234])
for idx in 1 2 3 4; do
local zidx
zidx=$(($idx - 1))
zidx="$(($idx - 1))"
json_get_var ckey "key${idx}"
[ -n "$ckey" ] && \
append $var "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N$T"
done
wep_keyidx=$((key - 1))
wep_keyidx="$((key - 1))"
;;
*)
append $var "wep_key0=$(prepare_key_wep "$key")" "$N$T"
@@ -43,22 +43,21 @@ hostapd_append_wpa_key_mgmt() {
case "$auth_type" in
psk|eap)
append wpa_key_mgmt "WPA-$auth_type_l"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-${auth_type_l}"
[ "${wpa:-2}" -ge 2 ] && [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-${auth_type_l}"
[ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-${auth_type_l}-SHA256"
;;
eap192)
append wpa_key_mgmt "WPA-EAP-SUITE-B-192"
append wpa_key_mgmt "WPA-EAP-SHA256"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP-SHA384"
;;
eap-eap256)
eap-eap2)
append wpa_key_mgmt "WPA-EAP"
append wpa_key_mgmt "WPA-EAP-SHA256"
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
;;
eap256)
append wpa_key_mgmt "WPA-EAP-SHA256"
eap2)
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP"
append wpa_key_mgmt "WPA-EAP-SHA256"
;;
sae)
append wpa_key_mgmt "SAE"
@@ -78,6 +77,10 @@ hostapd_append_wpa_key_mgmt() {
[ "$fils" -gt 0 ] && {
case "$auth_type" in
eap192)
append wpa_key_mgmt FILS-SHA384
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt FT-FILS-SHA384
;;
eap*)
append wpa_key_mgmt FILS-SHA256
[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt FT-FILS-SHA256
@@ -117,16 +120,14 @@ hostapd_common_add_device_config() {
config_add_int rssi_reject_assoc_rssi
config_add_int rssi_ignore_probe_request
config_add_int maxassoc
config_add_boolean maxassoc_ignore_probe
config_add_int reg_power_type
config_add_boolean stationary_ap
config_add_string acs_chan_bias
config_add_boolean acs_exclude_dfs
config_add_array hostapd_options
config_add_int airtime_mode
config_add_boolean multiple_bssid rnr_beacon he_co_locate ema
config_add_boolean mlo
config_add_int mbssid
hostapd_add_log_config
}
@@ -137,11 +138,10 @@ hostapd_prepare_device_config() {
local base_cfg=
json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
json_get_vars country country3 country_ie beacon_int:100 doth require_mode legacy_rates \
acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \
multiple_bssid he_co_locate rnr_beacon ema acs_exclude_dfs \
maxassoc_ignore_probe mlo
mbssid:0 band reg_power_type stationary_ap
hostapd_set_log_options base_cfg
@@ -151,12 +151,6 @@ hostapd_prepare_device_config() {
set_default legacy_rates 0
set_default airtime_mode 0
set_default cell_density 0
set_default he_co_locate 0
set_default rnr_beacon 0
set_default multiple_bssid 0
set_default ema 0
set_default acs_exclude_dfs 0
set_default mlo 0
[ -n "$country" ] && {
append base_cfg "country_code=$country" "$N"
@@ -246,16 +240,17 @@ hostapd_prepare_device_config() {
[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
append base_cfg "beacon_int=$beacon_int" "$N"
[ -n "$rts_threshold" ] && append base_cfg "rts_threshold=$rts_threshold" "$N"
append base_cfg "dtim_period=$dtim_period" "$N"
[ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N"
[ -n "$maxassoc" ] && append base_cfg "iface_max_num_sta=$maxassoc" "$N"
[ "$maxassoc_ignore_probe" -gt 0 ] && append base_cfg "no_probe_resp_if_max_sta=1" "$N"
[ "$rnr_beacon" -gt 0 ] && append base_cfg "rnr_beacon=$rnr_beacon" "$N"
# [ "$he_co_locate" -gt 0 ] && append base_cfg "he_co_locate=$he_co_locate" "$N"
[ "$multiple_bssid" -gt 0 ] && append base_cfg "mbssid=$multiple_bssid" "$N"
[ "$ema" -gt 0 ] && append base_cfg "ema=$ema" "$N"
[ "$mlo" -gt 0 ] && append base_cfg "mlo=1" "$N"
[ "$acs_exclude_dfs" -gt 0 ] && append base_cfg "acs_exclude_dfs=$acs_exclude_dfs" "$N"
[ "$mbssid" -gt 0 ] && [ "$mbssid" -le 2 ] && append base_cfg "mbssid=$mbssid" "$N"
[ "$band" = "6g" ] && {
set_default reg_power_type 0
append base_cfg "he_6ghz_reg_pwr_type=$reg_power_type" "$N"
}
set_default stationary_ap 1
append base_cfg "stationary_ap=$stationary_ap" "$N"
json_get_values opts hostapd_options
for val in $opts; do
@@ -270,7 +265,7 @@ EOF
hostapd_common_add_bss_config() {
config_add_string 'bssid:macaddr' 'ssid:string'
config_add_boolean wds wmm uapsd hidden utf8_ssid
config_add_boolean wds wmm uapsd hidden utf8_ssid ppsk
config_add_int maxassoc max_inactivity
config_add_boolean disassoc_low_ack isolate short_preamble skip_inactivity_poll
@@ -287,24 +282,15 @@ hostapd_common_add_bss_config() {
config_add_int ieee80211w
config_add_int eapol_version
config_add_string 'auth_server:host' 'server:host'
config_add_array auth_server acct_server
config_add_string 'server:host'
config_add_string auth_secret key
config_add_int 'auth_port:port' 'port:port'
config_add_string acct_server
config_add_string acct_secret
config_add_int acct_port
config_add_string acct_server_secondary
config_add_string acct_secret_secondary
config_add_int acct_port_secondary
config_add_int acct_interval
config_add_string auth_server_secondary
config_add_string auth_secret_secondary
config_add_int auth_port_secondary
config_add_int bss_load_update_period chan_util_avg_period
config_add_string dae_client
@@ -337,7 +323,7 @@ hostapd_common_add_bss_config() {
config_add_string wps_device_type wps_device_name wps_manufacturer wps_pin
config_add_string multi_ap_backhaul_ssid multi_ap_backhaul_key
config_add_boolean wnm_sleep_mode wnm_sleep_mode_no_keys bss_transition
config_add_boolean wnm_sleep_mode wnm_sleep_mode_no_keys bss_transition mbo
config_add_int time_advertisement
config_add_string time_zone
config_add_string vendor_elements
@@ -379,7 +365,7 @@ hostapd_common_add_bss_config() {
config_add_boolean hs20 disable_dgaf osen
config_add_int anqp_domain_id
config_add_int hs20_deauth_req_timeout hs20_release
config_add_int hs20_deauth_req_timeout
config_add_array hs20_oper_friendly_name
config_add_array osu_provider
config_add_array operator_icon
@@ -400,17 +386,16 @@ hostapd_common_add_bss_config() {
config_add_array radius_auth_req_attr
config_add_array radius_acct_req_attr
config_add_int eap_server
config_add_string eap_user_file ca_cert server_cert private_key private_key_passwd server_id
config_add_int eap_server radius_server_auth_port
config_add_string eap_user_file ca_cert server_cert private_key private_key_passwd server_id radius_server_clients
config_add_boolean fils
config_add_string fils_dhcp
config_add_boolean ratelimit
config_add_int ocv
config_add_string uci_section
config_add_boolean dynamic_probe_resp
config_add_boolean apup
config_add_string apup_peer_ifname_prefix
}
hostapd_set_vlan_file() {
@@ -559,83 +544,18 @@ append_airtime_sta_weight() {
[ -n "$1" ] && append bss_conf "airtime_sta_weight=$1" "$N"
}
append_radius_server() {
append_auth_server() {
[ -n "$1" ] || return
append bss_conf "auth_server_addr=$1" "$N"
append bss_conf "auth_server_port=$auth_port" "$N"
[ -n "$auth_secret" ] && append bss_conf "auth_server_shared_secret=$auth_secret" "$N"
}
json_get_vars \
auth_server auth_secret auth_port \
auth_server_secondary auth_secret_secondary auth_port_secondary \
dae_client dae_secret dae_port \
dynamic_ownip ownip radius_client_addr \
eap_reauth_period request_cui \
erp_domain mobility_domain \
fils_realm fils_dhcp
set_default dynamic_ownip 1
# legacy compatibility
[ -n "$auth_server" ] || json_get_var auth_server server
[ -n "$auth_port" ] || json_get_var auth_port port
[ -n "$auth_secret" ] || json_get_var auth_secret key
[ "$fils" -gt 0 ] && {
set_default erp_domain "$mobility_domain"
set_default erp_domain "$(echo "$ssid" | md5sum | head -c 8)"
set_default fils_realm "$erp_domain"
append bss_conf "erp_send_reauth_start=1" "$N"
append bss_conf "erp_domain=$erp_domain" "$N"
append bss_conf "fils_realm=$fils_realm" "$N"
append bss_conf "fils_cache_id=$(echo "$fils_realm" | md5sum | head -c 4)" "$N"
[ "$fils_dhcp" = "*" ] && {
json_get_values network network
fils_dhcp=
for net in $network; do
fils_dhcp="$(ifstatus "$net" | jsonfilter -e '@.data.dhcpserver')"
[ -n "$fils_dhcp" ] && break
done
[ -z "$fils_dhcp" -a -n "$network_bridge" -a -n "$network_ifname" ] && \
fils_dhcp="$(udhcpc -B -n -q -s /lib/netifd/dhcp-get-server.sh -t 1 -i "$network_ifname" 2>/dev/null)"
}
[ -n "$fils_dhcp" ] && append bss_conf "dhcp_server=$fils_dhcp" "$N"
}
set_default auth_port 1812
set_default auth_port_secondary 1812
set_default dae_port 3799
set_default request_cui 0
[ "$eap_server" -eq 0 ] && {
append bss_conf "auth_server_addr=$auth_server" "$N"
append bss_conf "auth_server_port=$auth_port" "$N"
append bss_conf "auth_server_shared_secret=$auth_secret" "$N"
}
[ -n "$auth_server_secondary" ] && {
append bss_conf "auth_server_addr=$auth_server_secondary" "$N"
append bss_conf "auth_server_port=$auth_port_secondary" "$N"
[ -n "$auth_secret_secondary" ] && \
append bss_conf "auth_server_shared_secret=$auth_secret_secondary" "$N"
}
[ "$request_cui" -gt 0 ] && append bss_conf "radius_request_cui=$request_cui" "$N"
[ -n "$eap_reauth_period" ] && append bss_conf "eap_reauth_period=$eap_reauth_period" "$N"
[ -n "$dae_client" -a -n "$dae_secret" ] && {
append bss_conf "radius_das_port=$dae_port" "$N"
append bss_conf "radius_das_client=$dae_client $dae_secret" "$N"
}
json_for_each_item append_radius_auth_req_attr radius_auth_req_attr
if [ -n "$ownip" ]; then
append bss_conf "own_ip_addr=$ownip" "$N"
elif [ "$dynamic_ownip" -gt 0 ]; then
append bss_conf "dynamic_own_ip_addr=$dynamic_ownip" "$N"
fi
[ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N"
[ "$macfilter" = radius ] && append bss_conf "macaddr_acl=2" "$N"
append_acct_server() {
[ -n "$1" ] || return
append bss_conf "acct_server_addr=$1" "$N"
append bss_conf "acct_server_port=$acct_port" "$N"
[ -n "$acct_secret" ] && append bss_conf "acct_server_shared_secret=$acct_secret" "$N"
}
hostapd_set_bss_options() {
@@ -645,7 +565,7 @@ hostapd_set_bss_options() {
wireless_vif_parse_encryption
local bss_conf bss_md5sum
local bss_conf bss_md5sum ft_key
local wep_rekey wpa_group_rekey wpa_pair_rekey wpa_master_rekey wpa_key_mgmt
json_get_vars \
@@ -656,14 +576,13 @@ hostapd_set_bss_options() {
wps_independent wps_device_type wps_device_name wps_manufacturer wps_pin \
macfilter ssid utf8_ssid wmm uapsd hidden short_preamble rsn_preauth \
iapp_interface eapol_version dynamic_vlan ieee80211w nasid \
acct_server acct_secret acct_port acct_interval \
acct_server_secondary acct_secret_secondary acct_port_secondary \
acct_secret acct_port acct_interval \
bss_load_update_period chan_util_avg_period sae_require_mfp sae_pwe \
multi_ap multi_ap_backhaul_ssid multi_ap_backhaul_key skip_inactivity_poll \
airtime_bss_weight airtime_bss_limit airtime_sta_weight \
ppsk airtime_bss_weight airtime_bss_limit airtime_sta_weight \
multicast_to_unicast_all proxy_arp per_sta_vif \
eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \
vendor_elements fils uci_section dynamic_probe_resp
eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id radius_server_clients radius_server_auth_port \
vendor_elements fils ocv apup
set_default fils 0
set_default isolate 0
@@ -679,15 +598,15 @@ hostapd_set_bss_options() {
set_default tdls_prohibit 0
set_default eapol_version $((wpa & 1))
set_default acct_port 1813
set_default acct_port_secondary 1813
set_default bss_load_update_period 60
set_default chan_util_avg_period 600
set_default utf8_ssid 1
set_default multi_ap 0
set_default ppsk 0
set_default airtime_bss_weight 0
set_default airtime_bss_limit 0
set_default eap_server 0
set_default dynamic_probe_resp 0
set_default apup 0
/usr/sbin/hostapd -vfils || fils=0
@@ -729,31 +648,23 @@ hostapd_set_bss_options() {
[ -n "$nasid" ] && append bss_conf "nas_identifier=$nasid" "$N"
[ -n "$acct_server" ] && {
append bss_conf "acct_server_addr=$acct_server" "$N"
append bss_conf "acct_server_port=$acct_port" "$N"
[ -n "$acct_secret" ] && \
append bss_conf "acct_server_shared_secret=$acct_secret" "$N"
[ -n "$acct_interval" ] && \
append bss_conf "radius_acct_interim_interval=$acct_interval" "$N"
json_for_each_item append_radius_acct_req_attr radius_acct_req_attr
}
[ -n "$acct_interval" ] && \
append bss_conf "radius_acct_interim_interval=$acct_interval" "$N"
json_for_each_item append_acct_server acct_server
json_for_each_item append_radius_acct_req_attr radius_acct_req_attr
[ -n "$acct_server_secondary" ] && {
append bss_conf "acct_server_addr=$acct_server_secondary" "$N"
append bss_conf "acct_server_port=$acct_port_secondary" "$N"
[ -n "$acct_secret_secondary" ] && \
append bss_conf "acct_server_shared_secret=$acct_secret_secondary" "$N"
}
[ -n "$ocv" ] && append bss_conf "ocv=$ocv" "$N"
case "$auth_type" in
sae|owe|eap192|eap256)
sae|owe|eap2|eap192)
set_default ieee80211w 2
set_default sae_require_mfp 1
[ "$ppsk" -eq 0 ] && set_default sae_pwe 2
;;
psk-sae|psk2-radius|eap-eap256)
psk-sae|eap-eap2)
set_default ieee80211w 1
set_default sae_require_mfp 1
[ "$ppsk" -eq 0 ] && set_default sae_pwe 2
;;
esac
[ -n "$sae_require_mfp" ] && append bss_conf "sae_require_mfp=$sae_require_mfp" "$N"
@@ -773,14 +684,16 @@ hostapd_set_bss_options() {
# Here we make the assumption that if we're in open mode
# with WPS enabled, we got to be in unconfigured state.
wps_not_configured=1
vlan_possible=1
[ "$macfilter" = radius ] && {
append_radius_server
}
;;
psk|sae|psk-sae)
json_get_vars key wpa_psk_file
if [ ${#key} -eq 64 ]; then
if [ "$ppsk" -ne 0 ]; then
json_get_vars auth_secret auth_port
set_default auth_port 1812
json_for_each_item append_auth_server auth_server
append bss_conf "macaddr_acl=2" "$N"
append bss_conf "wpa_psk_radius=2" "$N"
elif [ ${#key} -eq 64 ]; then
append bss_conf "wpa_psk=$key" "$N"
elif [ ${#key} -ge 8 ] && [ ${#key} -le 63 ]; then
append bss_conf "wpa_passphrase=$key" "$N"
@@ -796,16 +709,73 @@ hostapd_set_bss_options() {
[ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N"
set_default dynamic_vlan 0
[ "$macfilter" = radius ] && {
append_radius_server
}
vlan_possible=1
wps_possible=1
;;
eap|eap192|eap-eap256|eap256)
append_radius_server
eap|eap2|eap-eap2|eap192)
json_get_vars \
auth_server auth_secret auth_port \
dae_client dae_secret dae_port \
dynamic_ownip ownip radius_client_addr \
eap_reauth_period request_cui \
erp_domain mobility_domain \
fils_realm fils_dhcp
# radius can provide VLAN ID for clients
vlan_possible=1
set_default dynamic_ownip 1
# legacy compatibility
[ -n "$auth_server" ] || json_get_var auth_server server
[ -n "$auth_port" ] || json_get_var auth_port port
[ -n "$auth_secret" ] || json_get_var auth_secret key
[ "$fils" -gt 0 ] && {
set_default erp_domain "$mobility_domain"
set_default erp_domain "$(echo "$ssid" | md5sum | head -c 8)"
set_default fils_realm "$erp_domain"
append bss_conf "erp_send_reauth_start=1" "$N"
append bss_conf "erp_domain=$erp_domain" "$N"
append bss_conf "fils_realm=$fils_realm" "$N"
append bss_conf "fils_cache_id=$(echo "$fils_realm" | md5sum | head -c 4)" "$N"
[ "$fils_dhcp" = "*" ] && {
json_get_values network network
fils_dhcp=
for net in $network; do
fils_dhcp="$(ifstatus "$net" | jsonfilter -e '@.data.dhcpserver')"
[ -n "$fils_dhcp" ] && break
done
[ -z "$fils_dhcp" -a -n "$network_bridge" -a -n "$network_ifname" ] && \
fils_dhcp="$(udhcpc -B -n -q -s /lib/netifd/dhcp-get-server.sh -t 1 -i "$network_ifname" 2>/dev/null)"
}
[ -n "$fils_dhcp" ] && append bss_conf "dhcp_server=$fils_dhcp" "$N"
}
set_default auth_port 1812
set_default dae_port 3799
set_default request_cui 0
[ "$eap_server" -eq 0 ] && json_for_each_item append_auth_server auth_server
[ "$request_cui" -gt 0 ] && append bss_conf "radius_request_cui=$request_cui" "$N"
[ -n "$eap_reauth_period" ] && append bss_conf "eap_reauth_period=$eap_reauth_period" "$N"
[ -n "$dae_client" -a -n "$dae_secret" ] && {
append bss_conf "radius_das_port=$dae_port" "$N"
append bss_conf "radius_das_client=$dae_client $dae_secret" "$N"
}
json_for_each_item append_radius_auth_req_attr radius_auth_req_attr
if [ -n "$ownip" ]; then
append bss_conf "own_ip_addr=$ownip" "$N"
elif [ "$dynamic_ownip" -gt 0 ]; then
append bss_conf "dynamic_own_ip_addr=$dynamic_ownip" "$N"
fi
[ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N"
append bss_conf "eapol_key_index_workaround=1" "$N"
append bss_conf "ieee8021x=1" "$N"
@@ -818,14 +788,26 @@ hostapd_set_bss_options() {
append bss_conf "wep_default_key=$wep_keyidx" "$N"
[ -n "$wep_rekey" ] && append bss_conf "wep_rekey_period=$wep_rekey" "$N"
;;
psk2-radius)
append bss_conf "wpa_psk_radius=3" "$N"
append_radius_server
vlan_possible=1
esac
case "$auth_type" in
none|owe|psk|sae|psk-sae|wep)
json_get_vars \
auth_server auth_port auth_secret \
ownip radius_client_addr
[ -n "$auth_server" ] && {
set_default auth_port 1812
json_for_each_item append_auth_server auth_server
[ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N"
[ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N"
append bss_conf "macaddr_acl=2" "$N"
}
;;
esac
local auth_algs=$((($auth_mode_shared << 1) | $auth_mode_open))
local auth_algs="$((($auth_mode_shared << 1) | $auth_mode_open))"
append bss_conf "auth_algs=${auth_algs:-1}" "$N"
append bss_conf "wpa=$wpa" "$N"
[ -n "$wpa_pairwise" ] && append bss_conf "wpa_pairwise=$wpa_pairwise" "$N"
@@ -887,10 +869,11 @@ hostapd_set_bss_options() {
append bss_conf "iapp_interface=$ifname" "$N"
}
json_get_vars time_advertisement time_zone wnm_sleep_mode wnm_sleep_mode_no_keys bss_transition
json_get_vars time_advertisement time_zone wnm_sleep_mode wnm_sleep_mode_no_keys bss_transition mbo
set_default bss_transition 0
set_default wnm_sleep_mode 0
set_default wnm_sleep_mode_no_keys 0
set_default mbo 0
[ -n "$time_advertisement" ] && append bss_conf "time_advertisement=$time_advertisement" "$N"
[ -n "$time_zone" ] && append bss_conf "time_zone=$time_zone" "$N"
@@ -899,9 +882,11 @@ hostapd_set_bss_options() {
[ "$wnm_sleep_mode_no_keys" -eq "1" ] && append bss_conf "wnm_sleep_mode_no_keys=1" "$N"
fi
[ "$bss_transition" -eq "1" ] && append bss_conf "bss_transition=1" "$N"
[ "$mbo" -eq 1 ] && append bss_conf "mbo=1" "$N"
json_get_vars ieee80211k rrm_neighbor_report rrm_beacon_report
json_get_vars ieee80211k rrm_neighbor_report rrm_beacon_report rnr
set_default ieee80211k 0
set_default rnr 0
if [ "$ieee80211k" -eq "1" ]; then
set_default rrm_neighbor_report 1
set_default rrm_beacon_report 1
@@ -912,6 +897,7 @@ hostapd_set_bss_options() {
[ "$rrm_neighbor_report" -eq "1" ] && append bss_conf "rrm_neighbor_report=1" "$N"
[ "$rrm_beacon_report" -eq "1" ] && append bss_conf "rrm_beacon_report=1" "$N"
[ "$rnr" -eq "1" ] && append bss_conf "rnr=1" "$N"
json_get_vars ftm_responder stationary_ap lci civic
set_default ftm_responder 0
@@ -925,39 +911,44 @@ hostapd_set_bss_options() {
}
fi
json_get_vars ieee80211r
set_default ieee80211r 0
if [ "$wpa" -ge "1" ]; then
json_get_vars ieee80211r
set_default ieee80211r 0
if [ "$fils" -gt 0 ]; then
json_get_vars fils_realm
set_default fils_realm "$(echo "$ssid" | md5sum | head -c 8)"
fi
append bss_conf "wpa_disable_eapol_key_retries=$wpa_disable_eapol_key_retries" "$N"
hostapd_append_wpa_key_mgmt
[ -n "$wpa_key_mgmt" ] && append bss_conf "wpa_key_mgmt=$wpa_key_mgmt" "$N"
fi
if [ "$wpa" -ge "2" ]; then
if [ "$ieee80211r" -gt "0" ]; then
json_get_vars mobility_domain ft_psk_generate_local ft_over_ds reassociation_deadline
set_default mobility_domain "$(echo "$ssid" | md5sum | head -c 4)"
set_default ft_over_ds 1
set_default ft_over_ds 0
set_default reassociation_deadline 1000
skip_kh_setup=0
case "$auth_type" in
psk|psk-sae)
psk)
set_default ft_psk_generate_local 1
skip_kh_setup="$ft_psk_generate_local"
;;
*)
set_default ft_psk_generate_local 0
;;
esac
case "$auth_type" in
*sae*) skip_kh_setup=0;;
esac
[ -n "$network_ifname" ] && append bss_conf "ft_iface=$network_ifname" "$N"
append bss_conf "mobility_domain=$mobility_domain" "$N"
append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N"
append bss_conf "ft_over_ds=$ft_over_ds" "$N"
append bss_conf "reassociation_deadline=$reassociation_deadline" "$N"
if [ "$skip_kh_setup" -eq "0" ]; then
if [ "$ft_psk_generate_local" -eq "0" ]; then
json_get_vars r0_key_lifetime r1_key_holder pmk_r1_push
json_get_values r0kh r0kh
json_get_values r1kh r1kh
@@ -966,10 +957,14 @@ hostapd_set_bss_options() {
set_default pmk_r1_push 0
[ -n "$r0kh" -a -n "$r1kh" ] || {
key=`echo -n "$mobility_domain/$auth_secret" | md5sum | awk '{print $1}'`
if [ -z "$auth_secret" -a -z "$key" ]; then
wireless_setup_vif_failed FT_KEY_CANT_BE_DERIVED
return 1
fi
ft_key=`echo -n "$mobility_domain/${auth_secret:-${key}}" | md5sum | awk '{print $1}'`
set_default r0kh "ff:ff:ff:ff:ff:ff,*,$key"
set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$key"
set_default r0kh "ff:ff:ff:ff:ff:ff,*,$ft_key"
set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$ft_key"
}
[ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N"
@@ -984,18 +979,7 @@ hostapd_set_bss_options() {
done
fi
fi
if [ "$fils" -gt 0 ]; then
json_get_vars fils_realm
set_default fils_realm "$(echo "$ssid" | md5sum | head -c 8)"
fi
append bss_conf "wpa_disable_eapol_key_retries=$wpa_disable_eapol_key_retries" "$N"
hostapd_append_wpa_key_mgmt
[ -n "$wpa_key_mgmt" ] && append bss_conf "wpa_key_mgmt=$wpa_key_mgmt" "$N"
fi
if [ "$wpa" -ge "2" ]; then
if [ -n "$network_bridge" -a "$rsn_preauth" = 1 ]; then
set_default auth_cache 1
append bss_conf "rsn_preauth=1" "$N"
@@ -1020,16 +1004,11 @@ hostapd_set_bss_options() {
json_get_vars ieee80211w_mgmt_cipher ieee80211w_max_timeout ieee80211w_retry_timeout
append bss_conf "ieee80211w=$ieee80211w" "$N"
[ "$ieee80211w" -gt "0" ] && {
case "$auth_type" in
eap192)
if [ "$auth_type" = "eap192" ]; then
append bss_conf "group_mgmt_cipher=BIP-GMAC-256" "$N"
append bss_conf "group_cipher=GCMP-256" "$N"
;;
*)
else
append bss_conf "group_mgmt_cipher=${ieee80211w_mgmt_cipher:-AES-128-CMAC}" "$N"
;;
esac
fi
[ -n "$ieee80211w_max_timeout" ] && \
append bss_conf "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N"
[ -n "$ieee80211w_retry_timeout" ] && \
@@ -1144,13 +1123,12 @@ hostapd_set_bss_options() {
local hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \
osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \
hs20_t_c_server_url hs20_release
hs20_t_c_server_url
json_get_vars hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \
osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \
hs20_t_c_server_url hs20_release
hs20_t_c_server_url
set_default hs20 0
set_default hs20_release 1
set_default disable_dgaf $hs20
set_default osen 0
set_default anqp_domain_id 0
@@ -1158,7 +1136,6 @@ hostapd_set_bss_options() {
if [ "$hs20" = "1" ]; then
append bss_conf "hs20=1" "$N"
append_hs20_icons
append bss_conf "hs20_release=$hs20_release" "$N"
append bss_conf "disable_dgaf=$disable_dgaf" "$N"
append bss_conf "osen=$osen" "$N"
append bss_conf "anqp_domain_id=$anqp_domain_id" "$N"
@@ -1184,6 +1161,8 @@ hostapd_set_bss_options() {
[ -n "$private_key" ] && append bss_conf "private_key=$private_key" "$N"
[ -n "$private_key_passwd" ] && append bss_conf "private_key_passwd=$private_key_passwd" "$N"
[ -n "$server_id" ] && append bss_conf "server_id=$server_id" "$N"
[ -n "$radius_server_clients" ] && append bss_conf "radius_server_clients=$radius_server_clients" "$N"
[ -n "$radius_server_auth_port" ] && append bss_conf "radius_server_auth_port=$radius_server_auth_port" "$N"
fi
set_default multicast_to_unicast_all 0
@@ -1200,7 +1179,15 @@ hostapd_set_bss_options() {
append bss_conf "per_sta_vif=$per_sta_vif" "$N"
fi
[ -n "$uci_section" ] && append bss_conf "uci_section=$uci_section" "$N"
if [ "$apup" -gt 0 ]; then
append bss_conf "apup=$apup" "$N"
local apup_peer_ifname_prefix
json_get_vars apup_peer_ifname_prefix
if [ -n "$apup_peer_ifname_prefix" ] ; then
append bss_conf "apup_peer_ifname_prefix=$apup_peer_ifname_prefix" "$N"
fi
fi
json_get_values opts hostapd_bss_options
for val in $opts; do
@@ -1226,7 +1213,7 @@ hostapd_set_log_options() {
set_default log_iapp 1
set_default log_mlme 1
local log_mask=$(( \
local log_mask="$(( \
($log_80211 << 0) | \
($log_8021x << 1) | \
($log_radius << 2) | \
@@ -1234,7 +1221,7 @@ hostapd_set_log_options() {
($log_driver << 4) | \
($log_iapp << 5) | \
($log_mlme << 6) \
))
))"
append "$var" "logger_syslog=$log_mask" "$N"
append "$var" "logger_syslog_level=$log_level" "$N"
@@ -1343,15 +1330,15 @@ wpa_supplicant_add_network() {
json_get_vars \
ssid bssid key \
basic_rate mcast_rate \
ieee80211w ieee80211r fils \
ieee80211w ieee80211r fils ocv \
multi_ap \
default_disabled
case "$auth_type" in
sae|owe|eap-eap256)
sae|owe|eap2|eap192)
set_default ieee80211w 2
;;
psk-sae|eap192|eap256)
psk-sae)
set_default ieee80211w 1
;;
esac
@@ -1378,7 +1365,7 @@ wpa_supplicant_add_network() {
}
[ "$_w_mode" = "mesh" ] && {
json_get_vars mesh_id mesh_fwding mesh_rssi_threshold
json_get_vars mesh_id mesh_fwding mesh_rssi_threshold encryption
[ -n "$mesh_id" ] && ssid="${mesh_id}"
append network_data "mode=5" "$N$T"
@@ -1386,7 +1373,7 @@ wpa_supplicant_add_network() {
[ -n "$mesh_rssi_threshold" ] && append network_data "mesh_rssi_threshold=${mesh_rssi_threshold}" "$N$T"
[ -n "$freq" ] && wpa_supplicant_set_fixed_freq "$freq" "$htmode"
[ "$noscan" = "1" ] && append network_data "noscan=1" "$N$T"
append wpa_key_mgmt "SAE"
[ "$encryption" = "none" -o -z "$encryption" ] || append wpa_key_mgmt "SAE"
scan_ssid=""
}
@@ -1395,6 +1382,8 @@ wpa_supplicant_add_network() {
[ "$default_disabled" = 1 ] && append network_data "disabled=1" "$N$T"
}
[ -n "$ocv" ] && append network_data "ocv=$ocv" "$N$T"
case "$auth_type" in
none) ;;
owe)
@@ -1418,18 +1407,18 @@ wpa_supplicant_add_network() {
key_mgmt="$wpa_key_mgmt"
if [ ${#key} -eq 64 ]; then
passphrase="psk=${key}"
if [ "$_w_mode" = "mesh" ] || [ "$auth_type" = "sae" ]; then
passphrase="sae_password=\"${key}\""
else
if [ "$_w_mode" = "mesh" ]; then
passphrase="sae_password=\"${key}\""
if [ ${#key} -eq 64 ]; then
passphrase="psk=${key}"
else
passphrase="psk=\"${key}\""
fi
fi
append network_data "$passphrase" "$N$T"
;;
eap|eap192|eap-eap256|eap256)
eap|eap2|eap192)
hostapd_append_wpa_key_mgmt
key_mgmt="$wpa_key_mgmt"
@@ -1633,30 +1622,3 @@ EOF
fi
return 0
}
wpa_supplicant_run() {
local ifname="$1"
local hostapd_ctrl="$2"
_wpa_supplicant_common "$ifname"
ubus wait_for wpa_supplicant
local supplicant_res="$(ubus call wpa_supplicant config_add "{ \
\"driver\": \"${_w_driver:-wext}\", \"ctrl\": \"$_rpath\", \
\"iface\": \"$ifname\", \"config\": \"$_config\" \
${network_bridge:+, \"bridge\": \"$network_bridge\"} \
${hostapd_ctrl:+, \"hostapd_ctrl\": \"$hostapd_ctrl\"} \
}")"
ret="$?"
[ "$ret" != 0 -o -z "$supplicant_res" ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED
wireless_add_process "$(jsonfilter -s "$supplicant_res" -l 1 -e @.pid)" "/usr/sbin/wpa_supplicant" 1 1
return $ret
}
hostapd_common_cleanup() {
killall meshd-nl80211
}

View File

@@ -1,6 +1,6 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open } from "common";
import { wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open, wdev_set_radio_mask } from "common";
let ubus = libubus.connect(null, 60);
@@ -22,6 +22,32 @@ hostapd.data.file_fields = {
eap_sim_db: true,
};
hostapd.data.iface_fields = {
ft_iface: true,
upnp_iface: true,
snoop_iface: true,
bridge: true,
iapp_interface: true,
};
hostapd.data.bss_info_fields = {
// radio
hw_mode: true,
channel: true,
ieee80211ac: true,
ieee80211ax: true,
// bss
bssid: true,
ssid: true,
wpa: true,
wpa_key_mgmt: true,
wpa_pairwise: true,
auth_algs: true,
ieee80211w: true,
owe_transition_ifname: true,
};
function iface_remove(cfg)
{
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
@@ -31,7 +57,7 @@ function iface_remove(cfg)
wdev_remove(bss.ifname);
}
function iface_gen_config(phy, config, start_disabled)
function iface_gen_config(config, start_disabled)
{
let str = `data:
${join("\n", config.radio.data)}
@@ -92,7 +118,7 @@ function iface_freq_info(iface, config, params)
function iface_add(phy, config, phy_status)
{
let config_inline = iface_gen_config(phy, config, !!phy_status);
let config_inline = iface_gen_config(config, !!phy_status);
let bss = config.bss[0];
let ret = hostapd.add_iface(`bss_config=${phy}:${config_inline}`);
@@ -123,12 +149,16 @@ function iface_config_macaddr_list(config)
return macaddr_list;
}
function iface_update_supplicant_macaddr(phy, config)
function iface_update_supplicant_macaddr(phydev, config)
{
let macaddr_list = [];
for (let i = 0; i < length(config.bss); i++)
push(macaddr_list, config.bss[i].bssid);
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", {
phy: phydev.name,
radio: phydev.radio ?? -1,
macaddr: macaddr_list
});
}
function __iface_pending_next(pending, state, ret, data)
@@ -143,19 +173,22 @@ function __iface_pending_next(pending, state, ret, data)
delete pending.defer;
switch (state) {
case "init":
let macaddr_list = [];
for (let i = 0; i < length(config.bss); i++)
push(macaddr_list, config.bss[i].bssid);
pending.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
iface_update_supplicant_macaddr(phydev, config);
return "create_bss";
case "create_bss":
let err = wdev_create(phy, bss.ifname, { mode: "ap" });
let err = phydev.wdev_add(bss.ifname, {
mode: "ap",
radio: phydev.radio,
});
if (err) {
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
return null;
}
pending.call("wpa_supplicant", "phy_status", { phy: phy });
pending.call("wpa_supplicant", "phy_status", {
phy: phydev.phy,
radio: phydev.radio,
});
return "check_phy";
case "check_phy":
let phy_status = data;
@@ -165,12 +198,20 @@ function __iface_pending_next(pending, state, ret, data)
hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
}
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
pending.call("wpa_supplicant", "phy_set_state", {
phy: phydev.phy,
radio: phydev.radio,
stop: true
});
return "wpas_stopped";
case "wpas_stopped":
if (!iface_add(phy, config))
hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
pending.call("wpa_supplicant", "phy_set_state", {
phy: phydev.phy,
radio: phydev.radio,
stop: false
});
return null;
case "done":
default:
@@ -185,9 +226,14 @@ function iface_pending_next(ret, data)
let cfg = this;
while (pending) {
this.next_state = __iface_pending_next(cfg, this.next_state, ret, data);
if (!this.next_state) {
__iface_pending_next(cfg, "done");
try {
this.next_state = __iface_pending_next(cfg, this.next_state, ret, data);
if (!this.next_state) {
__iface_pending_next(cfg, "done");
return;
}
} catch(e) {
hostapd.printf(`Exception: ${e}\n${e.stacktrace[0].context}`);
return;
}
pending = !this.defer;
@@ -229,6 +275,16 @@ function iface_pending_init(phydev, config)
pending.next();
}
function iface_macaddr_init(phydev, config, macaddr_list)
{
let macaddr_data = {
num_global: config.num_global_macaddr ?? 1,
mbssid: config.mbssid ?? 0,
};
return phydev.macaddr_init(macaddr_list, macaddr_data);
}
function iface_restart(phydev, config, old_config)
{
let phy = phydev.name;
@@ -246,7 +302,7 @@ function iface_restart(phydev, config, old_config)
return;
}
phydev.macaddr_init(iface_config_macaddr_list(config));
iface_macaddr_init(phydev, config, iface_config_macaddr_list(config));
for (let i = 0; i < length(config.bss); i++) {
let bss = config.bss[i];
if (bss.default_macaddr)
@@ -314,9 +370,24 @@ function bss_remove_file_fields(config)
return new_cfg;
}
function bss_ifindex_list(config)
{
config = filter(config, (line) => !!hostapd.data.iface_fields[split(line, "=")[0]]);
return join(",", map(config, (line) => {
try {
let file = "/sys/class/net/" + split(line, "=")[1] + "/ifindex";
let val = trim(readfile(file));
return val;
} catch (e) {
return "";
}
}));
}
function bss_config_hash(config)
{
return hostapd.sha1(remove_file_fields(config) + "");
return hostapd.sha1(remove_file_fields(config) + bss_ifindex_list(config));
}
function bss_find_existing(config, prev_config, prev_hash)
@@ -348,7 +419,7 @@ function get_config_bss(config, idx)
return hostapd.bss[ifname];
}
function iface_reload_config(phydev, config, old_config)
function iface_reload_config(name, phydev, config, old_config)
{
let phy = phydev.name;
@@ -358,13 +429,13 @@ function iface_reload_config(phydev, config, old_config)
if (is_equal(old_config.bss, config.bss))
return true;
if (hostapd.data.pending_config[phy])
if (hostapd.data.pending_config[name])
return false;
if (!old_config.bss || !old_config.bss[0])
return false;
let iface = hostapd.interfaces[phy];
let iface = hostapd.interfaces[name];
let iface_name = old_config.bss[0].ifname;
if (!iface) {
hostapd.printf(`Could not find previous interface ${iface_name}`);
@@ -459,7 +530,7 @@ function iface_reload_config(phydev, config, old_config)
return false;
let ifname = old_config.bss[i].ifname;
hostapd.printf(`Remove bss '${ifname}' on phy '${phy}'`);
hostapd.printf(`Remove bss '${ifname}' on phy '${name}'`);
prev_bss.delete();
wdev_remove(ifname);
}
@@ -500,11 +571,7 @@ function iface_reload_config(phydev, config, old_config)
}
// Step 6: assign BSSID for newly created interfaces
let macaddr_data = {
num_global: config.num_global_macaddr ?? 1,
mbssid: config.mbssid ?? 0,
};
macaddr_list = phydev.macaddr_init(macaddr_list, macaddr_data);
macaddr_list = iface_macaddr_init(phydev, config, macaddr_list);
for (let i = 0; i < length(config.bss); i++) {
if (bss_list[i])
continue;
@@ -528,13 +595,13 @@ function iface_reload_config(phydev, config, old_config)
let addr = phydev.macaddr_next(i);
if (!addr) {
hostapd.printf(`Failed to generate mac address for phy ${phy}`);
hostapd.printf(`Failed to generate mac address for phy ${name}`);
return false;
}
bsscfg.bssid = addr;
}
let config_inline = iface_gen_config(phy, config);
let config_inline = iface_gen_config(config);
// Step 7: fill in the gaps with new interfaces
for (let i = 0; i < length(config.bss); i++) {
@@ -544,17 +611,17 @@ function iface_reload_config(phydev, config, old_config)
if (bss)
continue;
hostapd.printf(`Add bss ${ifname} on phy ${phy}`);
hostapd.printf(`Add bss ${ifname} on phy ${name}`);
bss_list[i] = iface.add_bss(config_inline, i);
if (!bss_list[i]) {
hostapd.printf(`Failed to add new bss ${ifname} on phy ${phy}`);
hostapd.printf(`Failed to add new bss ${ifname} on phy ${name}`);
return false;
}
}
// Step 8: update interface bss order
if (!iface.set_bss_order(bss_list)) {
hostapd.printf(`Failed to update BSS order on phy '${phy}'`);
hostapd.printf(`Failed to update BSS order on phy '${name}'`);
return false;
}
@@ -585,7 +652,7 @@ function iface_reload_config(phydev, config, old_config)
if (is_equal(config.bss[i], bss_list_cfg[i]))
continue;
hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`);
hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${name}'`);
if (bss.set_config(config_inline, i) < 0) {
hostapd.printf(`Failed to set config for bss ${ifname}`);
return false;
@@ -595,35 +662,36 @@ function iface_reload_config(phydev, config, old_config)
return true;
}
function iface_set_config(phy, config)
function iface_set_config(name, config)
{
let old_config = hostapd.data.config[phy];
let old_config = hostapd.data.config[name];
hostapd.data.config[phy] = config;
hostapd.data.config[name] = config;
if (!config) {
hostapd.remove_iface(phy);
hostapd.remove_iface(name);
return iface_remove(old_config);
}
let phydev = phy_open(phy);
let phy = config.phy;
let phydev = phy_open(phy, config.radio_idx);
if (!phydev) {
hostapd.printf(`Failed to open phy ${phy}`);
return false;
}
try {
let ret = iface_reload_config(phydev, config, old_config);
let ret = iface_reload_config(name, phydev, config, old_config);
if (ret) {
iface_update_supplicant_macaddr(phy, config);
hostapd.printf(`Reloaded settings for phy ${phy}`);
iface_update_supplicant_macaddr(phydev, config);
hostapd.printf(`Reloaded settings for phy ${name}`);
return 0;
}
} catch (e) {
hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`);
hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`);
}
hostapd.printf(`Restart interface for phy ${phy}`);
hostapd.printf(`Restart interface for phy ${name}`);
let ret = iface_restart(phydev, config, old_config);
return ret;
@@ -642,13 +710,18 @@ function config_add_bss(config, name)
return bss;
}
function iface_load_config(filename)
function iface_load_config(phy, radio, filename)
{
let f = open(filename, "r");
if (!f)
return null;
if (radio < 0)
radio = null;
let config = {
phy,
radio_idx: radio,
radio: {
data: []
},
@@ -675,7 +748,7 @@ function iface_load_config(filename)
if (val[0] == "#num_global_macaddr" ||
val[0] == "mbssid")
config[val[0]] = int(val[1]);
config[substr(val[0], 1)] = int(val[1]);
push(config.radio.data, line);
}
@@ -723,16 +796,39 @@ function ex_wrap(func) {
};
}
function phy_name(phy, radio)
{
if (!phy)
return null;
if (radio != null && radio >= 0)
phy += "." + radio;
return phy;
}
function bss_config(bss_name) {
for (let phy, config in hostapd.data.config) {
if (!config)
continue;
for (let bss in config.bss)
if (bss.ifname == bss_name)
return [ config, bss ];
}
}
let main_obj = {
reload: {
args: {
phy: "",
radio: 0,
},
call: ex_wrap(function(req) {
let phy_list = req.args.phy ? [ req.args.phy ] : keys(hostapd.data.config);
let phy_list = req.args.phy ? [ phy_name(req.args.phy, req.args.radio) ] : keys(hostapd.data.config);
for (let phy_name in phy_list) {
let phy = hostapd.data.config[phy_name];
let config = iface_load_config(phy.orig_file);
let config = iface_load_config(phy.phy, radio, phy.orig_file);
iface_set_config(phy_name, config);
}
@@ -742,6 +838,7 @@ let main_obj = {
apsta_state: {
args: {
phy: "",
radio: 0,
up: true,
frequency: 0,
sec_chan_offset: 0,
@@ -749,10 +846,10 @@ let main_obj = {
csa_count: 0,
},
call: ex_wrap(function(req) {
if (req.args.up == null || !req.args.phy)
let phy = phy_name(req.args.phy, req.args.radio);
if (req.args.up == null || !phy)
return libubus.STATUS_INVALID_ARGUMENT;
let phy = req.args.phy;
let config = hostapd.data.config[phy];
if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname)
return 0;
@@ -788,10 +885,11 @@ let main_obj = {
},
config_get_macaddr_list: {
args: {
phy: ""
phy: "",
radio: 0,
},
call: ex_wrap(function(req) {
let phy = req.args.phy;
let phy = phy_name(req.args.phy, req.args.radio);
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
@@ -810,30 +908,34 @@ let main_obj = {
config_set: {
args: {
phy: "",
radio: 0,
config: "",
prev_config: "",
},
call: ex_wrap(function(req) {
let phy = req.args.phy;
let radio = req.args.radio;
let name = phy_name(phy, radio);
let file = req.args.config;
let prev_file = req.args.prev_config;
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
if (prev_file && !hostapd.data.config[phy]) {
let config = iface_load_config(prev_file);
if (prev_file && !hostapd.data.config[name]) {
let config = iface_load_config(phy, radio, prev_file);
if (config)
config.radio.data = [];
hostapd.data.config[phy] = config;
hostapd.data.config[name] = config;
}
let config = iface_load_config(file);
let config = iface_load_config(phy, radio, file);
hostapd.printf(`Set new config for phy ${phy}: ${file}`);
iface_set_config(phy, config);
hostapd.printf(`Set new config for phy ${name}: ${file}`);
iface_set_config(name, config);
hostapd.data.auth_obj.notify("reload", { phy });
if (hostapd.data.auth_obj)
hostapd.data.auth_obj.notify("reload", { phy, radio });
return {
pid: hostapd.getpid()
@@ -869,11 +971,38 @@ let main_obj = {
return 0;
})
},
bss_info: {
args: {
iface: ""
},
call: ex_wrap(function(req) {
if (!req.args.iface)
return libubus.STATUS_INVALID_ARGUMENT;
let config = bss_config(req.args.iface);
if (!config)
return libubus.STATUS_NOT_FOUND;
let bss = config[1];
config = config[0];
let ret = {};
for (let line in [ ...config.radio.data, ...bss.data ]) {
let fields = split(line, "=", 2);
let name = fields[0];
if (hostapd.data.bss_info_fields[name])
ret[name] = fields[1];
}
return ret;
})
},
};
hostapd.data.ubus = ubus;
hostapd.data.obj = ubus.publish("hostapd", main_obj);
let auth_obj = {};
hostapd.data.auth_obj = ubus.publish("hostapd-auth", auth_obj);
@@ -889,7 +1018,7 @@ function bss_event(type, name, data) {
return {
shutdown: function() {
for (let phy in hostapd.data.config)
iface_set_config(phy, null);
iface_set_config(phy);
hostapd.ubus.disconnect();
},
afc_request: function(iface, data) {
@@ -898,13 +1027,22 @@ return {
return;
return ret.data;
},
bss_add: function(name, obj) {
bss_create: function(phy, name, obj) {
phy = hostapd.data.config[phy];
if (!phy)
return;
if (phy.radio_idx != null && phy.radio_idx >= 0)
wdev_set_radio_mask(name, 1 << phy.radio_idx);
},
bss_add: function(phy, name, obj) {
bss_event("add", name);
},
bss_reload: function(name, obj, reconf) {
bss_event("reload", name, { reconf: reconf != 0 });
bss_reload: function(phy, name, obj, reconf) {
//bss_event("reload", name, { reconf: reconf != 0 });
bss_event("reload", name, { reconf: false });
},
bss_remove: function(name, obj) {
bss_remove: function(phy, name, obj) {
bss_event("remove", name);
},
sta_auth: function(iface, sta) {
@@ -913,7 +1051,8 @@ return {
let data_cb = (type, data) => {
ret = { ...ret, ...data };
};
hostapd.data.auth_obj.notify("sta_auth", msg, data_cb, null, null, 1000);
if (hostapd.data.auth_obj)
hostapd.data.auth_obj.notify("sta_auth", msg, data_cb, null, null, 1000);
return ret;
},
sta_connected: function(iface, sta, data) {
@@ -922,7 +1061,8 @@ return {
let data_cb = (type, data) => {
ret = { ...ret, ...data };
};
hostapd.data.auth_obj.notify("sta_connected", msg, data_cb, null, null, 1000);
if (hostapd.data.auth_obj)
hostapd.data.auth_obj.notify("sta_connected", msg, data_cb, null, null, 1000);
return ret;
},
};

View File

@@ -0,0 +1,355 @@
#!/usr/bin/env ucode
'use strict';
import * as uloop from 'uloop';
import * as libubus from 'ubus';
uloop.init();
let ubus = libubus.connect();
let interfaces = {};
let ssids = {};
let cache = {};
let subs_hapd = [];
let reload_timer;
let gc_timer;
let timeout = 48 * 60 * 60;
function event_cb_6g(req) {
//printf('6g %s %.J\n', req.data, req.type);
if (req.type != 'auth' && req.type != 'probe')
return 0;
let addr = req.data.address;
let iface = interfaces[req.data.ifname];
if (!iface)
return 0;
let ssid = iface.ssid;
if (!ssid || !length(ssids[ssid].keys))
return 0;
let ssid_cache = cache[ssid];
if (ssid_cache && ssid_cache[addr])
return 0;
if (req.type == 'probe') {
printf(`Ignore probe ${req.type} on ${req.data.ifname} from ${addr}\n`);
return 1;
}
printf(`reject ${req.type} on ${req.data.ifname} from ${addr}\n`);
return 5;
}
function event_cb(req) {
//printf('normal %s %.J\n', req.data, req.type);
if (req.type != 'probe')
return 0;
let addr = req.data.address;
let iface = interfaces[req.data.ifname];
if (!iface)
return 0;
let ssid = iface.ssid;
if (!ssid || !length(ssids[ssid].keys))
return 0;
let ssid_cache = cache[ssid];
if (ssid_cache && ssid_cache[addr])
return 0;
printf(`reply to ${req.type} on ${req.data.ifname} from ${addr} without 6G RNR\n`);
return 2;
}
function create_6g_subscriber() {
for (let cur_sub in subs_hapd)
cur_sub.remove();
subs_hapd = [];
for (let ifname, iface in interfaces) {
let obj = 'hostapd.' + ifname;
let cur_sub;
if (iface.band == '6g')
cur_sub = ubus.subscriber((req) => event_cb_6g(req));
else
cur_sub = ubus.subscriber((req) => event_cb(req));
cur_sub.subscribe(obj);
push(subs_hapd, cur_sub);
printf(`subscribe ${ifname}\n`);
ubus.call(obj, 'notify_response', { notify_response: 1 });
}
}
function cache_gc() {
let ts = time();
for (let ssid in keys(cache)) {
if (!ssids[ssid]) {
delete cache[ssid];
continue;
}
let ssid_cache = cache[ssid];
ssid = ssids[ssid];
for (let addr in keys(ssid_cache)) {
let sta = ssid_cache[addr];
let keep = ts < cache.timeout;
if (keep && !ssid.keys[sta.key])
keep = false;
if (keep)
sta.keydata = ssid.keys[sta.key];
if (!keep)
delete cache[addr];
}
}
}
function netifd_reload() {
let data = ubus.call('network.wireless', 'status');
ssids = {};
interfaces = {};
for (let radio_name, radio in data) {
if (!radio.up)
continue;
for (let iface in radio.interfaces) {
let config = iface.config;
if (config.mode != 'ap' || !iface.ifname)
continue;
let band = radio.config.band;
let nr_data = ubus.call('hostapd.' + iface.ifname, 'rrm_nr_get_own');
let nr;
if (nr_data && nr_data.value && nr_data.value[2])
nr = nr_data.value[2];
interfaces[iface.ifname] = {
band, nr,
ssid: config.ssid,
};
ssids[config.ssid] ??= {
interfaces: [],
keys: {},
bands: {},
};
let ssid = ssids[config.ssid];
push(ssid.interfaces, iface.ifname);
ssid.bands[band] = iface.ifname;
for (let sta in iface.stations) {
let stacfg = sta.config;
let key = stacfg.key;
if (!key)
continue;
let keydata = {};
let vid = stacfg.vid;
if (vid)
keydata.vlan = +vid;
let mac = stacfg.mac;
if (mac)
keydata.mac = mac;
ssid.keys[key] = keydata;
}
}
}
printf('New config: %.J\n', { ssids, interfaces });
cache_gc();
create_6g_subscriber();
}
function iface_ssid(ifname) {
let iface = interfaces[ifname];
if (!iface)
return;
return iface.ssid;
}
function sta_cache_entry_get(ssid, addr) {
let ssid_cache = cache[ssid] ?? {};
let entry = ssid_cache[addr];
if (entry)
entry.timeout = time() + timeout;
printf(`Get cache entry ssid=${ssid} addr=${addr}: ${entry}\n`);
return entry;
}
function sta_cache_entry_add(ssid, addr, key) {
cache[ssid] ??= {};
let ssid_cache = cache[ssid];
let ssid_data = ssids[ssid];
let keydata = ssid_data.keys[key];
let cache_data = {
timeout: time() + timeout,
ssid, key,
data: keydata ?? {},
};
ssid_cache[addr] = cache_data;
printf(`Added cache entry ssid=${ssid} addr=${addr}\n`);
return cache_data;
}
function ssid_psk(ssid, addr) {
ssid = ssids[ssid];
if (!ssid)
return [];
let specific = [];
let rest = [];
for (let k, v in ssid.keys)
if (v.mac == addr)
push(specific, k);
else if (!v.mac)
push(rest, k);
if (length(specific))
return specific;
return rest;
}
function sta_auth_psk(ifname, addr) {
let ssid = iface_ssid(ifname);
if (!ssid)
return;
if (interfaces[ifname]?.band == '6g') {
let cache = sta_cache_entry_get(ssid, addr);
if (cache)
return [ cache.key ];
} else if (cache[ssid]) {
delete cache[ssid][addr];
}
return ssid_psk(ssid, addr);
}
function sta_auth_cache(ifname, addr, idx, phrase) {
let ssid = iface_ssid(ifname);
if (!ssid)
return;
let cache = sta_cache_entry_get(ssid, addr);
if (cache)
return cache.data;
let psk = ssid_psk(ssid, addr);
if (!psk)
return;
psk = psk[idx];
if (!psk)
psk = phrase;
if (!psk)
return;
cache = sta_cache_entry_add(ssid, addr, psk);
if (!cache)
return;
let ssid_data = ssids[ssid];
if (!ssid_data)
return cache.data;
let target_ifname = ssid_data.bands['6g'];
if (!target_ifname)
return cache.data;
let target_iface = interfaces[target_ifname];
if (!target_iface)
return cache.data;
cache.timer = uloop.timer(30 * 1000, () => {
let msg = {
addr,
disassociation_imminent: false,
neighbors: [
target_iface.nr
],
abridged: false,
};
printf(`ubus call hostapd.${ifname} bss_transition_request '${msg}'\n`);
ubus.call('hostapd.' + ifname, 'bss_transition_request', msg);
delete cache.timer;
});
return cache.data;
}
function auth_cb(msg) {
let data = msg.data;
printf(`Event ${msg.type}: ${msg.data}\n`);
switch (msg.type) {
case 'sta_auth':
return {
psk: sta_auth_psk(data.iface, data.sta),
force_psk: true,
};
case 'sta_connected':
if (data.psk_idx == null)
return;
return sta_auth_cache(data.iface, data.sta, data.psk_idx, data.psk);
case 'reload':
netifd_reload();
reload_timer.set(5000);
break;
}
}
let ubus_methods = {
state: {
call: function(req) {
return {
interfaces,
ssids,
cache,
};
},
args: {
}
},
flush: {
call: function() {
for (let ssid, data in ssids) {
let band = '6g';
let iface = data.bands[band];
if (!iface)
continue;
let clients = ubus.call('hostapd.' + iface, 'get_clients');
for (let addr, client in clients.clients) {
if (!cache[ssid])
continue;
delete cache[ssid][addr];
ubus.call('hostapd.' + iface, 'del_client', { addr });
}
}
},
args: {}
},
};
reload_timer = uloop.timer(-1, () => { netifd_reload(); });
gc_timer = uloop.timer(1000, () => { gc_timer.set(30 * 1000); cache_gc(); });
ubus.publish('mpsk', ubus_methods);
let sub = ubus.subscriber(auth_cb);
let listener = ubus.listener('ubus.object.add', (event, msg) => {
if (msg.path == 'hostapd-auth')
sub.subscribe(msg.path);
});
sub.subscribe('hostapd-auth');
netifd_reload();
uloop.run();

View File

@@ -0,0 +1,13 @@
#!/bin/sh /etc/rc.common
START=19
USE_PROCD=1
NAME=mpskd
start_service() {
procd_open_instance mpskd
procd_set_param command /usr/share/hostap/mpskd
procd_set_param respawn
procd_close_instance
}

View File

@@ -1,24 +1,13 @@
#!/usr/bin/env ucode
'use strict';
import { vlist_new, is_equal, wdev_create, wdev_remove, phy_open } from "/usr/share/hostap/common.uc";
import { vlist_new, is_equal, wdev_set_mesh_params, wdev_remove, wdev_set_up, phy_open } from "/usr/share/hostap/common.uc";
import { readfile, writefile, basename, readlink, glob } from "fs";
let libubus = require("ubus");
let keep_devices = {};
let phy = shift(ARGV);
let phy_name = shift(ARGV);
let command = shift(ARGV);
let phydev;
const mesh_params = [
"mesh_retry_timeout", "mesh_confirm_timeout", "mesh_holding_timeout", "mesh_max_peer_links",
"mesh_max_retries", "mesh_ttl", "mesh_element_ttl", "mesh_hwmp_max_preq_retries",
"mesh_path_refresh_time", "mesh_min_discovery_timeout", "mesh_hwmp_active_path_timeout",
"mesh_hwmp_preq_min_interval", "mesh_hwmp_net_diameter_traversal_time", "mesh_hwmp_rootmode",
"mesh_hwmp_rann_interval", "mesh_gate_announcements", "mesh_sync_offset_max_neighor",
"mesh_rssi_threshold", "mesh_hwmp_active_path_to_root_timeout", "mesh_hwmp_root_interval",
"mesh_hwmp_confirmation_interval", "mesh_awake_window", "mesh_plink_timeout",
"mesh_auto_open_plinks", "mesh_fwding", "mesh_power_mode"
];
let phy, phydev;
function iface_stop(wdev)
{
@@ -33,7 +22,7 @@ function iface_start(wdev)
let ifname = wdev.ifname;
if (readfile(`/sys/class/net/${ifname}/ifindex`)) {
system([ "ip", "link", "set", "dev", ifname, "down" ]);
wdev_set_up(ifname, false);
wdev_remove(ifname);
}
let wdev_config = {};
@@ -41,12 +30,13 @@ function iface_start(wdev)
wdev_config[key] = wdev[key];
if (!wdev_config.macaddr && wdev.mode != "monitor")
wdev_config.macaddr = phydev.macaddr_next();
wdev_create(phy, ifname, wdev_config);
system([ "ip", "link", "set", "dev", ifname, "up" ]);
phydev.wdev_add(ifname, wdev_config);
wdev_set_up(ifname, true);
let htmode = wdev.htmode || "NOHT";
if (wdev.freq)
system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`);
system(`iw dev ${ifname} set freq ${wdev.freq} ${htmode}`);
if (wdev.mode == "adhoc") {
let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ];
let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, htmode, "fixed-freq" ];
if (wdev.bssid)
push(cmd, wdev.bssid);
for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ])
@@ -54,25 +44,14 @@ function iface_start(wdev)
push(cmd, key, wdev[key]);
system(cmd);
} else if (wdev.mode == "mesh") {
let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ];
let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, htmode ];
for (let key in [ "mcast-rate", "beacon-interval" ])
if (wdev[key])
push(cmd, key, wdev[key]);
system(cmd);
cmd = ["iw", "dev", ifname, "set", "mesh_param" ];
let len = length(cmd);
for (let param in mesh_params)
if (wdev[param])
push(cmd, param, wdev[param]);
if (len == length(cmd))
return;
system(cmd);
wdev_set_mesh_params(ifname, wdev);
}
}
function iface_cb(new_if, old_if)
@@ -106,20 +85,15 @@ function delete_ifname(config)
delete config[key].ifname;
}
function add_existing(phy, config)
function add_existing(phydev, config)
{
let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`);
wdevs = map(wdevs, (arg) => basename(arg));
for (let wdev in wdevs) {
phydev.for_each_wdev((wdev) => {
if (config[wdev])
continue;
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy)
continue;
return;
if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
config[wdev] = {};
}
});
}
function usage()
@@ -135,7 +109,7 @@ Commands:
const commands = {
set_config: function(args) {
let statefile = `/var/run/wdev-${phy}.json`;
let statefile = `/var/run/wdev-${phy_name}.json`;
let new_config = shift(args);
for (let dev in ARGV)
@@ -158,12 +132,12 @@ const commands = {
if (type(old_config) == "object")
config.data = old_config;
add_existing(phy, config.data);
add_existing(phydev, config.data);
add_ifname(config.data);
drop_inactive(config.data);
let ubus = libubus.connect();
let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phydev.name, radio: phydev.radio ?? -1 });
let macaddr_list = [];
if (type(data) == "object" && data.macaddr)
macaddr_list = data.macaddr;
@@ -187,7 +161,7 @@ const commands = {
let macaddr = phydev.macaddr_generate(data);
if (!macaddr) {
warn(`Could not get MAC address for phy ${phy}\n`);
warn(`Could not get MAC address for phy ${phy_name}\n`);
exit(1);
}
@@ -195,12 +169,14 @@ const commands = {
},
};
if (!phy || !command | !commands[command])
if (!phy_name || !command | !commands[command])
usage();
phydev = phy_open(phy);
let phy_split = split(phy_name, ":");
phydev = phy_open(phy_split[0], phy_split[1]);
phy = phydev.phy;
if (!phydev) {
warn(`PHY ${phy} does not exist\n`);
warn(`PHY ${phy_name} does not exist\n`);
exit(1);
}

View File

@@ -1,6 +1,6 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_open } from "common";
import { wdev_create, wdev_set_mesh_params, wdev_remove, is_equal, wdev_set_up, vlist_new, phy_open } from "common";
let ubus = libubus.connect();
@@ -37,9 +37,10 @@ function iface_start(phydev, iface, macaddr_list)
wpas.data.iface_phy[ifname] = phy;
wdev_remove(ifname);
let ret = wdev_create(phy, ifname, wdev_config);
let ret = phydev.wdev_add(ifname, wdev_config);
if (ret)
wpas.printf(`Failed to create device ${ifname}: ${ret}`);
wdev_set_up(ifname, true);
wpas.add_iface(iface.config);
iface.running = true;
}
@@ -60,22 +61,29 @@ function iface_cb(new_if, old_if)
iface_stop(old_if);
}
function prepare_config(config)
function prepare_config(config, radio)
{
config.config_data = readfile(config.config);
return { config: config };
return { config };
}
function set_config(phy_name, config_list)
function set_config(config_name, phy_name, radio, num_global_macaddr, config_list)
{
let phy = wpas.data.config[phy_name];
let phy = wpas.data.config[config_name];
if (radio < 0)
radio = null;
if (!phy) {
phy = vlist_new(iface_cb, false);
wpas.data.config[phy_name] = phy;
phy.name = phy_name;
wpas.data.config[config_name] = phy;
}
phy.radio = radio;
phy.num_global_macaddr = num_global_macaddr;
let values = [];
for (let config in config_list)
push(values, [ config.iface, prepare_config(config) ]);
@@ -91,30 +99,43 @@ function start_pending(phy_name)
if (!phy || !phy.data)
return;
let phydev = phy_open(phy_name);
let phydev = phy_open(phy.name, phy.radio);
if (!phydev) {
wpas.printf(`Could not open phy ${phy_name}`);
return;
}
let macaddr_list = wpas.data.macaddr_list[phy_name];
phydev.macaddr_init(macaddr_list);
phydev.macaddr_init(macaddr_list, { num_global: phy.num_global_macaddr });
for (let ifname in phy.data)
iface_start(phydev, phy.data[ifname]);
}
function phy_name(phy, radio)
{
if (!phy)
return null;
if (radio != null && radio >= 0)
phy += "." + radio;
return phy;
}
let main_obj = {
phy_set_state: {
args: {
phy: "",
radio: 0,
stop: true,
},
call: function(req) {
if (!req.args.phy || req.args.stop == null)
let name = phy_name(req.args.phy, req.args.radio);
if (!name || req.args.stop == null)
return libubus.STATUS_INVALID_ARGUMENT;
let phy = wpas.data.config[req.args.phy];
let phy = wpas.data.config[name];
if (!phy)
return libubus.STATUS_NOT_FOUND;
@@ -123,7 +144,7 @@ let main_obj = {
for (let ifname in phy.data)
iface_stop(phy.data[ifname]);
} else {
start_pending(req.args.phy);
start_pending(name);
}
} catch (e) {
wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`);
@@ -135,10 +156,11 @@ let main_obj = {
phy_set_macaddr_list: {
args: {
phy: "",
radio: 0,
macaddr: [],
},
call: function(req) {
let phy = req.args.phy;
let phy = phy_name(req.args.phy, req.args.radio);
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
@@ -148,13 +170,15 @@ let main_obj = {
},
phy_status: {
args: {
phy: ""
phy: "",
radio: 0,
},
call: function(req) {
if (!req.args.phy)
let phy = phy_name(req.args.phy, req.args.radio);
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
let phy = wpas.data.config[req.args.phy];
phy = wpas.data.config[phy];
if (!phy)
return libubus.STATUS_NOT_FOUND;
@@ -184,20 +208,23 @@ let main_obj = {
config_set: {
args: {
phy: "",
radio: 0,
num_global_macaddr: 0,
config: [],
defer: true,
},
call: function(req) {
if (!req.args.phy)
let phy = phy_name(req.args.phy, req.args.radio);
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
wpas.printf(`Set new config for phy ${req.args.phy}`);
wpas.printf(`Set new config for phy ${phy}`);
try {
if (req.args.config)
set_config(req.args.phy, req.args.config);
set_config(phy, req.args.phy, req.args.radio, req.args.num_global_macaddr, req.args.config);
if (!req.args.defer)
start_pending(req.args.phy);
start_pending(phy);
} catch (e) {
wpas.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`);
return libubus.STATUS_INVALID_ARGUMENT;
@@ -241,6 +268,33 @@ let main_obj = {
return 0;
}
},
bss_info: {
args: {
iface: "",
},
call: function(req) {
let ifname = req.args.iface;
if (!ifname)
return libubus.STATUS_INVALID_ARGUMENT;
let iface = wpas.interfaces[ifname];
if (!iface)
return libubus.STATUS_NOT_FOUND;
let status = iface.ctrl("STATUS");
if (!status)
return libubus.STATUS_NOT_FOUND;
let ret = {};
status = split(status, "\n");
for (let line in status) {
line = split(line, "=", 2);
ret[line[0]] = line[1];
}
return ret;
}
},
};
wpas.data.ubus = ubus;
@@ -316,6 +370,23 @@ return {
}
iface_hostapd_notify(phy, ifname, iface, state);
if (state != "COMPLETED")
return;
let phy_data = wpas.data.config[phy];
if (!phy_data)
return;
let iface_data = phy_data.data[ifname];
if (!iface_data)
return;
let wdev_config = iface_data.config;
if (!wdev_config || wdev_config.mode != "mesh")
return;
wdev_set_mesh_params(ifname, wdev_config);
},
event: function(ifname, iface, ev, info) {
let phy = wpas.data.iface_phy[ifname];

View File

@@ -1,3 +1,10 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 17 Mar 2013 20:47:18 +0000
Subject: [PATCH] hostapd: initial prototype of an ubus binding
Supports listing, removing and banning clients, and hooking into
probe/assoc/auth requests via object subscribe.
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common
@@ -13,32 +20,110 @@
ifdef CONFIG_CODE_COVERAGE
CFLAGS += -O0 -fprofile-arcs -ftest-coverage
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -18,6 +18,7 @@
#include "utils/list.h"
#include "ap_config.h"
#include "drivers/driver.h"
+#include "ubus.h"
--- a/src/ap/airtime_policy.c
+++ b/src/ap/airtime_policy.c
@@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta
{
struct sta_info *sta;
#define OCE_STA_CFON_ENABLED(hapd) \
((hapd->conf->oce & OCE_STA_CFON) && \
@@ -184,6 +185,7 @@ struct hostapd_data {
struct hostapd_iface *iface;
struct hostapd_config *iconf;
struct hostapd_bss_config *conf;
+ struct hostapd_ubus_bss ubus;
int interface_added; /* virtual interface added for this BSS */
unsigned int started:1;
unsigned int disabled:1;
@@ -695,6 +697,7 @@ hostapd_alloc_bss_data(struct hostapd_if
struct hostapd_bss_config *bss);
int hostapd_setup_interface(struct hostapd_iface *iface);
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
void hostapd_interface_deinit(struct hostapd_iface *iface);
void hostapd_interface_free(struct hostapd_iface *iface);
struct hostapd_iface * hostapd_alloc_iface(void);
- for (sta = hapd->sta_list; sta; sta = sta->next)
- sta_set_airtime_weight(hapd, sta, weight);
+ for (sta = hapd->sta_list; sta; sta = sta->next) {
+ unsigned int sta_weight = weight;
+
+ if (sta->dyn_airtime_weight)
+ sta_weight = (weight * sta->dyn_airtime_weight) / 256;
+
+ sta_set_airtime_weight(hapd, sta, sta_weight);
+ }
}
@@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap
unsigned int weight;
if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) {
- weight = get_weight_for_sta(hapd, sta->addr);
+ if (sta->dyn_airtime_weight)
+ weight = sta->dyn_airtime_weight;
+ else
+ weight = get_weight_for_sta(hapd, sta->addr);
if (weight)
return sta_set_airtime_weight(hapd, sta, weight);
}
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1036,6 +1036,12 @@ void handle_probe_req(struct hostapd_dat
u16 csa_offs[2];
size_t csa_offs_len;
struct radius_sta rad_info;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_PROBE_REQ,
+ .mgmt_frame = mgmt,
+ .ssi_signal = ssi_signal,
+ .elems = &elems,
+ };
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
ssi_signal < hapd->iconf->rssi_ignore_probe_request)
@@ -1222,6 +1228,12 @@ void handle_probe_req(struct hostapd_dat
}
#endif /* CONFIG_P2P */
+ if (hostapd_ubus_handle_event(hapd, &req)) {
+ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n",
+ MAC2STR(mgmt->sa));
+ return;
+ }
+
/* TODO: verify that supp_rates contains at least one matching rate
* with AP configuration */
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1211,6 +1211,8 @@ int hostapd_dfs_pre_cac_expired(struct h
"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
+ hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2);
+
/* Proceed only if DFS is not offloaded to the driver */
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
return 0;
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d
u16 reason = WLAN_REASON_UNSPECIFIED;
int status = WLAN_STATUS_SUCCESS;
const u8 *p2p_dev_addr = NULL;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_ASSOC_REQ,
+ .addr = addr,
+ };
if (addr == NULL) {
/*
@@ -237,6 +241,12 @@ int hostapd_notif_assoc(struct hostapd_d
goto fail;
}
+ if (hostapd_ubus_handle_event(hapd, &req)) {
+ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
+ MAC2STR(req.addr));
+ goto fail;
+ }
+
#ifdef CONFIG_P2P
if (elems.p2p) {
wpabuf_free(sta->p2p_ie);
@@ -1020,6 +1030,7 @@ void hostapd_event_ch_switch(struct host
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
"freq=%d dfs=%d", freq, is_dfs);
+ hostapd_ubus_notify_csa(hapd, freq);
} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
/* Complete AP configuration for the first bring up. */
if (is_dfs0 > 0 &&
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -455,6 +455,7 @@ void hostapd_free_hapd_data(struct hosta
@@ -82,6 +167,32 @@
hostapd_interface_deinit(iface);
wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
__func__, driver, drv_priv);
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -18,6 +18,7 @@
#include "utils/list.h"
#include "ap_config.h"
#include "drivers/driver.h"
+#include "ubus.h"
#define OCE_STA_CFON_ENABLED(hapd) \
((hapd->conf->oce & OCE_STA_CFON) && \
@@ -184,6 +185,7 @@ struct hostapd_data {
struct hostapd_iface *iface;
struct hostapd_config *iconf;
struct hostapd_bss_config *conf;
+ struct hostapd_ubus_bss ubus;
int interface_added; /* virtual interface added for this BSS */
unsigned int started:1;
unsigned int disabled:1;
@@ -695,6 +697,7 @@ hostapd_alloc_bss_data(struct hostapd_if
struct hostapd_bss_config *bss);
int hostapd_setup_interface(struct hostapd_iface *iface);
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
void hostapd_interface_deinit(struct hostapd_iface *iface);
void hostapd_interface_free(struct hostapd_iface *iface);
struct hostapd_iface * hostapd_alloc_iface(void);
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2778,7 +2778,7 @@ static void handle_auth(struct hostapd_d
@@ -93,20 +204,18 @@
u16 fc;
const u8 *challenge = NULL;
u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
@@ -2787,7 +2787,12 @@ static void handle_auth(struct hostapd_d
struct radius_sta rad_info;
const u8 *dst, *sa, *bssid;
bool mld_sta = false;
-
@@ -2817,6 +2817,11 @@ static void handle_auth(struct hostapd_d
else
sa = mgmt->sa;
#endif /* CONFIG_IEEE80211BE */
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_AUTH_REQ,
+ .mgmt_frame = mgmt,
+ .ssi_signal = rssi,
+ };
+
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
(unsigned long) len);
auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
@@ -2978,6 +2983,13 @@ static void handle_auth(struct hostapd_d
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
@@ -164,84 +273,27 @@
sta = ap_get_sta(hapd, mgmt->sa);
if (!sta) {
@@ -5763,6 +5788,7 @@ static void handle_deauth(struct hostapd
@@ -5764,6 +5789,8 @@ static void handle_deauth(struct hostapd
/* Clear the PTKSA cache entries for PASN */
ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
+ hostapd_ubus_notify(hapd, "deauth", mgmt->sa);
+ hostapd_ubus_notify(hapd, "deauth", mgmt->sa);
+
sta = ap_get_sta(hapd, mgmt->sa);
if (!sta) {
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1036,6 +1036,12 @@ void handle_probe_req(struct hostapd_dat
u16 csa_offs[2];
size_t csa_offs_len;
struct radius_sta rad_info;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_PROBE_REQ,
+ .mgmt_frame = mgmt,
+ .ssi_signal = ssi_signal,
+ .elems = &elems,
+ };
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
ssi_signal < hapd->iconf->rssi_ignore_probe_request)
@@ -1222,6 +1228,12 @@ void handle_probe_req(struct hostapd_dat
}
#endif /* CONFIG_P2P */
+ if (hostapd_ubus_handle_event(hapd, &req)) {
+ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n",
+ MAC2STR(mgmt->sa));
wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR
--- a/src/ap/rrm.c
+++ b/src/ap/rrm.c
@@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report
return;
wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s",
MAC2STR(addr), token, rep_mode, report);
+ if (len < sizeof(struct rrm_measurement_beacon_report))
+ return;
+ }
+
/* TODO: verify that supp_rates contains at least one matching rate
* with AP configuration */
+ hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len);
}
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d
u16 reason = WLAN_REASON_UNSPECIFIED;
int status = WLAN_STATUS_SUCCESS;
const u8 *p2p_dev_addr = NULL;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_ASSOC_REQ,
+ .addr = addr,
+ };
if (addr == NULL) {
/*
@@ -237,6 +241,12 @@ int hostapd_notif_assoc(struct hostapd_d
goto fail;
}
+ if (hostapd_ubus_handle_event(hapd, &req)) {
+ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
+ MAC2STR(req.addr));
+ goto fail;
+ }
+
#ifdef CONFIG_P2P
if (elems.p2p) {
wpabuf_free(sta->p2p_ie);
@@ -1020,6 +1030,7 @@ void hostapd_event_ch_switch(struct host
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
"freq=%d dfs=%d", freq, is_dfs);
+ hostapd_ubus_notify_csa(hapd, freq);
} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
/* Complete AP configuration for the first bring up. */
if (is_dfs0 > 0 &&
@@ -1031,6 +1042,7 @@ void hostapd_event_ch_switch(struct host
}
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
"freq=%d dfs=%d", freq, is_dfs);
+ hostapd_ubus_notify_csa(hapd, freq);
} else if (is_dfs &&
hostapd_is_dfs_required(hapd->iface) &&
!hostapd_is_dfs_chan_available(hapd->iface) &&
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -471,6 +471,7 @@ void ap_handle_timer(void *eloop_ctx, vo
@@ -289,7 +341,7 @@
#ifdef CONFIG_P2P
if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) {
os_snprintf(ip_addr, sizeof(ip_addr),
@@ -1362,6 +1377,12 @@ void ap_sta_set_authorized(struct hostap
@@ -1362,6 +1377,13 @@ void ap_sta_set_authorized(struct hostap
}
#endif /* CONFIG_P2P */
@@ -299,182 +351,43 @@
+ if (auth_alg)
+ os_snprintf(alg_buf, sizeof(alg_buf),
+ " auth_alg=%s", auth_alg);
+
keyid = ap_sta_wpa_get_keyid(hapd, sta);
if (keyid) {
os_snprintf(keyid_buf, sizeof(keyid_buf),
@@ -1380,8 +1401,9 @@ void ap_sta_set_authorized(struct hostap
@@ -1380,17 +1402,19 @@ void ap_sta_set_authorized(struct hostap
dpp_pkhash, SHA256_MAC_LEN);
}
- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s",
- buf, ip_addr, keyid_buf, dpp_pkhash_buf);
+ hostapd_ubus_notify_authorized(hapd, sta);
+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s",
+ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s",
+ buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf);
if (hapd->msg_ctx_parent &&
hapd->msg_ctx_parent != hapd->msg_ctx)
@@ -1391,11 +1413,12 @@ void ap_sta_set_authorized(struct hostap
dpp_pkhash_buf);
wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
- AP_STA_CONNECTED "%s%s%s%s",
+ AP_STA_CONNECTED "%s%s%s%s%s",
buf, ip_addr, keyid_buf,
- dpp_pkhash_buf);
+ dpp_pkhash_buf, alg_buf);
} else {
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
+ hostapd_ubus_notify(hapd, "disassoc", sta->addr);
if (hapd->msg_ctx_parent &&
hapd->msg_ctx_parent != hapd->msg_ctx)
wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
- AP_STA_DISCONNECTED "%s", buf);
+ AP_STA_DISCONNECTED "%s", buf);
}
#ifdef CONFIG_FST
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -269,6 +269,7 @@ static void hostapd_wpa_auth_psk_failure
struct hostapd_data *hapd = ctx;
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
MAC2STR(addr));
+ hostapd_ubus_notify(hapd, "key-mismatch", addr);
}
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -194,6 +194,13 @@ ifdef CONFIG_EAPOL_TEST
CFLAGS += -Werror -DEAPOL_TEST
endif
+ifdef CONFIG_UBUS
+CFLAGS += -DUBUS_SUPPORT
+OBJS += ubus.o
+OBJS += ../src/utils/uloop.o
+LIBS += -lubox -lubus
+endif
+
ifdef CONFIG_CODE_COVERAGE
CFLAGS += -O0 -fprofile-arcs -ftest-coverage
LIBS += -lgcov
@@ -989,6 +996,9 @@ ifdef CONFIG_CTRL_IFACE_MIB
CFLAGS += -DCONFIG_CTRL_IFACE_MIB
endif
OBJS += ../src/ap/ctrl_iface_ap.o
+ifdef CONFIG_UBUS
+OBJS += ../src/ap/ubus.o
+endif
endif
CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -7635,6 +7635,8 @@ struct wpa_supplicant * wpa_supplicant_a
}
#endif /* CONFIG_P2P */
+ wpas_ubus_add_bss(wpa_s);
+
return wpa_s;
}
@@ -7661,6 +7663,8 @@ int wpa_supplicant_remove_iface(struct w
struct wpa_supplicant *parent = wpa_s->parent;
#endif /* CONFIG_MESH */
+ wpas_ubus_free_bss(wpa_s);
+
/* Remove interface from the global list of interfaces */
prev = global->ifaces;
if (prev == wpa_s) {
@@ -8007,8 +8011,12 @@ int wpa_supplicant_run(struct wpa_global
eloop_register_signal_terminate(wpa_supplicant_terminate, global);
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
+ wpas_ubus_add(global);
+
eloop_run();
+ wpas_ubus_free(global);
+
return 0;
}
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -21,6 +21,7 @@
#include "config_ssid.h"
#include "wmm_ac.h"
#include "pasn/pasn_common.h"
+#include "ubus.h"
extern const char *const wpa_supplicant_version;
extern const char *const wpa_supplicant_license;
@@ -324,6 +325,8 @@ struct wpa_global {
#endif /* CONFIG_WIFI_DISPLAY */
struct psk_list_entry *add_psk; /* From group formation */
+
+ struct ubus_object ubus_global;
};
@@ -655,6 +658,7 @@ struct wpa_supplicant {
unsigned char own_addr[ETH_ALEN];
unsigned char perm_addr[ETH_ALEN];
char ifname[100];
+ struct wpas_ubus_bss ubus;
#ifdef CONFIG_MATCH_IFACE
int matched;
#endif /* CONFIG_MATCH_IFACE */
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -33,6 +33,7 @@
#include "p2p/p2p.h"
#include "p2p_supplicant.h"
#include "wps_supplicant.h"
+#include "ubus.h"
#ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
@@ -402,6 +403,8 @@ static int wpa_supplicant_wps_cred(void
wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
cred->cred_attr, cred->cred_attr_len);
+ wpas_ubus_notify(wpa_s, cred);
+
if (wpa_s->conf->wps_cred_processing == 1)
return 0;
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -204,7 +204,7 @@ int main(int argc, char *argv[])
for (;;) {
c = getopt(argc, argv,
- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W");
+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:nNo:O:p:P:qsTtuv::W");
if (c < 0)
break;
switch (c) {
@@ -272,6 +272,9 @@ int main(int argc, char *argv[])
params.conf_p2p_dev = optarg;
break;
#endif /* CONFIG_P2P */
+ case 'n':
+ iface_count = 0;
+ break;
case 'o':
params.override_driver = optarg;
break;
--- a/src/ap/rrm.c
+++ b/src/ap/rrm.c
@@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report
return;
wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s",
MAC2STR(addr), token, rep_mode, report);
+ if (len < sizeof(struct rrm_measurement_beacon_report))
+ return;
+ hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len);
}
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -322,6 +322,7 @@ struct sta_info {
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_AIRTIME_POLICY
unsigned int airtime_weight;
+ unsigned int dyn_airtime_weight;
struct os_reltime backlogged_until;
#endif /* CONFIG_AIRTIME_POLICY */
--- a/src/ap/vlan_init.c
+++ b/src/ap/vlan_init.c
@@ -514,58 +427,6 @@
return hostapd_vlan_if_remove(hapd, vlan->ifname);
}
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1211,6 +1211,8 @@ int hostapd_dfs_pre_cac_expired(struct h
"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
+ hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2);
+
/* Proceed only if DFS is not offloaded to the driver */
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
return 0;
--- a/src/ap/airtime_policy.c
+++ b/src/ap/airtime_policy.c
@@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta
{
struct sta_info *sta;
- for (sta = hapd->sta_list; sta; sta = sta->next)
- sta_set_airtime_weight(hapd, sta, weight);
+ for (sta = hapd->sta_list; sta; sta = sta->next) {
+ unsigned int sta_weight = weight;
+
+ if (sta->dyn_airtime_weight)
+ sta_weight = (weight * sta->dyn_airtime_weight) / 256;
+
+ sta_set_airtime_weight(hapd, sta, sta_weight);
+ }
}
@@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap
unsigned int weight;
if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) {
- weight = get_weight_for_sta(hapd, sta->addr);
+ if (sta->dyn_airtime_weight)
+ weight = sta->dyn_airtime_weight;
+ else
+ weight = get_weight_for_sta(hapd, sta->addr);
if (weight)
return sta_set_airtime_weight(hapd, sta, weight);
}
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -322,6 +322,7 @@ struct sta_info {
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_AIRTIME_POLICY
unsigned int airtime_weight;
+ unsigned int dyn_airtime_weight;
struct os_reltime backlogged_until;
#endif /* CONFIG_AIRTIME_POLICY */
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -455,7 +455,8 @@ static void ieee802_11_rx_bss_trans_mgmt
@@ -606,6 +467,16 @@
wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries",
pos, end - pos);
}
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -269,6 +269,7 @@ static void hostapd_wpa_auth_psk_failure
struct hostapd_data *hapd = ctx;
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
MAC2STR(addr));
+ hostapd_ubus_notify(hapd, "key-mismatch", addr);
}
--- a/src/utils/eloop.c
+++ b/src/utils/eloop.c
@@ -77,6 +77,9 @@ struct eloop_sock_table {
@@ -754,3 +625,129 @@
+
+ eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler);
+}
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -194,6 +194,13 @@ ifdef CONFIG_EAPOL_TEST
CFLAGS += -Werror -DEAPOL_TEST
endif
+ifdef CONFIG_UBUS
+CFLAGS += -DUBUS_SUPPORT
+OBJS += ubus.o
+OBJS += ../src/utils/uloop.o
+LIBS += -lubox -lubus
+endif
+
ifdef CONFIG_CODE_COVERAGE
CFLAGS += -O0 -fprofile-arcs -ftest-coverage
LIBS += -lgcov
@@ -989,6 +996,9 @@ ifdef CONFIG_CTRL_IFACE_MIB
CFLAGS += -DCONFIG_CTRL_IFACE_MIB
endif
OBJS += ../src/ap/ctrl_iface_ap.o
+ifdef CONFIG_UBUS
+OBJS += ../src/ap/ubus.o
+endif
endif
CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -204,7 +204,7 @@ int main(int argc, char *argv[])
for (;;) {
c = getopt(argc, argv,
- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W");
+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:nNo:O:p:P:qsTtuv::W");
if (c < 0)
break;
switch (c) {
@@ -272,6 +272,9 @@ int main(int argc, char *argv[])
params.conf_p2p_dev = optarg;
break;
#endif /* CONFIG_P2P */
+ case 'n':
+ iface_count = 0;
+ break;
case 'o':
params.override_driver = optarg;
break;
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -7635,6 +7635,8 @@ struct wpa_supplicant * wpa_supplicant_a
}
#endif /* CONFIG_P2P */
+ wpas_ubus_add_bss(wpa_s);
+
return wpa_s;
}
@@ -7661,6 +7663,8 @@ int wpa_supplicant_remove_iface(struct w
struct wpa_supplicant *parent = wpa_s->parent;
#endif /* CONFIG_MESH */
+ wpas_ubus_free_bss(wpa_s);
+
/* Remove interface from the global list of interfaces */
prev = global->ifaces;
if (prev == wpa_s) {
@@ -8007,8 +8011,12 @@ int wpa_supplicant_run(struct wpa_global
eloop_register_signal_terminate(wpa_supplicant_terminate, global);
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
+ wpas_ubus_add(global);
+
eloop_run();
+ wpas_ubus_free(global);
+
return 0;
}
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -21,6 +21,7 @@
#include "config_ssid.h"
#include "wmm_ac.h"
#include "pasn/pasn_common.h"
+#include "ubus.h"
extern const char *const wpa_supplicant_version;
extern const char *const wpa_supplicant_license;
@@ -324,6 +325,8 @@ struct wpa_global {
#endif /* CONFIG_WIFI_DISPLAY */
struct psk_list_entry *add_psk; /* From group formation */
+
+ struct ubus_object ubus_global;
};
@@ -655,6 +658,7 @@ struct wpa_supplicant {
unsigned char own_addr[ETH_ALEN];
unsigned char perm_addr[ETH_ALEN];
char ifname[100];
+ struct wpas_ubus_bss ubus;
#ifdef CONFIG_MATCH_IFACE
int matched;
#endif /* CONFIG_MATCH_IFACE */
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -33,6 +33,7 @@
#include "p2p/p2p.h"
#include "p2p_supplicant.h"
#include "wps_supplicant.h"
+#include "ubus.h"
#ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
@@ -402,6 +403,8 @@ static int wpa_supplicant_wps_cred(void
wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
cred->cred_attr, cred->cred_attr_len);
+ wpas_ubus_notify(wpa_s, cred);
+
if (wpa_s->conf->wps_cred_processing == 1)
return 0;

View File

@@ -1,3 +1,11 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Fri, 26 May 2023 10:23:59 +0200
Subject: [PATCH] Add ucode support, use ucode for the main ubus object
This implements vastly improved dynamic configuration reload support.
It can handle configuration changes on individual wifi interfaces, as well
as adding/removing interfaces.
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm.
@@ -24,6 +32,24 @@
endif
ifdef CONFIG_CODE_COVERAGE
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -4921,6 +4921,7 @@ try_again:
return -1;
}
+ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
return 0;
@@ -5022,6 +5023,7 @@ fail:
os_free(fname);
interface->global_ctrl_sock = s;
+ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive,
interface, NULL);
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -991,6 +991,7 @@ int main(int argc, char *argv[])
@@ -42,6 +68,114 @@
hostapd_global_ctrl_iface_deinit(&interfaces);
/* Deinitialize all interfaces */
for (i = 0; i < interfaces.count; i++) {
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -393,6 +393,23 @@ static inline int hostapd_drv_stop_ap(st
return hapd->driver->stop_ap(hapd->drv_priv);
}
+static inline int hostapd_drv_if_rename(struct hostapd_data *hapd,
+ enum wpa_driver_if_type type,
+ const char *ifname,
+ const char *new_name)
+{
+ if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv)
+ return -1;
+ return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name);
+}
+
+static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd)
+{
+ if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv)
+ return 0;
+ return hapd->driver->set_first_bss(hapd->drv_priv);
+}
+
static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
struct wpa_channel_info *ci)
{
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -276,6 +276,8 @@ int hostapd_reload_config(struct hostapd
size_t j;
int i;
+ hostapd_ucode_reload_bss(hapd);
+
if (iface->config_fname == NULL) {
/* Only in-memory config in use - assume it has been updated */
hostapd_clear_old(iface);
@@ -455,6 +457,7 @@ void hostapd_free_hapd_data(struct hosta
hapd->beacon_set_done = 0;
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
+ hostapd_ucode_free_bss(hapd);
hostapd_ubus_free_bss(hapd);
accounting_deinit(hapd);
hostapd_deinit_wpa(hapd);
@@ -619,6 +622,7 @@ void hostapd_cleanup_iface_partial(struc
static void hostapd_cleanup_iface(struct hostapd_iface *iface)
{
wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+ hostapd_ucode_free_iface(iface);
eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
NULL);
@@ -1209,6 +1213,7 @@ static int hostapd_start_beacon(struct h
hapd->driver->set_operstate(hapd->drv_priv, 1);
hostapd_ubus_add_bss(hapd);
+ hostapd_ucode_add_bss(hapd);
return 0;
}
@@ -1231,8 +1236,7 @@ static int hostapd_start_beacon(struct h
* initialized. Most of the modules that are initialized here will be
* deinitialized in hostapd_cleanup().
*/
-static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
- bool start_beacon)
+int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon)
{
struct hostapd_bss_config *conf = hapd->conf;
u8 ssid[SSID_MAX_LEN + 1];
@@ -1302,6 +1306,8 @@ static int hostapd_setup_bss(struct host
os_memcpy(hapd->own_addr, if_addr, ETH_ALEN);
}
+ hostapd_ucode_create_bss(hapd);
+
if (conf->wmm_enabled < 0)
conf->wmm_enabled = hapd->iconf->ieee80211n |
hapd->iconf->ieee80211ax;
@@ -2257,7 +2263,7 @@ static int hostapd_owe_iface_iter2(struc
#endif /* CONFIG_OWE */
-static void hostapd_owe_update_trans(struct hostapd_iface *iface)
+void hostapd_owe_update_trans(struct hostapd_iface *iface)
{
#ifdef CONFIG_OWE
/* Check whether the enabled BSS can complete OWE transition mode
@@ -2718,7 +2724,7 @@ hostapd_alloc_bss_data(struct hostapd_if
}
-static void hostapd_bss_deinit(struct hostapd_data *hapd)
+void hostapd_bss_deinit(struct hostapd_data *hapd)
{
if (!hapd)
return;
@@ -3511,7 +3517,8 @@ int hostapd_remove_iface(struct hapd_int
hapd_iface = interfaces->iface[i];
if (hapd_iface == NULL)
return -1;
- if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
+ if (!os_strcmp(hapd_iface->phy, buf) ||
+ !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
hapd_iface->driver_ap_teardown =
!!(hapd_iface->drv_flags &
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -19,6 +19,7 @@
@@ -92,82 +226,306 @@
void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
void hostapd_periodic_iface(struct hostapd_iface *iface);
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
+void hostapd_owe_update_trans(struct hostapd_iface *iface);
+void hostapd_owe_update_trans(struct hostapd_iface *iface);;
void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap);
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -276,6 +276,8 @@ int hostapd_reload_config(struct hostapd
size_t j;
int i;
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3787,6 +3787,25 @@ struct wpa_driver_ops {
const char *ifname);
+ hostapd_ucode_reload_bss(hapd);
/**
+ * if_rename - Rename a virtual interface
+ * @priv: Private driver interface data
+ * @type: Interface type
+ * @ifname: Interface name of the virtual interface to be renamed
+ * (NULL when renaming the AP BSS interface)
+ * @new_name: New interface name of the virtual interface
+ * Returns: 0 on success, -1 on failure
+ */
+ int (*if_rename)(void *priv, enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name);
+
if (iface->config_fname == NULL) {
/* Only in-memory config in use - assume it has been updated */
hostapd_clear_old(iface);
@@ -455,6 +457,7 @@ void hostapd_free_hapd_data(struct hosta
hapd->beacon_set_done = 0;
+ /**
+ * set_first_bss - Make a virtual interface the first (primary) bss
+ * @priv: Private driver interface data
+ * Returns: 0 on success, -1 on failure
+ */
+ int (*set_first_bss)(void *priv);
+
+ /**
* set_sta_vlan - Bind a station into a specific interface (AP only)
* @priv: Private driver interface data
* @ifname: Interface (main or virtual BSS or VLAN)
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -73,6 +73,16 @@ enum nlmsgerr_attrs {
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
+ hostapd_ucode_free_bss(hapd);
hostapd_ubus_free_bss(hapd);
accounting_deinit(hapd);
hostapd_deinit_wpa(hapd);
@@ -619,6 +622,7 @@ void hostapd_cleanup_iface_partial(struc
static void hostapd_cleanup_iface(struct hostapd_iface *iface)
#endif /* ANDROID */
+static void handle_nl_debug_hook(struct nl_msg *msg, int tx)
+{
+ const struct nlmsghdr *nlh;
+
+ if (!wpa_netlink_hook)
+ return;
+
+ nlh = nlmsg_hdr(msg);
+ wpa_netlink_hook(tx, nlh, nlh->nlmsg_len);
+}
static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
{
wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+ hostapd_ucode_free_iface(iface);
eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
NULL);
@@ -1209,6 +1213,7 @@ static int hostapd_start_beacon(struct h
hapd->driver->set_operstate(hapd->drv_priv, 1);
@@ -379,6 +389,11 @@ static int no_seq_check(struct nl_msg *m
return NL_OK;
}
hostapd_ubus_add_bss(hapd);
+ hostapd_ucode_add_bss(hapd);
+static int debug_handler(struct nl_msg *msg, void *arg)
+{
+ handle_nl_debug_hook(msg, 0);
+ return NL_OK;
+}
static void nl80211_nlmsg_clear(struct nl_msg *msg)
{
@@ -443,6 +458,7 @@ static int send_and_recv(struct nl80211_
err = 1;
+ nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
if (ack_handler_custom) {
@@ -919,6 +935,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs
os_free(w);
return NULL;
}
+ nl_cb_set(w->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
no_seq_check, NULL);
nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
@@ -1333,7 +1350,7 @@ static void wpa_driver_nl80211_event_rtm
}
wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
+ if (drv->first_bss->ifindex != ifi->ifi_index) {
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface down",
drv->first_bss->ifname);
@@ -1369,7 +1386,7 @@ static void wpa_driver_nl80211_event_rtm
}
wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
+ if (drv->first_bss->ifindex != ifi->ifi_index) {
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface up",
drv->first_bss->ifname);
@@ -1992,6 +2009,7 @@ static int wpa_driver_nl80211_init_nl_gl
/* Continue without vendor events */
}
+ nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
no_seq_check, NULL);
nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
@@ -2160,6 +2178,7 @@ static int nl80211_init_bss(struct i802_
if (!bss->nl_cb)
return -1;
+ nl_cb_set(bss->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
no_seq_check, NULL);
nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
@@ -8432,6 +8451,7 @@ static void *i802_init(struct hostapd_da
char master_ifname[IFNAMSIZ];
int ifindex, br_ifindex = 0;
int br_added = 0;
+ int err;
bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
params->global_priv, 1,
@@ -8491,21 +8511,17 @@ static void *i802_init(struct hostapd_da
(params->num_bridge == 0 || !params->bridge[0]))
add_ifidx(drv, br_ifindex, drv->ifindex);
- if (bss->added_if_into_bridge || bss->already_in_bridge) {
- int err;
-
- drv->rtnl_sk = nl_socket_alloc();
- if (drv->rtnl_sk == NULL) {
- wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
- goto failed;
- }
+ drv->rtnl_sk = nl_socket_alloc();
+ if (drv->rtnl_sk == NULL) {
+ wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
+ goto failed;
+ }
- err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
- if (err) {
- wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
- nl_geterror(err));
- goto failed;
- }
+ err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
+ if (err) {
+ wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
+ nl_geterror(err));
+ goto failed;
}
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
@@ -8874,6 +8890,50 @@ static int wpa_driver_nl80211_if_remove(
return 0;
}
@@ -1231,7 +1236,7 @@ static int hostapd_start_beacon(struct h
* initialized. Most of the modules that are initialized here will be
* deinitialized in hostapd_cleanup().
*/
-static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
+int hostapd_setup_bss(struct hostapd_data *hapd, int first,
bool start_beacon)
{
struct hostapd_bss_config *conf = hapd->conf;
@@ -2257,7 +2262,7 @@ static int hostapd_owe_iface_iter2(struc
#endif /* CONFIG_OWE */
+static int wpa_driver_nl80211_if_rename(struct i802_bss *bss,
+ enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name)
+{
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct ifinfomsg ifi = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = bss->ifindex,
+ };
+ struct nl_msg *msg;
+ int res = -ENOMEM;
+
+ if (ifname)
+ ifi.ifi_index = if_nametoindex(ifname);
+
+ msg = nlmsg_alloc_simple(RTM_SETLINK, 0);
+ if (!msg)
+ return res;
+
+ if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
+ goto out;
+
+ if (nla_put_string(msg, IFLA_IFNAME, new_name))
+ goto out;
+
+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
+ if (res < 0)
+ goto out;
+
+ res = nl_wait_for_ack(drv->rtnl_sk);
+ if (res) {
+ wpa_printf(MSG_INFO,
+ "nl80211: Renaming device %s to %s failed: %s",
+ ifname ? ifname : bss->ifname, new_name, nl_geterror(res));
+ goto out;
+ }
+
+ if (type == WPA_IF_AP_BSS && !ifname)
+ os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname));
+
+out:
+ nlmsg_free(msg);
+ return res;
+}
-static void hostapd_owe_update_trans(struct hostapd_iface *iface)
+void hostapd_owe_update_trans(struct hostapd_iface *iface)
static int cookie_handler(struct nl_msg *msg, void *arg)
{
#ifdef CONFIG_OWE
/* Check whether the enabled BSS can complete OWE transition mode
@@ -2718,7 +2723,7 @@ hostapd_alloc_bss_data(struct hostapd_if
@@ -10472,6 +10532,37 @@ static int driver_nl80211_if_remove(void
}
-static void hostapd_bss_deinit(struct hostapd_data *hapd)
+void hostapd_bss_deinit(struct hostapd_data *hapd)
+static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name)
+{
+ struct i802_bss *bss = priv;
+ return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name);
+}
+
+
+static int driver_nl80211_set_first_bss(void *priv)
+{
+ struct i802_bss *bss = priv, *tbss;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+
+ if (drv->first_bss == bss)
+ return 0;
+
+ for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
+ if (tbss->next != bss)
+ continue;
+
+ tbss->next = bss->next;
+ bss->next = drv->first_bss;
+ drv->first_bss = bss;
+ drv->ctx = bss->ctx;
+ return 0;
+ }
+
+ return -1;
+}
+
+
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
size_t data_len, int noack,
unsigned int freq,
@@ -13656,6 +13747,8 @@ const struct wpa_driver_ops wpa_driver_n
.set_acl = wpa_driver_nl80211_set_acl,
.if_add = wpa_driver_nl80211_if_add,
.if_remove = driver_nl80211_if_remove,
+ .if_rename = driver_nl80211_if_rename,
+ .set_first_bss = driver_nl80211_set_first_bss,
.send_mlme = driver_nl80211_send_mlme,
.get_hw_feature_data = nl80211_get_hw_feature_data,
.sta_add = wpa_driver_nl80211_sta_add,
--- a/src/utils/wpa_debug.c
+++ b/src/utils/wpa_debug.c
@@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NU
#define WPAS_TRACE_PFX "wpas <%d>: "
#endif /* CONFIG_DEBUG_LINUX_TRACING */
+void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
+void (*wpa_hexdump_hook)(int level, const char *title, const void *buf,
+ size_t len);
+void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
int wpa_debug_level = MSG_INFO;
int wpa_debug_show_keys = 0;
@@ -210,6 +214,12 @@ void _wpa_printf(int level, const char *
{
if (!hapd)
return;
@@ -3511,7 +3516,8 @@ int hostapd_remove_iface(struct hapd_int
hapd_iface = interfaces->iface[i];
if (hapd_iface == NULL)
return -1;
- if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
+ if (!os_strcmp(hapd_iface->phy, buf) ||
+ !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
hapd_iface->driver_ap_teardown =
!!(hapd_iface->drv_flags &
va_list ap;
+ if (wpa_printf_hook) {
+ va_start(ap, fmt);
+ wpa_printf_hook(level, fmt, ap);
+ va_end(ap);
+ }
+
if (level >= wpa_debug_level) {
#ifdef CONFIG_ANDROID_LOG
va_start(ap, fmt);
@@ -260,6 +270,9 @@ void _wpa_hexdump(int level, const char
{
size_t i;
+ if (wpa_hexdump_hook)
+ wpa_hexdump_hook(level, title, buf, len);
+
#ifdef CONFIG_DEBUG_LINUX_TRACING
if (wpa_debug_tracing_file != NULL) {
fprintf(wpa_debug_tracing_file,
--- a/src/utils/wpa_debug.h
+++ b/src/utils/wpa_debug.h
@@ -11,6 +11,10 @@
#include "wpabuf.h"
+extern void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
+extern void (*wpa_hexdump_hook)(int level, const char *title,
+ const void *buf, size_t len);
+extern void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
extern int wpa_debug_level;
extern int wpa_debug_show_keys;
extern int wpa_debug_timestamp;
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -197,8 +197,20 @@ endif
@@ -202,6 +560,16 @@
endif
CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5435,6 +5435,7 @@ void supplicant_event(void *ctx, enum wp
event_to_string(event), event);
#endif /* CONFIG_NO_STDOUT_DEBUG */
+ wpas_ucode_event(wpa_s, event, data);
switch (event) {
case EVENT_AUTH:
#ifdef CONFIG_FST
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1096,6 +1096,7 @@ void wpa_supplicant_set_state(struct wpa
@@ -276,246 +644,6 @@
#ifdef CONFIG_MATCH_IFACE
int matched;
#endif /* CONFIG_MATCH_IFACE */
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -4921,6 +4921,7 @@ try_again:
return -1;
}
+ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
return 0;
@@ -5022,6 +5023,7 @@ fail:
os_free(fname);
interface->global_ctrl_sock = s;
+ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive,
interface, NULL);
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3787,6 +3787,25 @@ struct wpa_driver_ops {
const char *ifname);
/**
+ * if_rename - Rename a virtual interface
+ * @priv: Private driver interface data
+ * @type: Interface type
+ * @ifname: Interface name of the virtual interface to be renamed
+ * (NULL when renaming the AP BSS interface)
+ * @new_name: New interface name of the virtual interface
+ * Returns: 0 on success, -1 on failure
+ */
+ int (*if_rename)(void *priv, enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name);
+
+ /**
+ * set_first_bss - Make a virtual interface the first (primary) bss
+ * @priv: Private driver interface data
+ * Returns: 0 on success, -1 on failure
+ */
+ int (*set_first_bss)(void *priv);
+
+ /**
* set_sta_vlan - Bind a station into a specific interface (AP only)
* @priv: Private driver interface data
* @ifname: Interface (main or virtual BSS or VLAN)
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5435,6 +5435,7 @@ void supplicant_event(void *ctx, enum wp
event_to_string(event), event);
#endif /* CONFIG_NO_STDOUT_DEBUG */
+ wpas_ucode_event(wpa_s, event, data);
switch (event) {
case EVENT_AUTH:
#ifdef CONFIG_FST
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -393,6 +393,23 @@ static inline int hostapd_drv_stop_ap(st
return hapd->driver->stop_ap(hapd->drv_priv);
}
+static inline int hostapd_drv_if_rename(struct hostapd_data *hapd,
+ enum wpa_driver_if_type type,
+ const char *ifname,
+ const char *new_name)
+{
+ if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv)
+ return -1;
+ return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name);
+}
+
+static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd)
+{
+ if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv)
+ return 0;
+ return hapd->driver->set_first_bss(hapd->drv_priv);
+}
+
static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
struct wpa_channel_info *ci)
{
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1333,7 +1333,7 @@ static void wpa_driver_nl80211_event_rtm
}
wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
+ if (drv->first_bss->ifindex != ifi->ifi_index) {
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface down",
drv->first_bss->ifname);
@@ -1369,7 +1369,7 @@ static void wpa_driver_nl80211_event_rtm
}
wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
+ if (drv->first_bss->ifindex != ifi->ifi_index) {
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface up",
drv->first_bss->ifname);
@@ -8432,6 +8432,7 @@ static void *i802_init(struct hostapd_da
char master_ifname[IFNAMSIZ];
int ifindex, br_ifindex = 0;
int br_added = 0;
+ int err;
bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
params->global_priv, 1,
@@ -8491,21 +8492,17 @@ static void *i802_init(struct hostapd_da
(params->num_bridge == 0 || !params->bridge[0]))
add_ifidx(drv, br_ifindex, drv->ifindex);
- if (bss->added_if_into_bridge || bss->already_in_bridge) {
- int err;
-
- drv->rtnl_sk = nl_socket_alloc();
- if (drv->rtnl_sk == NULL) {
- wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
- goto failed;
- }
+ drv->rtnl_sk = nl_socket_alloc();
+ if (drv->rtnl_sk == NULL) {
+ wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
+ goto failed;
+ }
- err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
- if (err) {
- wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
- nl_geterror(err));
- goto failed;
- }
+ err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
+ if (err) {
+ wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
+ nl_geterror(err));
+ goto failed;
}
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
@@ -8874,6 +8871,50 @@ static int wpa_driver_nl80211_if_remove(
return 0;
}
+static int wpa_driver_nl80211_if_rename(struct i802_bss *bss,
+ enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name)
+{
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct ifinfomsg ifi = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = bss->ifindex,
+ };
+ struct nl_msg *msg;
+ int res = -ENOMEM;
+
+ if (ifname)
+ ifi.ifi_index = if_nametoindex(ifname);
+
+ msg = nlmsg_alloc_simple(RTM_SETLINK, 0);
+ if (!msg)
+ return res;
+
+ if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
+ goto out;
+
+ if (nla_put_string(msg, IFLA_IFNAME, new_name))
+ goto out;
+
+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
+ if (res < 0)
+ goto out;
+
+ res = nl_wait_for_ack(drv->rtnl_sk);
+ if (res) {
+ wpa_printf(MSG_INFO,
+ "nl80211: Renaming device %s to %s failed: %s",
+ ifname ? ifname : bss->ifname, new_name, nl_geterror(res));
+ goto out;
+ }
+
+ if (type == WPA_IF_AP_BSS && !ifname)
+ os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname));
+
+out:
+ nlmsg_free(msg);
+ return res;
+}
static int cookie_handler(struct nl_msg *msg, void *arg)
{
@@ -10472,6 +10513,37 @@ static int driver_nl80211_if_remove(void
}
+static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name)
+{
+ struct i802_bss *bss = priv;
+ return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name);
+}
+
+
+static int driver_nl80211_set_first_bss(void *priv)
+{
+ struct i802_bss *bss = priv, *tbss;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+
+ if (drv->first_bss == bss)
+ return 0;
+
+ for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
+ if (tbss->next != bss)
+ continue;
+
+ tbss->next = bss->next;
+ bss->next = drv->first_bss;
+ drv->first_bss = bss;
+ drv->ctx = bss->ctx;
+ return 0;
+ }
+
+ return -1;
+}
+
+
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
size_t data_len, int noack,
unsigned int freq,
@@ -13656,6 +13728,8 @@ const struct wpa_driver_ops wpa_driver_n
.set_acl = wpa_driver_nl80211_set_acl,
.if_add = wpa_driver_nl80211_if_add,
.if_remove = driver_nl80211_if_remove,
+ .if_rename = driver_nl80211_if_rename,
+ .set_first_bss = driver_nl80211_set_first_bss,
.send_mlme = driver_nl80211_send_mlme,
.get_hw_feature_data = nl80211_get_hw_feature_data,
.sta_add = wpa_driver_nl80211_sta_add,
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -547,12 +547,17 @@ static const char * sae_get_password(str
@@ -537,24 +665,25 @@
for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
if (!is_broadcast_ether_addr(pw->peer_addr) &&
os_memcmp(pw->peer_addr, sta->addr, ETH_ALEN) != 0)
@@ -582,6 +588,31 @@ static const char * sae_get_password(str
}
@@ -573,12 +578,28 @@ static const char * sae_get_password(str
pt = hapd->conf->ssid.pt;
}
+use_sta_psk:
+ if (!password && sta) {
+ for (psk = sta->psk; psk; psk = psk->next) {
if (!password) {
for (psk = sta->psk; psk; psk = psk->next) {
- if (psk->is_passphrase) {
- password = psk->passphrase;
+ if (!psk->is_passphrase)
+ continue;
+
+ password = psk->passphrase;
+ if (!sta->use_sta_psk)
+ break;
+
+#ifdef CONFIG_SAE
+ if (sta->sae_pt) {
+ pt = sta->sae_pt;
+ break;
+ }
break;
}
+
+ pt = sae_derive_pt(conf->sae_groups, ssid->ssid,
+ ssid->ssid_len,
@@ -563,13 +692,11 @@
+ NULL);
+ sta->sae_pt = pt;
+ break;
+ }
+ }
+
if (pw_entry)
*pw_entry = pw;
if (s_pt)
@@ -3097,6 +3128,12 @@ static void handle_auth(struct hostapd_d
+#endif
}
}
@@ -3097,6 +3118,12 @@ static void handle_auth(struct hostapd_d
goto fail;
}
@@ -584,17 +711,19 @@
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -425,6 +425,9 @@ void ap_free_sta(struct hostapd_data *ha
@@ -425,6 +425,11 @@ void ap_free_sta(struct hostapd_data *ha
forced_memzero(sta->last_tk, WPA_TK_MAX_LEN);
#endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_SAE
+ if (sta->sae_pt)
+ sae_deinit_pt(sta->sae_pt);
+#endif
+
os_free(sta);
}
@@ -1326,6 +1329,8 @@ void ap_sta_set_authorized(struct hostap
@@ -1326,6 +1331,8 @@ void ap_sta_set_authorized(struct hostap
sta->flags &= ~WLAN_STA_AUTHORIZED;
}
@@ -625,7 +754,7 @@
if (vlan_id)
*vlan_id = 0;
if (psk_len)
@@ -387,13 +388,18 @@ static const u8 * hostapd_wpa_auth_get_p
@@ -387,13 +388,16 @@ static const u8 * hostapd_wpa_auth_get_p
* returned psk which should not be returned again.
* logic list (all hostapd_get_psk; all sta->psk)
*/
@@ -633,29 +762,22 @@
+ psk = NULL;
if (sta && sta->psk && !psk) {
struct hostapd_sta_wpa_psk_short *pos;
+ int psk_idx;
+ int psk_idx = 1;
if (vlan_id)
*vlan_id = 0;
psk = sta->psk->psk;
+ sta->psk_idx = psk_idx = 1;
for (pos = sta->psk; pos; pos = pos->next) {
+ psk_idx++;
- for (pos = sta->psk; pos; pos = pos->next) {
+ for (pos = sta->psk; pos; pos = pos->next, psk_idx++) {
if (pos->is_passphrase) {
if (pbkdf2_sha1(pos->passphrase,
hapd->conf->ssid.ssid,
@@ -406,10 +412,14 @@ static const u8 * hostapd_wpa_auth_get_p
pos->is_passphrase = 0;
}
if (pos->psk == prev_psk) {
+ sta->psk_idx = psk_idx;
psk = pos->next ? pos->next->psk : NULL;
@@ -410,6 +414,8 @@ static const u8 * hostapd_wpa_auth_get_p
break;
}
}
+
+ if (!psk)
+ sta->psk_idx = 0;
+ if (psk)
+ sta->psk_idx = psk_idx;
}
return psk;
}

View File

@@ -19,11 +19,9 @@ Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
src/ap/hostapd.h | 3 ++-
5 files changed, 76 insertions(+), 5 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 0216821..f180376 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -2674,6 +2674,87 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
@@ -2674,6 +2674,87 @@ static int hostapd_ctrl_check_freq_param
}
#endif /* NEED_AP_MLME */
@@ -111,7 +109,7 @@ index 0216821..f180376 100644
static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
char *pos)
@@ -3718,6 +3799,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
@@ -3718,6 +3799,9 @@ static int hostapd_ctrl_iface_receive_pr
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
reply_len = -1;
@@ -121,11 +119,9 @@ index 0216821..f180376 100644
} else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
reply_size);
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index ef33968..dd898b7 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -1163,6 +1163,27 @@ static int hostapd_cli_cmd_fst(struct wpa_ctrl *ctrl, int argc, char *argv[])
@@ -1163,6 +1163,27 @@ static int hostapd_cli_cmd_fst(struct wp
}
#endif /* CONFIG_FST */
@@ -153,7 +149,7 @@ index ef33968..dd898b7 100644
static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
int argc, char *argv[])
@@ -1676,6 +1697,9 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
@@ -1676,6 +1697,9 @@ static const struct hostapd_cli_cmd host
"<cs_count> <freq> [sec_channel_offset=] [center_freq1=]\n"
" [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n"
" = initiate channel switch announcement" },
@@ -163,11 +159,9 @@ index ef33968..dd898b7 100644
{ "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL,
"<addr> <url>\n"
" = send WNM-Notification Subscription Remediation Request" },
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 63a0ee8..7ca22f9 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -969,10 +969,14 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
@@ -969,10 +969,14 @@ int hostapd_ctrl_iface_status(struct hos
ret = os_snprintf(buf + len, buflen - len,
"he_oper_chwidth=%d\n"
"he_oper_centr_freq_seg0_idx=%d\n"
@@ -184,11 +178,9 @@ index 63a0ee8..7ca22f9 100644
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 5dd052c..e90bfc3 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -3740,7 +3740,7 @@ int hostapd_csa_in_progress(struct hostapd_iface *iface)
@@ -3698,7 +3698,7 @@ int hostapd_csa_in_progress(struct hosta
#ifdef NEED_AP_MLME
@@ -197,7 +189,7 @@ index 5dd052c..e90bfc3 100644
{
os_free(beacon->head);
beacon->head = NULL;
@@ -4177,7 +4177,7 @@ void hostapd_cleanup_cca_params(struct hostapd_data *hapd)
@@ -4135,7 +4135,7 @@ void hostapd_cleanup_cca_params(struct h
}
@@ -206,16 +198,13 @@ index 5dd052c..e90bfc3 100644
struct cca_settings *settings)
{
struct hostapd_iface *iface = hapd->iface;
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 09bf8af..b21f4bd 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -736,10 +736,12 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
void hostapd_periodic_iface(struct hostapd_iface *iface);
@@ -743,9 +743,11 @@ void hostapd_periodic_iface(struct hosta
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
void hostapd_owe_update_trans(struct hostapd_iface *iface);
void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
+void free_beacon_data(struct beacon_data *beacon);
int hostapd_check_max_sta(struct hostapd_data *hapd);
void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap);
void hostapd_cleanup_cca_params(struct hostapd_data *hapd);

View File

@@ -479,7 +479,7 @@ Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
hapd->interface_added = 1;
if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
conf->iface, addr, hapd,
@@ -1368,8 +1384,18 @@ static int hostapd_setup_bss(struct host
@@ -1368,10 +1384,20 @@ static int hostapd_setup_bss(struct host
if (!addr)
os_memcpy(hapd->own_addr, if_addr, ETH_ALEN);
@@ -494,6 +494,8 @@ Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
+ }
}
hostapd_ucode_create_bss(hapd);
+setup_mld:
if (is_zero_ether_addr(conf->bssid))
os_memcpy(conf->bssid, hapd->own_addr, ETH_ALEN);

View File

@@ -0,0 +1,20 @@
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -14314,6 +14314,8 @@ static int wpa_driver_nl80211_can_share_
const u8 *addr;
int ret = -1;
+ return -1;
+
/* create a dummy drv to read the phyname */
if (params->global_priv == NULL)
return ret;
@@ -14367,7 +14369,7 @@ static int wpa_driver_nl80211_can_share_
params->ifname, addr, ctx, drv_priv,
force_ifname, if_addr,
params->num_bridge && params->bridge[0] ? params->bridge[0] : NULL,
- 0, 1)) {
+ 1, 1)) {
wpa_printf(MSG_DEBUG, "nl80211: Failed to add BSS. Expect issues!");
goto free_all;
}

View File

@@ -0,0 +1,20 @@
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -525,7 +525,7 @@ static void ap_ht40_scan_retry(void *elo
wpa_printf(MSG_ERROR,
"Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)",
ret, strerror(-ret), iface->num_ht40_scan_tries);
- eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
+ eloop_register_timeout(10, 0, ap_ht40_scan_retry, iface, NULL);
return;
}
@@ -582,7 +582,7 @@ static int ieee80211n_check_40mhz(struct
ret, strerror(-ret));
iface->num_ht40_scan_tries = 1;
eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
- eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL);
+ eloop_register_timeout(10, 0, ap_ht40_scan_retry, iface, NULL);
return 1;
}

View File

@@ -0,0 +1,24 @@
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -977,11 +977,9 @@ add:
break;
}
}
- /* if not add it by deleting the older wiphy */
- if (!found) {
- dl_list_del(&bss->drv->wiphy_list);
+ /* if not add it */
+ if (!found)
dl_list_add(&w->drvs, &bss->drv->wiphy_list);
- }
dl_list_add(&w->bsss, &bss->wiphy_list);
bss->wiphy_data = w;
@@ -2285,7 +2283,6 @@ static void * wpa_driver_nl80211_drv_ini
drv->ctx = ctx;
drv->hostapd = !!hostapd;
drv->eapol_sock = -1;
- dl_list_init(&drv->wiphy_list);
/*
* There is no driver capability flag for this, so assume it is

View File

@@ -1,6 +1,6 @@
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2848,6 +2848,14 @@ static int hostapd_config_fill(struct ho
@@ -2784,6 +2784,14 @@ static int hostapd_config_fill(struct ho
line, bss->max_num_sta, MAX_STA_COUNT);
return 1;
}
@@ -17,17 +17,17 @@
} else if (os_strcmp(buf, "extended_key_id") == 0) {
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -733,6 +733,7 @@ void hostapd_cleanup_cs_params(struct ho
void hostapd_periodic_iface(struct hostapd_iface *iface);
@@ -850,6 +850,7 @@ void hostapd_periodic_iface(struct hosta
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
void hostapd_owe_update_trans(struct hostapd_iface *iface);
void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
+int hostapd_check_max_sta(struct hostapd_data *hapd);
void free_beacon_data(struct beacon_data *beacon);
void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap);
void hostapd_cleanup_cca_params(struct hostapd_data *hapd);
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -267,6 +267,30 @@ static int hostapd_iface_conf_changed(st
@@ -279,6 +279,30 @@ static int hostapd_iface_conf_changed(st
return 0;
}
@@ -60,7 +60,7 @@
{
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1252,7 +1252,7 @@ void handle_probe_req(struct hostapd_dat
@@ -1664,7 +1664,7 @@ void handle_probe_req(struct hostapd_dat
if (hapd->conf->no_probe_resp_if_max_sta &&
is_multicast_ether_addr(mgmt->da) &&
is_multicast_ether_addr(mgmt->bssid) &&
@@ -71,7 +71,7 @@
" since no room for additional STA",
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1036,6 +1036,8 @@ struct hostapd_config {
@@ -1060,6 +1060,8 @@ struct hostapd_config {
unsigned int track_sta_max_num;
unsigned int track_sta_max_age;

View File

@@ -0,0 +1,44 @@
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -3665,6 +3665,7 @@ static int wpa_ft_process_auth_req(struc
const u8 *identity, *radius_cui;
size_t identity_len = 0, radius_cui_len = 0;
size_t pmk_r1_len, kdk_len, len, bmle_len;
+ struct os_reltime now;
*resp_ies = NULL;
*resp_ies_len = 0;
@@ -3788,10 +3789,19 @@ pmk_r1_derived:
os_memcpy(sm->pmk_r1, pmk_r1, pmk_r1_len);
sm->pmk_r1_len = pmk_r1_len;
- if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
- wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
- "ANonce");
- return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ if (os_get_reltime(&now) < 0 ||
+ os_reltime_expired(&now, &sm->ANonce_time, 1)) {
+ if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
+ wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
+ "ANonce");
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ }
+ sm->ANonce_time.sec = now.sec;
+ sm->ANonce_time.usec = now.usec;
+ wpa_printf(MSG_INFO, "FT: ANonce was randomized");
+ } else {
+ wpa_printf(MSG_INFO, "FT: ANonce has not expired");
+
}
/* Now that we know the correct PMK-R1 length and as such, the length
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -54,6 +54,7 @@ struct wpa_state_machine {
bool MICVerified;
bool GUpdateStationKeys;
u8 ANonce[WPA_NONCE_LEN];
+ struct os_reltime ANonce_time;
u8 SNonce[WPA_NONCE_LEN];
u8 alt_SNonce[WPA_NONCE_LEN];
u8 alt_replay_counter[WPA_REPLAY_COUNTER_LEN];

View File

@@ -0,0 +1,43 @@
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3337,6 +3337,8 @@ static int hostapd_config_fill(struct ho
bss->ignore_broadcast_ssid = atoi(pos);
} else if (os_strcmp(buf, "no_probe_resp_if_max_sta") == 0) {
bss->no_probe_resp_if_max_sta = atoi(pos);
+ } else if (os_strcmp(buf, "dynamic_probe_resp") == 0) {
+ bss->dynamic_probe_resp = atoi(pos);
#ifdef CONFIG_WEP
} else if (os_strcmp(buf, "wep_default_key") == 0) {
bss->ssid.wep.idx = atoi(pos);
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -459,6 +459,7 @@ struct hostapd_bss_config {
int ap_max_inactivity;
int ignore_broadcast_ssid;
int no_probe_resp_if_max_sta;
+ int dynamic_probe_resp;
int wmm_enabled;
int wmm_uapsd;
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -920,7 +920,8 @@ void handle_probe_req(struct hostapd_dat
}
#endif /* CONFIG_P2P */
- if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
+ if (!hapd->conf->dynamic_probe_resp &&
+ hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
elems.ssid_list_len == 0 && elems.short_ssid_list_len == 0) {
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
"broadcast SSID ignored", MAC2STR(mgmt->sa));
@@ -967,7 +968,8 @@ void handle_probe_req(struct hostapd_dat
return;
}
- if (hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
+ if (!hapd->conf->dynamic_probe_resp &&
+ hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
"broadcast SSID ignored", MAC2STR(mgmt->sa));
return;

View File

@@ -0,0 +1,147 @@
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -584,6 +584,7 @@ static void handle_auth_ft_finish(void *
hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
+ hostapd_ubus_notify(hapd, "ft-finish", sta->addr);
sta->flags |= WLAN_STA_AUTH;
mlme_authenticate_indication(hapd, sta);
}
@@ -5574,6 +5575,8 @@ static void handle_assoc(struct hostapd_
}
sta = ap_get_sta(hapd, mgmt->sa);
+ if (sta && reassoc)
+ memcpy(sta->origin_ap, mgmt->u.reassoc_req.current_ap, 6);
#ifdef CONFIG_IEEE80211R_AP
if (!sta) {
wpa_printf(MSG_DEBUG,
@@ -5732,6 +5735,7 @@ static void handle_assoc(struct hostapd_
.type = HOSTAPD_UBUS_ASSOC_REQ,
.mgmt_frame = mgmt,
.ssi_signal = rssi,
+ .reassoc = reassoc,
};
/* followed by SSID and Supported rates; and HT capabilities if 802.11n
@@ -6784,7 +6788,7 @@ static void handle_assoc_cb(struct hosta
* Open, static WEP, FT protocol, or FILS; no separate
* authorization step.
*/
- ap_sta_set_authorized(hapd, sta, 1);
+ _ap_sta_set_authorized(hapd, sta, 1, reassoc);
}
if (reassoc)
--- a/src/ap/ubus.c
+++ b/src/ap/ubus.c
@@ -1869,6 +1869,8 @@ int hostapd_ubus_handle_event(struct hos
if (req->ssi_signal)
blobmsg_add_u32(&b, "signal", req->ssi_signal);
blobmsg_add_u32(&b, "freq", hapd->iface->freq);
+ if (req->reassoc && req->mgmt_frame)
+ blobmsg_add_macaddr(&b, "origin", req->mgmt_frame->u.reassoc_req.current_ap);
if (req->elems) {
if(req->elems->ht_capabilities)
@@ -1939,6 +1941,7 @@ void hostapd_ubus_notify(struct hostapd_
blob_buf_init(&b, 0);
blobmsg_add_macaddr(&b, "address", addr);
blobmsg_add_string(&b, "ifname", hapd->conf->iface);
+ blobmsg_printf(&b, "target", MACSTR, MAC2STR(hapd->conf->bssid));
ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
}
@@ -1957,7 +1960,7 @@ void hostapd_ubus_notify_csa(struct host
}
-void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta)
+void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, int reassoc)
{
if (!hapd->ubus.obj.has_subscribers)
return;
@@ -1974,6 +1977,9 @@ void hostapd_ubus_notify_authorized(stru
blobmsg_add_u32(&b, "", sta->bandwidth[1]);
blobmsg_close_array(&b, r);
}
+ if (reassoc)
+ blobmsg_add_macaddr(&b, "origin", sta->origin_ap);
+ blobmsg_printf(&b, "target", MACSTR, MAC2STR(hapd->conf->bssid));
ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1);
}
--- a/src/ap/ubus.h
+++ b/src/ap/ubus.h
@@ -23,6 +23,7 @@ struct hostapd_ubus_request {
const struct ieee802_11_elems *elems;
int ssi_signal; /* dBm */
const u8 *addr;
+ int reassoc;
};
struct hostapd_iface;
@@ -49,7 +50,7 @@ void hostapd_ubus_remove_vlan(struct hos
int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req);
void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac);
-void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta);
+void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, int reassoc);
void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
const u8 *addr, u8 token, u8 rep_mode,
struct rrm_measurement_beacon_report *rep,
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -1418,8 +1418,8 @@ const u8 * ap_sta_wpa_get_dpp_pkhash(str
}
-void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
- int authorized)
+void _ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
+ int authorized, int reassoc)
{
const u8 *dev_addr = NULL;
char buf[100];
@@ -1525,7 +1525,7 @@ void ap_sta_set_authorized(struct hostap
dpp_pkhash, SHA256_MAC_LEN);
}
- hostapd_ubus_notify_authorized(hapd, sta);
+ hostapd_ubus_notify_authorized(hapd, sta, reassoc);
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s",
buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf);
@@ -1555,6 +1555,11 @@ void ap_sta_set_authorized(struct hostap
}
#endif /* CONFIG_FST */
}
+void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
+ int authorized)
+{
+ _ap_sta_set_authorized(hapd, sta, authorized, 0);
+}
void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -108,6 +108,7 @@ struct sta_info {
struct sta_info *next; /* next entry in sta list */
struct sta_info *hnext; /* next entry in hash table list */
u8 addr[6];
+ u8 origin_ap[6];
be32 ipaddr;
struct dl_list ip6addr; /* list head for struct ip6addr */
u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
@@ -441,6 +442,9 @@ const u8 * ap_sta_wpa_get_dpp_pkhash(str
void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *addr, u16 reason);
+void _ap_sta_set_authorized(struct hostapd_data *hapd,
+ struct sta_info *sta, int authorized,
+ int reassoc);
void ap_sta_set_authorized(struct hostapd_data *hapd,
struct sta_info *sta, int authorized);
static inline int ap_sta_is_authorized(struct sta_info *sta)

View File

@@ -0,0 +1,11 @@
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -755,7 +755,7 @@ struct radius_attr_hdr * radius_msg_add_
ext->length = sizeof(*ext) + 1 + alen;
ext->ext_type = ext_type;
wpabuf_put_u8(msg->buf, data_len > alen ? 0x80 : 0);
- wpabuf_put_data(msg->buf, data, data_len);
+ wpabuf_put_data(msg->buf, data, alen);
data += alen;
data_len -= alen;
if (radius_msg_add_attr_to_array(

View File

@@ -0,0 +1,67 @@
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3003,6 +3003,8 @@ static int hostapd_config_fill(struct ho
bss->ft_over_ds = atoi(pos);
} else if (os_strcmp(buf, "ft_psk_generate_local") == 0) {
bss->ft_psk_generate_local = atoi(pos);
+ } else if (os_strcmp(buf, "ft_key") == 0) {
+ strncpy(bss->ft_key, pos, sizeof(bss->ft_key));
#endif /* CONFIG_IEEE80211R_AP */
#ifndef CONFIG_NO_CTRL_IFACE
} else if (os_strcmp(buf, "ctrl_interface") == 0) {
@@ -4958,8 +4960,22 @@ int hostapd_set_iface(struct hostapd_con
return -1;
}
- for (i = 0; i < conf->num_bss; i++)
+ for (i = 0; i < conf->num_bss; i++) {
+ if (*conf->bss[i]->ft_key) {
+ u8 buffer[128];
+ sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X %02X%02X%02X%02X%02X%02X %s", MAC2STR(conf->bss[i]->bssid), MAC2STR(conf->bss[i]->bssid), conf->bss[i]->ft_key);
+ add_r0kh(conf->bss[i], buffer);
+ sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X %02X:%02X:%02X:%02X:%02X:%02X %s", MAC2STR(conf->bss[i]->bssid), MAC2STR(conf->bss[i]->bssid), conf->bss[i]->ft_key);
+ add_r1kh(conf->bss[i], buffer);
+ sprintf(buffer, "ff:ff:ff:ff:ff:ff * %s", conf->bss[i]->ft_key);
+ add_r0kh(conf->bss[i], buffer);
+ sprintf(buffer, "00:00:00:00:00:00 00:00:00:00:00:00 %s", conf->bss[i]->ft_key);
+ add_r1kh(conf->bss[i], buffer);
+ hexstr2bin(conf->bss[i]->bssid, conf->bss[i]->r1_key_holder, FT_R1KH_ID_LEN);
+ conf->bss[i]->r0_key_holder_bssid = 1;
+ }
hostapd_set_security_params(conf->bss[i], 0);
+ }
if (hostapd_config_check(conf, 0)) {
wpa_printf(MSG_ERROR, "Configuration check failed");
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -398,6 +398,7 @@ struct hostapd_bss_config {
/* IEEE 802.11r - Fast BSS Transition */
u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN];
u8 r1_key_holder[FT_R1KH_ID_LEN];
+ int r0_key_holder_bssid;
u32 r0_key_lifetime; /* PMK-R0 lifetime seconds */
int rkh_pos_timeout;
int rkh_neg_timeout;
@@ -410,6 +411,7 @@ struct hostapd_bss_config {
int ft_over_ds;
int ft_psk_generate_local;
int r1_max_key_lifetime;
+ u8 ft_key[65];
#endif /* CONFIG_IEEE80211R_AP */
char *ctrl_interface; /* directory for UNIX domain sockets */
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -144,7 +144,10 @@ static void hostapd_wpa_auth_conf(struct
os_memcpy(wconf->ssid, conf->ssid.ssid, wconf->ssid_len);
os_memcpy(wconf->mobility_domain, conf->mobility_domain,
MOBILITY_DOMAIN_ID_LEN);
- if (conf->nas_identifier &&
+ if (1 || conf->r0_key_holder_bssid) {
+ sprintf(wconf->r0_key_holder, "%02X%02X%02X%02X%02X%02X", MAC2STR(conf->bssid));
+ wconf->r0_key_holder_len = 12;
+ } else if (conf->nas_identifier &&
os_strlen(conf->nas_identifier) <= FT_R0KH_ID_MAX_LEN) {
wconf->r0_key_holder_len = os_strlen(conf->nas_identifier);
os_memcpy(wconf->r0_key_holder, conf->nas_identifier,

View File

@@ -0,0 +1,86 @@
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3005,6 +3005,8 @@ static int hostapd_config_fill(struct ho
bss->ft_psk_generate_local = atoi(pos);
} else if (os_strcmp(buf, "ft_key") == 0) {
strncpy(bss->ft_key, pos, sizeof(bss->ft_key));
+ } else if (os_strcmp(buf, "ft_l2_refresh") == 0) {
+ bss->ft_l2_refresh = atoi(pos);
#endif /* CONFIG_IEEE80211R_AP */
#ifndef CONFIG_NO_CTRL_IFACE
} else if (os_strcmp(buf, "ctrl_interface") == 0) {
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -410,6 +410,7 @@ struct hostapd_bss_config {
int pmk_r1_push;
int ft_over_ds;
int ft_psk_generate_local;
+ int ft_l2_refresh;
int r1_max_key_lifetime;
u8 ft_key[65];
#endif /* CONFIG_IEEE80211R_AP */
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -1811,6 +1811,28 @@ static int hostapd_wpa_auth_get_ml_key_i
#endif /* CONFIG_IEEE80211BE */
+static void wpa_ft_refresh(void *eloop_data, void *user_data)
+{
+ struct hostapd_data *hapd = eloop_data;
+ struct ft_rrb_frame *frame;
+ struct l2_ethhdr *buf;
+ size_t len;
+
+ len = sizeof(*buf) + sizeof(*frame);
+ buf = os_zalloc(len);
+ frame = (struct ft_rrb_frame *)(buf + 1);
+ frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
+ frame->packet_type = FT_PACKET_REQUEST;
+ memset(buf->h_dest, 0xff, ETH_ALEN);
+ os_memcpy(buf->h_source, hapd->own_addr, ETH_ALEN);
+ buf->h_proto = host_to_be16(ETH_P_RRB);
+ l2_packet_send(hapd->l2, buf->h_dest, ETH_P_RRB, (u8 *) buf, len);
+ os_free(buf);
+
+ eloop_register_timeout(hapd->conf->ft_l2_refresh, 0, wpa_ft_refresh,
+ hapd, NULL);
+}
+
int hostapd_setup_wpa(struct hostapd_data *hapd)
{
struct wpa_auth_config _conf;
@@ -1931,6 +1953,9 @@ int hostapd_setup_wpa(struct hostapd_dat
"Failed to open ETH_P_OUI interface");
return -1;
}
+
+ if (hapd->conf->ft_l2_refresh)
+ wpa_ft_refresh(hapd, NULL);
}
#endif /* CONFIG_IEEE80211R_AP */
@@ -1947,7 +1972,6 @@ void hostapd_reconfig_wpa(struct hostapd
wpa_reconfig(hapd->wpa_auth, &wpa_auth_conf);
}
-
void hostapd_deinit_wpa(struct hostapd_data *hapd)
{
ieee80211_tkip_countermeasures_deinit(hapd);
@@ -1971,6 +1995,7 @@ void hostapd_deinit_wpa(struct hostapd_d
"information element from interface %s",
hapd->conf->iface);
}
+
}
ieee802_1x_deinit(hapd);
@@ -1979,6 +2004,7 @@ void hostapd_deinit_wpa(struct hostapd_d
hostapd_wpa_ft_rrb_rx_later(hapd, NULL); /* flush without delivering */
eloop_cancel_timeout(hostapd_oui_deliver_later, hapd, ELOOP_ALL_CTX);
hostapd_oui_deliver_later(hapd, NULL); /* flush without delivering */
+ eloop_cancel_timeout(wpa_ft_refresh, hapd, ELOOP_ALL_CTX);
l2_packet_deinit(hapd->l2);
hapd->l2 = NULL;
hostapd_wpa_unregister_ft_oui(hapd);

View File

@@ -0,0 +1,27 @@
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1995,6 +1995,13 @@ static int hostapd_owe_iface_iter(struct
is_zero_ether_addr(bss->own_addr))
continue;
+ if (!os_memcmp(hapd->conf->owe_transition_bssid, bss->own_addr,
+ ETH_ALEN) &&
+ hapd->conf->owe_transition_ssid_len == bss->conf->ssid.ssid_len &&
+ !os_memcmp(hapd->conf->owe_transition_ssid, bss->conf->ssid.ssid,
+ bss->conf->ssid.ssid_len))
+ return 0;
+
os_memcpy(hapd->conf->owe_transition_bssid, bss->own_addr,
ETH_ALEN);
os_memcpy(hapd->conf->owe_transition_ssid,
@@ -2011,10 +2018,6 @@ static int hostapd_owe_iface_iter(struct
int hostapd_owe_trans_get_info(struct hostapd_data *hapd)
{
- if (hapd->conf->owe_transition_ssid_len > 0 &&
- !is_zero_ether_addr(hapd->conf->owe_transition_bssid))
- return 0;
-
/* Find transition mode SSID/BSSID information from a BSS operated by
* this hostapd instance. */
if (!hapd->iface->interfaces ||

View File

@@ -0,0 +1,53 @@
From 98b6503b87bb36bf2f5ae16e52e230e8870c867f Mon Sep 17 00:00:00 2001
From: Venkat Chimata <venkata@shasta.cloud>
Date: Fri, 28 Jun 2024 14:39:31 +0530
Subject: [PATCH] hostapd: Fix DVLAN + 802.1x issue
In case of swconfig switches, the basename of the interface should be based on the last dot.
Earlier it was done based on the first dot, which would result in incorrect basename.
For example if the interface name is eth0.4087 then the vlan->ifname would be eth0.4087. (A dot at the end) .
Before this patch, the basename was returned as eth0. It should be eth0.4087
Also fixed the return code by adding a default value of 0 and removed an unncessary check
for if_add before ubus add call.
Signed-off-by: Venkat Chimata <venkata@shasta.cloud>
---
src/ap/vlan_init.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/ap/vlan_init.c b/src/ap/vlan_init.c
index 3e27671..cfeb1e5 100644
--- a/src/ap/vlan_init.c
+++ b/src/ap/vlan_init.c
@@ -23,7 +23,8 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
int existsok)
{
bool vlan_exists = iface_exists(vlan->ifname);
- int ret;
+ int ret = 0;
+
#ifdef CONFIG_WEP
int i;
@@ -38,7 +39,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
#endif /* CONFIG_WEP */
if (!hapd->driver || !hapd->driver->if_add) {
- char *dot = strstr(vlan->ifname, ".");
+ char *dot = strrchr(vlan->ifname, '.');
if (dot)
*dot = '\0';
ret = 0;
@@ -59,7 +60,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
if (hapd->wpa_auth)
ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id);
- if (!ret && !vlan_exists && hapd->driver->if_add)
+ if (!ret && !vlan_exists)
hostapd_ubus_add_vlan(hapd, vlan);
if (ret == 0)
--
2.34.1

View File

@@ -3,6 +3,7 @@
#include "utils/includes.h"
#include "utils/common.h"
#include "utils/ucode.h"
#include "sta_info.h"
#include "hostapd.h"
#include "beacon.h"
#include "hw_features.h"
@@ -87,12 +88,16 @@ static uc_value_t *
uc_hostapd_add_iface(uc_vm_t *vm, size_t nargs)
{
uc_value_t *iface = uc_fn_arg(0);
char *data;
int ret;
if (ucv_type(iface) != UC_STRING)
return ucv_int64_new(-1);
ret = hostapd_add_iface(interfaces, ucv_string_get(iface));
data = strdup(ucv_string_get(iface));
ret = hostapd_add_iface(interfaces, data);
free(data);
hostapd_ucode_update_interfaces();
return ucv_int64_new(ret);
@@ -530,10 +535,12 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
return NULL;
#define UPDATE_VAL(field, name) \
if ((intval = ucv_int64_get(ucv_object_get(info, name, NULL))) && \
!errno && intval != conf->field) do { \
conf->field = intval; \
changed = true; \
do { \
intval = ucv_int64_get(ucv_object_get(info, name, NULL)); \
if (!errno && intval != conf->field) { \
conf->field = intval; \
changed = true; \
} \
} while(0)
conf = iface->conf;
@@ -607,6 +614,7 @@ out:
conf->ru_punct_ofdma,
conf->bandwidth_device,
conf->center_freq_device);
ieee802_11_set_beacon(hapd);
}
hostapd_owe_update_trans(iface);
@@ -777,7 +785,6 @@ int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta)
{
struct hostapd_sta_wpa_psk_short *psk = sta->psk;
char addr[sizeof(MACSTR)];
uc_value_t *val, *cur;
int ret = 0;
@@ -794,8 +801,6 @@ void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta
val = ucv_object_new(vm);
if (sta->psk_idx)
ucv_object_add(val, "psk_idx", ucv_int64_new(sta->psk_idx - 1));
if (sta->psk)
ucv_object_add(val, "psk", ucv_string_new(sta->psk->passphrase));
uc_value_push(ucv_get(val));
val = wpa_ucode_call(3);
@@ -908,31 +913,18 @@ out:
return ret;
}
void hostapd_ucode_add_bss(struct hostapd_data *hapd)
void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type)
{
uc_value_t *val;
if (wpa_ucode_call_prepare("bss_add"))
if (wpa_ucode_call_prepare(type))
return;
val = hostapd_ucode_bss_get_uval(hapd);
uc_value_push(ucv_get(ucv_string_new(hapd->iface->phy)));
uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
uc_value_push(ucv_get(val));
ucv_put(wpa_ucode_call(2));
ucv_gc(vm);
}
void hostapd_ucode_reload_bss(struct hostapd_data *hapd)
{
uc_value_t *val;
if (wpa_ucode_call_prepare("bss_reload"))
return;
val = hostapd_ucode_bss_get_uval(hapd);
uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
uc_value_push(ucv_get(val));
ucv_put(wpa_ucode_call(2));
ucv_put(wpa_ucode_call(3));
ucv_gc(vm);
}

View File

@@ -23,14 +23,17 @@ int hostapd_ucode_init(struct hapd_interfaces *ifaces);
void hostapd_ucode_free(void);
void hostapd_ucode_free_iface(struct hostapd_iface *iface);
void hostapd_ucode_free_bss(struct hostapd_data *hapd);
void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type);
int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta);
void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta);
void hostapd_ucode_add_bss(struct hostapd_data *hapd);
void hostapd_ucode_free_bss(struct hostapd_data *hapd);
void hostapd_ucode_reload_bss(struct hostapd_data *hapd);
int hostapd_ucode_afc_request(struct hostapd_iface *iface, const char *request,
char *buf, size_t len);
#ifdef CONFIG_APUP
void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname);
#endif // def CONFIG_APUP
#else
static inline int hostapd_ucode_init(struct hapd_interfaces *ifaces)
@@ -43,7 +46,7 @@ static inline void hostapd_ucode_free(void)
static inline void hostapd_ucode_free_iface(struct hostapd_iface *iface)
{
}
static inline void hostapd_ucode_reload_bss(struct hostapd_data *hapd)
static inline void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type)
{
}
static inline int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
@@ -53,13 +56,25 @@ static inline int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_i
static inline void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta)
{
}
static inline void hostapd_ucode_add_bss(struct hostapd_data *hapd)
{
}
static inline void hostapd_ucode_free_bss(struct hostapd_data *hapd)
{
}
#endif
static inline void hostapd_ucode_create_bss(struct hostapd_data *hapd)
{
hostapd_ucode_bss_cb(hapd, "bss_create");
}
static inline void hostapd_ucode_add_bss(struct hostapd_data *hapd)
{
hostapd_ucode_bss_cb(hapd, "bss_add");
}
static inline void hostapd_ucode_reload_bss(struct hostapd_data *hapd)
{
hostapd_ucode_bss_cb(hapd, "bss_reload");
}
#endif

View File

@@ -22,7 +22,8 @@ DEFAULT_PACKAGES += \
kmod-qca-ssdk-qca-nohnat kmod-qca-nss-dp-qca \
kmod-qca-nss-ppe-bridge-mgr kmod-qca-nss-ppe-vlan-mgr \
iwinfo kmod-ath12k-qca ath12k-firmware-qcn92xx \
kmod-leds-gpio swconfig kmod-fs-ext4 losetup
kmod-leds-gpio swconfig kmod-fs-ext4 losetup wpad-openssl \
ucode-mod-nl80211 ucode-mod-rtnl
GENERIC_LINUX_CONFIG = $(PLATFORM_DIR)/generic/config-$(KERNEL_PATCHVER)-platform

View File

@@ -1,68 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2014, 2021, The Linux Foundation. All rights reserved.
# Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
[ -e /etc/config/network ] && exit 0
touch /etc/config/network
CFG=/etc/board.json
. /lib/functions/uci-defaults.sh
ipq53xx_setup_interfaces()
{
local board="$1"
case "$board" in
qcom,ipq5332-ap-emulation |\
qcom,ipq5332-db-mi01.1 |\
qcom,ipq5332-db-mi02.1 |\
qcom,ipq5332-db-mi03.1)
ucidef_set_interfaces_lan_wan "eth1" "eth0"
;;
qcom,ipq5332-ap-mi01.2 |\
qcom,ipq5332-ap-mi01.2-c2 |\
qcom,ipq5332-ap-mi01.2-qcn9160-c1 |\
qcom,ipq5332-ap-mi01.3 |\
qcom,ipq5332-ap-mi01.3-c2 |\
qcom,ipq5332-ap-mi01.4 |\
qcom,ipq5332-ap-mi01.6 |\
qcom,ipq5332-ap-mi01.7 |\
qcom,ipq5332-ap-mi01.9 |\
qcom,ipq5332-ap-mi01.12 |\
qcom,ipq5332-ap-mi01.14 |\
qcom,ipq5332-ap-mi03.1 |\
qcom,ipq5332-ap-mi04.1 |\
qcom,ipq5332-ap-mi04.1-c2)
ucidef_set_interfaces_lan_wan "eth1" "eth0"
ucidef_add_switch "switch1"
ucidef_add_switch_attr "switch1" "enable" false
;;
*)
echo "Unsupported hardware. Network interfaces not intialized"
;;
esac
}
board_config_update
board=$(board_name)
ipq53xx_setup_interfaces $board
board_config_flush
exit 0

View File

@@ -51,7 +51,7 @@ qcom_setup_macs()
board_config_update
board=$(board_name)
ipq53xx_setup_interfaces $board
qcom_setup_macs $board
#qcom_setup_macs $board
board_config_flush
exit 0

View File

@@ -1,9 +1,7 @@
#!/bin/sh
export >> /tmp/foo
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions.sh
. /lib/functions/system.sh
@@ -25,6 +23,17 @@ caldata_extract() {
caldata_die "failed to extract calibration data from $mtd"
}
ath12k_generate_macs_eap105() {
touch /lib/firmware/ath12k-macs
eth=$(cat /sys/class/net/eth0/address)
mac1=$(macaddr_add $eth 2)
mac2=$(macaddr_add $eth 3)
mac3=$(macaddr_add $eth 4)
echo -ne \\x${mac1//:/\\x} >> /lib/firmware/ath12k-macs
echo -ne \\x${mac2//:/\\x} >> /lib/firmware/ath12k-macs
echo -ne \\x${mac3//:/\\x} >> /lib/firmware/ath12k-macs
}
board=$(board_name)
case "$FIRMWARE" in
@@ -46,6 +55,13 @@ ath12k/QCN92XX/hw1.0/cal-pci-0001:01:00.0.bin)
;;
esac
;;
ath12k-macs)
case "$board" in
edgecore,eap105)
ath12k_generate_macs_eap105
;;
esac
;;
*)
exit 1
;;

View File

@@ -0,0 +1,392 @@
# Copyright (C) 2014 OpenWrt.org
#
. /lib/functions.sh
# 'kernel' partition or UBI volume on NAND contains the kernel
CI_KERNPART="${CI_KERNPART:-kernel}"
# 'ubi' partition on NAND contains UBI
CI_UBIPART="${CI_UBIPART:-ubi}"
# 'rootfs' UBI volume on NAND contains the rootfs
CI_ROOTPART="${CI_ROOTPART:-rootfs}"
# ipq807x qsdk kernel misbehaves
CI_IPQ807X=0
# update BOOTCONFIG partitions (rotate rootfs/rootfs_1)
CI_BOOTCFG=0
# update uboot-env if upgrade suceeded
CI_FWSETENV=
ubi_mknod() {
local dir="$1"
local dev="/dev/$(basename $dir)"
[ -e "$dev" ] && return 0
local devid="$(cat $dir/dev)"
local major="${devid%%:*}"
local minor="${devid##*:}"
mknod "$dev" c $major $minor
}
nand_find_volume() {
local ubidevdir ubivoldir
ubidevdir="/sys/devices/virtual/ubi/$1"
[ ! -d "$ubidevdir" ] && return 1
for ubivoldir in $ubidevdir/${1}_*; do
[ ! -d "$ubivoldir" ] && continue
if [ "$( cat $ubivoldir/name )" = "$2" ]; then
basename $ubivoldir
ubi_mknod "$ubivoldir"
return 0
fi
done
}
nand_find_ubi() {
local ubidevdir ubidev mtdnum
mtdnum="$( find_mtd_index $1 )"
[ ! "$mtdnum" ] && return 1
for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
[ ! -d "$ubidevdir" ] && continue
cmtdnum="$( cat $ubidevdir/mtd_num )"
[ ! "$mtdnum" ] && continue
if [ "$mtdnum" = "$cmtdnum" ]; then
ubidev=$( basename $ubidevdir )
ubi_mknod "$ubidevdir"
echo $ubidev
return 0
fi
done
}
nand_get_magic_long() {
dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
}
get_magic_long_tar() {
( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
}
identify_magic() {
local magic=$1
case "$magic" in
"55424923")
echo "ubi"
;;
"31181006")
echo "ubifs"
;;
"68737173")
echo "squashfs"
;;
"d00dfeed")
echo "fit"
;;
"4349"*)
echo "combined"
;;
*)
echo "unknown $magic"
;;
esac
}
identify() {
identify_magic $(nand_get_magic_long "$1" "${2:-0}")
}
identify_tar() {
identify_magic $(get_magic_long_tar "$1" "$2")
}
nand_restore_config() {
sync
local ubidev=$( nand_find_ubi $CI_UBIPART )
local ubivol="$( nand_find_volume $ubidev rootfs_data )"
[ ! "$ubivol" ] &&
ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
mkdir /tmp/new_root
if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
echo "mounting ubifs $ubivol failed"
rmdir /tmp/new_root
return 1
fi
mv "$1" "/tmp/new_root/$BACKUP_FILE"
umount /tmp/new_root
sync
rmdir /tmp/new_root
}
nand_upgrade_prepare_ubi() {
local rootfs_length="$1"
local rootfs_type="$2"
local rootfs_data_max="$(fw_printenv -n rootfs_data_max 2>/dev/null)"
[ -n "$rootfs_data_max" ] && rootfs_data_max=$(printf %d "$rootfs_data_max")
local kernel_length="$3"
local has_env="${4:-0}"
[ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1
local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
if [ ! "$mtdnum" ]; then
echo "cannot find ubi mtd partition $CI_UBIPART"
return 1
fi
[ "$CI_IPQ807X" = 1 ] && ubidetach -f -m $mtdnum
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
if [ ! "$ubidev" ]; then
ubiattach -m "$mtdnum"
sync
ubidev="$( nand_find_ubi "$CI_UBIPART" )"
fi
if [ ! "$ubidev" ]; then
ubiformat /dev/mtd$mtdnum -y
ubiattach -m "$mtdnum"
sync
ubidev="$( nand_find_ubi "$CI_UBIPART" )"
[ "$has_env" -gt 0 ] && {
ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
}
fi
local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
local ubiblk ubiblkvol
for ubiblk in /dev/ubiblock*_? ; do
[ -e "$ubiblk" ] || continue
echo "removing ubiblock${ubiblk:13}"
ubiblkvol=ubi${ubiblk:13}
if ! ubiblock -r /dev/$ubiblkvol; then
echo "cannot remove $ubiblk"
return 1
fi
done
# kill volumes
[ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
[ "$root_ubivol" -a "$root_ubivol" != "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
[ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
# update kernel
if [ -n "$kernel_length" ]; then
if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
echo "cannot create kernel volume"
return 1;
fi
fi
# update rootfs
if [ -n "$rootfs_length" ]; then
local rootfs_size_param
if [ "$rootfs_type" = "ubifs" ]; then
rootfs_size_param="-m"
else
rootfs_size_param="-s $rootfs_length"
fi
if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then
echo "cannot create rootfs volume"
return 1;
fi
fi
# create rootfs_data for non-ubifs rootfs
if [ "$rootfs_type" != "ubifs" ]; then
local availeb=$(cat /sys/devices/virtual/ubi/$ubidev/avail_eraseblocks)
local ebsize=$(cat /sys/devices/virtual/ubi/$ubidev/eraseblock_size)
local avail_size=$(( $availeb * $ebsize ))
local rootfs_data_size_param="-m"
if [ -n "$rootfs_data_max" ] &&
[ "$rootfs_data_max" != "0" ] &&
[ "$rootfs_data_max" -le "$avail_size" ]; then
rootfs_data_size_param="-s $rootfs_data_max"
fi
if ! ubimkvol /dev/$ubidev -N rootfs_data $rootfs_data_size_param; then
echo "cannot initialize rootfs_data volume"
return 1
fi
fi
sync
return 0
}
nand_qca_update_bootconfig() {
local primary="0"
local mtdnum
local part
[ -f /proc/boot_info/rootfs/primaryboot ] || return
[ -f /proc/boot_info/getbinary_bootconfig ] || return
[ "$(cat /proc/boot_info/rootfs/primaryboot)" = "0" ] && primary="1"
echo "$primary" > /proc/boot_info/rootfs/primaryboot 2>/dev/null
for part in "0:BOOTCONFIG" "0:BOOTCONFIG1"; do
mtdnum="$(find_mtd_index "$part")"
[ -c "/dev/mtd${mtdnum}" ] && {
mtd -qq write /proc/boot_info/getbinary_bootconfig \
"/dev/mtd${mtdnum}" 2>/dev/null &&\
echo "partition '$part' updated"
}
done
}
nand_do_upgrade_success() {
local conf_tar="/tmp/sysupgrade.tgz"
sync
[ "$CI_BOOTCFG" = 1 ] && nand_qca_update_bootconfig
[ -n "$CI_FWSETENV" ] && fw_setenv $CI_FWSETENV
[ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
echo "sysupgrade successful"
umount -a
sleep 5
reboot -f
}
# Flash the UBI image to MTD partition
nand_upgrade_ubinized() {
local ubi_file="$1"
local mtdnum="$(find_mtd_index "$CI_UBIPART")"
[ ! "$mtdnum" ] && {
CI_UBIPART="rootfs"
mtdnum="$(find_mtd_index "$CI_UBIPART")"
}
if [ ! "$mtdnum" ]; then
echo "cannot find mtd device $CI_UBIPART"
umount -a
reboot -f
fi
local mtddev="/dev/mtd${mtdnum}"
ubidetach -p "${mtddev}" || true
sync
ubiformat "${mtddev}" -y -f "${ubi_file}"
ubiattach -p "${mtddev}"
nand_do_upgrade_success
}
# Write the UBIFS image to UBI volume
nand_upgrade_ubifs() {
local rootfs_length=$( (cat $1 | wc -c) 2> /dev/null)
nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "" ""
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
nand_do_upgrade_success
}
nand_upgrade_fit() {
local fit_file="$1"
local fit_length="$(wc -c < "$fit_file")"
nand_upgrade_prepare_ubi "" "" "$fit_length" "1"
local fit_ubidev="$(nand_find_ubi "$CI_UBIPART")"
local fit_ubivol="$(nand_find_volume $fit_ubidev "$CI_KERNPART")"
ubiupdatevol /dev/$fit_ubivol -s $fit_length $fit_file
nand_do_upgrade_success
}
nand_upgrade_tar() {
local tar_file="$1"
local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$')
board_dir=${board_dir%/}
kernel_length=$( (tar xf "$tar_file" ${board_dir}/kernel -O | wc -c) 2> /dev/null)
local has_rootfs=0
local rootfs_length
local rootfs_type
tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1
[ "$has_rootfs" = "1" ] && {
rootfs_length=$( (tar xf "$tar_file" ${board_dir}/root -O | wc -c) 2> /dev/null)
rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
}
local has_kernel=1
local has_env=0
[ "$CI_IPQ807X" = 0 -a "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
tar xf $tar_file ${board_dir}/kernel -O | mtd write - $CI_KERNPART
}
[ "$CI_IPQ807X" = 0 ] && {
[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=
}
nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "${has_kernel:+$kernel_length}" "$has_env"
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
[ "$has_kernel" = "1" ] && {
local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
tar xf "$tar_file" ${board_dir}/kernel -O | \
ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
}
[ "$has_rootfs" = "1" ] && {
local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
tar xf "$tar_file" ${board_dir}/root -O | \
ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
}
nand_do_upgrade_success
}
# Recognize type of passed file and start the upgrade process
nand_do_upgrade() {
local file_type=$(identify $1)
[ ! "$( find_mtd_index "$CI_UBIPART" )" ] && CI_UBIPART="rootfs"
case "$file_type" in
"fit") nand_upgrade_fit $1;;
"ubi") nand_upgrade_ubinized $1;;
"ubifs") nand_upgrade_ubifs $1;;
*) nand_upgrade_tar $1;;
esac
}
# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts
# 3 types of files:
# 1) UBI - should contain an ubinized image, header is checked for the proper
# MAGIC
# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume,
# header is checked for the proper MAGIC
# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty
# "CONTROL" file (at this point its content isn't verified)
#
# You usually want to call this function in platform_check_image.
#
# $(1): board name, used in case of passing TAR file
# $(2): file to be checked
nand_do_platform_check() {
local board_name="$1"
local tar_file="$2"
local control_length=$( (tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null)
local file_type="$(identify $2)"
[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" -a "$file_type" != "fit" ] && {
echo "Invalid sysupgrade file."
return 1
}
return 0
}

View File

@@ -1,593 +1,24 @@
#
# Copyright (c) 2020, The Linux Foundation. All rights reserved.
#
# Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
. /lib/functions/system.sh
. /lib/functions.sh
. /lib/upgrade/common.sh
RAMFS_COPY_DATA="/etc/fw_env.config /var/lock/fw_printenv.lock"
RAMFS_COPY_BIN="/usr/bin/dumpimage /usr/sbin/ubiattach /usr/sbin/ubidetach
/usr/sbin/ubiformat /usr/sbin/ubiupdatevol /bin/rm /usr/bin/find
/usr/sbin/mkfs.ext4 /usr/sbin/fw_printenv /sbin/lsmod"
get_full_section_name() {
local img=$1
local sec=$2
dumpimage -l ${img} | grep "^ Image.*(${sec})" | \
sed 's,^ Image.*(\(.*\)),\1,'
}
image_contains() {
local img=$1
local sec=$2
dumpimage -l ${img} | grep -q "^ Image.*(${sec}.*)" || return 1
}
print_sections() {
local img=$1
dumpimage -l ${img} | awk '/^ Image.*(.*)/ { print gensub(/Image .* \((.*)\)/,"\\1", $0) }'
}
image_has_mandatory_section() {
local img=$1
local mandatory_sections=$2
for sec in ${mandatory_sections}; do
image_contains $img ${sec} || {\
return 1
}
done
}
image_demux() {
local img=$1
for sec in $(print_sections ${img}); do
local fullname=$(get_full_section_name ${img} ${sec})
local position=$(dumpimage -l ${img} | grep "(${fullname})" | awk '{print $2}')
version=$(dumpimage -V 2>&1 | awk '{split($3, a, "."); print a[1]}')
if [ "$version" == "2016" ]; then
dumpimage -i ${img} -o /tmp/${fullname}.bin -T "flat_dt" -p "${position}" ${fullname} > /dev/null || { \
echo "Error while extracting \"${sec}\" from ${img}"
return 1
}
else
dumpimage -o /tmp/${fullname}.bin -T "flat_dt" -p "${position}" ${img} > /dev/null || { \
echo "Error while extracting \"${sec}\" from ${img}"
return 1
}
fi
done
return 0
}
image_is_FIT() {
if ! dumpimage -l $1 > /dev/null 2>&1; then
echo "$1 is not a valid FIT image"
return 1
fi
return 0
}
do_flash_mtd() {
local bin=$1
local mtdname=$2
local append=""
local mtdname_rootfs="rootfs"
local boot_layout=`find / -name boot_layout`
local flash_type=`fw_printenv | grep flash_type=11`
local mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
if [ ! -n "$mtdpart" ]; then
echo "$mtdname is not available" && return
fi
local pgsz=$(cat /sys/class/mtd/${mtdpart}/writesize)
local mtdpart_rootfs=$(grep "\"${mtdname_rootfs}\"" /proc/mtd | awk -F: '{print $1}')
[ -f "$UPGRADE_BACKUP" -a "$2" == "rootfs" ] && append="-j $UPGRADE_BACKUP"
dd if=/tmp/${bin}.bin bs=${pgsz} conv=sync | mtd $append -e "/dev/${mtdpart}" write - "/dev/${mtdpart}"
}
do_flash_emmc() {
local bin=$1
local emmcblock=$2
dd if=/dev/zero of=${emmcblock} &> /dev/null
dd if=/tmp/${bin}.bin of=${emmcblock}
}
do_flash_partition() {
local bin=$1
local mtdname=$2
local emmcblock="$(find_mmc_part "$mtdname")"
if [ -e "$emmcblock" ]; then
do_flash_emmc $bin $emmcblock
else
do_flash_mtd $bin $mtdname
fi
}
get_alternate_bootconfig() {
local age0=$(cat /proc/boot_info/bootconfig0/age)
local age1=$(cat /proc/boot_info/bootconfig1/age)
if [ -e /proc/upgrade_info/trybit ]; then
if [ $age0 -le $age1 ]; then
echo "bootconfig0"
else
echo "bootconfig1"
fi
else
echo "bootconfig0 bootconfig1"
fi
}
get_current_bootconfig() {
local bcname=$1
local age0=$(cat /proc/boot_info/bootconfig0/age)
local age1=$(cat /proc/boot_info/bootconfig1/age)
if [ -e /proc/upgrade_info/trybit ]; then
if [ $age0 -le $age1 ]; then
echo "bootconfig1"
else
echo "bootconfig0"
fi
else
echo $bcname
fi
}
do_flash_bootconfig() {
local bin=$1
local mtdname=$2
# Fail safe upgrade
if [ -f /proc/boot_info/$bin/getbinary_bootconfig ]; then
cat /proc/boot_info/$bin/getbinary_bootconfig > /tmp/${bin}.bin
do_flash_partition $bin $mtdname
fi
}
do_flash_failsafe_partition() {
local bin=$1
local mtdname=$2
local emmcblock
local primaryboot
local default_mtd
local primary_bcname
#Failsafe upgrade
default_mtd=$mtdname
for bcname in $(get_alternate_bootconfig)
do
[ -f /proc/boot_info/$bcname/$default_mtd/upgradepartition ] && {
primary_bcname=$(get_current_bootconfig $bcname)
primaryboot=$(cat /proc/boot_info/$primary_bcname/$default_mtd/primaryboot)
mtdname=$(cat /proc/boot_info/$bcname/$default_mtd/upgradepartition)
echo $((primaryboot ^= 1)) > /proc/boot_info/$bcname/$default_mtd/primaryboot
}
done
emmcblock="$(find_mmc_part "$mtdname")"
if [ -e "$emmcblock" ]; then
do_flash_emmc $bin $emmcblock
else
do_flash_mtd $bin $mtdname
fi
}
do_flash_ubi() {
local bin=$1
local mtdname=$2
local mtdpart
local primaryboot
local default_mtd
local primary_bcname
mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
ubidetach -f -p /dev/${mtdpart}
# Fail safe upgrade
default_mtd=$mtdname
for bcname in $(get_alternate_bootconfig)
do
[ -f /proc/boot_info/$bcname/$default_mtd/upgradepartition ] && {
primary_bcname=$(get_current_bootconfig $bcname)
primaryboot=$(cat /proc/boot_info/$primary_bcname/$default_mtd/primaryboot)
mtdname=$(cat /proc/boot_info/$bcname/$default_mtd/upgradepartition)
echo $((primaryboot ^= 1)) > /proc/boot_info/$bcname/$default_mtd/primaryboot
}
done
mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
ubiformat /dev/${mtdpart} -y -f /tmp/${bin}.bin
}
do_flash_failsafe_ubi_volume() {
local bin=$1
local mtdname=$2
local vol_name=$3
local tmpfile="${bin}.bin"
local mtdpart
local default_mtd
default_mtd=$mtdname
for bcname in $(get_alternate_bootconfig)
do
[ -f /proc/boot_info/$bcname/$default_mtd/upgradepartition ] && {
mtdname=$(cat /proc/boot_info/$bcname/$default_mtd/upgradepartition)
}
done
mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}')
if [ ! -n "$mtdpart" ]; then
echo "$mtdname is not available" && return
fi
ubiattach -p /dev/${mtdpart}
volumes=$(ls /sys/class/ubi/*/ | grep ubi._.*)
for vol in ${volumes}
do
[ -f /sys/class/ubi/${vol}/name ] && name=$(cat /sys/class/ubi/${vol}/name)
[ ${name} == ${vol_name} ] && m_vol=${vol}
done
ubiupdatevol /dev/${m_vol} /tmp/${tmpfile}
}
do_flash_tz() {
local sec=$1
local mtdpart=$(grep "\"0:QSEE\"" /proc/mtd | awk -F: '{print $1}')
local emmcblock="$(find_mmc_part "0:QSEE")"
if [ -n "$mtdpart" -o -e "$emmcblock" ]; then
do_flash_failsafe_partition ${sec} "0:QSEE"
do_flash_failsafe_partition ${sec} "0:QSEE_1"
fi
}
do_flash_ddr() {
local sec=$1
local mtdpart=$(grep "\"0:CDT\"" /proc/mtd | awk -F: '{print $1}')
local emmcblock="$(find_mmc_part "0:CDT")"
if [ -n "$mtdpart" -o -e "$emmcblock" ]; then
do_flash_failsafe_partition ${sec} "0:CDT"
fi
}
to_lower ()
{
echo $1 | awk '{print tolower($0)}'
}
to_upper ()
{
echo $1 | awk '{print toupper($0)}'
}
image_is_nand()
{
local nand_part="$(find_mtd_part "ubi_rootfs")"
[ -e "$nand_part" ] || return 1
}
get_fw_name() {
wifi_ipq="ignored"
image_suffix1="qcn9224_v2_single_dualmac"
image_suffix2="qcn6432cs"
image_suffix3="qcn6432"
image_suffix4="qcn9224_v2_qcn6432"
image_suffix5="qcn9224_v2_qcn9160"
machineid=$(fw_printenv -l /tmp/. machid | cut -d '=' -f 2)
case "${machineid}" in
"F060000"|\
"8060000"|\
"8060001"|\
"8060003"|\
"8060006"|\
"1060001"|\
"1060002"|\
"8060201")
wifi_ipq="ipq5332_"$image_suffix1
;;
"8060002"|\
"8060004")
wifi_ipq="ipq5332_"$image_suffix2
;;
"1060003"|\
"8060102"|\
"8060007")
wifi_ipq="ipq5332_"$image_suffix3
;;
"8060202"|\
"8060302")
wifi_ipq="ipq5332_"$image_suffix4
;;
"8060101")
wifi_ipq="ipq5332_"$image_suffix5
;;
*)
wifi_ipq="ipq5332_qcn9224_v2_single_dualmac_qcn9160"
;;
esac
echo $wifi_ipq
}
flash_section() {
local sec=$1
local board=$(board_name)
local board_model=$(to_lower $(grep -o "RDP.*" /proc/device-tree/model | awk -F/ '{print $2}'))
case "${sec}" in
hlos*) image_is_nand && return || do_flash_failsafe_partition ${sec} "0:HLOS";;
rootfs*) image_is_nand && return || do_flash_failsafe_partition ${sec} "rootfs";;
wifi_fw_$(get_fw_name)-*) do_flash_failsafe_partition ${sec} "0:WIFIFW"; do_flash_failsafe_ubi_volume ${sec} "rootfs" "wifi_fw" ;;
ubi*) image_is_nand || return && do_flash_ubi ${sec} "rootfs";;
sbl1*) do_flash_partition ${sec} "0:SBL1"; \
do_flash_partition ${sec} "0:SBL1_1";;
u-boot*) do_flash_failsafe_partition ${sec} "0:APPSBL";;
ddr-$(to_upper $board_model)_*) do_flash_ddr ${sec};;
ddr-${board_model}-*) do_flash_failsafe_partition ${sec} "0:DDRCONFIG";;
tz*) do_flash_tz ${sec};;
tme*) do_flash_partition ${sec} "0:TME"; \
do_flash_partition ${sec} "0:TME_1";;
devcfg*) do_flash_failsafe_partition ${sec} "0:DEVCFG";;
*) echo "Section ${sec} ignored"; return 1;;
esac
echo "Flashed ${sec}"
}
erase_emmc_config() {
local mtdpart=$(cat /proc/mtd | grep rootfs)
local emmcblock="$(find_mmc_part "rootfs_data")"
if [ -z "$mtdpart" -a -e "$emmcblock" ]; then
yes | mkfs.ext4 "$emmcblock"
fi
}
RAMFS_COPY_BIN='fw_printenv fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
platform_check_image() {
local board=$(board_name)
local board_model=$(to_lower $(grep -o "RDP.*" /proc/device-tree/model | awk -F/ '{print $2}'))
local mandatory_nand="ubi"
local mandatory_nor_emmc="hlos fs"
local mandatory_nor="hlos"
local mandatory_section_found=0
local ddr_section="ddr"
local optional="sb11 sbl2 u-boot lkboot ddr-${board_model} tz rpm"
local ignored="mibib bootconfig"
image_is_FIT $1 || return 1
image_has_mandatory_section $1 ${mandatory_nand} && {\
mandatory_section_found=1
}
image_has_mandatory_section $1 ${mandatory_nor_emmc} && {\
mandatory_section_found=1
}
image_has_mandatory_section $1 ${mandatory_nor} && {\
mandatory_section_found=1
}
if [ $mandatory_section_found -eq 0 ]; then
echo "Error: mandatory section(s) missing from \"$1\". Abort..."
return 1
fi
image_has_mandatory_section $1 $ddr_section && {\
image_contains $1 ddr-$board_model || {\
image_contains $1 ddr-$(to_upper $board_model) || {\
return 1
}
}
}
for sec in ${optional}; do
image_contains $1 ${sec} || {\
echo "Warning: optional section \"${sec}\" missing from \"$1\". Continue..."
}
done
for sec in ${ignored}; do
image_contains $1 ${sec} && {\
echo "Warning: section \"${sec}\" will be ignored from \"$1\". Continue..."
}
done
echo 1711 > /proc/sys/vm/min_free_kbytes
echo 3 > /proc/sys/vm/drop_caches
image_demux $1 || {\
echo "Error: \"$1\" couldn't be extracted. Abort..."
return 1
}
[ -f /tmp/hlos_version ] && rm -f /tmp/*_version
dumpimage -c $1
if [[ "$?" == 0 ]];then
return $?
else
echo "Rebooting the system"
reboot
return 1
fi
local magic_long="$(get_magic_long "$1")"
[ "$magic_long" = "73797375" ] && return 0
return 1
}
platform_do_upgrade() {
local board=$(board_name)
CI_UBIPART="rootfs"
CI_ROOTPART="ubi_rootfs"
CI_IPQ807X=1
# verify some things exist before erasing
if [ ! -e $1 ]; then
echo "Error: Can't find $1 after switching to ramfs, aborting upgrade!"
reboot
fi
for sec in $(print_sections $1); do
if [ ! -e /tmp/${sec}.bin ]; then
echo "Error: Cant' find ${sec} after switching to ramfs, aborting upgrade!"
reboot
fi
done
case "$board" in
qcom,devsoc-ap-emulation |\
qcom,ipq5332-ap-mi01.2 |\
qcom,ipq5332-ap-mi01.2-c2 |\
qcom,ipq5332-ap-mi01.2-qcn9160-c1 |\
qcom,ipq5332-ap-mi01.3 |\
qcom,ipq5332-ap-mi01.3-c2 |\
qcom,ipq5332-ap-mi01.4 |\
qcom,ipq5332-ap-mi01.6 |\
qcom,ipq5332-ap-mi01.7 |\
qcom,ipq5332-ap-mi01.9 |\
qcom,ipq5332-ap-mi01.12 |\
qcom,ipq5332-ap-mi01.14 |\
qcom,ipq5332-ap-mi04.1 |\
qcom,ipq5332-ap-mi04.1-c2 |\
qcom,ipq5332-db-mi01.1 |\
qcom,ipq5332-db-mi02.1)
for sec in $(print_sections $1); do
flash_section ${sec}
done
for bcname in $(get_alternate_bootconfig)
do
if [ $bcname = "bootconfig0" ]; then
do_flash_bootconfig $bcname "0:BOOTCONFIG"
else
do_flash_bootconfig $bcname "0:BOOTCONFIG1"
fi
done
erase_emmc_config
return 0;
board=$(board_name)
case $board in
cig,wf189|\
edgecore,eap105)
nand_upgrade_tar "$1"
;;
esac
echo "Upgrade failed!"
return 1;
}
age_do_upgrade(){
age0=$(cat /proc/boot_info/bootconfig0/age)
age1=$(cat /proc/boot_info/bootconfig1/age)
if [ -e /proc/upgrade_info/trybit ]; then
if [ $age0 -eq $age1 ]; then
ageinc=$((age0+1))
echo $ageinc > /proc/boot_info/bootconfig0/age
do_flash_bootconfig bootconfig0 "0:BOOTCONFIG"
elif [ $age0 -lt $age1 ]; then
ageinc=$((age0+2))
echo $ageinc > /proc/boot_info/bootconfig0/age
do_flash_bootconfig bootconfig0 "0:BOOTCONFIG"
else
ageinc=$((age1+2))
echo $ageinc > /proc/boot_info/bootconfig1/age
do_flash_bootconfig bootconfig1 "0:BOOTCONFIG1"
fi
else
echo "Not in Try mode"
fi
}
get_magic_long_at() {
dd if="$1" skip=$(( 65536 / 4 * $2 )) bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
}
# find rootfs_data start magic
platform_get_offset() {
offsetcount=0
magiclong="x"
while magiclong=$( get_magic_long_at "$1" "$offsetcount" ) && [ -n "$magiclong" ]; do
case "$magiclong" in
"deadc0de"|"19852003")
echo $(( $offsetcount * 65536 ))
return
;;
esac
offsetcount=$(( $offsetcount + 1 ))
done
echo $(( $offsetcount * 65536 ))
}
platform_copy_config() {
local nand_part="$(find_mtd_part "ubi_rootfs")"
local emmcblock="$(find_mmc_part "rootfs")"
local upgradepart
mkdir -p /tmp/overlay
#setting Try bit
if [ -e /proc/upgrade_info/trybit ]; then
echo 1 > /proc/upgrade_info/trybit
fi
for bcname in $(get_alternate_bootconfig)
do
[ -f /proc/boot_info/$bcname/rootfs/upgradepartition ] && {
upgradepart=$(cat /proc/boot_info/$bcname/rootfs/upgradepartition)
}
done
if [ -e "${nand_part%% *}" ]; then
local mtdpart
mtdpart=$(grep "\"${upgradepart}\"" /proc/mtd | awk -F: '{print $1}')
ubiattach -p /dev/${mtdpart}
mount -t ubifs ubi0:rootfs_data /tmp/overlay
elif [ -e "$emmcblock" ]; then
losetup --detach-all
local data_blockoffset="$(platform_get_offset $(ls /tmp/rootfs-*))"
local loopdev="$(losetup -f)"
[ "$upgradepart" == "rootfs" ] && upgradepart="rootfs_1" || upgradepart="rootfs"
emmcblock="$(find_mmc_part ${upgradepart})"
losetup -o $data_blockoffset $loopdev $emmcblock || {
echo "Failed to mount looped rootfs_data."
reboot
}
echo y | mkfs.ext4 -F -L rootfs_data $loopdev
mount -t ext4 "$loopdev" /tmp/overlay
cp /tmp/sysupgrade.tgz /tmp/overlay/
sync
umount /tmp/overlay
fi
cp /tmp/sysupgrade.tgz /tmp/overlay/
sync
umount /tmp/overlay
}

View File

@@ -127,7 +127,7 @@ CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
CONFIG_BOUNCE=y
# CONFIG_BPF_KPROBE_OVERRIDE is not set
# CONFIG_BPFILTER is not set
# CONFIG_BRIDGE_VLAN_FILTERING is not set
CONFIG_BRIDGE_VLAN_FILTERING=y
# CONFIG_BT_HCIBTUSB_MTK is not set
# CONFIG_BT_MTKSDIO is not set
CONFIG_BUILD_BIN2C=y
@@ -1214,4 +1214,5 @@ CONFIG_HWMON=y
# CONFIG_BOOTCONFIG_PARTITION is not set
CONFIG_ARM_PMU=y
# CONFIG_SECCRYPT is not set
CONFIG_RTK_MSSDK_PHY=y
# CONFIG_NF_CONNTRACK_CHAIN_EVENTS is not set

View File

@@ -15,14 +15,18 @@
#include "ipq5332-default-memory.dtsi"
/ {
model = "Qualcomm Technologies, Inc. IPQ5332/RDP468/AP-MI01.6";
compatible = "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332-rdp468", "qcom,ipq5332";
model = "EdgeCore eap105";
compatible = "edgecore,eap105", "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332";
aliases {
serial0 = &blsp1_uart0;
serial1 = &blsp1_uart1;
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
led-boot = &led_power;
led-failsafe = &led_power;
led-running = &led_power;
led-upgrade = &led_power;
};
chosen {
@@ -31,120 +35,48 @@
soc@0 {
mdio:mdio@90000 {
pinctrl-0 = <&mdio1_pins &mdio0_pins>;
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
/*gpio51 for manhattan reset*/
phy-reset-gpio = <&tlmm 51 GPIO_ACTIVE_LOW>;
phy-reset-gpio = <&tlmm 24 GPIO_ACTIVE_LOW &tlmm 22 GPIO_ACTIVE_LOW>;
phyaddr_fixup = <0xC90F018>;
uniphyaddr_fixup = <0xC90F014>;
mdio_clk_fixup; /* MDIO clock sequence fix up flag */
status = "okay";
phy0: ethernet-phy@0 {
reg = <1>;
fixup;
};
phy1: ethernet-phy@1 {
reg = <2>;
fixup;
compatible = "ethernet-phy-id001c.c916";
};
phy2: ethernet-phy@2 {
reg = <3>;
fixup;
};
phy3: ethernet-phy@3 {
reg = <4>;
fixup;
phy1: ethernet-phy@1 {
reg = <1>;
compatible = "ethernet-phy-id001c.c868";
};
};
ess-instance {
num_devices = <0x2>;
ess-switch@3a000000 {
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x2>; /* lan port bitmap */
switch_wan_bmp = <0x4>; /* wan port bitmap */
switch_mac_mode = <0xc>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
switch_mac_mode = <0xf>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xd>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
forced-speed = <2500>;
forced-duplex = <1>;
};
port@1 {
port_id = <2>;
phy_address = <4>;
};
};
led_source@5 {
source = <5>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
};
ess-switch1@1 {
compatible = "qcom,ess-switch-qca8386";
device_id = <1>;
switch_access_mode = "mdio";
mdio-bus = <&mdio>;
switch_mac_mode = <0xc>; /* mac mode for uniphy instance0 */
switch_mac_mode1 = <0xff>; /* mac mode1 for uniphy instance1 */
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0xe>; /* lan port bitmap */
switch_wan_bmp = <0x0>; /* wan port bitmap */
link-polling-required = <0>;
fdb_sync = "interrupt";
link-intr-gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>;
qcom,port_phyinfo {
port@0 {
port_id = <0>;
forced-speed = <2500>;
forced-duplex = <1>;
};
port@1 {
port_id = <1>;
phy_address = <1>;
};
port@2 {
port_id = <2>;
phy_address = <2>;
mdiobus = <&mdio>;
ethernet-phy-ieee802.3-c45;
};
port@3 {
port_id = <3>;
phy_address = <3>;
port@1 {
port_id = <2>;
phy_address = <1>;
mdiobus = <&mdio>;
ethernet-phy-ieee802.3-c45;
};
};
led_source@2 {
source = <2>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
led_source@5 {
source = <5>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
led_source@8 {
source = <8>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
};
};
@@ -156,7 +88,7 @@
qcom,mactype = <1>;
local-mac-address = [000000000000];
mdio-bus = <&mdio>;
qcom,phy-mdio-addr = <4>;
qcom,phy-mdio-addr = <1>;
qcom,link-poll = <1>;
phy-mode = "sgmii";
};
@@ -168,9 +100,10 @@
reg = <0x3a500000 0x4000>;
qcom,mactype = <1>;
local-mac-address = [000000000000];
mdio-bus = <&mdio>;
qcom,phy-mdio-addr = <2>;
qcom,link-poll = <1>;
phy-mode = "sgmii";
qcom,mht-dev = <1>;
qcom,is_switch_connected = <1>;
};
/* EDMA host driver configuration for the board */
@@ -243,29 +176,33 @@
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&gpio_leds_default>;
pinctrl-names = "default";
compatible = "gpio-leds";
led-0 {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_WLAN;
gpios = <&tlmm 36 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "phy0tx";
default-state = "off";
};
};
led@37 {
label = "red:status";
gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
led_power: led@38 {
label = "blue:status";
gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
led@39 {
label = "green:status";
gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
status = "okay";
button@1 {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
label = "rst";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
@@ -319,7 +256,8 @@
status = "okay";
flash@0 {
compatible = "micron,n25q128a11", "jedec,spi-nor";
compatible = "n25q128a11";
//, "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
@@ -527,7 +465,7 @@
};
button_pins: button-state {
pins = "gpio35";
pins = "gpio25";
function = "gpio";
drive-strength = <8>;
bias-pull-up;

View File

@@ -0,0 +1,569 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* drivers/net/phy/realtek.c
*
* Driver for Realtek PHYs
*
* Author: Johnson Leung <r58129@freescale.com>
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*/
#include <linux/bitops.h>
#include <linux/phy.h>
#include <linux/module.h>
#define RTL821x_PHYSR 0x11
#define RTL821x_PHYSR_DUPLEX BIT(13)
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
#define RTL821x_INER 0x12
#define RTL8211B_INER_INIT 0x6400
#define RTL8211E_INER_LINK_STATUS BIT(10)
#define RTL8211F_INER_LINK_STATUS BIT(4)
#define RTL821x_INSR 0x13
#define RTL821x_EXT_PAGE_SELECT 0x1e
#define RTL821x_PAGE_SELECT 0x1f
#define RTL8211F_INSR 0x1d
#define RTL8211F_TX_DELAY BIT(8)
#define RTL8211E_TX_DELAY BIT(1)
#define RTL8211E_RX_DELAY BIT(2)
#define RTL8211E_MODE_MII_GMII BIT(3)
#define RTL8201F_ISR 0x1e
#define RTL8201F_IER 0x13
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
#define RTL_SUPPORTS_5000FULL BIT(14)
#define RTL_SUPPORTS_2500FULL BIT(13)
#define RTL_SUPPORTS_10000FULL BIT(0)
#define RTL_ADV_2500FULL BIT(7)
#define RTL_LPADV_10000FULL BIT(11)
#define RTL_LPADV_5000FULL BIT(6)
#define RTL_LPADV_2500FULL BIT(5)
#define RTL_GENERIC_PHYID 0x001cc800
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
static int rtl821x_read_page(struct phy_device *phydev)
{
return __phy_read(phydev, RTL821x_PAGE_SELECT);
}
static int rtl821x_write_page(struct phy_device *phydev, int page)
{
return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
}
static int rtl8201_ack_interrupt(struct phy_device *phydev)
{
int err;
err = phy_read(phydev, RTL8201F_ISR);
return (err < 0) ? err : 0;
}
static int rtl821x_ack_interrupt(struct phy_device *phydev)
{
int err;
err = phy_read(phydev, RTL821x_INSR);
return (err < 0) ? err : 0;
}
static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
int err;
err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
return (err < 0) ? err : 0;
}
static int rtl8201_config_intr(struct phy_device *phydev)
{
u16 val;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
val = BIT(13) | BIT(12) | BIT(11);
else
val = 0;
return phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
}
static int rtl8211b_config_intr(struct phy_device *phydev)
{
int err;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, RTL821x_INER,
RTL8211B_INER_INIT);
else
err = phy_write(phydev, RTL821x_INER, 0);
return err;
}
static int rtl8211e_config_intr(struct phy_device *phydev)
{
int err;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, RTL821x_INER,
RTL8211E_INER_LINK_STATUS);
else
err = phy_write(phydev, RTL821x_INER, 0);
return err;
}
static int rtl8211f_config_intr(struct phy_device *phydev)
{
u16 val;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
val = RTL8211F_INER_LINK_STATUS;
else
val = 0;
return phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
}
static int rtl8211_config_aneg(struct phy_device *phydev)
{
int ret;
ret = genphy_config_aneg(phydev);
if (ret < 0)
return ret;
/* Quirk was copied from vendor driver. Unfortunately it includes no
* description of the magic numbers.
*/
if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
phy_write(phydev, 0x17, 0x2138);
phy_write(phydev, 0x0e, 0x0260);
} else {
phy_write(phydev, 0x17, 0x2108);
phy_write(phydev, 0x0e, 0x0000);
}
return 0;
}
static int rtl8211c_config_init(struct phy_device *phydev)
{
/* RTL8211C has an issue when operating in Gigabit slave mode */
return phy_set_bits(phydev, MII_CTRL1000,
CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
}
static int rtl8211f_config_init(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
u16 val;
int ret;
printk(" RTL8211F Init !!! \n");
/* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
* rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
*/
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_RXID:
val = 0;
break;
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val = RTL8211F_TX_DELAY;
break;
default: /* the rest of the modes imply leaving delay as is. */
return 0;
}
ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
val);
if (ret < 0) {
dev_err(dev, "Failed to update the TX delay register\n");
return ret;
} else if (ret) {
dev_dbg(dev,
"%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
val ? "Enabling" : "Disabling");
} else {
dev_dbg(dev,
"2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
val ? "enabled" : "disabled");
}
return 0;
}
static int rtl8211e_config_init(struct phy_device *phydev)
{
int ret = 0, oldpage;
u16 val;
/* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RGMII:
val = 0;
break;
case PHY_INTERFACE_MODE_RGMII_ID:
val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
break;
case PHY_INTERFACE_MODE_RGMII_RXID:
val = RTL8211E_RX_DELAY;
break;
case PHY_INTERFACE_MODE_RGMII_TXID:
val = RTL8211E_TX_DELAY;
break;
default: /* the rest of the modes imply leaving delays as is. */
return 0;
}
/* According to a sample driver there is a 0x1c config register on the
* 0xa4 extension page (0x7) layout. It can be used to disable/enable
* the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
* also be used to customize the whole configuration register:
* 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
* 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
* for details).
*/
oldpage = phy_select_page(phydev, 0x7);
if (oldpage < 0)
goto err_restore_page;
ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
if (ret)
goto err_restore_page;
ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
val);
err_restore_page:
return phy_restore_page(phydev, oldpage, ret);
}
static int rtl8211b_suspend(struct phy_device *phydev)
{
phy_write(phydev, MII_MMD_DATA, BIT(9));
return genphy_suspend(phydev);
}
static int rtl8211b_resume(struct phy_device *phydev)
{
phy_write(phydev, MII_MMD_DATA, 0);
return genphy_resume(phydev);
}
static int rtl8366rb_config_init(struct phy_device *phydev)
{
int ret;
ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
RTL8366RB_POWER_SAVE_ON);
if (ret) {
dev_err(&phydev->mdio.dev,
"error enabling power management\n");
}
return ret;
}
static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
{
int ret;
if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
rtl821x_write_page(phydev, 0xa5c);
ret = __phy_read(phydev, 0x12);
rtl821x_write_page(phydev, 0);
} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
rtl821x_write_page(phydev, 0xa5d);
ret = __phy_read(phydev, 0x10);
rtl821x_write_page(phydev, 0);
} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
rtl821x_write_page(phydev, 0xa5d);
ret = __phy_read(phydev, 0x11);
rtl821x_write_page(phydev, 0);
} else {
ret = -EOPNOTSUPP;
}
return ret;
}
static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
u16 val)
{
int ret;
if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
rtl821x_write_page(phydev, 0xa5d);
ret = __phy_write(phydev, 0x10, val);
rtl821x_write_page(phydev, 0);
} else {
ret = -EOPNOTSUPP;
}
return ret;
}
static int rtl8125_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
{
int ret = rtlgen_read_mmd(phydev, devnum, regnum);
if (ret != -EOPNOTSUPP)
return ret;
if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
rtl821x_write_page(phydev, 0xa6e);
ret = __phy_read(phydev, 0x16);
rtl821x_write_page(phydev, 0);
} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
rtl821x_write_page(phydev, 0xa6d);
ret = __phy_read(phydev, 0x12);
rtl821x_write_page(phydev, 0);
} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
rtl821x_write_page(phydev, 0xa6d);
ret = __phy_read(phydev, 0x10);
rtl821x_write_page(phydev, 0);
}
return ret;
}
static int rtl8125_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
u16 val)
{
int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
if (ret != -EOPNOTSUPP)
return ret;
if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
rtl821x_write_page(phydev, 0xa6d);
ret = __phy_write(phydev, 0x12, val);
rtl821x_write_page(phydev, 0);
}
return ret;
}
static int rtl8125_get_features(struct phy_device *phydev)
{
int val;
val = phy_read_paged(phydev, 0xa61, 0x13);
if (val < 0)
return val;
linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
phydev->supported, val & RTL_SUPPORTS_2500FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
phydev->supported, val & RTL_SUPPORTS_5000FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
phydev->supported, val & RTL_SUPPORTS_10000FULL);
return genphy_read_abilities(phydev);
}
static int rtl8125_config_aneg(struct phy_device *phydev)
{
int ret = 0;
if (phydev->autoneg == AUTONEG_ENABLE) {
u16 adv2500 = 0;
if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
phydev->advertising))
adv2500 = RTL_ADV_2500FULL;
ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
RTL_ADV_2500FULL, adv2500);
if (ret < 0)
return ret;
}
return __genphy_config_aneg(phydev, ret);
}
static int rtl8125_read_status(struct phy_device *phydev)
{
if (phydev->autoneg == AUTONEG_ENABLE) {
int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
if (lpadv < 0)
return lpadv;
linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
}
return genphy_read_status(phydev);
}
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
{
int val;
phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
val = phy_read(phydev, 0x13);
phy_write(phydev, RTL821x_PAGE_SELECT, 0);
return val >= 0 && val & RTL_SUPPORTS_2500FULL;
}
static int rtlgen_match_phy_device(struct phy_device *phydev)
{
return phydev->phy_id == RTL_GENERIC_PHYID &&
!rtlgen_supports_2_5gbps(phydev);
}
static int rtl8125_match_phy_device(struct phy_device *phydev)
{
return phydev->phy_id == RTL_GENERIC_PHYID &&
rtlgen_supports_2_5gbps(phydev);
}
static struct phy_driver realtek_drvs[] = {
{
PHY_ID_MATCH_EXACT(0x00008201),
.name = "RTL8201CP Ethernet",
}, {
PHY_ID_MATCH_EXACT(0x001cc816),
.name = "RTL8201F Fast Ethernet",
.ack_interrupt = &rtl8201_ack_interrupt,
.config_intr = &rtl8201_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_MODEL(0x001cc880),
.name = "RTL8208 Fast Ethernet",
.read_mmd = genphy_read_mmd_unsupported,
.write_mmd = genphy_write_mmd_unsupported,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc910),
.name = "RTL8211 Gigabit Ethernet",
.config_aneg = rtl8211_config_aneg,
.read_mmd = &genphy_read_mmd_unsupported,
.write_mmd = &genphy_write_mmd_unsupported,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc912),
.name = "RTL8211B Gigabit Ethernet",
.ack_interrupt = &rtl821x_ack_interrupt,
.config_intr = &rtl8211b_config_intr,
.read_mmd = &genphy_read_mmd_unsupported,
.write_mmd = &genphy_write_mmd_unsupported,
.suspend = rtl8211b_suspend,
.resume = rtl8211b_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc913),
.name = "RTL8211C Gigabit Ethernet",
.config_init = rtl8211c_config_init,
.read_mmd = &genphy_read_mmd_unsupported,
.write_mmd = &genphy_write_mmd_unsupported,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc914),
.name = "RTL8211DN Gigabit Ethernet",
.ack_interrupt = rtl821x_ack_interrupt,
.config_intr = rtl8211e_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc915),
.name = "RTL8211E Gigabit Ethernet",
.config_init = &rtl8211e_config_init,
.ack_interrupt = &rtl821x_ack_interrupt,
.config_intr = &rtl8211e_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc916),
.name = "RTL8211F Gigabit Ethernet",
.config_init = &rtl8211f_config_init,
.ack_interrupt = &rtl8211f_ack_interrupt,
.config_intr = &rtl8211f_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
.name = "Generic FE-GE Realtek PHY",
.match_phy_device = rtlgen_match_phy_device,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
.read_mmd = rtlgen_read_mmd,
.write_mmd = rtlgen_write_mmd,
}, {
.name = "RTL8125 2.5Gbps internal",
.match_phy_device = rtl8125_match_phy_device,
.get_features = rtl8125_get_features,
.config_aneg = rtl8125_config_aneg,
.read_status = rtl8125_read_status,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
.read_mmd = rtl8125_read_mmd,
.write_mmd = rtl8125_write_mmd,
}, {
PHY_ID_MATCH_EXACT(0x001cc961),
.name = "RTL8366RB Gigabit Ethernet",
.config_init = &rtl8366rb_config_init,
/* These interrupts are handled by the irq controller
* embedded inside the RTL8366RB, they get unmasked when the
* irq is requested and ACKed by reading the status register,
* which is done by the irqchip code.
*/
.ack_interrupt = genphy_no_ack_interrupt,
.config_intr = genphy_no_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
},
};
module_phy_driver(realtek_drvs);
static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
{ PHY_ID_MATCH_VENDOR(0x001cc800) },
{ }
};
MODULE_DEVICE_TABLE(mdio, realtek_tbl);

View File

@@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
config RTK_MSSDK_PHY
tristate "Realtek MSSDK PHYs"
help
Currently supports the RTL8261N,RTL8264B,RTL8251B PHYs.

View File

@@ -0,0 +1,19 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
ccflags-y := -DRTK_PHYDRV_IN_LINUX
obj-$(CONFIG_RTK_MSSDK_PHY) += rtk-ms-phy.o
rtk-ms-phy-objs := rtk_phy.o
rtk-ms-phy-objs += rtk_osal.o
# files from SDK
rtk-ms-phy-objs += phy_patch.o
rtk-ms-phy-objs += phy_rtl826xb_patch.o
rtk-ms-phy-objs += phy_rtl8251b_patch.o
# rtk phylib
rtk-ms-phy-objs += rtk_phylib.o
rtk-ms-phy-objs += rtk_phylib_rtl826xb.o

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,165 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __COMMON_ERROR_H__
#define __COMMON_ERROR_H__
/*
* Include Files
*/
#if defined(RTK_PHYDRV_IN_LINUX)
#include "type.h"
#else
#include <common/type.h>
#endif
/*
* Data Type Declaration
*/
typedef enum rt_error_common_e
{
RT_ERR_FAILED = -1, /* General Error */
/* 0x0000xxxx for common error code */
RT_ERR_OK = 0, /* 0x00000000, OK */
RT_ERR_INPUT = 0xF001, /* 0x0000F001, invalid input parameter */
RT_ERR_UNIT_ID, /* 0x0000F002, invalid unit id */
RT_ERR_PORT_ID, /* 0x0000F003, invalid port id */
RT_ERR_PORT_MASK, /* 0x0000F004, invalid port mask */
RT_ERR_PORT_LINKDOWN, /* 0x0000F005, link down port status */
RT_ERR_ENTRY_INDEX, /* 0x0000F006, invalid entry index */
RT_ERR_NULL_POINTER, /* 0x0000F007, input parameter is null pointer */
RT_ERR_QUEUE_ID, /* 0x0000F008, invalid queue id */
RT_ERR_QUEUE_NUM, /* 0x0000F009, invalid queue number */
RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000F00a, busy watting time out */
RT_ERR_MAC, /* 0x0000F00b, invalid mac address */
RT_ERR_OUT_OF_RANGE, /* 0x0000F00c, input parameter out of range */
RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000F00d, functions not supported by this chip model */
RT_ERR_SMI, /* 0x0000F00e, SMI error */
RT_ERR_NOT_INIT, /* 0x0000F00f, The module is not initial */
RT_ERR_CHIP_NOT_FOUND, /* 0x0000F010, The chip can not found */
RT_ERR_NOT_ALLOWED, /* 0x0000F011, actions not allowed by the function */
RT_ERR_DRIVER_NOT_FOUND, /* 0x0000F012, The driver can not found */
RT_ERR_SEM_LOCK_FAILED, /* 0x0000F013, Failed to lock semaphore */
RT_ERR_SEM_UNLOCK_FAILED, /* 0x0000F014, Failed to unlock semaphore */
RT_ERR_THREAD_EXIST, /* 0x0000F015, Thread exist */
RT_ERR_THREAD_CREATE_FAILED, /* 0x0000F016, Thread create fail */
RT_ERR_FWD_ACTION, /* 0x0000F017, Invalid forwarding Action */
RT_ERR_IPV4_ADDRESS, /* 0x0000F018, Invalid IPv4 address */
RT_ERR_IPV6_ADDRESS, /* 0x0000F019, Invalid IPv6 address */
RT_ERR_PRIORITY, /* 0x0000F01a, Invalid Priority value */
RT_ERR_FID, /* 0x0000F01b, invalid fid */
RT_ERR_ENTRY_NOTFOUND, /* 0x0000F01c, specified entry not found */
RT_ERR_DROP_PRECEDENCE, /* 0x0000F01d, invalid drop precedence */
RT_ERR_NOT_FINISH, /* 0x0000F01e, Action not finish, still need to wait */
RT_ERR_TIMEOUT, /* 0x0000F01f, Time out */
RT_ERR_REG_ARRAY_INDEX_1, /* 0x0000F020, invalid index 1 of register array */
RT_ERR_REG_ARRAY_INDEX_2, /* 0x0000F021, invalid index 2 of register array */
RT_ERR_ETHER_TYPE, /* 0x0000F022, invalid ether type */
RT_ERR_MBUF_PKT_NOT_AVAILABLE, /* 0x0000F023, mbuf->packet is not available */
RT_ERR_QOS_INVLD_RSN, /* 0x0000F024, invalid pkt to CPU reason */
RT_ERR_CB_FUNCTION_EXIST, /* 0x0000F025, Callback function exist */
RT_ERR_CB_FUNCTION_FULL, /* 0x0000F026, Callback function number is full */
RT_ERR_CB_FUNCTION_NOT_FOUND, /* 0x0000F027, Callback function can not found */
RT_ERR_TBL_FULL, /* 0x0000F028, The table is full */
RT_ERR_TRUNK_ID, /* 0x0000F029, invalid trunk id */
RT_ERR_TYPE, /* 0x0000F02a, invalid type */
RT_ERR_ENTRY_EXIST, /* 0x0000F02b, entry exists */
RT_ERR_CHIP_UNDEFINED_VALUE, /* 0x0000F02c, chip returned an undefined value */
RT_ERR_EXCEEDS_CAPACITY, /* 0x0000F02d, exceeds the capacity of hardware */
RT_ERR_ENTRY_REFERRED, /* 0x0000F02e, entry is still being referred */
RT_ERR_OPER_DENIED, /* 0x0000F02f, operation denied */
RT_ERR_PORT_NOT_SUPPORTED, /* 0x0000F030, functions not supported by this port */
RT_ERR_SOCKET, /* 0x0000F031, socket error */
RT_ERR_MEM_ALLOC, /* 0x0000F032, insufficient memory resource */
RT_ERR_ABORT, /* 0x0000F033, operation aborted */
RT_ERR_DEV_ID, /* 0x0000F034, invalid device id */
RT_ERR_DRIVER_NOT_SUPPORTED, /* 0x0000F035, functions not supported by this driver */
RT_ERR_NOT_SUPPORTED, /* 0x0000F036, functions not supported */
RT_ERR_SER, /* 0x0000F037, ECC or parity error */
RT_ERR_MEM_NOT_ALIGN, /* 0x0000F038, memory address is not aligned */
RT_ERR_SEM_FAKELOCK_OK, /* 0x0000F039, attach thread lock a semaphore which was already locked */
RT_ERR_CHECK_FAILED, /* 0x0000F03a, check result is failed */
RT_ERR_COMMON_END = 0xFFFF /* The symbol is the latest symbol of common error */
} rt_error_common_t;
/*
* Macro Definition
*/
#define RT_PARAM_CHK(expr, errCode)\
do {\
if ((int32)(expr)) {\
return errCode; \
}\
} while (0)
#define RT_PARAM_CHK_EHDL(expr, errCode, err_hdl)\
do {\
if ((int32)(expr)) {\
{err_hdl}\
return errCode; \
}\
} while (0)
#define RT_INIT_CHK(state)\
do {\
if (INIT_COMPLETED != (state)) {\
return RT_ERR_NOT_INIT;\
}\
} while (0)
#define RT_INIT_REENTRY_CHK(state)\
do {\
if (INIT_COMPLETED == (state)) {\
osal_printf(" %s had already been initialized!\n", __FUNCTION__);\
return RT_ERR_OK;\
}\
} while (0)
#define RT_INIT_REENTRY_CHK_NO_WARNING(state)\
do {\
if (INIT_COMPLETED == (state)) {\
return RT_ERR_OK;\
}\
} while (0)
#define RT_ERR_CHK(op, ret)\
do {\
if ((ret = (op)) != RT_ERR_OK)\
return ret;\
} while(0)
#define RT_ERR_HDL(op, errHandle, ret)\
do {\
if ((ret = (op)) != RT_ERR_OK)\
goto errHandle;\
} while(0)
#define RT_ERR_CHK_EHDL(op, ret, err_hdl)\
do {\
if ((ret = (op)) != RT_ERR_OK)\
{\
{err_hdl}\
return ret;\
}\
} while(0)
#define RT_NULL_HDL(pointer, err_label)\
do {\
if (NULL == (pointer)) {\
goto err_label;\
}\
} while (0)
#define RT_ERR_VOID_CHK(op, ret)\
do {\
if ((ret = (op)) != RT_ERR_OK) {\
osal_printf("Fail in %s %d, ret %x!\n", __FUNCTION__, __LINE__, ret);\
return ;}\
} while(0)
#endif /* __COMMON_ERROR_H__ */

View File

@@ -0,0 +1,179 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
/*
* Include Files
*/
#if defined(RTK_PHYDRV_IN_LINUX)
#include "rtk_osal.h"
#else
#include <common/rt_type.h>
#include <common/rt_error.h>
#include <common/debug/rt_log.h>
#include <hal/common/halctrl.h>
#include <hal/phy/phy_patch.h>
#endif
/*
* Function Declaration
*/
uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op)
{
if (patch_mode != PHY_PATCH_MODE_CMP)
{
return patch_op;
}
else
{
switch (compare_op)
{
case RTK_PATCH_CMP_WS:
return RTK_PATCH_OP_SKIP;
case RTK_PATCH_CMP_W:
case RTK_PATCH_CMP_WC:
case RTK_PATCH_CMP_SWC:
default:
return RTK_PATCH_OP_TO_CMP(patch_op, compare_op);
}
}
}
int32 phy_patch_op(rt_phy_patch_db_t *pPhy_patchDb, uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_op, uint16 portmask, uint16 pagemmd, uint16 addr, uint8 msb, uint8 lsb, uint16 data, uint8 patch_mode)
{
rtk_hwpatch_t op;
op.patch_op = patch_op;
op.portmask = portmask;
op.pagemmd = pagemmd;
op.addr = addr;
op.msb = msb;
op.lsb = lsb;
op.data = data;
op.compare_op = RTK_PATCH_CMP_W;
return pPhy_patchDb->fPatch_op(unit, port, portOffset, &op, patch_mode);
}
static int32 _phy_patch_process(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch, int32 size, uint8 patch_mode)
{
int32 i = 0;
int32 ret = 0;
int32 chk_ret = RT_ERR_OK;
int32 n;
rtk_hwpatch_t *patch = pPatch;
rt_phy_patch_db_t *pPatchDb = NULL;
PHYPATCH_DB_GET(unit, port, pPatchDb);
if (size <= 0)
{
return RT_ERR_OK;
}
n = size / sizeof(rtk_hwpatch_t);
for (i = 0; i < n; i++)
{
ret = pPatchDb->fPatch_op(unit, port, portOffset, &patch[i], patch_mode);
if ((ret != RT_ERR_ABORT) && (ret != RT_ERR_OK))
{
if ((ret == RT_ERR_CHECK_FAILED) && (patch_mode == PHY_PATCH_MODE_CMP))
{
osal_printf("PATCH CHECK: Failed entry:%u|%u|0x%X|0x%X|%u|%u|0x%X\n",
i + 1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].msb, patch[i].lsb, patch[i].data);
chk_ret = RT_ERR_CHECK_FAILED;
continue;
}
else
{
RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u %s failed! %u[%u][0x%X][0x%X][0x%X] ret=0x%X\n", unit, port, __FUNCTION__,
i+1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].data, ret);
return ret;
}
}
}
return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK;
}
/* Function Name:
* phy_patch
* Description:
* apply initial patch data to PHY
* Input:
* unit - unit id
* port - port id
* portOffset - the index offset of port based the base port in the PHY chip
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_CHECK_FAILED
* RT_ERR_NOT_SUPPORTED
* Note:
* None
*/
int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode)
{
int32 ret = RT_ERR_OK;
int32 chk_ret = RT_ERR_OK;
uint32 i = 0;
uint8 patch_type = 0;
rt_phy_patch_db_t *pPatchDb = NULL;
rtk_hwpatch_seq_t *table = NULL;
PHYPATCH_DB_GET(unit, port, pPatchDb);
if ((pPatchDb == NULL) || (pPatchDb->fPatch_op == NULL) || (pPatchDb->fPatch_flow == NULL))
{
RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u phy_patch, db is NULL\n", unit, port);
return RT_ERR_DRIVER_NOT_SUPPORTED;
}
if (patch_mode == PHY_PATCH_MODE_CMP)
{
table = pPatchDb->cmp_table;
}
else
{
table = pPatchDb->seq_table;
}
RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: U%u P%u portOffset:%u patch_mode:%u\n", unit, port, portOffset, patch_mode);
for (i = 0; i < RTK_PATCH_SEQ_MAX; i++)
{
patch_type = table[i].patch_type;
RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: table[%u] patch_type:%u\n", i, patch_type);
if (RTK_PATCH_TYPE_IS_DATA(patch_type))
{
ret = _phy_patch_process(unit, port, portOffset, table[i].patch.data.conf, table[i].patch.data.size, patch_mode);
if (ret == RT_ERR_CHECK_FAILED)
chk_ret = ret;
else if (ret != RT_ERR_OK)
{
RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret);
return ret;
}
}
else if (RTK_PATCH_TYPE_IS_FLOW(patch_type))
{
RT_ERR_CHK_EHDL(pPatchDb->fPatch_flow(unit, port, portOffset, table[i].patch.flow_id, patch_mode),
ret, RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret););
}
else
{
break;
}
}
return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK;
}

View File

@@ -0,0 +1,174 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __HAL_PHY_PATCH_H__
#define __HAL_PHY_PATCH_H__
/*
* Include Files
*/
#if defined(RTK_PHYDRV_IN_LINUX)
#include "rtk_phylib_def.h"
#else
#include <common/rt_type.h>
#include <common/rt_autoconf.h>
#endif
/*
* Symbol Definition
*/
#define PHYPATCH_PHYCTRL_IN_HALCTRL 0 /* 3.6.x: 1 ,4.0.x: 1, 4.1.x+: 0 */
#define PHYPATCH_FMAILY_IN_HWP 0 /* 3.6.x: 1 ,4.0.x: 0, 4.1.x+: 0 */
#define PHY_PATCH_MODE_BCAST_DEFAULT PHY_PATCH_MODE_BCAST /* 3.6.x: PHY_PATCH_MODE_BCAST_BUS ,4.0.x+: PHY_PATCH_MODE_BCAST */
#define PHY_PATCH_MODE_NORMAL 0
#define PHY_PATCH_MODE_CMP 1
#define PHY_PATCH_MODE_BCAST 2
#define PHY_PATCH_MODE_BCAST_BUS 3
#define RTK_PATCH_CMP_W 0 /* write */
#define RTK_PATCH_CMP_WC 1 /* compare */
#define RTK_PATCH_CMP_SWC 2 /* sram compare */
#define RTK_PATCH_CMP_WS 3 /* skip */
#define RTK_PATCH_OP_SECTION_SIZE 50
#define RTK_PATCH_OP_TO_CMP(_op, _cmp) (_op + (RTK_PATCH_OP_SECTION_SIZE * _cmp))
/* 0~49 normal op */
#define RTK_PATCH_OP_PHY 0
#define RTK_PATCH_OP_PHYOCP 1
#define RTK_PATCH_OP_TOP 2
#define RTK_PATCH_OP_TOPOCP 3
#define RTK_PATCH_OP_PSDS0 4
#define RTK_PATCH_OP_PSDS1 5
#define RTK_PATCH_OP_MSDS 6
#define RTK_PATCH_OP_MAC 7
/* 50~99 normal op for compare */
#define RTK_PATCH_OP_CMP_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_WC)
#define RTK_PATCH_OP_CMP_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_WC)
#define RTK_PATCH_OP_CMP_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_WC)
#define RTK_PATCH_OP_CMP_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_WC)
#define RTK_PATCH_OP_CMP_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_WC)
#define RTK_PATCH_OP_CMP_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_WC)
#define RTK_PATCH_OP_CMP_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_WC)
#define RTK_PATCH_OP_CMP_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_WC)
/* 100~149 normal op for sram compare */
#define RTK_PATCH_OP_CMP_SRAM_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_SWC)
#define RTK_PATCH_OP_CMP_SRAM_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_SWC)
#define RTK_PATCH_OP_CMP_SRAM_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_SWC)
#define RTK_PATCH_OP_CMP_SRAM_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_SWC)
#define RTK_PATCH_OP_CMP_SRAM_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_SWC)
#define RTK_PATCH_OP_CMP_SRAM_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_SWC)
#define RTK_PATCH_OP_CMP_SRAM_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_SWC)
#define RTK_PATCH_OP_CMP_SRAM_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_SWC)
/* 200~255 control op */
#define RTK_PATCH_OP_DELAY_MS 200
#define RTK_PATCH_OP_SKIP 255
/*
patch type PHY_PATCH_TYPE_NONE => empty
patch type: PHY_PATCH_TYPE_TOP ~ (PHY_PATCH_TYPE_END-1) => data array
patch type: PHY_PATCH_TYPE_END ~ (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOW_MAX) => flow
*/
#define RTK_PATCH_TYPE_IS_DATA(_patch_type) (_patch_type > PHY_PATCH_TYPE_NONE && _patch_type < PHY_PATCH_TYPE_END)
#define RTK_PATCH_TYPE_IS_FLOW(_patch_type) (_patch_type >= PHY_PATCH_TYPE_END && _patch_type <= (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX))
/*
* Macro Definition
*/
#if PHYPATCH_PHYCTRL_IN_HALCTRL
#define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \
do {\
hal_control_t *pHalCtrl = NULL;\
if ((pHalCtrl = hal_ctrlInfo_get(_unit)) == NULL)\
return RT_ERR_FAILED;\
_pPatchDb = (pHalCtrl->pPhy_ctrl[_port]->pPhy_patchDb);\
} while(0)
#else
#if defined(RTK_PHYDRV_IN_LINUX)
#else
#include <hal/phy/phydef.h>
#include <hal/phy/phy_probe.h>
#endif
#define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \
do {\
rt_phyctrl_t *pPhyCtrl = NULL;\
if ((pPhyCtrl = phy_phyctrl_get(_unit, _port)) == NULL)\
return RT_ERR_FAILED;\
_pPatchDb = (pPhyCtrl->pPhy_patchDb);\
} while(0)
#endif
#if PHYPATCH_FMAILY_IN_HWP
#define PHYPATCH_IS_RTKSDS(_unit) (HWP_9300_FAMILY_ID(_unit) || HWP_9310_FAMILY_ID(_unit))
#else
#define PHYPATCH_IS_RTKSDS(_unit) (RTK_9300_FAMILY_ID(_unit) || RTK_9310_FAMILY_ID(_unit) || RTK_9311B_FAMILY_ID(_unit) || RTK_9330_FAMILY_ID(_unit))
#endif
#define PHYPATCH_TABLE_ASSIGN(_pPatchDb, _table, _idx, _patch_type, _para) \
do {\
if (RTK_PATCH_TYPE_IS_DATA(_patch_type)) {\
_pPatchDb->_table[_idx].patch_type = _patch_type;\
_pPatchDb->_table[_idx].patch.data.conf = _para;\
_pPatchDb->_table[_idx].patch.data.size = sizeof(_para);\
}\
else if (RTK_PATCH_TYPE_IS_FLOW(_patch_type)) {\
_pPatchDb->_table[_idx].patch_type = _patch_type;\
_pPatchDb->_table[_idx].patch.flow_id = _patch_type;\
}\
else {\
_pPatchDb->_table[_idx].patch_type = PHY_PATCH_TYPE_NONE;\
}\
} while(0)
#define PHYPATCH_SEQ_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, seq_table, _idx, _patch_type, _para)
#define PHYPATCH_CMP_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, cmp_table, _idx, _patch_type, _para)
#define PHYPATCH_COMPARE(_mmdpage, _reg, _msb, _lsb, _exp, _real, _mask) \
do {\
uint32 _rData = REG32_FIELD_GET(_real, _lsb, _mask);\
if (_exp != _rData) {\
osal_printf("PATCH CHECK: %u(0x%X).%u(0x%X)[%u:%u] = 0x%X (!= 0x%X)\n", _mmdpage, _mmdpage, _reg, _reg, _msb, _lsb, _rData, _exp);\
return RT_ERR_CHECK_FAILED;\
}\
} while (0)
/*
* Function Declaration
*/
extern uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op);
extern int32 phy_patch_op(rt_phy_patch_db_t *pPhy_patchDb, uint32 unit, rtk_port_t port, uint8 portOffset,
uint8 patch_op, uint16 portmask, uint16 pagemmd, uint16 addr, uint8 msb, uint8 lsb, uint16 data,
uint8 patch_mode);
/* Function Name:
* phy_patch
* Description:
* apply initial patch data to PHY
* Input:
* unit - unit id
* port - port id
* portOffset - the index offset of port based the base port in the PHY chip
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_CHECK_FAILED
* RT_ERR_NOT_SUPPORTED
* Note:
* None
*/
extern int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode);
#endif /* __HAL_PHY_PATCH_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#include <linux/module.h>
#include <linux/phy.h>
#include "type.h"
#ifndef __PHY_RTL8251B_PATCH_H__
#define __PHY_RTL8251B_PATCH_H__
#ifndef SUCCESS
#define SUCCESS 1
#endif
#ifndef FAILURE
#define FAILURE 0
#endif
#ifndef BOOL
#define BOOL uint32
#endif
#ifndef UINT32
#define UINT32 uint32
#endif
#ifndef UINT16
#define UINT16 uint16
#endif
#ifndef UINT8
#define UINT8 uint8
#endif
#define MMD_PMAPMD 1
#define MMD_PCS 3
#define MMD_AN 7
#define MMD_VEND1 30 /* Vendor specific 2 */
#define MMD_VEND2 31 /* Vendor specific 2 */
typedef struct
{
UINT16 dev;
UINT16 addr;
UINT16 value;
} MMD_REG;
int32 MmdPhyRead(struct phy_device *phydev,UINT16 dev,UINT16 addr,UINT16 *data);
int32 MmdPhyWrite(struct phy_device *phydev,UINT16 dev,UINT16 addr,UINT16 data);
extern int32 rtl8251b_phy_init(struct phy_device *phydev);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __HAL_PHY_PHY_RTL826XB_PATCH_H__
#define __HAL_PHY_PHY_RTL826XB_PATCH_H__
/*
* Include Files
*/
#if defined(RTK_PHYDRV_IN_LINUX)
#include "rtk_osal.h"
#include "rtk_phylib_def.h"
#else
#include <common/rt_type.h>
#include <rtk/port.h>
#endif
/* Function Name:
* phy_rtl826xb_patch
* Description:
* apply patch data to PHY
* Input:
* unit - unit id
* baseport - base port id on the PHY chip
* portOffset - the index offset base on baseport for the port to patch
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_NOT_SUPPORTED
* RT_ERR_ABORT
* Note:
* None
*/
extern int32 phy_rtl826xb_patch(uint32 unit, rtk_port_t baseport, uint8 portOffset);
/* Function Name:
* phy_rtl826xb_broadcast_patch
* Description:
* apply patch data to PHY
* Input:
* unit - unit id
* baseport - base port id on the PHY chip
* portOffset - the index offset base on baseport for the port to patch
* perChip - 1 for per-chip mode, 0 for per-bus mode
* Output:
* None
* Return:
* RT_ERR_OK
* RT_ERR_FAILED
* RT_ERR_NOT_SUPPORTED
* RT_ERR_ABORT
* Note:
* None
*/
extern int32 phy_rtl826xb_broadcast_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 perChip);
extern int32 phy_rtl826xb_patch_db_init(uint32 unit, rtk_port_t port, rt_phy_patch_db_t **pPhy_patchDb);
#endif /* __HAL_PHY_PHY_RTL826XB_PATCH_H__ */

View File

@@ -0,0 +1,56 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#include "type.h"
#include "error.h"
#include "rtk_phylib_def.h"
#include <linux/version.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
#include <linux/phy.h>
int32
osal_time_usecs_get(osal_usecs_t *pUsec)
{
struct timespec64 ts;
RT_PARAM_CHK((NULL == pUsec), RT_ERR_NULL_POINTER);
ktime_get_ts64(&ts);
*pUsec = (osal_usecs_t)((ts.tv_sec * USEC_PER_SEC) + (ts.tv_nsec / NSEC_PER_USEC));
return RT_ERR_OK;
}
void *
osal_alloc(uint32 size)
{
void *p;
p = kmalloc((size_t)size, GFP_ATOMIC);
return p;
}
int32
phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData)
{
int32 rData = 0;
rData = phy_read_mmd(port, mmdAddr, mmdReg);
if (rData < 0)
return RT_ERR_FAILED;
*pData = (uint32)rData;
return RT_ERR_OK;
}
int32
phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data)
{
int ret = phy_write_mmd(port, mmdAddr, mmdReg, data);
return (ret < 0) ? RT_ERR_FAILED : RT_ERR_OK;
}

View File

@@ -0,0 +1,100 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __RTK_PHY_OSAL_H
#define __RTK_PHY_OSAL_H
#include <linux/kernel.h>
#include <linux/phy.h>
#include <linux/delay.h>
#include "type.h"
#include "error.h"
#include "phy_patch.h"
#include "rtk_phylib.h"
#ifdef PHYPATCH_DB_GET
#undef PHYPATCH_DB_GET
#endif
#define PHYPATCH_DB_GET(_unit, _pPhy_device, _pPatchDb) \
do { \
struct rtk_phy_priv *_pPriv = (_pPhy_device)->priv; \
rt_phy_patch_db_t *_pDb = _pPriv->patch; _pPatchDb = _pDb; \
/*printk("[PHYPATCH_DB_GET] ? [%s]\n", (_pDb != NULL) ? "E":"N");*/ \
} while(0)
#define HWP_9300_FAMILY_ID(_unit) 0
#define HWP_9310_FAMILY_ID(_unit) 0
#define RTK_9300_FAMILY_ID(_unit) 0
#define RTK_9310_FAMILY_ID(_unit) 0
#define RTK_9311B_FAMILY_ID(_unit) 0
#define RTK_9330_FAMILY_ID(_unit) 0
#ifndef WAIT_COMPLETE_VAR
#define WAIT_COMPLETE_VAR() \
osal_usecs_t _t, _now, _t_wait=0, _timeout; \
int32 _chkCnt=0;
#define WAIT_COMPLETE(_timeout_us) \
_timeout = _timeout_us; \
for(osal_time_usecs_get(&_t),osal_time_usecs_get(&_now),_t_wait=0,_chkCnt=0 ; \
(_t_wait <= _timeout); \
osal_time_usecs_get(&_now), _chkCnt++, _t_wait += ((_now >= _t) ? (_now - _t) : (0xFFFFFFFF - _t + _now)),_t = _now \
)
#define WAIT_COMPLETE_IS_TIMEOUT() (_t_wait > _timeout)
#endif
/* OSAL */
#include <linux/slab.h>
int32 osal_time_usecs_get(osal_usecs_t *pUsec);
void *osal_alloc(uint32 size);
#define osal_time_mdelay mdelay
#include <linux/ctype.h> /* for Kernel Space */
#include <linux/kernel.h>
#include <linux/string.h>
#define osal_strlen strlen
#define osal_strcmp strcmp
#define osal_strcpy strcpy
#define osal_strncpy strncpy
#define osal_strcat strcat
#define osal_strchr strchr
#define osal_memset memset
#define osal_memcpy memcpy
#define osal_memcmp memcmp
#define osal_strdup strdup
#define osal_strncmp strncmp
#define osal_strstr strstr
#define osal_strtok strtok
#define osal_strtok_r strtok_r
#define osal_toupper toupper
#define osal_printf printk
/* HWP */
#define HWP_PORT_SMI(unit, port) 0
#define HWP_PHY_MODEL_BY_PORT(unit, port) 0
#define HWP_PHY_ADDR(unit, port) 0
#define HWP_PHY_BASE_MACID(unit, p) 0
#define HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) if (bcast_phyad < 0x1F && p != NULL)
/* RT_LOG */
//#define RT_LOG(level, module, fmt, args...) do { printk("RT_LOG:"fmt, ## args); } while(0)
#define RT_LOG(level, module, fmt, args...) do {} while(0)
#define RT_ERR(error_code, module, fmt, args...) do {} while(0)
#define RT_INIT_ERR(error_code, module, fmt, args...) do {} while(0)
#define RT_INIT_MSG(fmt, args...) do {} while(0)
#define phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, bcast_phyad) 0
/* reg access */
int32 phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData);
int32 phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data);
#endif /* __RTK_PHY_OSAL_H */

View File

@@ -0,0 +1,352 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/delay.h>
#include "phy_rtl826xb_patch.h"
#include "phy_rtl8251b_patch.h"
#include "rtk_phylib_rtl826xb.h"
#include "rtk_phylib.h"
#define REALTEK_PHY_ID_RTL8261N 0x001CCAF3
#define REALTEK_PHY_ID_RTL8264B 0x001CC813
#define REALTEK_PHY_ID_RTL8251B 0x001CC86A
#define REALTEK_PHY_ID_RTL8251B_VB 0x001CC868
#define REALTEK_PHY_ID_RTL8251BE 0x001CC862 //Engineer sample
static int rtl8251_match_phy_device(struct phy_device *phydev)
{
return (phydev->phy_id == REALTEK_PHY_ID_RTL8251B) ||
(phydev->phy_id == REALTEK_PHY_ID_RTL8251B_VB) ||
(phydev->phy_id == REALTEK_PHY_ID_RTL8251BE);
}
static int rtl826xb_get_features(struct phy_device *phydev)
{
int ret;
ret = genphy_c45_pma_read_abilities(phydev);
if (ret)
return ret;
linkmode_or(phydev->supported, phydev->supported, PHY_BASIC_FEATURES);
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
phydev->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
phydev->supported);
/* not support 10M modes */
linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
phydev->supported);
linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
phydev->supported);
return 0;
}
static int rtl826xb_probe(struct phy_device *phydev)
{
struct rtk_phy_priv *priv = NULL;
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct rtk_phy_priv), GFP_KERNEL);
if (!priv)
{
return -ENOMEM;
}
memset(priv, 0, sizeof(struct rtk_phy_priv));
if (phy_rtl826xb_patch_db_init(0, phydev, &(priv->patch)) != RT_ERR_OK)
return -ENOMEM;
priv->phytype = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (RTK_PHYLIB_RTL8261N) : (RTK_PHYLIB_RTL8264B);
priv->isBasePort = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (1) : (((phydev->mdio.addr % 4) == 0) ? (1) : (0));
phydev->priv = priv;
return 0;
}
static int rtkphy_config_init(struct phy_device *phydev)
{
int ret = 0;
switch (phydev->drv->phy_id)
{
case REALTEK_PHY_ID_RTL8261N:
case REALTEK_PHY_ID_RTL8264B:
phydev_info(phydev, "%s:%u [RTL8261N/RTL826XB] phy_id: 0x%X PHYAD:%d\n", __FUNCTION__, __LINE__, phydev->drv->phy_id, phydev->mdio.addr);
#if 1 /* toggle reset */
phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 1);
phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 0);
mdelay(30);
#endif
ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_NORMAL);
if (ret)
{
phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret);
return ret;
}
#if 0 /* Debug: patch check */
ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_CMP);
if (ret)
{
phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] phy_patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret);
return ret;
}
printk("[%s,%u] patch chk %s\n", __FUNCTION__, __LINE__, (ret == 0) ? "PASS" : "FAIL");
#endif
#if 0 /* Debug: USXGMII*/
{
uint32 data = 0;
rtk_phylib_826xb_sds_read(phydev, 0x07, 0x10, 15, 0, &data);
printk("[%s,%u] SDS 0x07, 0x10 : 0x%X\n", __FUNCTION__, __LINE__, data);
rtk_phylib_826xb_sds_read(phydev, 0x06, 0x12, 15, 0, &data);
printk("[%s,%u] SDS 0x06, 0x12 : 0x%X\n", __FUNCTION__, __LINE__, data);
}
{
u16 sdspage = 0x5, sdsreg = 0x0;
u16 regData = (sdspage & 0x3f) | ((sdsreg & 0x1f) << 6) | BIT(15);
u16 readData = 0;
phy_write_mmd(phydev, 30, 323, regData);
do
{
udelay(10);
readData = phy_read_mmd(phydev, 30, 323);
} while ((readData & BIT(15)) != 0);
readData = phy_read_mmd(phydev, 30, 322);
printk("[%s,%d] sds link [%s] (0x%X)\n", __FUNCTION__, __LINE__, (readData & BIT(12)) ? "UP" : "DOWN", readData);
}
#endif
break;
case REALTEK_PHY_ID_RTL8251B:
case REALTEK_PHY_ID_RTL8251B_VB:
case REALTEK_PHY_ID_RTL8251BE:
printk(" RTL8251BE Init !!! \n");
ret = rtl8251b_phy_init(phydev);
if (ret != SUCCESS)
{
phydev_err(phydev, "%s:%u [RTL8251B] patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret);
return ret;
}
else
{
ret = 0;
}
break;
default:
phydev_err(phydev, "%s:%u Unknow phy_id: 0x%X\n", __FUNCTION__, __LINE__, phydev->drv->phy_id);
return -EPERM;
}
return ret;
}
static int rtkphy_c45_suspend(struct phy_device *phydev)
{
int ret = 0;
ret = rtk_phylib_c45_power_low(phydev);
phydev->speed = SPEED_UNKNOWN;
phydev->duplex = DUPLEX_UNKNOWN;
phydev->pause = 0;
phydev->asym_pause = 0;
return ret;
}
static int rtkphy_c45_resume(struct phy_device *phydev)
{
return rtk_phylib_c45_power_normal(phydev);
}
static int rtkphy_c45_config_aneg(struct phy_device *phydev)
{
bool changed = false;
u16 reg = 0;
int ret = 0;
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
if (phydev->autoneg == AUTONEG_DISABLE)
return genphy_c45_pma_setup_forced(phydev);
ret = genphy_c45_an_config_aneg(phydev);
if (ret < 0)
return ret;
if (ret > 0)
changed = true;
reg = 0;
if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
phydev->advertising))
reg |= BIT(9);
if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
phydev->advertising))
reg |= BIT(8);
ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xA412,
BIT(9) | BIT(8) , reg);
if (ret < 0)
return ret;
if (ret > 0)
changed = true;
return genphy_c45_check_and_restart_aneg(phydev, changed);
}
static int rtkphy_c45_aneg_done(struct phy_device *phydev)
{
return genphy_c45_aneg_done(phydev);
}
static int rtkphy_c45_read_status(struct phy_device *phydev)
{
int ret = 0, status = 0;
phydev->speed = SPEED_UNKNOWN;
phydev->duplex = DUPLEX_UNKNOWN;
phydev->pause = 0;
phydev->asym_pause = 0;
ret = genphy_c45_read_link(phydev);
if (ret)
return ret;
if (phydev->autoneg == AUTONEG_ENABLE)
{
linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
phydev->lp_advertising);
ret = genphy_c45_read_lpa(phydev);
if (ret)
return ret;
status = phy_read_mmd(phydev, 31, 0xA414);
if (status < 0)
return status;
linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
phydev->lp_advertising, status & BIT(11));
phy_resolve_aneg_linkmode(phydev);
}
else
{
ret = genphy_c45_read_pma(phydev);
}
/* mdix*/
status = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_SWAPPOL);
if (status < 0)
return status;
switch (status & 0x3)
{
case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
phydev->mdix = ETH_TP_MDI;
break;
case 0:
phydev->mdix = ETH_TP_MDI_X;
break;
default:
phydev->mdix = ETH_TP_MDI_INVALID;
break;
}
phydev->interface=0x17; // USXGMII Mode
return ret;
}
static struct phy_driver rtk_phy_drivers[] = {
{
PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N),
.name = "Realtek RTL8261N",
.get_features = rtl826xb_get_features,
.config_init = rtkphy_config_init,
.probe = rtl826xb_probe,
.suspend = rtkphy_c45_suspend,
.resume = rtkphy_c45_resume,
.config_aneg = rtkphy_c45_config_aneg,
.aneg_done = rtkphy_c45_aneg_done,
.read_status = rtkphy_c45_read_status,
},
{
PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B),
.name = "Realtek RTL8264B",
.get_features = rtl826xb_get_features,
.config_init = rtkphy_config_init,
.probe = rtl826xb_probe,
.suspend = rtkphy_c45_suspend,
.resume = rtkphy_c45_resume,
.config_aneg = rtkphy_c45_config_aneg,
.aneg_done = rtkphy_c45_aneg_done,
.read_status = rtkphy_c45_read_status,
},
{
PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8251B),
.name = "Realtek RTL8251B",
.match_phy_device = rtl8251_match_phy_device,
.get_features = rtl826xb_get_features,
.config_init = rtkphy_config_init,
.suspend = rtkphy_c45_suspend,
.resume = rtkphy_c45_resume,
.config_aneg = rtkphy_c45_config_aneg,
.aneg_done = rtkphy_c45_aneg_done,
.read_status = rtkphy_c45_read_status,
},
{
PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8251B_VB),
.name = "Realtek RTL8251B-VB",
.match_phy_device = rtl8251_match_phy_device,
.get_features = rtl826xb_get_features,
.config_init = rtkphy_config_init,
.suspend = rtkphy_c45_suspend,
.resume = rtkphy_c45_resume,
.config_aneg = rtkphy_c45_config_aneg,
.aneg_done = rtkphy_c45_aneg_done,
.read_status = rtkphy_c45_read_status,
},
{
PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8251BE),
.name = "Realtek RTL8251BE",
.match_phy_device = rtl8251_match_phy_device,
.get_features = rtl826xb_get_features,
.config_init = rtkphy_config_init,
.suspend = rtkphy_c45_suspend,
.resume = rtkphy_c45_resume,
.config_aneg = rtkphy_c45_config_aneg,
.aneg_done = rtkphy_c45_aneg_done,
.read_status = rtkphy_c45_read_status,
},
};
module_phy_driver(rtk_phy_drivers);
static struct mdio_device_id __maybe_unused rtk_phy_tbl[] = {
{ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N) },
{ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B) },
{ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8251B) },
{ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8251B_VB) },
{ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8251BE) },
{ },
};
MODULE_DEVICE_TABLE(mdio, rtk_phy_tbl);
MODULE_AUTHOR("Realtek");
MODULE_DESCRIPTION("Realtek PHY drivers");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,109 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#include "rtk_phylib.h"
#include <linux/phy.h>
#include <linux/delay.h>
/* OSAL */
void rtk_phylib_mdelay(uint32 msec)
{
#if defined(RTK_PHYDRV_IN_LINUX)
mdelay(msec);
#else
osal_time_mdelay(msec);
#endif
}
void rtk_phylib_udelay(uint32 usec)
{
#if defined(RTK_PHYDRV_IN_LINUX)
if (1000 <= usec)
{
mdelay(usec/1000);
usec = usec % 1000;
}
udelay(usec);
#else
osal_time_udelay(usec);
#endif
}
/* Register Access APIs */
int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data)
{
int32 ret = 0;
uint32 mask = 0;
mask = UINT32_BITS_MASK(msb,lsb);
#if defined(RTK_PHYDRV_IN_LINUX)
ret = phy_modify_mmd(phydev, mmd, reg, mask, data);
#else
{
uint32 rData = 0, wData = 0;
if ((msb != 15) || (lsb != 0))
{
if ((ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData)) != RT_ERR_OK)
return ret;
}
wData = REG32_FIELD_SET(rData, data, lsb, mask);
ret = phy_common_general_reg_mmd_set(phydev->unit, phydev->port, page, reg, wData);
}
#endif
return ret;
}
int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData)
{
int32 ret = 0;
uint32 rData = 0;
uint32 mask = 0;
mask = UINT32_BITS_MASK(msb,lsb);
#if defined(RTK_PHYDRV_IN_LINUX)
rData = phy_read_mmd(phydev, mmd, reg);
#else
{
ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData);
}
#endif
*pData = REG32_FIELD_GET(rData, lsb, mask);
return ret;
}
/* Function Driver */
int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev)
{
int32 ret = 0;
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 0));
return 0;
}
int32 rtk_phylib_c45_power_low(rtk_phydev *phydev)
{
int32 ret = 0;
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 1));
return 0;
}
int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable)
{
int32 ret = 0;
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 3, 0, 14, 14, (enable == 0) ? 0 : 1));
return 0;
}

View File

@@ -0,0 +1,101 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __RTK_PHYLIB_H
#define __RTK_PHYLIB_H
#if defined(RTK_PHYDRV_IN_LINUX)
#include "type.h"
#include "rtk_phylib_def.h"
#else
//#include SDK headers
#endif
#if defined(RTK_PHYDRV_IN_LINUX)
#define PR_INFO(_fmt, _args...) pr_info(_fmt, ##_args)
#define PR_DBG(_fmt, _args...) pr_debug(_fmt, ##_args)
#define PR_ERR(_fmt, _args...) pr_err("ERROR: "_fmt, ##_args)
#define RTK_PHYLIB_ERR_FAILED (-EPERM)
#define RTK_PHYLIB_ERR_INPUT (-EINVAL)
#define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (-ENOSPC)
#define RTK_PHYLIB_ERR_TIMEOUT (-ETIME)
#define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (-ENODATA)
#else
#define PR_INFO(_fmt, _args...) RT_LOG(LOG_INFO, (MOD_HAL|MOD_PHY), _fmt, ##_args)
#define PR_DBG(_fmt, _args...) RT_LOG(LOG_DEBUG, (MOD_HAL|MOD_PHY), _fmt, ##_args)
#define PR_ERR(_fmt, _args...) RT_LOG(LOG_MAJOR_ERR, (MOD_HAL|MOD_PHY), _fmt, ##_args)
#define RTK_PHYLIB_ERR_FAILED (RT_ERR_FAILED)
#define RTK_PHYLIB_ERR_INPUT (RT_ERR_INPUT)
#define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (RT_ERR_EXCEEDS_CAPACITY)
#define RTK_PHYLIB_ERR_TIMEOUT (RT_ERR_BUSYWAIT_TIMEOUT)
#define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (RT_ERR_ENTRY_NOTFOUND)
#endif
typedef enum rtk_phylib_phy_e
{
RTK_PHYLIB_NONE,
RTK_PHYLIB_RTL8261N,
RTK_PHYLIB_RTL8264B,
RTK_PHYLIB_END
} rtk_phylib_phy_t;
struct rtk_phy_priv {
rtk_phylib_phy_t phytype;
uint8 isBasePort;
rt_phy_patch_db_t *patch;
};
#if defined(RTK_PHYDRV_IN_LINUX)
typedef struct phy_device rtk_phydev;
#else
struct rtk_phy_dev_s
{
uint32 unit;
rtk_port_t port;
struct rtk_phy_priv *priv;
};
typedef struct rtk_phy_dev_s rtk_phydev;
#endif
#define RTK_PHYLIB_ERR_CHK(op)\
do {\
if ((ret = (op)) != 0)\
return ret;\
} while(0)
#define RTK_PHYLIB_VAL_TO_BYTE_ARRAY(_val, _valbytes, _array, _start, _bytes)\
do{\
uint32 _i = 0;\
for (_i = 0; _i < _bytes; _i++)\
_array[_start+_i] = (_val >> (8* (_valbytes - _i - 1)));\
}while(0)
#define RTK_PHYLIB_BYTE_ARRAY_TO_VAL(_val, _array, _start, _bytes)\
do{\
uint32 _i = 0;\
for (_i = 0; _i < _bytes; _i++)\
_val = (_val << 8) | _array[_start + _i];\
}while(0)
/* OSAL */
void rtk_phylib_mdelay(uint32 msec);
void rtk_phylib_udelay(uint32 usec);
/* Register Access APIs */
int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data);
int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData);
/* Function Driver */
int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev);
int32 rtk_phylib_c45_power_low(rtk_phydev *phydev);
int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable);
#endif /* __RTK_PHYLIB_H */

View File

@@ -0,0 +1,166 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __RTK_PHYLIB_DEF_H
#define __RTK_PHYLIB_DEF_H
#include "type.h"
//#define PHY_C22_MMD_PAGE 0
#define PHY_C22_MMD_PAGE 0x0A41
#define PHY_C22_MMD_DEV_REG 13
#define PHY_C22_MMD_ADD_REG 14
/* MDIO Manageable Device(MDD) address*/
#define PHY_MMD_PMAPMD 1
#define PHY_MMD_PCS 3
#define PHY_MMD_AN 7
#define PHY_MMD_VEND1 30 /* Vendor specific 1 */
#define PHY_MMD_VEND2 31 /* Vendor specific 2 */
#define BIT_0 0x00000001U
#define BIT_1 0x00000002U
#define BIT_2 0x00000004U
#define BIT_3 0x00000008U
#define BIT_4 0x00000010U
#define BIT_5 0x00000020U
#define BIT_6 0x00000040U
#define BIT_7 0x00000080U
#define BIT_8 0x00000100U
#define BIT_9 0x00000200U
#define BIT_10 0x00000400U
#define BIT_11 0x00000800U
#define BIT_12 0x00001000U
#define BIT_13 0x00002000U
#define BIT_14 0x00004000U
#define BIT_15 0x00008000U
#define BIT_16 0x00010000U
#define BIT_17 0x00020000U
#define BIT_18 0x00040000U
#define BIT_19 0x00080000U
#define BIT_20 0x00100000U
#define BIT_21 0x00200000U
#define BIT_22 0x00400000U
#define BIT_23 0x00800000U
#define BIT_24 0x01000000U
#define BIT_25 0x02000000U
#define BIT_26 0x04000000U
#define BIT_27 0x08000000U
#define BIT_28 0x10000000U
#define BIT_29 0x20000000U
#define BIT_30 0x40000000U
#define BIT_31 0x80000000U
#define MASK_1_BITS (BIT_1 - 1)
#define MASK_2_BITS (BIT_2 - 1)
#define MASK_3_BITS (BIT_3 - 1)
#define MASK_4_BITS (BIT_4 - 1)
#define MASK_5_BITS (BIT_5 - 1)
#define MASK_6_BITS (BIT_6 - 1)
#define MASK_7_BITS (BIT_7 - 1)
#define MASK_8_BITS (BIT_8 - 1)
#define MASK_9_BITS (BIT_9 - 1)
#define MASK_10_BITS (BIT_10 - 1)
#define MASK_11_BITS (BIT_11 - 1)
#define MASK_12_BITS (BIT_12 - 1)
#define MASK_13_BITS (BIT_13 - 1)
#define MASK_14_BITS (BIT_14 - 1)
#define MASK_15_BITS (BIT_15 - 1)
#define MASK_16_BITS (BIT_16 - 1)
#define MASK_17_BITS (BIT_17 - 1)
#define MASK_18_BITS (BIT_18 - 1)
#define MASK_19_BITS (BIT_19 - 1)
#define MASK_20_BITS (BIT_20 - 1)
#define MASK_21_BITS (BIT_21 - 1)
#define MASK_22_BITS (BIT_22 - 1)
#define MASK_23_BITS (BIT_23 - 1)
#define MASK_24_BITS (BIT_24 - 1)
#define MASK_25_BITS (BIT_25 - 1)
#define MASK_26_BITS (BIT_26 - 1)
#define MASK_27_BITS (BIT_27 - 1)
#define MASK_28_BITS (BIT_28 - 1)
#define MASK_29_BITS (BIT_29 - 1)
#define MASK_30_BITS (BIT_30 - 1)
#define MASK_31_BITS (BIT_31 - 1)
#define REG32_FIELD_SET(_data, _val, _fOffset, _fMask) ((_data & ~(_fMask)) | ((_val << (_fOffset)) & (_fMask)))
#define REG32_FIELD_GET(_data, _fOffset, _fMask) ((_data & (_fMask)) >> (_fOffset))
#define UINT32_BITS_MASK(_mBit, _lBit) ((0xFFFFFFFF >> (31 - _mBit)) ^ ((1 << _lBit) - 1))
typedef struct phy_device * rtk_port_t;
#if 1 /* ss\sdk\include\hal\phy\phydef.h */
/* unified patch format */
typedef enum rtk_phypatch_type_e
{
PHY_PATCH_TYPE_NONE = 0,
PHY_PATCH_TYPE_TOP = 1,
PHY_PATCH_TYPE_SDS,
PHY_PATCH_TYPE_AFE,
PHY_PATCH_TYPE_UC,
PHY_PATCH_TYPE_UC2,
PHY_PATCH_TYPE_NCTL0,
PHY_PATCH_TYPE_NCTL1,
PHY_PATCH_TYPE_NCTL2,
PHY_PATCH_TYPE_ALGXG,
PHY_PATCH_TYPE_ALG1G,
PHY_PATCH_TYPE_NORMAL,
PHY_PATCH_TYPE_DATARAM,
PHY_PATCH_TYPE_RTCT,
PHY_PATCH_TYPE_END
} rtk_phypatch_type_t;
#define RTK_PATCH_TYPE_FLOW(_id) (PHY_PATCH_TYPE_END + _id)
#define RTK_PATCH_TYPE_FLOWID_MAX PHY_PATCH_TYPE_END
#define RTK_PATCH_SEQ_MAX ( PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX -1)
typedef struct rtk_hwpatch_s
{
uint8 patch_op;
uint8 portmask;
uint16 pagemmd;
uint16 addr;
uint8 msb;
uint8 lsb;
uint16 data;
uint8 compare_op;
uint16 sram_p;
uint16 sram_rr;
uint16 sram_rw;
uint16 sram_a;
} rtk_hwpatch_t;
typedef struct rtk_hwpatch_data_s
{
rtk_hwpatch_t *conf;
uint32 size;
} rtk_hwpatch_data_t;
typedef struct rtk_hwpatch_seq_s
{
uint8 patch_type;
union
{
rtk_hwpatch_data_t data;
uint8 flow_id;
} patch;
} rtk_hwpatch_seq_t;
typedef struct rt_phy_patch_db_s
{
/* patch operation */
int32 (*fPatch_op)(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch_data, uint8 patch_mode);
int32 (*fPatch_flow)(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_flow, uint8 patch_mode);
/* patch data */
rtk_hwpatch_seq_t seq_table[RTK_PATCH_SEQ_MAX];
rtk_hwpatch_seq_t cmp_table[RTK_PATCH_SEQ_MAX];
} rt_phy_patch_db_t;
#endif
#endif /* __RTK_PHYLIB_DEF_H */

View File

@@ -0,0 +1,57 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#include "rtk_phylib_rtl826xb.h"
/* Indirect Register Access APIs */
int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData)
{
int32 ret = 0;
uint32 rData = 0;
uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8000);
uint32 i = 0;
uint32 mask = 0;
mask = UINT32_BITS_MASK(msb,lsb);
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op));
for (i = 0; i < 10; i++)
{
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 323, 15, 15, &rData));
if (rData == 0)
{
break;
}
rtk_phylib_udelay(10);
}
if (i == 10)
{
return -1;
}
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 322, 15, 0, &rData));
*pData = REG32_FIELD_GET(rData, lsb, mask);
return ret;
}
int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data)
{
int32 ret = 0;
uint32 wData = 0, rData = 0;
uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8800);
uint32 mask = 0;
mask = UINT32_BITS_MASK(msb,lsb);
RTK_PHYLIB_ERR_CHK(rtk_phylib_826xb_sds_read(phydev, page, reg, 15, 0, &rData));
wData = REG32_FIELD_SET(rData, data, lsb, mask);
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 321, 15, 0, wData));
RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op));
return ret;
}

View File

@@ -0,0 +1,19 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __RTK_PHYLIB_RTL826XB_H
#define __RTK_PHYLIB_RTL826XB_H
#if defined(RTK_PHYDRV_IN_LINUX)
#include "rtk_phylib.h"
#else
//#include SDK headers
#endif
int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData);
int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data);
#endif /* __RTK_PHYLIB_RTL826XB_H */

View File

@@ -0,0 +1,117 @@
/*
* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved.
*/
#ifndef __COMMON_TYPE_H__
#define __COMMON_TYPE_H__
/*
* Symbol Definition
*/
#define USING_RTSTK_PKT_AS_RAIL
#ifndef NULL
#define NULL 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif
#ifndef IP6_ADDR_LEN
#define IP6_ADDR_LEN 16
#endif
/*
* Data Type Declaration
*/
#ifndef uint64
typedef unsigned long long uint64;
#endif
#ifndef int64
typedef signed long long int64;
#endif
#ifndef uint32
typedef unsigned int uint32;
#endif
#ifndef int32
typedef signed int int32;
#endif
#ifndef uint16
typedef unsigned short uint16;
#endif
#ifndef int16
typedef signed short int16;
#endif
#ifndef uint8
typedef unsigned char uint8;
#endif
#ifndef int8
typedef signed char int8;
#endif
//#define CONFIG_SDK_WORDSIZE_64 /* not ready */
#ifdef CONFIG_SDK_WORDSIZE_64
typedef long int intptr;
typedef unsigned long int uintptr;
#else
typedef int intptr;
typedef unsigned int uintptr;
#endif
#ifndef ipaddr_t
typedef uint32 ipaddr_t; /* ipv4 address type */
#endif
/* configuration mode type */
typedef enum rtk_enable_e
{
DISABLED = 0,
ENABLED,
RTK_ENABLE_END
} rtk_enable_t;
/* initial state of module */
typedef enum init_state_e
{
INIT_NOT_COMPLETED = 0,
INIT_COMPLETED,
INIT_STATE_END
} init_state_t;
/* ethernet address type */
typedef struct rtk_mac_s
{
uint8 octet[ETHER_ADDR_LEN];
} rtk_mac_t;
typedef uint32 osal_time_t;
typedef uint32 osal_usecs_t;
/*
* Macro Definition
*/
#endif /* __COMMON_TYPE_H__ */

View File

@@ -28,6 +28,7 @@ endef
define Device/edgecore_eap105
DEVICE_TITLE := Edgecore EAP105
DEVICE_DTS := ipq5332-edgecore-eap105
DEVICE_DTS_DIR := ../dts
DEVICE_DTS_CONFIG := config@mi01.6
IMAGES := sysupgrade.tar nand-factory.bin nand-factory.ubi
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
@@ -35,4 +36,4 @@ define Device/edgecore_eap105
IMAGE/nand-factory.ubi := append-ubi
DEVICE_PACKAGES := ath12k-wifi-edgecore-eap105 ath12k-firmware-qcn92xx-split-phy ath12k-firmware-ipq53xx
endef
#TARGET_DEVICES += edgecore_eap105
TARGET_DEVICES += edgecore_eap105

View File

@@ -0,0 +1,19 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -440,7 +440,7 @@ config XILINX_GMII2RGMII
This driver support xilinx GMII to RGMII IP core it provides
the Reduced Gigabit Media Independent Interface(RGMII) between
Ethernet physical media devices and the Gigabit Ethernet controller.
-
+source "drivers/net/phy/rtk/Kconfig"
endif # PHYLIB
config MICREL_KS8995MA
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -103,3 +103,5 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o
obj-$(CONFIG_TERANETICS_PHY) += teranetics.o
obj-$(CONFIG_VITESSE_PHY) += vitesse.o
obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
+obj-$(CONFIG_RTK_MSSDK_PHY) += rtk/
+

View File

@@ -393,20 +393,8 @@ define Build/InstallDev
rm -f $(1)/usr/include/mac80211-backport/linux/module.h
endef
EXTERNAL_FILE_DIR:=$(CURDIR)/files
#EXTERNAL_FILE_DIR:=$(CURDIR)/files-qca
define KernelPackage/cfg80211/install
$(INSTALL_DIR) $(1)/lib/wifi $(1)/etc/hotplug.d/ieee80211
$(INSTALL_DIR) $(1)/lib/wifi $(1)/etc/hotplug.d/devcoredump
$(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless
$(INSTALL_DIR) $(1)/lib/wifi/sawf
$(INSTALL_DIR) $(1)/lib/wifi/sawf/telemetry
$(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi
$(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless
# $(INSTALL_BIN) $(EXTERNAL_FILE_DIR)/files/lib/wifi-config.sh $(1)/etc/hotplug.d/ieee80211/01-wifi-detect
$(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211
$(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect
$(CP) ./files/* $(1)/
endef
define KernelPackage/ath-qca/install
@@ -414,13 +402,6 @@ define KernelPackage/ath-qca/install
$(CP) $(PKG_BUILD_DIR)/include/ath/ath_sawf.h $(STAGING_DIR)/usr/include/
endef
define KernelPackage/ath11k-qca/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(EXTERNAL_FILE_DIR)/files/etc/init.d/ath11k_nss_enable.sh $(1)/etc/init.d
$(INSTALL_BIN) $(EXTERNAL_FILE_DIR)/files/etc/init.d/ath11k_uboot_mod_params.sh $(1)/etc/init.d
$(INSTALL_BIN) $(EXTERNAL_FILE_DIR)/files/etc/init.d/qca-nss-pbuf $(1)/etc/init.d
endef
define KernelPackage/ath12k-qca/install
$(call KernelPackage/ath/install)
endef

View File

@@ -0,0 +1,6 @@
#!/bin/sh
[ "${ACTION}" = "add" ] && {
/sbin/wifi config
[ -d /etc/config-shadow ] && cp /etc/config/wireless /etc/config-shadow/wireless
}

492
feeds/qca/mac80211/files/lib/netifd/wireless/mac80211.sh Normal file → Executable file
View File

@@ -19,15 +19,20 @@ wdev_tool() {
ucode /usr/share/hostap/wdev.uc "$@"
}
ubus_call() {
flock /var/run/hostapd.lock ubus call "$@"
}
drv_mac80211_init_device_config() {
hostapd_common_add_device_config
config_add_string path phy 'macaddr:macaddr'
config_add_string tx_burst
config_add_string distance
config_add_int beacon_int chanbw frag rts
config_add_int rxantenna txantenna antenna_gain txpower min_tx_power
config_add_int num_global_macaddr
config_add_string ifname_prefix
config_add_int radio beacon_int chanbw frag rts
config_add_int rxantenna txantenna txpower min_tx_power
config_add_int num_global_macaddr multiple_bssid
config_add_boolean noscan ht_coex acs_exclude_dfs background_radar
config_add_array ht_capab
config_add_array channels
@@ -49,6 +54,8 @@ drv_mac80211_init_device_config() {
rx_antenna_pattern \
tx_antenna_pattern \
he_spr_sr_control \
he_spr_psr_enabled \
he_bss_color_enabled \
he_twt_required
config_add_int \
beamformer_antennas \
@@ -68,19 +75,6 @@ drv_mac80211_init_device_config() {
short_gi_40 \
max_amsdu \
dsss_cck_40
config_add_int \
ru_punct_bitmap \
ru_punct_acs_threshold \
ccfs \
eht_su_beamformee \
eht_su_beamformer \
eht_mu_beamformer \
eht_ulmumimo_80mhz \
eht_ulmumimo_160mhz \
eht_ulmumimo_320mhz
config_add_boolean \
ru_punct_ofdma \
disable_eml_cap
}
drv_mac80211_init_iface_config() {
@@ -95,8 +89,6 @@ drv_mac80211_init_iface_config() {
config_add_int dtim_period
config_add_int start_disabled
config_add_int fils_discovery_max_interval
# mesh
config_add_string mesh_id
config_add_int $MP_CONFIG_INT
@@ -145,7 +137,7 @@ mac80211_hostapd_setup_base() {
json_select config
[ "$auto_channel" -gt 0 ] && channel=0
[ "$auto_channel" -gt 0 ] && channel=acs_survey
[ "$auto_channel" -gt 0 ] && json_get_vars acs_exclude_dfs
[ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] &&
@@ -158,7 +150,7 @@ mac80211_hostapd_setup_base() {
[ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \
channel_list="$channel"
[ "$min_tx_power" -gt 0 ] && append base_cfg "min_tx_power=$min_tx_power"
[ "$min_tx_power" -gt 0 ] && append base_cfg "min_tx_power=$min_tx_power" "$N"
set_default noscan 0
@@ -168,77 +160,79 @@ mac80211_hostapd_setup_base() {
chan_ofs=0
[ "$band" = "6g" ] && chan_ofs=1
ieee80211n=1
ht_capab=
case "$htmode" in
VHT20|HT20|HE20) ;;
HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160|EHT40|EHT80|EHT160|EHT320)
case "$hwmode" in
a)
case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in
1) ht_capab="[HT40+]";;
0) ht_capab="[HT40-]";;
esac
;;
*)
case "$htmode" in
HT40+) ht_capab="[HT40+]";;
HT40-) ht_capab="[HT40-]";;
*)
if [ "$channel" -lt 7 ]; then
ht_capab="[HT40+]"
else
ht_capab="[HT40-]"
fi
;;
esac
;;
esac
[ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]"
;;
*) ieee80211n= ;;
esac
if [ "$band" != "6g" ]; then
ieee80211n=1
ht_capab=
case "$htmode" in
VHT20|HT20|HE20|EHT20) ;;
HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160|EHT40|EHT80|EHT160)
case "$hwmode" in
a)
case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in
1) ht_capab="[HT40+]";;
0) ht_capab="[HT40-]";;
esac
;;
*)
case "$htmode" in
HT40+) ht_capab="[HT40+]";;
HT40-) ht_capab="[HT40-]";;
*)
if [ "$channel" -lt 7 ]; then
ht_capab="[HT40+]"
else
ht_capab="[HT40-]"
fi
;;
esac
;;
esac
[ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]"
;;
*) ieee80211n= ;;
esac
[ -n "$ieee80211n" ] && {
append base_cfg "ieee80211n=1" "$N"
[ -n "$ieee80211n" ] && {
append base_cfg "ieee80211n=1" "$N"
set_default ht_coex 0
append base_cfg "ht_coex=$ht_coex" "$N"
set_default ht_coex 0
append base_cfg "ht_coex=$ht_coex" "$N"
json_get_vars \
ldpc:1 \
greenfield:0 \
short_gi_20:1 \
short_gi_40:1 \
tx_stbc:1 \
rx_stbc:3 \
max_amsdu:1 \
dsss_cck_40:1
json_get_vars \
ldpc:1 \
greenfield:0 \
short_gi_20:1 \
short_gi_40:1 \
tx_stbc:1 \
rx_stbc:3 \
max_amsdu:1 \
dsss_cck_40:1
ht_cap_mask=0
for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
ht_cap_mask="$(($ht_cap_mask | $cap))"
done
ht_cap_mask=0
for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
ht_cap_mask="$(($ht_cap_mask | $cap))"
done
cap_rx_stbc=$((($ht_cap_mask >> 8) & 3))
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))"
cap_rx_stbc=$((($ht_cap_mask >> 8) & 3))
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))"
mac80211_add_capabilities ht_capab_flags $ht_cap_mask \
LDPC:0x1::$ldpc \
GF:0x10::$greenfield \
SHORT-GI-20:0x20::$short_gi_20 \
SHORT-GI-40:0x40::$short_gi_40 \
TX-STBC:0x80::$tx_stbc \
RX-STBC1:0x300:0x100:1 \
RX-STBC12:0x300:0x200:1 \
RX-STBC123:0x300:0x300:1 \
MAX-AMSDU-7935:0x800::$max_amsdu \
DSSS_CCK-40:0x1000::$dsss_cck_40
mac80211_add_capabilities ht_capab_flags $ht_cap_mask \
LDPC:0x1::$ldpc \
GF:0x10::$greenfield \
SHORT-GI-20:0x20::$short_gi_20 \
SHORT-GI-40:0x40::$short_gi_40 \
TX-STBC:0x80::$tx_stbc \
RX-STBC1:0x300:0x100:1 \
RX-STBC12:0x300:0x200:1 \
RX-STBC123:0x300:0x300:1 \
MAX-AMSDU-7935:0x800::$max_amsdu \
DSSS_CCK-40:0x1000::$dsss_cck_40
ht_capab="$ht_capab$ht_capab_flags"
[ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N"
}
ht_capab="$ht_capab$ht_capab_flags"
[ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N"
}
fi
# 802.11ac
enable_ac=0
@@ -282,28 +276,45 @@ mac80211_hostapd_setup_base() {
case "$channel" in
36|40|44|48|52|56|60|64) idx=50;;
100|104|108|112|116|120|124|128) idx=114;;
149|153|157|161|165|169|173|177) idx=163;;
esac
fi
enable_ac=1
vht_oper_chwidth=2
vht_center_seg0=$idx
;;
esac
esac
[ "$band" = "5g" ] && {
json_get_vars background_radar:0
[ "$background_radar" -eq 1 ] && append base_cfg "enable_background_radar=1" "$N"
}
eht_oper_chwidth=$vht_oper_chwidth
eht_center_seg0=$vht_center_seg0
[ "$band" = "6g" ] && {
op_class=
case "$htmode" in
HE20) op_class=131;;
EHT320) op_class=137;;
HE*|EHT*) op_class=$((132 + $vht_oper_chwidth))
HE20|EHT20) op_class=131;;
EHT320)
case "$channel" in
1|5|9|13|17|21|25|29|33|37|41|45|49|53|57|61) idx=31;;
65|69|73|77|81|85|89|93|97|101|105|109|113|117|121|125) idx=95;;
129|133|137|141|145|149|153|157|161|165|169|173|177|181|185|189) idx=159;;
193|197|201|205|209|213|217|221) idx=191;;
esac
op_class=137
eht_center_seg0=$idx
eht_oper_chwidth=9
;;
HE*|EHT*) op_class=$((132 + $vht_oper_chwidth));;
esac
[ -n "$op_class" ] && append base_cfg "op_class=$op_class" "$N"
}
[ "$hwmode" = "a" ] || enable_ac=0
[ "$band" = "6g" ] && enable_ac=0
if [ "$enable_ac" != "0" ]; then
json_get_vars \
@@ -341,6 +352,11 @@ mac80211_hostapd_setup_base() {
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))"
[ "$vht_oper_chwidth" -lt 2 ] && {
vht160=0
short_gi_160=0
}
mac80211_add_capabilities vht_capab $vht_cap \
RXLDPC:0x10::$rxldpc \
SHORT-GI-80:0x20::$short_gi_80 \
@@ -424,10 +440,7 @@ mac80211_hostapd_setup_base() {
enable_be=0
case "$htmode" in
HE*) enable_ax=1 ;;
EHT*)
enable_ax=1
enable_be=1
;;
EHT*) enable_ax=1; enable_be=1 ;;
esac
if [ "$enable_ax" != "0" ]; then
@@ -442,38 +455,15 @@ mac80211_hostapd_setup_base() {
he_bss_color:128 \
he_bss_color_enabled:1
he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1)
he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: .*AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1)
he_phy_cap=${he_phy_cap:2}
he_mac_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1)
he_mac_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: .*AP/,$p' | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1)
he_mac_cap=${he_mac_cap:2}
append base_cfg "ieee80211ax=1" "$N"
[ "$hwmode" = "a" ] && {
append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N"
append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N"
[ "$enable_be" != "0" ] && {
case "$htmode" in
EHT320)
local eht_idx=130
if [ "$band" = "6g" ]; then
case "$channel" in
1|5|9|13|17|21|25|29|33|37|41|45) idx=31;;
49|53|57|61|65|69|73|77) idx=63;;
81|85|89|93|97|101|105|109) idx=95;;
113|117|121|125|129|133|137|141) idx=127;;
145|149|153|157|161|165|169|173) idx=159;;
177|181|185|189|193|197|201|205|209|213|217|221) idx=191;;
esac
fi
append base_cfg "eht_oper_chwidth=9" "$N"
append base_cfg "eht_oper_centr_freq_seg0_idx=$eht_idx" "$N"
;;
*)
append base_cfg "eht_oper_chwidth=$vht_oper_chwidth" "$N"
append base_cfg "eht_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N"
;;
esac
}
}
mac80211_add_he_capabilities \
@@ -525,66 +515,11 @@ mac80211_hostapd_setup_base() {
fi
if [ "$enable_be" != "0" ]; then
json_get_vars \
ru_punct_bitmap:0 \
ru_punct_ofdma:0 \
ru_punct_acs_threshold:0 \
ccfs:0 \
eht_su_beamformee:1 \
eht_su_beamformer:1 \
eht_mu_beamformer:1 \
eht_ulmumimo_80mhz \
eht_ulmumimo_160mhz \
eht_ulmumimo_320mhz \
disable_eml_cap:1
append base_cfg "ieee80211be=1" "$N"
append base_cfg "eht_su_beamformer=$eht_su_beamformer" "$N"
append base_cfg "eht_mu_beamformer=$eht_mu_beamformer" "$N"
append base_cfg "eht_su_beamformee=$eht_su_beamformee" "$N"
[ -n "$disable_eml_cap" ] && append base_cfg "disable_eml_cap=$disable_eml_cap" "$N"
if [ -n "$eht_ulmumimo_80mhz" ]; then
if [ $eht_ulmumimo_80mhz -eq 0 ]; then
append base_cfg "eht_ulmumimo_80mhz=0" "$N"
elif [ $eht_ulmumimo_80mhz -gt 0 ]; then
append base_cfg "eht_ulmumimo_80mhz=1" "$N"
fi
else
append base_cfg "eht_ulmumimo_80mhz=-1" "$N"
fi
if [ -n "$eht_ulmumimo_160mhz" ]; then
if [ $eht_ulmumimo_160mhz -eq 0 ]; then
append base_cfg "eht_ulmumimo_160mhz=0" "$N"
elif [ $eht_ulmumimo_160mhz -gt 0 ]; then
append base_cfg "eht_ulmumimo_160mhz=1" "$N"
fi
else
append base_cfg "eht_ulmumimo_160mhz=-1" "$N"
fi
if [ -n "$eht_ulmumimo_320mhz" ]; then
if [ $eht_ulmumimo_320mhz -eq 0 ]; then
append base_cfg "eht_ulmumimo_320mhz=0" "$N"
elif [ $eht_ulmumimo_320mhz -gt 0 ]; then
append base_cfg "eht_ulmumimo_320mhz=1" "$N"
fi
else
append base_cfg "eht_ulmumimo_320mhz=-1" "$N"
fi
if [ -n $ru_punct_bitmap ] && [ $ru_punct_bitmap -gt 0 ]; then
append base_cfg "ru_punct_bitmap=$ru_punct_bitmap" "$N"
fi
if [ -n $ru_punct_ofdma ] && [ $ru_punct_ofdma -gt 0 ]; then
append base_cfg "ru_punct_ofdma=$ru_punct_ofdma" "$N"
fi
if [ -n $ru_punct_acs_threshold ] && [ $ru_punct_acs_threshold -gt 0 ]; then
append base_cfg "ru_punct_acs_threshold=$ru_punct_acs_threshold" "$N"
fi
[ -n "$use_ru_puncture_dfs" ] && append base_cfg "use_ru_puncture_dfs=$use_ru_puncture_dfs" "$N"
[ "$hwmode" = "a" ] && {
append base_cfg "eht_oper_chwidth=$eht_oper_chwidth" "$N"
append base_cfg "eht_oper_centr_freq_seg0_idx=$eht_center_seg0" "$N"
}
fi
hostapd_prepare_device_config "$hostapd_conf_file" nl80211
@@ -593,6 +528,8 @@ ${channel:+channel=$channel}
${channel_list:+chanlist=$channel_list}
${hostapd_noscan:+noscan=1}
${tx_burst:+tx_queue_data2_burst=$tx_burst}
${multiple_bssid:+mbssid=$multiple_bssid}
#num_global_macaddr=$num_global_macaddr
$base_cfg
EOF
@@ -610,11 +547,9 @@ mac80211_hostapd_setup_bss() {
hostapd_set_bss_options hostapd_cfg "$phy" "$vif" || return 1
json_get_vars wds wds_bridge dtim_period max_listen_int start_disabled
json_get_vars fils_discovery_max_interval
set_default wds 0
set_default start_disabled 0
set_default fils_discovery_max_interval 0
[ "$wds" -gt 0 ] && {
append hostapd_cfg "wds_sta=1" "$N"
@@ -622,15 +557,7 @@ mac80211_hostapd_setup_bss() {
}
[ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N"
[ "$band" = "6g" ] && {
if [ "$fils_discovery_max_interval" -gt 0 ] && [ "$fils_discovery_max_interval" -le 20 ]; then
append hostapd_cfg "fils_discovery_max_interval=$fils_discovery_max_interval" "$N"
else
append hostapd_cfg "fils_discovery_max_interval=20" "$N"
fi
}
cat >> /var/run/hostapd-$phy.conf <<EOF
cat >> /var/run/hostapd-$phy$vif_phy_suffix.conf <<EOF
$hostapd_cfg
bssid=$macaddr
${default_macaddr:+#default_macaddr}
@@ -650,18 +577,80 @@ mac80211_generate_mac() {
local phy="$1"
local id="${macidx:-0}"
wdev_tool "$phy" get_macaddr id=$id num_global=$num_global_macaddr mbssid=$multiple_bssid
wdev_tool "$phy$phy_suffix" get_macaddr id=$id num_global=$num_global_macaddr mbssid=${multiple_bssid:-0}
}
get_board_phy_name() (
local path="$1"
local fallback_phy=""
__check_phy() {
local val="$1"
local key="$2"
local ref_path="$3"
json_select "$key"
json_get_vars path
json_select ..
[ "${ref_path%+*}" = "$path" ] && fallback_phy=$key
[ "$ref_path" = "$path" ] || return 0
echo "$key"
exit
}
json_load_file /etc/board.json
json_for_each_item __check_phy wlan "$path"
[ -n "$fallback_phy" ] && echo "${fallback_phy}.${path##*+}"
)
rename_board_phy_by_path() {
local path="$1"
local new_phy="$(get_board_phy_name "$path")"
[ -z "$new_phy" -o "$new_phy" = "$phy" ] && return
iw "$phy" set name "$new_phy" && phy="$new_phy"
}
rename_board_phy_by_name() (
local phy="$1"
local suffix="${phy##*.}"
[ "$suffix" = "$phy" ] && suffix=
json_load_file /etc/board.json
json_select wlan
json_select "${phy%.*}" || return 0
json_get_vars path
prev_phy="$(iwinfo nl80211 phyname "path=$path${suffix:++$suffix}")"
[ -n "$prev_phy" ] || return 0
[ "$prev_phy" = "$phy" ] && return 0
iw "$prev_phy" set name "$phy"
)
find_phy() {
[ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0
[ -n "$phy" ] && {
rename_board_phy_by_name "$phy"
[ -d /sys/class/ieee80211/$phy ] && return 0
}
[ -n "$path" ] && {
phy="$(iwinfo nl80211 phyname "path=$path")"
[ -n "$phy" ] && return 0
[ -n "$phy" ] && {
rename_board_phy_by_path "$path"
return 0
}
}
[ -n "$macaddr" ] && {
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0
grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && {
path="$(iwinfo nl80211 path "$phy")"
rename_board_phy_by_path "$path"
return 0
}
done
}
return 1
@@ -671,13 +660,28 @@ mac80211_check_ap() {
has_ap=1
}
mac80211_set_ifname() {
local prefix="$1"
local type="$2"
eval "ifname=\"$prefix$type\${idx_$type:-0}\"; idx_$type=\$((\${idx_$type:-0 } + 1))"
}
mac80211_prepare_vif() {
json_select config
json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file
[ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}"
if_idx=$((${if_idx:-0} + 1))
[ -n "$ifname" ] || {
local prefix;
case "$mode" in
ap|sta|mesh) prefix=$mode;;
adhoc) prefix=ibss;;
monitor) prefix=mon;;
esac
mac80211_set_ifname "$ifname_prefix" "$prefix"
}
append active_ifnames "$ifname"
set_default wds 0
@@ -685,11 +689,13 @@ mac80211_prepare_vif() {
json_add_string _ifname "$ifname"
default_macaddr=
[ -n "$macaddr" ] || {
if [ -z "$macaddr" ]; then
macaddr="$(mac80211_generate_mac $phy)"
macidx="$(($macidx + 1))"
macidx="$(($macidx + 1))"
default_macaddr=1
}
elif [ "$macaddr" = 'random' ]; then
macaddr="$(macaddr_random)"
fi
json_add_string _macaddr "$macaddr"
json_add_string _default_macaddr "$default_macaddr"
json_select ..
@@ -872,12 +878,15 @@ mac80211_set_vif_txpower() {
json_select config
json_get_var ifname _ifname
json_get_vars vif_txpower wds
json_get_vars vif_txpower
json_select ..
set_default wds 0
[ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00"
[ "$wds" -gt 0 ] && echo 1 > /sys/kernel/debug/ieee80211/$phy/netdev\:$ifname/disable_offload
set_default vif_txpower "$txpower"
if [ -n "$vif_txpower" ]; then
iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00"
else
iw dev "$ifname" set txpower auto
fi
}
wpa_supplicant_init_config() {
@@ -917,11 +926,14 @@ wpa_supplicant_add_interface() {
wpa_supplicant_set_config() {
local phy="$1"
local radio="$2"
local prev
json_set_namespace wpa_supp prev
json_close_array
json_add_string phy "$phy"
json_add_int radio "$radio"
json_add_int num_global_macaddr "$num_global_macaddr"
json_add_boolean defer 1
local data="$(json_dump)"
@@ -934,7 +946,7 @@ wpa_supplicant_set_config() {
ubus wait_for wpa_supplicant
}
local supplicant_res="$(ubus call wpa_supplicant config_set "$data")"
local supplicant_res="$(ubus_call wpa_supplicant config_set "$data")"
ret="$?"
[ "$ret" != 0 -o -z "$supplicant_res" ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED
@@ -943,13 +955,16 @@ wpa_supplicant_set_config() {
}
hostapd_set_config() {
local phy="$1"
local radio="$2"
[ -n "$hostapd_ctrl" ] || {
ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null
return 0;
}
ubus wait_for hostapd
local hostapd_res="$(ubus call hostapd config_set "{ \"phy\": \"$phy\", \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")"
local hostapd_res="$(ubus_call hostapd config_set "{ \"phy\": \"$phy\", \"radio\": $radio, \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")"
ret="$?"
[ "$ret" != 0 -o -z "$hostapd_res" ] && {
wireless_setup_failed HOSTAPD_START_FAILED
@@ -961,10 +976,11 @@ hostapd_set_config() {
wpa_supplicant_start() {
local phy="$1"
local radio="$2"
[ -n "$wpa_supp_init" ] || return 0
ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'" }' > /dev/null
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "num_global_macaddr": '"$num_global_macaddr"' }' > /dev/null
}
mac80211_setup_supplicant() {
@@ -976,7 +992,7 @@ mac80211_setup_supplicant() {
if [ "$mode" = "sta" ]; then
wpa_supplicant_add_network "$ifname"
else
wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan"
wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$hostapd_noscan"
fi
wpa_supplicant_add_interface "$ifname" "$mode"
@@ -1047,7 +1063,7 @@ $1 ~ /Band/ {
}
band_match && $3 == "MHz" && $4 == channel {
print $2
print int($2)
exit
}
'
@@ -1065,32 +1081,39 @@ mac80211_set_noscan() {
}
drv_mac80211_cleanup() {
hostapd_common_cleanup
:
}
mac80211_reset_config() {
local phy="$1"
hostapd_conf_file="/var/run/hostapd-$phy$vif_phy_suffix.conf"
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "config": [] }' > /dev/null
wdev_tool "$phy$phy_suffix" set_config '{}'
}
hostapd_conf_file="/var/run/hostapd-$phy.conf"
ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null
ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'", "config": [] }' > /dev/null
wdev_tool "$phy" set_config '{}'
mac80211_set_suffix() {
[ "$radio" = "-1" ] && radio=
phy_suffix="${radio:+:$radio}"
vif_phy_suffix="${radio:+.$radio}"
set_default radio -1
}
drv_mac80211_setup() {
json_select config
json_get_vars \
phy macaddr path \
radio phy macaddr path \
country chanbw distance \
txpower antenna_gain \
txpower \
rxantenna txantenna \
frag rts beacon_int:100 htmode \
multiple_bssid:0 \
num_global_macaddr
num_global_macaddr:1 multiple_bssid \
ifname_prefix
json_get_values basic_rate_list basic_rate
json_get_values scan_list scan_list
json_select ..
mac80211_set_suffix
json_select data && {
json_get_var prev_rxantenna rxantenna
json_get_var prev_txantenna txantenna
@@ -1102,8 +1125,8 @@ drv_mac80211_setup() {
wireless_set_retry 0
return 1
}
[ "$band" = "6g" ] && set_default multiple_bssid 1
set_default ifname_prefix "$phy$vif_phy_suffix-"
local wdev
local cwdev
@@ -1119,7 +1142,7 @@ drv_mac80211_setup() {
}
}
hostapd_conf_file="/var/run/hostapd-$phy.conf"
hostapd_conf_file="/var/run/hostapd-$phy$vif_phy_suffix.conf"
macidx=0
staidx=0
@@ -1133,24 +1156,15 @@ drv_mac80211_setup() {
set_default rxantenna 0xffffffff
set_default txantenna 0xffffffff
set_default distance 0
set_default antenna_gain 0
set_default num_global_macaddr 1
[ "$txantenna" = "all" ] && txantenna=0xffffffff
[ "$rxantenna" = "all" ] && rxantenna=0xffffffff
[ "$rxantenna" = "$prev_rxantenna" -a "$txantenna" = "$prev_txantenna" ] || mac80211_reset_config "$phy"
wireless_set_data phy="$phy" txantenna="$txantenna" rxantenna="$rxantenna"
wireless_set_data phy="$phy" radio="$radio" txantenna="$txantenna" rxantenna="$rxantenna"
# iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
# iw phy "$phy" set antenna_gain $antenna_gain >/dev/null 2>&1
# iw phy "$phy" set distance "$distance" >/dev/null 2>&1
if [ -n "$txpower" ]; then
iw phy "$phy" set txpower fixed "${txpower%%.*}00"
else
iw phy "$phy" set txpower auto
fi
iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
iw phy "$phy" set distance "$distance" >/dev/null 2>&1
[ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
[ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
@@ -1179,13 +1193,13 @@ drv_mac80211_setup() {
for_each_interface "ap sta adhoc mesh monitor" mac80211_prepare_vif
for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_set_config "$phy"
[ -x /usr/sbin/hostapd ] && hostapd_set_config "$phy"
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_set_config "$phy" "$radio"
[ -x /usr/sbin/hostapd ] && hostapd_set_config "$phy" "$radio"
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy"
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy" "$radio"
json_set_namespace wdev_uc prev
wdev_tool "$phy" set_config "$(json_dump)" $active_ifnames
wdev_tool "$phy$phy_suffix" set_config "$(json_dump)" $active_ifnames
json_set_namespace "$prev"
for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower
@@ -1212,19 +1226,15 @@ list_phy_interfaces() {
drv_mac80211_teardown() {
json_select data
json_get_vars phy
json_get_vars phy radio
json_select ..
[ -n "$phy" ] || {
echo "Bug: PHY is undefined for device '$1'"
return 1
}
mac80211_set_suffix
mac80211_reset_config "$phy"
for wdev in $(list_phy_interfaces "$phy"); do
ip link set dev "$wdev" down
iw dev "$wdev" del
done
}
add_driver mac80211

View File

@@ -2,494 +2,8 @@
append DRIVERS "mac80211"
MLD_VAP_DETAILS="/lib/netifd/wireless/wifi_mld_cfg.config"
update_mld_vap_details() {
local _mlds
local _devices_up
local _ifaces
config_load wireless
mld_vaps_count=0
radio_up_count=0
sta_vaps_count=0
sta_radio=0
mac80211_get_wifi_mlds() {
append _mlds $1
}
config_foreach mac80211_get_wifi_mlds wifi-mld
if [ -z "$_mlds" ]; then
return
fi
mac80211_get_wifi_ifaces() {
config_get iface_mode $1 mode
if [ -n "$iface_mode" ]; then
case "$iface_mode" in
ap) append _ifaces $1 ;;
sta) append _staifaces $1 ;;
esac
fi
}
config_foreach mac80211_get_wifi_ifaces wifi-iface
for _mld in $_mlds
do
for _ifname in $_ifaces
do
config_get mld_name $_ifname mld
config_get mldevice $_ifname device
config_get mlcaps $mldevice mlo_capable
if ! [[ "$mldevices" =~ "$mldevice" ]]; then
append mldevices $mldevice
fi
if [ -n "$mlcaps" ] && [ $mlcaps -eq 1 ] && \
[ -n "$mld_name" ] && [ "$_mld" = "$mld_name" ]; then
mld_vaps_count=$((mld_vaps_count+1))
fi
done
for _staifname in $_staifaces
do
config_get mld_name $_staifname mld
config_get mldevice $_staifname device
if ! [[ "$sta_mldevices" =~ "$mldevice" ]]; then
append sta_mldevices $mldevice
fi
if [ -n "$mld_name" ] && [ "$_mld" = "$mld_name" ]; then
sta_vaps_count=$((sta_vaps_count+1))
fi
done
done
for mldev in $mldevices
do
# Length of radio name should be 12 in order to ensure only single wiphy wifi-devices are taken into account
if [ ${#mldev} -ne 12 ]; then
continue;
fi
config_get disabled "$mldev" disabled
if [ -z "$disabled" ] || [ "$disabled" -eq 0 ]; then
radio_up_count=$((radio_up_count+1))
fi
done
for sta_mld in $sta_mldevices
do
if [ ${#sta_mld} -ne 12 ]; then
continue;
fi
config_get disabled "$sta_mld" disabled
if [ -z "$disabled" ] || [ "$disabled" -eq 0 ]; then
sta_radio=$((sta_radio+1))
fi
done
echo "radio_up_count=$radio_up_count mld_vaps_count=$mld_vaps_count" > $MLD_VAP_DETAILS
echo "sta_radio=$sta_radio sta_vaps_count=$sta_vaps_count" >> $MLD_VAP_DETAILS
}
pre_wifi_updown() {
:
}
post_wifi_updown() {
:
}
check_mac80211_device() {
local device="$1"
local path="$2"
local macaddr="$3"
[ -n "$found" ] && return 0
phy_path=
config_get phy "$device" phy
[ -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"
if (eht && band == "1:") mode="EHT20"
if (eht && band == "2:") mode="EHT80"
if (eht && band == "4:") mode="EHT160"
sub("\\[", "", channel)
sub("\\]", "", channel)
bands = bands band channel ":" mode " "
}
band=""
}
$1 == "Band" {
band = $2
channel = ""
vht = ""
ht = ""
he = ""
eht = ""
}
$0 ~ "Capabilities:" {
ht=1
}
$0 ~ "VHT Capabilities" {
vht=1
}
$0 ~ "HE Iftypes" {
he=1
}
$0 ~ "EHT Iftypes" {
eht=1
}
$0 ~ "EHT MAC Capabilities (0x0000" {
eht=0
}
$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
append mode_band $band
append channel $chan
append htmode $mode
done
}
check_devidx() {
case "$1" in
radio[0-9]*)
local idx="${1#radio}"
[ "$devidx" -ge "${1#radio}" ] && devidx=$((idx + 1))
;;
esac
}
pre_mac80211() {
local action=${1}
case "${action}" in
disable)
has_updated_cfg=$(ls /var/run/hostapd-*-updated-cfg 2>/dev/null | wc -l)
if [ "$has_updated_cfg" -gt 0 ]; then
rm -rf /var/run/hostapd-*updated-cfg
fi
rm -rf /var/run/wpa_supplicant-*-updated-cfg 2>/dev/null
if [ -f "$MLD_VAP_DETAILS" ]; then
rm -rf $MLD_VAP_DETAILS
fi
;;
esac
return 0
}
mac80211_validate_num_channels() {
dev=$1
n_hw_idx=$2
efreq=$3
match_found=0
bandidx=$4
sub_matched=0
i=0
#fetch the band channel list
band_nchans=$(eval ${3} | awk '{ print $4 }' | sed -e "s/\[//g" | sed -e "s/\]//g")
band_first_chan=$(echo $band_nchans | awk '{print $1}')
#entire band channel list without any separator
band_nchans=$(echo $band_nchans | tr -d ' ')
while [ $i -lt $n_hw_idx ]; do
#fetch the hw idx channel list
hw_nchans=$(iw phy ${dev} info | awk -v p1="$i channel list" -v p2="$((i+1)) channel list" ' $0 ~ p1{f=1;next} $0 ~ p2 {f=0} f')
first_chan=$(echo $hw_nchans | awk '{print $1}')
hw_nchans=$(echo $hw_nchans | tr -d ' ')
if [ "$band_nchans" = "$hw_nchans" ]; then
match_found=1
else
#check if subchannels matches
if echo "$band_nchans" | grep -q "${hw_nchans}";
then
sub_matched=$((sub_matched+1))
append chans $first_chan
fi
fi
i=$((i+1))
done
if [ $match_found -eq 0 ]; then
if [ $sub_matched -gt 1 ]; then
echo "$chans"
fi
else
echo ""
fi
}
mac80211_get_channel_list() {
dev=$1
n_hw_idx=$2
chan=$3
i=0
match_found=0
while [ $i -lt $n_hw_idx ]; do
hw_nchans=$(iw phy ${dev} info | awk -v p1="$i channel list" -v p2="$((i+1)) channel list" ' $0 ~ p1{f=1;next} $0 ~ p2 {f=0} f')
first_chan=$(echo $hw_nchans | awk '{print $1}')
higest_chan=$first_chan
for chidx in $hw_nchans; do
if [ $chidx -gt $higest_chan ]; then
higest_chan=$chidx;
fi
if [ "$chidx" == "$chan" ]; then
match_found=1
fi
done
if [ $match_found -eq 1 ]; then
break;
fi
i=$((i+1))
done
if [ $match_found -eq 1 ]; then
echo "$first_chan-$higest_chan";
else
echo ""
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=""
bandidx=1
mode_bandidx=1
#Check the single wiphy support
total_bands=$(iw phy ${dev} info | grep -E 'Band ' | wc -l)
if [ $total_bands -gt 1 ]; then
is_swiphy=1
fi
no_hw_idx=$(iw phy ${dev} info | grep -e "channel list" | wc -l)
get_band_defaults "$dev"
if [ $no_hw_idx -gt 0 ]; then
iter=$no_hw_idx
else
iter=$total_bands
fi
while [ $bandidx -le $iter ]
do
_mode_band=$(eval echo $mode_band | awk -v I=$mode_bandidx '{print $I}')
_channel=$(eval echo $channel | awk -v I=$mode_bandidx '{print $I}')
_htmode=$(eval echo $htmode | awk -v I=$mode_bandidx '{print $I}')
mode_bandidx=$(($mode_bandidx + 1))
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
found=
config_foreach check_mac80211_device wifi-device "$path" "$macaddr"
if [ -n "$found" ]; then
bandidx=$(($bandidx + 1))
continue
fi
if [ $is_swiphy ]; then
name=""radio$devidx\_band$(($bandidx - 1))""
expr="iw phy ${dev} info | awk '/Band ${bandidx}/{ f = 1; next } /Band /{ f = 0 } f'"
else
name="radio${devidx}"
expr="iw phy ${dev} info"
fi
expr_freq="$expr | awk '/Frequencies/,/valid /f'"
if [ $no_hw_idx -gt $total_bands ]; then
need_extraconfig=$(mac80211_validate_num_channels $dev $no_hw_idx "$expr_freq")
need_extraconfig=$(eval echo "${need_extraconfig}" | tr ' ' '\n' | sort -n)
fi
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
# We may need to handle similar logic for 6g band in future if it has split phy.
if [ ${_mode_band} == '5g' ] && [ -n "$need_extraconfig" ]; then
splitphy=1
for chan in ${need_extraconfig}
do
if [ $chan -eq 100 ]; then
chan=149
fi
chan_list=$(mac80211_get_channel_list $dev $no_hw_idx $chan)
uci -q batch <<-EOF
set wireless.${name}=wifi-device
set wireless.${name}.type=mac80211
${dev_id}
set wireless.${name}.channel=${chan}
set wireless.${name}.channels=${chan_list}
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
if [ $is_swiphy ] && [ $splitphy -gt 0 ]; then
bandidx=$(($bandidx + 1))
name=""radio$devidx\_band$(($bandidx - 1))""
splitphy=$(($splitphy - 1))
else
name="radio${devidx}"
fi
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 commit wireless
done
else
chan_list=$(mac80211_get_channel_list $dev $no_hw_idx $_channel)
uci -q batch <<-EOF
set wireless.${name}=wifi-device
set wireless.${name}.type=mac80211
${dev_id}
set wireless.${name}.channel=${_channel}
set wireless.${name}.channels=${chan_list}
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
EOF
if [ ${_mode_band} == '6g' ]; then
uci -q batch <<-EOF
set wireless.default_${name}.encryption=sae
set wireless.default_${name}.sae_pwe=1
set wireless.default_${name}.key=0123456789
EOF
else
uci -q set wireless.default_${name}.encryption=none
fi
uci -q commit wireless
fi
bandidx=$(($bandidx + 1))
done
devidx=$(($devidx + 1))
done
[ -e /tmp/.config_pending ] && return
ucode /usr/share/hostap/wifi-detect.uc
ucode /lib/wifi/mac80211.uc | uci -q batch
}

View File

@@ -0,0 +1,121 @@
#!/usr/bin/env ucode
import { readfile, stat } from "fs";
import * as uci from 'uci';
const bands_order = [ "6G", "5G", "2G" ];
const htmode_order = [ "EHT", "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, radio) {
for (let name, s in config) {
if (s[".type"] != "wifi-device")
continue;
if (radio != null && int(s.radio) != radio)
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;
let radios = length(info.radios) > 0 ? info.radios : [{ bands: info.bands }];
for (let radio in radios) {
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) => radio.bands[b])[0];
if (!band_name)
continue;
let band = info.bands[band_name];
let rband = radio.bands[band_name];
let channel = rband.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, radio.index))
continue;
let id = `phy='${phy_name}'`;
if (match(phy_name, /^phy[0-9]/))
id = `path='${phy.path}'`;
band_name = lc(band_name);
let country, defaults, num_global_macaddr;
if (board.wlan.defaults) {
defaults = board.wlan.defaults.ssids?.[band_name]?.ssid ? board.wlan.defaults.ssids?.[band_name] : board.wlan.defaults.ssids?.all;
country = board.wlan.defaults.country;
if (!country && band_name != '2g')
defaults = null;
num_global_macaddr = board.wlan.defaults.ssids?.[band_name]?.mac_count;
}
if (length(info.radios) > 0)
id += `\nset ${s}.radio='${radio.index}'`;
print(`set ${s}=wifi-device
set ${s}.type='mac80211'
set ${s}.${id}
set ${s}.band='${band_name}'
set ${s}.ifname_prefix='phy${band_name}-'
set ${s}.channel='${channel}'
set ${s}.htmode='${htmode}'
set ${s}.country='${country || ''}'
set ${s}.num_global_macaddr='${num_global_macaddr || ''}'
set ${s}.disabled='${defaults ? 0 : 1}'
`);
if (!stat('/etc/config-shadow/system'))
print(`set ${si}=wifi-iface
set ${si}.device='${name}'
set ${si}.network='lan'
set ${si}.mode='ap'
set ${si}.ssid='${defaults?.ssid || "OpenWrt"}'
set ${si}.encryption='${defaults?.encryption || "none"}'
set ${si}.key='${defaults?.key || ""}'
`);
config[name] = {};
commit = true;
}
}
if (commit)
print("commit wireless\n");

View File

@@ -1,5 +0,0 @@
#!/bin/sh
[ "${ACTION}" = "add" ] && {
/sbin/wifi config
}

View File

@@ -0,0 +1,266 @@
#!/usr/bin/env ucode
'use strict';
import { readfile, writefile, realpath, glob, basename, unlink, open, rename } from "fs";
import { is_equal } from "/usr/share/hostap/common.uc";
let nl = require("nl80211");
let board_file = "/etc/board.json";
let prev_board_data = json(readfile(board_file));
let board_data = json(readfile(board_file));
function phy_idx(name) {
return +rtrim(readfile(`/sys/class/ieee80211/${name}/index`));
}
function phy_path(name) {
let devpath = realpath(`/sys/class/ieee80211/${name}/device`);
devpath = replace(devpath, /^\/sys\/devices\//, "");
if (match(devpath, /^platform\/.*\/pci/))
devpath = replace(devpath, /^platform\//, "");
let dev_phys = map(glob(`/sys/class/ieee80211/${name}/device/ieee80211/*`), basename);
sort(dev_phys, (a, b) => phy_idx(a) - phy_idx(b));
let ofs = index(dev_phys, name);
if (ofs > 0)
devpath += `+${ofs}`;
return devpath;
}
function cleanup() {
let wlan = board_data.wlan;
for (let name in wlan)
if (substr(name, 0, 3) == "phy")
delete wlan[name];
else
delete wlan[name].info;
}
function wiphy_get_entry(phy, path) {
board_data.wlan ??= {};
let wlan = board_data.wlan;
for (let name in wlan)
if (wlan[name].path == path)
return wlan[name];
wlan[phy] = {
path: path
};
return wlan[phy];
}
function freq_to_channel(freq) {
if (freq < 1000)
return 0;
if (freq == 2484)
return 14;
if (freq == 5935)
return 2;
if (freq < 2484)
return (freq - 2407) / 5;
if (freq >= 4910 && freq <= 4980)
return (freq - 4000) / 5;
if (freq < 5950)
return (freq - 5000) / 5;
if (freq <= 45000)
return (freq - 5950) / 5;
if (freq >= 58320 && freq <= 70200)
return (freq - 56160) / 2160;
return 0;
}
function freq_range_match(ranges, freq) {
freq *= 1000;
for (let range in ranges) {
if (freq >= range[0] && freq <= range[1])
return true;
}
return false;
}
function wiphy_detect() {
let phys = nl.request(nl.const.NL80211_CMD_GET_WIPHY, nl.const.NLM_F_DUMP, { split_wiphy_dump: true });
if (!phys)
return;
for (let phy in phys) {
if (!phy)
continue;
let name = phy.wiphy_name;
let path = phy_path(name);
let info = {
antenna_rx: phy.wiphy_antenna_avail_rx,
antenna_tx: phy.wiphy_antenna_avail_tx,
bands: {},
radios: []
};
for (let radio in phy.radios) {
// S1G is not supported yet
radio.freq_ranges = filter(radio.freq_ranges,
(range) => range.end > 2000000
);
if (!length(radio.freq_ranges))
continue;
push(info.radios, {
index: radio.index,
freq_ranges: map(radio.freq_ranges,
(range) => [ range.start, range.end ]
),
bands: {}
});
}
let bands = info.bands;
for (let band in phy.wiphy_bands) {
if (!band || !band.freqs)
continue;
let freq = band.freqs[0].freq;
let band_info = {};
let band_name;
if (freq > 50000)
band_name = "60G";
else if (freq > 5900)
band_name = "6G";
else if (freq > 4000)
band_name = "5G";
else if (freq > 2000)
band_name = "2G";
else
continue;
bands[band_name] = band_info;
if (band.ht_capa > 0)
band_info.ht = true;
if (band.vht_capa > 0)
band_info.vht = true;
let he_phy_cap = 0;
let eht_phy_cap = 0;
for (let ift in band.iftype_data) {
if (!ift.he_cap_phy)
continue;
band_info.he = true;
he_phy_cap |= ift.he_cap_phy[0];
if (!ift.eht_cap_phy)
continue;
band_info.eht = true;
eht_phy_cap |= ift.eht_cap_phy[0];
}
if (band_name != "2G" &&
(he_phy_cap & 0x18) || ((band.vht_capa >> 2) & 0x3))
band_info.max_width = 160;
else if (band_name != "2G" &&
(he_phy_cap & 4) || band.vht_capa > 0)
band_info.max_width = 80;
else if ((band.ht_capa & 0x2) || (he_phy_cap & 0x2))
band_info.max_width = 40;
else
band_info.max_width = 20;
let modes = band_info.modes = [ "NOHT" ];
if (band_info.ht)
push(modes, "HT20");
if (band_info.vht)
push(modes, "VHT20");
if (band_info.he)
push(modes, "HE20");
if (band_info.eht)
push(modes, "EHT20");
if (band.ht_capa & 0x2) {
push(modes, "HT40");
if (band_info.vht)
push(modes, "VHT40")
}
if (he_phy_cap & 2)
push(modes, "HE40");
if (eht_phy_cap && he_phy_cap & 2)
push(modes, "EHT40");
for (let radio in info.radios) {
let freq_match = filter(band.freqs,
(freq) => freq_range_match(radio.freq_ranges, freq.freq)
);
if (!length(freq_match))
continue;
let radio_band = {};
radio.bands[band_name] = radio_band;
freq_match = filter(freq_match,
(freq) => !freq.disabled
);
let freq = freq_match[0];
if (freq)
radio_band.default_channel = freq_to_channel(freq.freq);
radio_band.channels = [];
radio_band.frequencies = [];
for (let f in freq_match) {
push(radio_band.channels, freq_to_channel(f.freq));
push(radio_band.frequencies, f.freq);
}
}
for (let freq in band.freqs) {
if (freq.disabled)
continue;
let chan = freq_to_channel(freq.freq);
if (!chan)
continue;
band_info.default_channel = chan;
break;
}
if (band_name == "2G")
continue;
if (he_phy_cap & 4)
push(modes, "HE40");
if (eht_phy_cap && he_phy_cap & 4)
push(modes, "EHT40");
if (band_info.vht)
push(modes, "VHT80");
if (he_phy_cap & 4)
push(modes, "HE80");
if (eht_phy_cap && he_phy_cap & 4)
push(modes, "EHT80");
if ((band.vht_capa >> 2) & 0x3)
push(modes, "VHT160");
if (he_phy_cap & 0x18)
push(modes, "HE160");
if (eht_phy_cap && he_phy_cap & 0x18)
push(modes, "EHT160");
if (eht_phy_cap & 2)
push(modes, "EHT320");
}
let entry = wiphy_get_entry(name, path);
entry.info = info;
}
}
cleanup();
wiphy_detect();
if (!is_equal(prev_board_data, board_data)) {
let new_file = board_file + ".new";
unlink(new_file);
let f = open(new_file, "wx");
if (!f)
exit(1);
f.write(sprintf("%.J\n", board_data));
f.close();
rename(new_file, board_file);
}

View File

@@ -0,0 +1,85 @@
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -5944,6 +5944,23 @@ out:
return ret;
}
+static const struct firmware *fw_macs;
+static int fw_macs_num = 0;
+
+int ath12k_get_custom_macs_num(int num)
+{
+ int ret = fw_macs_num;
+
+ fw_macs_num += num;
+
+ return ret;
+}
+
+const struct firmware* ath12k_get_custom_macs(void)
+{
+ return fw_macs;
+}
+
static int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
{
struct ath12k_base *ab = qmi->ab;
@@ -5993,6 +6010,8 @@ static int ath12k_qmi_event_load_bdf(str
return ret;
}
+ request_firmware(&fw_macs, "ath12k-macs", ab->dev);
+
return ret;
}
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -21,6 +21,8 @@
#include "peer.h"
#include "testmode.h"
+#include <linux/firmware.h>
+
struct ath12k_wmi_svc_ready_parse {
bool wmi_svc_bitmap_done;
};
@@ -9129,6 +9131,9 @@ mem_free:
return ret;
}
+const struct firmware* ath12k_get_custom_macs(void);
+int ath12k_get_custom_macs_num(int num);
+
static int ath12k_wmi_rdy_parse(struct ath12k_base *ab, u16 tag, u16 len,
const void *ptr, void *data)
{
@@ -9136,6 +9141,7 @@ static int ath12k_wmi_rdy_parse(struct a
struct wmi_ready_event fixed_param;
struct ath12k_wmi_mac_addr_params *addr_list;
struct ath12k_pdev *pdev;
+ const struct firmware *fw_entry;
u32 num_mac_addr;
int i;
@@ -9157,6 +9163,20 @@ static int ath12k_wmi_rdy_parse(struct a
addr_list = (struct ath12k_wmi_mac_addr_params *)ptr;
num_mac_addr = rdy_parse->num_extra_mac_addr;
+ fw_entry = ath12k_get_custom_macs();
+ if (fw_entry) {
+ int num = ath12k_get_custom_macs_num(ab->num_radios);
+ printk("applying ath12k-macs\n");
+ if (fw_entry->size >= ((num + ab->num_radios) * 6)) {
+ for (i = 0; i < ab->num_radios; i++) {
+ pdev = &ab->pdevs[i];
+ ether_addr_copy(pdev->mac_addr, &fw_entry->data[(num + i) * 6]);
+ }
+ }
+ ab->pdevs_macaddr_valid = true;
+ return 0;
+ }
+
if (!(ab->num_radios > 1 && num_mac_addr >= ab->num_radios))
break;

View File

@@ -0,0 +1,161 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 2 Jul 2024 13:35:56 +0200
Subject: [PATCH] wifi: nl80211: split helper function from
nl80211_put_iface_combinations
Create a helper function that puts the data from struct
ieee80211_iface_combination to a nl80211 message.
This will be used for adding per-radio interface combination data.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/22a0eee19dbcf98627239328bc66decd3395122c.1719919832.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1693,7 +1693,7 @@ nla_put_failure:
}
static int
-nl80211_put_per_hw_iface_combinations(struct wiphy *wiphy, struct sk_buff *msg,
+nl80211_put_per_hw_iface_combinations(struct sk_buff *msg,
const struct ieee80211_iface_combination *c)
{
struct nlattr *hw_combis;
@@ -1757,74 +1757,81 @@ nl80211_put_per_hw_iface_combinations(st
return 0;
}
-static int nl80211_put_iface_combinations(struct wiphy *wiphy,
- struct sk_buff *msg,
- bool large)
+static int nl80211_put_ifcomb_data(struct sk_buff *msg, bool large, int idx,
+ const struct ieee80211_iface_combination *c)
{
- struct nlattr *nl_combis;
- int i, j;
+ struct nlattr *nl_combi, *nl_limits;
+ int i;
- nl_combis = nla_nest_start_noflag(msg,
- NL80211_ATTR_INTERFACE_COMBINATIONS);
- if (!nl_combis)
+ nl_combi = nla_nest_start_noflag(msg, idx);
+ if (!nl_combi)
goto nla_put_failure;
- for (i = 0; i < wiphy->n_iface_combinations; i++) {
- const struct ieee80211_iface_combination *c;
- struct nlattr *nl_combi, *nl_limits;
+ nl_limits = nla_nest_start_noflag(msg, NL80211_IFACE_COMB_LIMITS);
+ if (!nl_limits)
+ goto nla_put_failure;
- c = &wiphy->iface_combinations[i];
+ for (i = 0; i < c->n_limits; i++) {
+ struct nlattr *nl_limit;
- nl_combi = nla_nest_start_noflag(msg, i + 1);
- if (!nl_combi)
+ nl_limit = nla_nest_start_noflag(msg, i + 1);
+ if (!nl_limit)
goto nla_put_failure;
-
- nl_limits = nla_nest_start_noflag(msg,
- NL80211_IFACE_COMB_LIMITS);
- if (!nl_limits)
+ if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX, c->limits[i].max))
goto nla_put_failure;
+ if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
+ c->limits[i].types))
+ goto nla_put_failure;
+ nla_nest_end(msg, nl_limit);
+ }
- for (j = 0; j < c->n_limits; j++) {
- struct nlattr *nl_limit;
+ nla_nest_end(msg, nl_limits);
- nl_limit = nla_nest_start_noflag(msg, j + 1);
- if (!nl_limit)
- goto nla_put_failure;
- if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
- c->limits[j].max))
- goto nla_put_failure;
- if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
- c->limits[j].types))
- goto nla_put_failure;
- nla_nest_end(msg, nl_limit);
- }
+ if (c->beacon_int_infra_match &&
+ nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
+ goto nla_put_failure;
+ if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
+ c->num_different_channels) ||
+ nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
+ c->max_interfaces))
+ goto nla_put_failure;
+ if (large &&
+ (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
+ c->radar_detect_widths) ||
+ nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
+ c->radar_detect_regions)))
+ goto nla_put_failure;
+ if (c->beacon_int_min_gcd &&
+ nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
+ c->beacon_int_min_gcd))
+ goto nla_put_failure;
- nla_nest_end(msg, nl_limits);
+ if (large && nl80211_put_per_hw_iface_combinations(msg, c))
+ goto nla_put_failure;
- if (c->beacon_int_infra_match &&
- nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
- goto nla_put_failure;
- if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
- c->num_different_channels) ||
- nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
- c->max_interfaces))
- goto nla_put_failure;
- if (large &&
- (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
- c->radar_detect_widths) ||
- nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
- c->radar_detect_regions)))
- goto nla_put_failure;
- if (c->beacon_int_min_gcd &&
- nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
- c->beacon_int_min_gcd))
- goto nla_put_failure;
+ nla_nest_end(msg, nl_combi);
- if (large && nl80211_put_per_hw_iface_combinations(wiphy, msg, c))
- goto nla_put_failure;
+ return 0;
+nla_put_failure:
+ return -ENOBUFS;
+}
- nla_nest_end(msg, nl_combi);
- }
+static int nl80211_put_iface_combinations(struct wiphy *wiphy,
+ struct sk_buff *msg,
+ bool large)
+{
+ struct nlattr *nl_combis;
+ int i;
+
+ nl_combis = nla_nest_start_noflag(msg,
+ NL80211_ATTR_INTERFACE_COMBINATIONS);
+ if (!nl_combis)
+ goto nla_put_failure;
+
+ for (i = 0; i < wiphy->n_iface_combinations; i++)
+ if (nl80211_put_ifcomb_data(msg, large, i + 1,
+ &wiphy->iface_combinations[i]))
+ goto nla_put_failure;
nla_nest_end(msg, nl_combis);

View File

@@ -0,0 +1,356 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 9 Jul 2024 10:38:30 +0200
Subject: [PATCH] wifi: cfg80211: add support for advertising multiple radios
belonging to a wiphy
The prerequisite for MLO support in cfg80211/mac80211 is that all the links
participating in MLO must be from the same wiphy/ieee80211_hw. To meet this
expectation, some drivers may need to group multiple discrete hardware each
acting as a link in MLO under single wiphy.
With this change, supported frequencies and interface combinations of each
individual radio are reported to user space. This allows user space to figure
out the limitations of what combination of channels can be used concurrently.
Even for non-MLO devices, this improves support for devices capable of
running on multiple channels at the same time.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/18a88f9ce82b1c9f7c12f1672430eaf2bb0be295.1720514221.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5165,7 +5165,9 @@ struct ieee80211_iface_per_hw {
* struct ieee80211_iface_combination - possible interface combination
*
* With this structure the driver can describe which interface
- * combinations it supports concurrently.
+ * combinations it supports concurrently. When set in a struct wiphy_radio,
+ * the combinations refer to combinations of interfaces currently active on
+ * that radio.
*
* Examples:
*
@@ -5593,6 +5595,38 @@ struct wiphy_iftype_akm_suites {
int n_akm_suites;
};
+/**
+ * struct wiphy_radio_freq_range - wiphy frequency range
+ * @start_freq: start range edge frequency (kHz)
+ * @end_freq: end range edge frequency (kHz)
+ */
+struct wiphy_radio_freq_range {
+ u32 start_freq;
+ u32 end_freq;
+};
+
+
+/**
+ * struct wiphy_radio - physical radio of a wiphy
+ * This structure describes a physical radio belonging to a wiphy.
+ * It is used to describe concurrent-channel capabilities. Only one channel
+ * can be active on the radio described by struct wiphy_radio.
+ *
+ * @freq_range: frequency range that the radio can operate on.
+ * @n_freq_range: number of elements in @freq_range
+ *
+ * @iface_combinations: Valid interface combinations array, should not
+ * list single interface types.
+ * @n_iface_combinations: number of entries in @iface_combinations array.
+ */
+struct wiphy_radio {
+ const struct wiphy_radio_freq_range *freq_range;
+ int n_freq_range;
+
+ const struct ieee80211_iface_combination *iface_combinations;
+ int n_iface_combinations;
+};
+
#define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff
/**
@@ -5834,6 +5868,9 @@ struct ieee80211_chans_per_hw {
* for each of the underlying hw.
* @num_hw: number of underlying hw for which the channels list are advertised
* in @hw_chans.
+ *
+ * @radio: radios belonging to this wiphy
+ * @n_radio: number of radios
*/
struct wiphy {
struct mutex mtx;
@@ -5989,6 +6026,9 @@ struct wiphy {
struct ieee80211_chans_per_hw **hw_chans;
int num_hw;
+ int n_radio;
+ const struct wiphy_radio *radio;
+
char priv[] __aligned(NETDEV_ALIGN);
};
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2060,6 +2060,10 @@ enum nl80211_commands {
* @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
* interface combinations. In each nested item, it contains attributes
* defined in &enum nl80211_if_combination_attrs.
+ * If the wiphy uses multiple radios (@NL80211_ATTR_WIPHY_RADIOS is set),
+ * this attribute contains the interface combinations of the first radio.
+ * See @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS for the global wiphy
+ * combinations for the sum of all radios.
* @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
* %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
* are managed in software: interfaces of these types aren't subject to
@@ -2892,6 +2896,14 @@ enum nl80211_commands {
* value must be such that the operating bandwidth is a subset of the
* device bandwidth.
*
+ * @NL80211_ATTR_WIPHY_RADIOS: Nested attribute describing physical radios
+ * belonging to this wiphy. See &enum nl80211_wiphy_radio_attrs.
+ *
+ * @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS: Nested attribute listing the
+ * supported interface combinations for all radios combined. In each
+ * nested item, it contains attributes defined in
+ * &enum nl80211_if_combination_attrs.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3463,6 +3475,9 @@ enum nl80211_attrs {
NL80211_ATTR_CHANNEL_WIDTH_DEVICE,
NL80211_ATTR_CENTER_FREQ_DEVICE,
+ NL80211_ATTR_WIPHY_RADIOS,
+ NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -8247,4 +8262,55 @@ enum nl80211_set_cu {
NUM_NL80211_CUS = BIT(2),
};
+
+/**
+ * enum nl80211_wiphy_radio_attrs - wiphy radio attributes
+ *
+ * @__NL80211_WIPHY_RADIO_ATTR_INVALID: Invalid
+ *
+ * @NL80211_WIPHY_RADIO_ATTR_INDEX: Index of this radio (u32)
+ * @NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE: Frequency range supported by this
+ * radio. Attribute may be present multiple times.
+ * @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface
+ * combination for this radio. Attribute may be present multiple times
+ * and contains attributes defined in &enum nl80211_if_combination_attrs.
+ *
+ * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal
+ * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute
+ */
+enum nl80211_wiphy_radio_attrs {
+ __NL80211_WIPHY_RADIO_ATTR_INVALID,
+
+ NL80211_WIPHY_RADIO_ATTR_INDEX,
+ NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
+ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
+
+ /* keep last */
+ __NL80211_WIPHY_RADIO_ATTR_LAST,
+ NL80211_WIPHY_RADIO_ATTR_MAX = __NL80211_WIPHY_RADIO_ATTR_LAST - 1,
+};
+
+/**
+ * enum nl80211_wiphy_radio_freq_range - wiphy radio frequency range
+ *
+ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID: Invalid
+ *
+ * @NL80211_WIPHY_RADIO_FREQ_ATTR_START: Frequency range start (u32).
+ * The unit is kHz.
+ * @NL80211_WIPHY_RADIO_FREQ_ATTR_END: Frequency range end (u32).
+ * The unit is kHz.
+ *
+ * @__NL80211_WIPHY_RADIO_FREQ_ATTR_LAST: Internal
+ * @NL80211_WIPHY_RADIO_FREQ_ATTR_MAX: Highest attribute
+ */
+enum nl80211_wiphy_radio_freq_range {
+ __NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID,
+
+ NL80211_WIPHY_RADIO_FREQ_ATTR_START,
+ NL80211_WIPHY_RADIO_FREQ_ATTR_END,
+
+ __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST,
+ NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1,
+};
+
#endif /* __LINUX_NL80211_H */
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1758,16 +1758,18 @@ nl80211_put_per_hw_iface_combinations(st
}
static int nl80211_put_ifcomb_data(struct sk_buff *msg, bool large, int idx,
- const struct ieee80211_iface_combination *c)
+ const struct ieee80211_iface_combination *c,
+ u16 nested)
{
struct nlattr *nl_combi, *nl_limits;
int i;
- nl_combi = nla_nest_start_noflag(msg, idx);
+ nl_combi = nla_nest_start_noflag(msg, idx | nested);
if (!nl_combi)
goto nla_put_failure;
- nl_limits = nla_nest_start_noflag(msg, NL80211_IFACE_COMB_LIMITS);
+ nl_limits = nla_nest_start_noflag(msg, NL80211_IFACE_COMB_LIMITS |
+ nested);
if (!nl_limits)
goto nla_put_failure;
@@ -1818,19 +1820,26 @@ nla_put_failure:
static int nl80211_put_iface_combinations(struct wiphy *wiphy,
struct sk_buff *msg,
- bool large)
+ int attr, int radio,
+ bool large, u16 nested)
{
+ const struct ieee80211_iface_combination *c;
struct nlattr *nl_combis;
- int i;
+ int i, n;
- nl_combis = nla_nest_start_noflag(msg,
- NL80211_ATTR_INTERFACE_COMBINATIONS);
+ nl_combis = nla_nest_start_noflag(msg, attr | nested);
if (!nl_combis)
goto nla_put_failure;
- for (i = 0; i < wiphy->n_iface_combinations; i++)
- if (nl80211_put_ifcomb_data(msg, large, i + 1,
- &wiphy->iface_combinations[i]))
+ if (radio >= 0) {
+ c = wiphy->radio[0].iface_combinations;
+ n = wiphy->radio[0].n_iface_combinations;
+ } else {
+ c = wiphy->iface_combinations;
+ n = wiphy->n_iface_combinations;
+ }
+ for (i = 0; i < n; i++)
+ if (nl80211_put_ifcomb_data(msg, large, i + 1, &c[i], nested))
goto nla_put_failure;
nla_nest_end(msg, nl_combis);
@@ -2599,6 +2608,80 @@ nl80211_put_ru_punct_supp_bw(struct cfg8
return 0;
}
+static int nl80211_put_radio(struct wiphy *wiphy, struct sk_buff *msg, int idx)
+{
+ const struct wiphy_radio *r = &wiphy->radio[idx];
+ struct nlattr *radio, *freq;
+ int i;
+
+ radio = nla_nest_start(msg, idx);
+ if (!radio)
+ return -ENOBUFS;
+
+ if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx))
+ goto nla_put_failure;
+
+ for (i = 0; i < r->n_freq_range; i++) {
+ const struct wiphy_radio_freq_range *range = &r->freq_range[i];
+
+ freq = nla_nest_start(msg, NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE);
+ if (!freq)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_WIPHY_RADIO_FREQ_ATTR_START,
+ range->start_freq) ||
+ nla_put_u32(msg, NL80211_WIPHY_RADIO_FREQ_ATTR_END,
+ range->end_freq))
+ goto nla_put_failure;
+
+ nla_nest_end(msg, freq);
+ }
+
+ for (i = 0; i < r->n_iface_combinations; i++)
+ if (nl80211_put_ifcomb_data(msg, true,
+ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
+ &r->iface_combinations[i],
+ NLA_F_NESTED))
+ goto nla_put_failure;
+
+ nla_nest_end(msg, radio);
+
+ return 0;
+
+nla_put_failure:
+ return -ENOBUFS;
+}
+
+static int nl80211_put_radios(struct wiphy *wiphy, struct sk_buff *msg)
+{
+ struct nlattr *radios;
+ int i;
+
+ if (!wiphy->n_radio)
+ return 0;
+
+ radios = nla_nest_start(msg, NL80211_ATTR_WIPHY_RADIOS);
+ if (!radios)
+ return -ENOBUFS;
+
+ for (i = 0; i < wiphy->n_radio; i++)
+ if (nl80211_put_radio(wiphy, msg, i))
+ goto fail;
+
+ nla_nest_end(msg, radios);
+
+ if (nl80211_put_iface_combinations(wiphy, msg,
+ NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
+ -1, true, NLA_F_NESTED))
+ return -ENOBUFS;
+
+ return 0;
+
+fail:
+ nla_nest_cancel(msg, radios);
+ return -ENOBUFS;
+}
+
struct nl80211_dump_wiphy_state {
s64 filter_wiphy;
long start;
@@ -2894,7 +2977,9 @@ static int nl80211_send_wiphy(struct cfg
goto nla_put_failure;
if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
- state->split))
+ NL80211_ATTR_INTERFACE_COMBINATIONS,
+ rdev->wiphy.n_radio ? 0 : -1,
+ state->split, 0))
goto nla_put_failure;
state->split_start++;
@@ -3211,10 +3296,16 @@ static int nl80211_send_wiphy(struct cfg
if (nl80211_put_ru_punct_supp_bw(rdev, msg))
goto nla_put_failure;
+ state->split_start++;
+ break;
+ case 17:
+ if (nl80211_put_radios(&rdev->wiphy, msg))
+ goto nla_put_failure;
+
/* done */
state->split_start++;
break;
- case 17:
+ case 18:
if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_MLO)
nla_put_flag(msg, NL80211_ATTR_MLO_SUPPORT);
if (nl80211_put_multi_hw_support(&rdev->wiphy, msg))

View File

@@ -0,0 +1,95 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 9 Jul 2024 10:38:32 +0200
Subject: [PATCH] wifi: cfg80211: add helper for checking if a chandef is valid
on a radio
Check if the full channel width is in the radio's frequency range.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/7c8ea146feb6f37cee62e5ba6be5370403695797.1720514221.git-series.nbd@nbd.name
[add missing Return: documentation]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6707,6 +6707,17 @@ static inline bool cfg80211_channel_is_p
}
/**
+ * cfg80211_radio_chandef_valid - Check if the radio supports the chandef
+ *
+ * @radio: wiphy radio
+ * @chandef: chandef for current channel
+ *
+ * Return: whether or not the given chandef is valid for the given radio
+ */
+bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
+ const struct cfg80211_chan_def *chandef);
+
+/**
* ieee80211_get_response_rate - get basic rate for a given rate
*
* @sband: the band to look for rates in
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -3044,3 +3044,38 @@ cfg80211_hw_chans_includes_dfs(const str
return false;
}
EXPORT_SYMBOL(cfg80211_hw_chans_includes_dfs);
+
+static bool
+ieee80211_radio_freq_range_valid(const struct wiphy_radio *radio,
+ u32 freq, u32 width)
+{
+ const struct wiphy_radio_freq_range *r;
+ int i;
+
+ for (i = 0; i < radio->n_freq_range; i++) {
+ r = &radio->freq_range[i];
+ if (freq - width / 2 >= r->start_freq &&
+ freq + width / 2 <= r->end_freq)
+ return true;
+ }
+
+ return false;
+}
+
+bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
+ const struct cfg80211_chan_def *chandef)
+{
+ u32 freq, width;
+
+ freq = ieee80211_chandef_to_khz(chandef);
+ width = nl80211_chan_width_to_mhz(chandef->width);
+ if (!ieee80211_radio_freq_range_valid(radio, freq, width))
+ return false;
+
+ freq = MHZ_TO_KHZ(chandef->center_freq2);
+ if (freq && !ieee80211_radio_freq_range_valid(radio, freq, width))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(cfg80211_radio_chandef_valid);
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -151,7 +151,7 @@ static bool cfg80211_edmg_chandef_valid(
return true;
}
-static int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
+int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
{
int mhz;
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -519,6 +519,7 @@ static inline unsigned int elapsed_jiffi
return jiffies_to_msecs(end + (ULONG_MAX - start) + 1);
}
+int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width);
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
struct cfg80211_chan_def *chandef);

View File

@@ -0,0 +1,301 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Wed, 9 Oct 2024 10:25:42 +0200
Subject: [PATCH] wifi: cfg80211: add option for vif allowed radios
This allows users to prevent a vif from affecting radios other than the
configured ones. This can be useful in cases where e.g. an AP is running
on one radio, and triggering a scan on another radio should not disturb it.
Changing the allowed radios list for a vif is supported, but only while
it is down.
While it is possible to achieve the same by always explicitly specifying
a frequency list for scan requests and ensuring that the wrong channel/band
is never accidentally set on an unrelated interface, this change makes
multi-radio wiphy setups a lot easier to deal with for CLI users.
By itself, this patch only enforces the radio mask for scanning requests
and remain-on-channel. Follow-up changes build on this to limit configured
frequencies.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/eefcb218780f71a1549875d149f1196486762756.1728462320.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2904,6 +2904,9 @@ enum nl80211_commands {
* nested item, it contains attributes defined in
* &enum nl80211_if_combination_attrs.
*
+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
+ * A value of 0 means all radios.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3478,6 +3481,8 @@ enum nl80211_attrs {
NL80211_ATTR_WIPHY_RADIOS,
NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
+ NL80211_ATTR_VIF_RADIO_MASK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1618,6 +1618,8 @@ void cfg80211_init_wdev(struct wireless_
/* allow mac80211 to determine the timeout */
wdev->ps_timeout = -1;
+ wdev->radio_mask = BIT(wdev->wiphy->n_radio) - 1;
+
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -890,6 +890,7 @@ static const struct nla_policy nl80211_p
[NL80211_ATTR_SET_CRITICAL_UPDATE] = { .type = NLA_U8 },
[NL80211_ATTR_CHANNEL_WIDTH_DEVICE] = { .type = NLA_U32 },
[NL80211_ATTR_CENTER_FREQ_DEVICE] = { .type = NLA_U32 },
+ [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -4372,7 +4373,8 @@ static int nl80211_send_iface(struct sk_
nla_put_u32(msg, NL80211_ATTR_GENERATION,
rdev->devlist_generation ^
(cfg80211_rdev_list_generation << 2)) ||
- nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
+ nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr) ||
+ nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, wdev->radio_mask))
goto nla_put_failure;
wdev_lock(wdev);
@@ -4695,6 +4697,29 @@ static int nl80211_valid_4addr(struct cf
return -EOPNOTSUPP;
}
+static int nl80211_parse_vif_radio_mask(struct genl_info *info,
+ u32 *radio_mask)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct nlattr *attr = info->attrs[NL80211_ATTR_VIF_RADIO_MASK];
+ u32 mask, allowed;
+
+ if (!attr) {
+ *radio_mask = 0;
+ return 0;
+ }
+
+ allowed = BIT(rdev->wiphy.n_radio) - 1;
+ mask = nla_get_u32(attr);
+ if (mask & ~allowed)
+ return -EINVAL;
+ if (!mask)
+ mask = allowed;
+ *radio_mask = mask;
+
+ return 1;
+}
+
static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4702,6 +4727,8 @@ static int nl80211_set_interface(struct
int err;
enum nl80211_iftype otype, ntype;
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ u32 radio_mask = 0;
bool change = false;
memset(&params, 0, sizeof(params));
@@ -4715,8 +4742,6 @@ static int nl80211_set_interface(struct
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
-
if (ntype != NL80211_IFTYPE_MESH_POINT)
return -EINVAL;
if (netif_running(dev))
@@ -4760,6 +4785,12 @@ static int nl80211_set_interface(struct
if (err > 0)
change = true;
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+ if (err < 0)
+ return err;
+ if (err && netif_running(dev))
+ return -EBUSY;
+
if (change)
err = cfg80211_change_iface(rdev, dev, ntype, &params);
else
@@ -4768,11 +4799,11 @@ static int nl80211_set_interface(struct
if (!err && params.use_4addr != -1)
dev->ieee80211_ptr->use_4addr = params.use_4addr;
- if (change && !err) {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
+ if (radio_mask)
+ wdev->radio_mask = radio_mask;
+ if (change && !err)
nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
- }
return err;
}
@@ -4783,6 +4814,7 @@ static int _nl80211_new_interface(struct
struct vif_params params;
struct wireless_dev *wdev;
struct sk_buff *msg;
+ u32 radio_mask;
int err;
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -4820,6 +4852,10 @@ static int _nl80211_new_interface(struct
if (err < 0)
return err;
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+ if (err < 0)
+ return err;
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -4865,6 +4901,9 @@ static int _nl80211_new_interface(struct
break;
}
+ if (radio_mask)
+ wdev->radio_mask = radio_mask;
+
if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
nlmsg_free(msg);
@@ -10189,7 +10228,8 @@ static int nl80211_trigger_scan(struct s
}
/* ignore disabled channels */
- if (chan->flags & IEEE80211_CHAN_DISABLED)
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(wdev, chan))
continue;
request->channels[i] = chan;
@@ -10692,7 +10732,8 @@ nl80211_parse_sched_scan(struct wiphy *w
chan = &wiphy->bands[band]->channels[j];
- if (chan->flags & IEEE80211_CHAN_DISABLED)
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(wdev, chan))
continue;
request->channels[i] = chan;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6399,6 +6399,7 @@ void wiphy_delayed_work_cancel(struct wi
* @links[].switch_count: CSA/CCA count for the bss
* @valid_links: bitmap describing what elements of @links are valid
* @critical_update: critical params updated on anyone wdev link
+ * @radio_mask: Bitmask of radios that this interface is allowed to operate on.
*/
struct wireless_dev {
struct wiphy *wiphy;
@@ -6521,6 +6522,8 @@ struct wireless_dev {
u8 reg_6g_power_mode;
bool critical_update;
+
+ u32 radio_mask;
};
static inline const u8 *wdev_address(struct wireless_dev *wdev)
@@ -6538,6 +6541,17 @@ static inline bool wdev_running(struct w
}
/**
+ * cfg80211_wdev_channel_allowed - Check if the wdev may use the channel
+ *
+ * @wdev: the wireless device
+ * @chan: channel to check
+ *
+ * Return: whether or not the wdev may use the channel
+ */
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan);
+
+/**
* wdev_priv - return wiphy priv from wireless_dev
*
* @wdev: The wireless device whose wiphy's priv pointer to return
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -902,7 +902,8 @@ static int cfg80211_scan_6ghz(struct cfg
struct ieee80211_channel *chan =
ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
- if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
+ if (!chan || chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(rdev_req->wdev, chan))
continue;
for (i = 0; i < rdev_req->n_channels; i++) {
@@ -3181,9 +3182,12 @@ int cfg80211_wext_siwscan(struct net_dev
continue;
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+ struct ieee80211_channel *chan;
+
/* ignore disabled channels */
- if (wiphy->bands[band]->channels[j].flags &
- IEEE80211_CHAN_DISABLED)
+ chan = &wiphy->bands[band]->channels[j];
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(creq->wdev, chan))
continue;
/* If we have a wireless request structure and the
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -3079,3 +3079,32 @@ bool cfg80211_radio_chandef_valid(const
return true;
}
EXPORT_SYMBOL(cfg80211_radio_chandef_valid);
+
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ const struct wiphy_radio *radio;
+ struct cfg80211_chan_def chandef;
+ u32 radio_mask;
+ int i;
+
+ radio_mask = wdev->radio_mask;
+ if (!wiphy->n_radio || radio_mask == BIT(wiphy->n_radio) - 1)
+ return true;
+
+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
+ for (i = 0; i < wiphy->n_radio; i++) {
+ if (!(radio_mask & BIT(i)))
+ continue;
+
+ radio = &wiphy->radio[i];
+ if (!cfg80211_radio_chandef_valid(radio, &chandef))
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(cfg80211_wdev_channel_allowed);

View File

@@ -0,0 +1,65 @@
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -16666,7 +16666,7 @@ static int ath12k_setup_per_hw_if_comb(s
}
static struct ieee80211_chans_per_hw *
-ath12k_setup_per_hw_chan(struct ath12k *ar)
+ath12k_setup_per_hw_chan(struct ath12k *ar, struct wiphy_radio_freq_range *freq)
{
struct ieee80211_chans_per_hw *chans;
struct ieee80211_supported_band *band;
@@ -16705,6 +16705,9 @@ ath12k_setup_per_hw_chan(struct ath12k *
freq_high = ATH12K_MAX_6G_FREQ;
}
+ freq->start_freq = freq_low * 1000;
+ freq->end_freq = freq_high * 1000;
+
n_channels = ath12k_reg_get_num_chans_in_band(ar, band, freq_low, freq_high);
chan_sz = struct_size(chans, chans, n_channels);
chans = kzalloc(chan_sz, GFP_KERNEL);
@@ -16728,20 +16731,41 @@ static int ath12k_alloc_per_hw_chans(str
struct ieee80211_chans_per_hw **chans;
struct ath12k *ar;
struct ieee80211_hw *hw = ah->hw;
+ struct wiphy_radio *radio;
+ struct wiphy_radio_freq_range *freq;
+ struct device *dev;
int i;
+
ar = ah->radio;
+ dev = ar->ab->dev;
+ radio = devm_kcalloc(dev, ah->num_radio, sizeof(*radio), GFP_KERNEL);
+ if (!radio)
+ return -ENOMEM;
+
+ freq = devm_kcalloc(dev, ah->num_radio, sizeof(*freq), GFP_KERNEL);
+ if (!freq)
+ return -ENOMEM;
chans = kzalloc(sizeof(*chans) * ah->num_radio,
GFP_KERNEL);
if (!chans)
return -ENOMEM;
+ hw->wiphy->radio = radio;
+ hw->wiphy->n_radio = ah->num_radio;
+
for (i = 0; i < ah->num_radio; i++) {
- chans[i] = ath12k_setup_per_hw_chan(ar);
+ radio->freq_range = freq;
+ radio->n_freq_range = 1;
+ radio->iface_combinations = hw->wiphy->iface_combinations;
+ radio->n_iface_combinations = hw->wiphy->n_iface_combinations;
+
+ chans[i] = ath12k_setup_per_hw_chan(ar, freq);
if (!chans[i])
goto err_free;
ar++;
-
+ radio++;
+ freq++;
}
hw->wiphy->hw_chans = chans;
hw->wiphy->num_hw = ah->num_radio;

View File

@@ -1,38 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ath12k-firmware
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
RSTRIP:=:
STRIP:=:
define Package/ath12k-firmware-default
SECTION:=firmware
CATEGORY:=Firmware
URL:=$(PKG_SOURCE_URL)
DEPENDS:=
endef
define Package/ath12k-firmware-qcn92xx
$(Package/ath12k-firmware-default)
TITLE:=ath12k firmware for QCN92XX devices
DEPENDS:=@TARGET_ipq95xx
endef
define Package/ath12k-firmware-qcn92xx/description
Standard ath12k firmware for QCN92XX from QCA
endef
define Build/Compile
endef
define Package/ath12k-firmware-qcn92xx/install
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
$(INSTALL_DATA) ./files/QCN92XX/* \
$(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
endef
$(eval $(call BuildPackage,ath12k-firmware-qcn92xx))

View File

@@ -1,181 +0,0 @@
seq_start;
seq_type:mem_req;
sink:etr_ddr,0x1,0x400;
seq_end;
seq_start;
seq_type:mac_event_trace;
subsys_cfg_start:umac;
cxc_eb0:0x2,0x0,0x0,0x0,0x0;
reo_eb0:0x4,0x61C81F4,0x0,0x0,0x0;
tqm_eb0:0x5,0xCDB3C6C6,0x803007E0,0x0,0x0;
tcl_eb0:0x6,0x25030034,0x3000,0x0,0x0;
wbm_eb0:0x7,0x880004,0x380000,0x0,0x0;
cxc_eb1:0x8,0x0,0x0,0x0,0x0;
tcl_eb1:0x9,0x25030034,0x3000,0x0,0x0;
reo_eb1:0xA,0x61C81F4,0x0,0x0,0x0;
tqm_eb1:0xB,0xCDB3C6C6,0x803007E0,0x0,0x0;
wbm_eb1:0xC,0x880004,0x380000,0x0,0x0;
mxi:0xD,0x122234,0x0,0x0,0x0;
wsib:0xE,0x0,0x0,0x0,0x0;
memw:0x0;
subsys_cfg_end:umac;
subsys_cfg_start:dmac;
swevt:0x0,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000;
txdma_eb0:0x1,0x200,0x0,0x0,0x0;
txdma_eb1:0x2,0xD9220,0xAF0,0x0,0x0;
txdma_eb2:0x3,0xD9220,0xAF0,0x0,0x0;
rxdma_eb0:0x4,0x93297E3F,0xC00000,0x0,0x0;
rxdma_eb1:0x5,0x707F,0x0,0x0,0x0;
txole_eb0:0x6,0xFFFFFFFF,0x0,0x0,0x0;
txole_eb1:0x7,0x781F0734,0x6,0x0,0x0;
txole_eb2:0x8,0x781F0734,0x6,0x0,0x0;
rxole_eb0:0x9,0xF,0x0,0x0,0x0;
rxole_eb1:0xA,0x7F,0x0,0x0,0x0;
rxole_eb2:0xB,0x7F,0x0,0x0,0x0;
crypto:0xC,0xFF3FFF,0x0,0x0,0x0;
mxi:0xD,0x122234,0x0,0x0,0x0;
sfm_eb0:0xE,0x40000003,0x7F8,0x0,0x0;
rxmon_eb0:0x14,0x22800010,0x40A00,0x0,0x0;
rxmon_eb1:0x15,0x18005000,0x18,0x0,0x0;
txmon_eb0:0x12,0x22800010,0x40A00,0x0,0x0;
txmon_eb1:0x13,0x98005000,0x199,0x0,0x0;
memw:0x0;
subsys_cfg_end:dmac;
subsys_cfg_start:pmac0;
swevt:0x0,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000;
hwsch:0x1,0x803FFFF7,0x30003,0x0,0x0;
pdg:0x2,0xE430F87,0x622856E,0x0,0x0;
txpcu_eb0:0x8,0xE87A047,0x132,0x0,0x0;
rxpcu_eb0:0x9,0x10060217,0x1F24500,0x0,0x0;
rri:0xa,0x0,0x0,0x0,0x0;
ampi:0xb,0x69C07,0x0,0x0,0x0;
mxi:0xd,0x122234,0x0,0x0,0x0;
txpcu_eb1:0x10,0x0,0x0,0x0,0x0;
sfm_eb1:0x12,0x40000003,0x7F8,0x0,0x0;
rxpcu_eb1:0x13,0x0,0x0,0x0,0x0;
hwmlo:0x1c,0x1C100004,0x0,0x0,0x0;
memw:0x0;
subsys_cfg_end:pmac0;
subsys_cfg_start:pmac1;
swevt:0x0,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000;
hwsch:0x1,0x803FFFF7,0x30003,0x0,0x0;
pdg:0x2,0xE430F87,0x622856E,0x0,0x0;
txpcu_eb0:0x8,0xE87A047,0x132,0x0,0x0;
rxpcu_eb0:0x9,0x10060217,0x1F24500,0x0,0x0;
rri:0xa,0x0,0x0,0x0,0x0;
ampi:0xb,0x69C07,0x0,0x0,0x0;
mxi:0xd,0x122234,0x0,0x0,0x0;
txpcu_eb1:0x10,0x0,0x0,0x0,0x0;
sfm_eb1:0x12,0x40000003,0x7F8,0x0,0x0;
rxpcu_eb1:0x13,0x0,0x0,0x0,0x0;
hwmlo:0x1c,0x1C100004,0x0,0x0,0x0;
memw:0x0;
subsys_cfg_end:pmac1;
seq_end;
seq_start;
seq_type:phy_event_trace;
subsys_cfg_start:phya0;
data_tlv:0;
wsi:0x0,0x00000000,0x00000000;
rfcntl:0x0,0x00000000,0x00000000;
tpc:0x0,0x00000000,0x00000000;
cal:0x0,0x00000000,0x00000000;
impcorr:0x0,0x00000000,0x00000000;
mpi:0x6,0x00000006,0x00000000;
fft:0x0,0x00000000,0x00000000;
txtd:0x0,0x00000000,0x00000000;
pmi:0x9,0x0000000A,0x00000000;
rxtd:0xa,0x0000000A,0x00000000;
demfront:0x0,0x00000000,0x00000000;
pcss:0xc,0x0000003E,0x00000000;
txfd:0x0,0x00000000,0x00000000;
robe:0x0,0x00000000,0x00000000;
dmac_0_1:0x0,0x00000000,0x00000000;
dmac_2_3:0x0,0x00000000,0x00000000;
dmac_4_5:0x0,0x00000000,0x00000000;
dmac_6:0x0,0x00000000,0x00000000;
eos:0x0,0x00000000,0x00000000;
subsys_cfg_end:phya0;
//subsys_cfg_start:phya1;
//data_tlv:1;
//wsi:0x0,0x00000000,0x00000000;
//rfcntl:0x0,0x00000000,0x00000000;
//tpc:0x0,0x00000000,0x00000000;
//cal:0x0,0x00000000,0x00000000;
//impcorr:0x0,0x00000000,0x00000000;
//mpi:0x6,0x00000006,0x00000000;
//fft:0x0,0x00000000,0x00000000;
//txtd:0x0,0x00000000,0x00000000;
//pmi:0x9,0x0000000A,0x00000000;
//rxtd:0xa,0x0000000A,0x00000000;
//demfront:0x0,0x00000000,0x00000000;
//pcss:0xc,0x0000003E,0x00000000;
//txfd:0x0,0x00000000,0x00000000;
//robe:0x0,0x00000000,0x00000000;
//dmac_0_1:0x0,0x00000000,0x00000000;
//dmac_2_3:0x0,0x00000000,0x00000000;
//dmac_4_5:0x0,0x00000000,0x00000000;
//dmac_6:0x0,0x00000000,0x00000000;
//eos:0x0,0x00000000,0x00000000;
//subsys_cfg_end:phya1;
seq_end;
//seq_start;
//seq_type:noc_trace;
//noc_id:umacnoc;
//syncoutperiod:0x1F;
//probe_id:0x0;
//probe_type:0x2;
//probe_andinv:0x0;
//probe_portsel:0x1;
//filter0_path:0x0;
//filter0_path_mask:0x0;
//filter0_addr_min_lo:0x0;
//filter0_addr_min_hi:0x0;
//filter0_addr_max_lo:0xFFFFFFFF;
//filter0_addr_max_hi:0xF;
//filter0_opcode:0x3;
//filter0_status:0x3;
//filter0_trtype:0x0;
//filter0_extid:0x0;
//filter0_extid_mask:0x0;
//filter1_path:0x0;
//filter1_path_mask:0x0;
//filter1_addr_min_lo:0x0;
//filter1_addr_min_hi:0x0;
//filter1_addr_max_lo:0xFFFFFFFF;
//filter1_addr_max_hi:0xF;
//filter1_opcode:0x3;
//filter1_status:0x3;
//filter1_trtype:0x0;
//filter1_extid:0x0;
//filter1_extid_mask:0x0;
//seq_end;
//seq_start;
//seq_type:mac_tlv_trace;
//subsys_cfg_start:pmac0;
//tlv_port:tqm_hwsch_tlv;
//tlv_config:tlv_type,other_tlv,specific_tlv,data_tlv;
//tlv_config:1,3,3,3;
//memw:0x2,0x10220A0,0xFFFFFDFF,0x10220B0,0x7FFFFFFF;
//subsys_cfg_end:pmac0;
//seq_end;
//seq_start;
//seq_start;
//seq_type:mac_tlv_trace;
//subsys_cfg_start:pmac1;
//tlv_port:tqm_hwsch_tlv;
//tlv_config:tlv_type,other_tlv,specific_tlv,data_tlv;
//tlv_config:1,3,3,3;
//memw:0x2,0x10220A0,0xFFFFFDFF,0x10220B0,0x7FFFFFFF;
//subsys_cfg_end:pmac1;
//seq_end;
//seq_start;
//seq_type:mac_obo_trace;
//subsys_cfg_start:pmac0;
//tbus_port:pdg_testbus, 0x7;
//memw:0x0;
//subsys_cfg_end:pmac0;
//seq_end;
//seq_start;
//seq_type:irq_trace;
//seq_end;

View File

@@ -1,47 +0,0 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/version.mk
PKG_NAME:=ath12k-wifi
PKG_RELEASE:=1
PKG_FLAGS:=nonshared
include $(INCLUDE_DIR)/package.mk
RSTRIP:=:
STRIP:=:
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
define Build/Compile
endef
#
# This is intended to be used on an interim basis until device-specific
# board data for new devices is available through the upstream compilation
#
# Please send a mail with your device-specific board files upstream.
# You can find instructions and examples on the linux-wireless wiki:
# <https://wireless.wiki.kernel.org/en/users/drivers/ath10k/boardfiles>
#
define Package/ath12k-wifi-default
SUBMENU:=ath12k Board-Specific Overrides
SECTION:=firmware
CATEGORY:=Firmware
DEPENDS:=@TARGET_ipq95xx
TITLE:=Custom Board
endef
define Package/ath12k-wifi-qcom-qcn92xx
$(call Package/ath12k-wifi-default)
TITLE:=board-2.bin for QCOM QCN92XX eval kits
endef
define Package/ath12k-wifi-qcom-qcn92xx/install
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
$(INSTALL_DATA) ./board-2.bin.QCN92XX $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/board-2.bin
endef
$(eval $(call BuildPackage,ath12k-wifi-qcom-qcn92xx))

Some files were not shown because too many files have changed in this diff Show More