[rdkb][common][bsp][Refactor ucode related parts]

[Description]
Refactor ucode related parts

[Release-log]

Change-Id: I76db3a59ea1a2c92441829e5911d078d6fab72a1
diff --git a/recipes-wifi/hostapd/files/hostapd.uc b/recipes-wifi/hostapd/files/hostapd.uc
index 593840c..163d619 100644
--- a/recipes-wifi/hostapd/files/hostapd.uc
+++ b/recipes-wifi/hostapd/files/hostapd.uc
@@ -60,6 +60,7 @@
 function iface_freq_info(iface, config, params)
 {
 	let freq = params.frequency;
+	let bw320_offset = params.bw320_offset;
 	if (!freq)
 		return null;
 
@@ -68,25 +69,29 @@
 		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;
-		}
+	if (params.ch_width >= 0){
+		width = params.ch_width;
+	} else {
+		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;
+			let val = match(line, /^(vht_oper_chwidth|he_oper_chwidth|eht_oper_chwidth)=(\d+)/);
+			if (!val)
+				continue;
 
-		val = int(val[2]);
-		if (val > width)
-			width = val;
+			val = int(val[2]);
+			if (val > width)
+				width = val;
+		}
 	}
 
 	if (freq < 4000)
 		width = 0;
 
-	return hostapd.freq_info(freq, sec_offset, width);
+	return hostapd.freq_info(freq, sec_offset, width, bw320_offset);
 }
 
 function iface_add(phy, config, phy_status)
@@ -278,12 +283,12 @@
 		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 iface_name = old_config.bss[0].ifname;
 	let first_bss = hostapd.bss[iface_name];
 	if (!first_bss) {
 		hostapd.printf(`Could not find bss of previous interface ${iface_name}`);
@@ -658,6 +663,8 @@
 			up: true,
 			frequency: 0,
 			sec_chan_offset: 0,
+			ch_width: -1,
+			bw320_offset: 1,
 			csa: true,
 			csa_count: 0,
 		},
@@ -665,6 +672,15 @@
 			if (req.args.up == null || !req.args.phy)
 				return libubus.STATUS_INVALID_ARGUMENT;
 
+			hostapd.printf(`ucode: mtk: apsta state update`);
+			hostapd.printf(`    * phy: ${req.args.phy}`);
+			hostapd.printf(`    * up: ${req.args.up}`);
+			hostapd.printf(`    * freqeuncy: ${req.args.frequency}`);
+			hostapd.printf(`    * sec_chan_offset: ${req.args.sec_chan_offset}`);
+			hostapd.printf(`    * ch_width: ${req.args.ch_width}`);
+			hostapd.printf(`    * bw320_offset: ${req.args.bw320_offset}`);
+			hostapd.printf(`    * csa: ${req.args.csa}`);
+
 			let phy = req.args.phy;
 			let config = hostapd.data.config[phy];
 			if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname)
@@ -784,6 +800,7 @@
 
 hostapd.data.ubus = ubus;
 hostapd.data.obj = ubus.publish("hostapd", main_obj);
+hostapd.udebug_set("hostapd", hostapd.data.ubus);
 
 function bss_event(type, name, data) {
 	let ubus = hostapd.data.ubus;
@@ -798,6 +815,7 @@
 	shutdown: function() {
 		for (let phy in hostapd.data.config)
 			iface_set_config(phy, null);
+		hostapd.udebug_set(null);
 		hostapd.ubus.disconnect();
 	},
 	bss_add: function(name, obj) {
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/common.uc b/recipes-wifi/hostapd/files/src-2.10.3/common.uc
deleted file mode 100644
index 4c33779..0000000
--- a/recipes-wifi/hostapd/files/src-2.10.3/common.uc
+++ /dev/null
@@ -1,373 +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,
-};
-
-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 });
-}
-
-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 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}`));
-}
-
-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, wdev_set_mesh_params, wdev_set_up, is_equal, vlist_new, phy_is_fullmac, phy_open };
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/hostapd.uc b/recipes-wifi/hostapd/files/src-2.10.3/hostapd.uc
deleted file mode 100644
index b85f523..0000000
--- a/recipes-wifi/hostapd/files/src-2.10.3/hostapd.uc
+++ /dev/null
@@ -1,814 +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();
-
-hostapd.data.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.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
-}
-
-function iface_restart(phydev, config, old_config)
-{
-	let phy = phydev.name;
-
-	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_update_supplicant_macaddr(phy, config);
-
-	let bss = config.bss[0];
-	let err = wdev_create(phy, bss.ifname, { mode: "ap" });
-	if (err)
-		hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
-
-	let ubus = hostapd.data.ubus;
-	let phy_status = ubus.call("wpa_supplicant", "phy_status", { phy: phy });
-	if (phy_status && phy_status.state == "COMPLETED") {
-		if (iface_add(phy, config, phy_status))
-			return;
-
-		hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
-	}
-
-	ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
-	if (!iface_add(phy, config))
-		hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
-	ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
-}
-
-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 (!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);
-
-			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);
-hostapd.udebug_set("hostapd", hostapd.data.ubus);
-
-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.udebug_set(null);
-		hostapd.ubus.disconnect();
-	},
-	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);
-	}
-};
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/wdev.uc b/recipes-wifi/hostapd/files/src-2.10.3/wdev.uc
deleted file mode 100644
index ff4d629..0000000
--- a/recipes-wifi/hostapd/files/src-2.10.3/wdev.uc
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env ucode
-'use strict';
-import { vlist_new, is_equal, wdev_create, 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 command = shift(ARGV);
-let phydev;
-
-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`)) {
-		wdev_set_up(ifname, false);
-		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);
-	wdev_set_up(ifname, true);
-	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);
-
-		wdev_set_mesh_params(ifname, wdev);
-	}
-}
-
-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);
diff --git a/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant.uc b/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant.uc
deleted file mode 100644
index 1709bb0..0000000
--- a/recipes-wifi/hostapd/files/src-2.10.3/wpa_supplicant.uc
+++ /dev/null
@@ -1,349 +0,0 @@
-let libubus = require("ubus");
-import { open, readfile } from "fs";
-import { wdev_create, wdev_set_mesh_params, wdev_remove, is_equal, wdev_set_up, 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}`);
-	wdev_set_up(ifname, true);
-	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);
-wpas.udebug_set("wpa_supplicant", wpas.data.ubus);
-
-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);
-
-		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];
-		if (!phy) {
-			wpas.printf(`no PHY for ifname ${ifname}`);
-			return;
-		}
-
-		if (ev == "CH_SWITCH_STARTED")
-			iface_channel_switch(phy, ifname, iface, info);
-	}
-};
diff --git a/recipes-wifi/hostapd/files/wpa_supplicant.uc b/recipes-wifi/hostapd/files/wpa_supplicant.uc
index d624f27..e320330 100644
--- a/recipes-wifi/hostapd/files/wpa_supplicant.uc
+++ b/recipes-wifi/hostapd/files/wpa_supplicant.uc
@@ -246,6 +246,7 @@
 
 wpas.data.ubus = ubus;
 wpas.data.obj = ubus.publish("wpa_supplicant", main_obj);
+wpas.udebug_set("wpa_supplicant", wpas.data.ubus);
 
 function iface_event(type, name, data) {
 	let ubus = wpas.data.ubus;
@@ -262,6 +263,7 @@
 	let status = iface.status();
 	let msg = { phy: phy };
 
+	wpas.printf(`ucode: mtk: wpa_s in state ${state} notifies hostapd`);
 	switch (state) {
 	case "DISCONNECTED":
 	case "AUTHENTICATING":
@@ -276,6 +278,8 @@
 		msg.up = true;
 		msg.frequency = status.frequency;
 		msg.sec_chan_offset = status.sec_chan_offset;
+		msg.ch_width = status.ch_width;
+		msg.bw320_offset = status.bw320_offset;
 		break;
 	default:
 		return;
@@ -292,6 +296,8 @@
 		csa: true,
 		csa_count: info.csa_count ? info.csa_count - 1 : 0,
 		frequency: info.frequency,
+		ch_width: info.ch_width,
+		bw320_offset: info.bw320_offset,
 		sec_chan_offset: info.sec_chan_offset,
 	};
 	ubus.call("hostapd", "apsta_state", msg);
diff --git a/recipes-wifi/hostapd/hostapd_2.10.3.bb b/recipes-wifi/hostapd/hostapd_2.10.3.bb
index 02af874..649df23 100644
--- a/recipes-wifi/hostapd/hostapd_2.10.3.bb
+++ b/recipes-wifi/hostapd/hostapd_2.10.3.bb
@@ -7,7 +7,7 @@
 DEPENDS = "libnl-tiny openssl ubus ucode udebug"
 DEPENDS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'telemetry2_0', 'telemetry', '', d)}"
 LDFLAGS_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'telemetry2_0', ' -ltelemetry_msgsender ', '', d)}"
-RDEPENDS_${PN} += "gawk ucode"
+RDEPENDS_${PN} += "gawk ucode udebug"
 
 FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
 FILESEXTRAPATHS_prepend := "${THISDIR}/files/patches-${PV}:"
diff --git a/recipes-wifi/ucode/ucode_git.bb b/recipes-wifi/ucode/ucode_git.bb
index 219806e..0a7ceef 100644
--- a/recipes-wifi/ucode/ucode_git.bb
+++ b/recipes-wifi/ucode/ucode_git.bb
@@ -9,7 +9,7 @@
     file://0001-change-cmakelist.patch \
 "
 
-SRCREV = "a6e75e02528e36f3610a7f0073453018336def2e"
+SRCREV = "6e89b89e95bbb140bbff5ab72b8c9632727bf6a6"
 PV = "git${SRCPV}"
 
 S = "${WORKDIR}/git"
diff --git a/recipes-wifi/udebug/Makefile b/recipes-wifi/udebug/Makefile
deleted file mode 100644
index 0a54515..0000000
--- a/recipes-wifi/udebug/Makefile
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Copyright (C) 2023 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=udebug
-CMAKE_INSTALL:=1
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL=$(PROJECT_GIT)/project/udebug.git
-PKG_MIRROR_HASH:=553a58a14b59dc7b22755557acbc74f0655a431442a4faca56d28cdb1ef14fb4
-PKG_SOURCE_DATE:=2023-12-06
-PKG_SOURCE_VERSION:=6d3f51f9fda706f0cf4732c762e4dbe8c21e12cf
-PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
-
-PKG_LICENSE:=GPL-2.0
-PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
-
-include $(INCLUDE_DIR)/package.mk
-include $(INCLUDE_DIR)/cmake.mk
-
-define Package/libudebug
-  SECTION:=libs
-  CATEGORY:=Libraries
-  TITLE:=udebug client library
-  DEPENDS:=+libubox +libubus
-endef
-
-define Package/udebugd
-  SECTION:=utils
-  CATEGORY:=Utilities
-  TITLE:=OpenWrt debug service
-  DEPENDS:=+libudebug
-endef
-
-define Package/udebugd/conffiles
-/etc/config/udebug
-endef
-
-define Package/ucode-mod-udebug
-  SECTION:=utils
-  CATEGORY:=Utilities
-  TITLE:=ucode udebug module
-  DEPENDS:=+libucode +libudebug
-endef
-
-define Package/udebug-cli
-  SECTION:=utils
-  CATEGORY:=Utilities
-  TITLE:=OpenWrt debug service CLI
-  DEPENDS:=+udebugd +ucode-mod-udebug
-endef
-
-define Package/libudebug/install
-	$(INSTALL_DIR) $(1)/usr/lib
-	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib
-endef
-
-define Package/ucode-mod-udebug/install
-	$(INSTALL_DIR) $(1)/usr/lib/ucode
-	$(CP) $(PKG_INSTALL_DIR)/usr/lib/ucode/*.so $(1)/usr/lib/ucode
-endef
-
-define Package/udebugd/install
-	$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config
-	$(INSTALL_BIN) ./files/udebug.config $(1)/etc/config/udebug
-	$(INSTALL_BIN) ./files/udebug.init $(1)/etc/init.d/udebug
-	$(CP) $(PKG_INSTALL_DIR)/usr/sbin/udebugd $(1)/usr/sbin
-endef
-
-define Package/udebug-cli/install
-	$(INSTALL_DIR) $(1)/usr/sbin
-	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/udebug-cli $(1)/usr/sbin/udebug
-endef
-
-$(eval $(call BuildPackage,libudebug))
-$(eval $(call BuildPackage,udebugd))
-$(eval $(call BuildPackage,ucode-mod-udebug))
-$(eval $(call BuildPackage,udebug-cli))
diff --git a/recipes-wifi/udebug/udebug_git.bb b/recipes-wifi/udebug/udebug_git.bb
index 71228f2..614e3a0 100644
--- a/recipes-wifi/udebug/udebug_git.bb
+++ b/recipes-wifi/udebug/udebug_git.bb
@@ -22,7 +22,7 @@
 FILES_SOLIBSDEV = ""
 
 FILES_${PN}-dev = "${includedir}/*"
-FILES_${PN} = "${bindir}/* ${libdir}/*.so* ${libdir}/ucode/*"
+FILES_${PN} = "${sbindir}/* ${libdir}/*.so* ${libdir}/ucode/*"
 
 inherit cmake pkgconfig python3native