[rdkb][common][bsp][Refactor and sync wifi from openwrt]

[Description]
a05cc330 [MAC80211][WiFi6][mt76][rebase patches]
4bd6fb05 [MAC80211][WiFi6][mt76][Support spatial reuse debug commands]
f59fb1fe [MAC80211][WiFi7][misc][Add wifi-scripts packages]
52ac14cd [MAC80211][WiFi6][hostapd][Fix DFS radar trigger issue during first setup CAC]
7e33638a [MAC80211][WiFi6][Rebase Patches][Fix patch fail on mt76-2024-02-04]
b81d400b [MAC80211][Rebase Patches][Add support for WMM PBC configuration]
6e1f46b8 [MAC80211][WiFi6][mt76][Add support for WMM PBC configuration]
4a12d531 [mac80211][wifi6][mt76][Remove revert patch and add sanity check]
46c5e65d [mac80211][wifi6][mt76][Fix tx statistics]
d9b7c50d [MAC80211][WiFi6][mt76][Fix patch fail]
c8c49a13 [MAC80211][WiFi6][mt76][Add no_beacon vendor command for cert]
620200d9 [MAC80211][WiFi6][mt76][Remove redundant argument in add_beacon function]
f5fe56a6 [MAC80211][WiFi6][hostapd][New support for single BSS operations]
ff6e20a8 [MAC80211][WiFi6][hostapd][ACS: remove chan/freq list check when scan request and factor calculation]
3f25a0e5 [MAC80211][WiFi6][mt76][Fix bug in VoW DebugFS command]
33cb7faf [MAC80211][WiFi6][core][Sync wifi7 cert SQC fix to wifi6]
3a1c492a [MAC80211][WiFi6][core][Add support for scan dwell time customization]
7e7a47e4 [mac80211][wifi6][mt76][Fix patch fail]
5fc4c9d6 [MAC80211][misc][Fix external build fail of MAC80211]
b5d42444 [mac80211][wifi6][mt76][add support for realtime Rx rate updates]
638298f6 [mac80211][WiFi7][misc][Fix patch fail]
5c710bc2 [MAC80211][WiFi6][mt76][Add efuse content dump for cal free data verification]

[Release-log]

Change-Id: Ia86a987807efb6f1ef119e2e46232ce08afca96e
diff --git a/recipes-wifi/hostapd/files/hostapd.uc b/recipes-wifi/hostapd/files/hostapd.uc
index 163d619..72209ea 100644
--- a/recipes-wifi/hostapd/files/hostapd.uc
+++ b/recipes-wifi/hostapd/files/hostapd.uc
@@ -2,9 +2,10 @@
 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();
+let ubus = libubus.connect(null, 60);
 
 hostapd.data.config = {};
+hostapd.data.pending_config = {};
 
 hostapd.data.file_fields = {
 	vlan_file: true,
@@ -132,12 +133,114 @@
 	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 });
+	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);
@@ -155,26 +258,7 @@
 			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 });
+	iface_pending_init(phydev, config);
 }
 
 function array_to_obj(arr, key, start)
@@ -279,6 +363,9 @@
 	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;