driver->hapd_deinit(drv_priv);
} else if (hostapd_mld_is_first_bss(iface->bss[0]) &&
driver->is_drv_shared &&
- !driver->is_drv_shared(drv_priv)) {
+ !driver->is_drv_shared(drv_priv,
+ iface->bss[0]->mld_link_id)) {
driver->hapd_deinit(drv_priv);
hostapd_mld_interface_freed(iface->bss[0]);
} else if (hostapd_if_link_remove(iface->bss[0],
/**
* is_drv_shared - Check whether the driver interface is shared
* @priv: Private driver interface data from init()
+ * @link_id: Link ID to match
+ * Returns: true if it is being used or else false.
*
* Checks whether the driver interface is being used by other partner
* BSS(s) or not. This is used to decide whether the driver interface
* needs to be deinitilized when one interface is getting deinitialized.
*
- * Returns: true if it is being used or else false.
+ * NOTE: @link_id will be used only when there is only one BSS
+ * present and if that single link is active. In that case, the
+ * link ID is matched with the active link_id to decide whether the
+ * driver interface is being used by other partner BSS(s).
*/
- bool (*is_drv_shared)(void *priv);
+ bool (*is_drv_shared)(void *priv, int link_id);
/**
* link_sta_remove - Remove a link STA from an MLD STA
}
-static bool nl80211_is_drv_shared(void *priv)
+static bool nl80211_is_drv_shared(void *priv, int link_id)
{
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
- unsigned int num_bss = 0;
+ unsigned int num_bss = 0, num_links = 0;
+ bool self = false;
+ u8 i;
/* If any other BSS exist, someone else is using this since at this
* time, we would have removed all BSSs created by this driver and only
/* This is the only BSS present */
bss = priv;
- /* If only one/no link is there no one is sharing */
- if (bss->valid_links <= 1)
+ for_each_link(bss->valid_links, i) {
+ num_links++;
+ if (i == link_id)
+ self = true;
+ }
+
+ /* More than one links means some one is still sharing */
+ if (num_links > 1)
+ return true;
+
+ /* Even if only one link is there, it should match the given
+ * link ID to assert that no one else is sharing. */
+ if (num_links == 1 && self)
return false;
- /* More than one link means someone is still using. To check if
- * only 1 bit is set, power of 2 condition can be checked. */
- if (!(bss->valid_links & (bss->valid_links - 1)))
+ /* No links are active means no one is sharing */
+ if (num_links == 0)
return false;
return true;