AP MLD: Stop AP per link

For AP MLD cases, the link id is required to determine the correct link
to stop in the stop_ap() driver op.

Signed-off-by: Chenming Huang <quic_chenhuan@quicinc.com>
This commit is contained in:
Chenming Huang 2023-11-24 13:48:59 +05:30 committed by Jouni Malinen
parent d084ef36b3
commit 8cdb0d3f24
3 changed files with 25 additions and 5 deletions

View file

@ -388,9 +388,15 @@ static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd) static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd)
{ {
int link_id = -1;
if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv) if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv)
return 0; return 0;
return hapd->driver->stop_ap(hapd->drv_priv); #ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap)
link_id = hapd->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
return hapd->driver->stop_ap(hapd->drv_priv, link_id);
} }
static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,

View file

@ -4544,13 +4544,14 @@ struct wpa_driver_ops {
/** /**
* stop_ap - Removes beacon from AP * stop_ap - Removes beacon from AP
* @priv: Private driver interface data * @priv: Private driver interface data
* @link_id: Link ID of the specified link; -1 for non-MLD
* Returns: 0 on success, -1 on failure (or if not supported) * Returns: 0 on success, -1 on failure (or if not supported)
* *
* This optional function can be used to disable AP mode related * This optional function can be used to disable AP mode related
* configuration. Unlike deinit_ap, it does not change to station * configuration. Unlike deinit_ap, it does not change to station
* mode. * mode.
*/ */
int (*stop_ap)(void *priv); int (*stop_ap)(void *priv, int link_id);
/** /**
* get_survey - Retrieve survey data * get_survey - Retrieve survey data

View file

@ -9570,17 +9570,30 @@ static int wpa_driver_nl80211_deinit_ap(void *priv)
} }
static int wpa_driver_nl80211_stop_ap(void *priv) static int wpa_driver_nl80211_stop_ap(void *priv, int link_id)
{ {
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
unsigned int i;
if (!is_ap_interface(drv->nlmode)) if (!is_ap_interface(drv->nlmode))
return -1; return -1;
if (link_id == -1) {
wpa_driver_nl80211_del_beacon_all(bss); wpa_driver_nl80211_del_beacon_all(bss);
return 0; return 0;
}
for (i = 0; i < bss->n_links; ++i) {
struct i802_link *link = &bss->links[i];
if (link->link_id == link_id) {
wpa_driver_nl80211_del_beacon(bss, link);
return 0;
}
}
return -1;
} }