From 8cdb0d3f2451aa457ca0267d439cfd9c6eaec011 Mon Sep 17 00:00:00 2001 From: Chenming Huang Date: Fri, 24 Nov 2023 13:48:59 +0530 Subject: [PATCH] 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 --- src/ap/ap_drv_ops.h | 8 +++++++- src/drivers/driver.h | 3 ++- src/drivers/driver_nl80211.c | 19 ++++++++++++++++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 331b0eaf4..f38b1850a 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -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) { + int link_id = -1; + if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv) 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, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index bff7502f1..ed76037d2 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4544,13 +4544,14 @@ struct wpa_driver_ops { /** * stop_ap - Removes beacon from AP * @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) * * This optional function can be used to disable AP mode related * configuration. Unlike deinit_ap, it does not change to station * mode. */ - int (*stop_ap)(void *priv); + int (*stop_ap)(void *priv, int link_id); /** * get_survey - Retrieve survey data diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index aa5ed58b2..c7fad43d5 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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 wpa_driver_nl80211_data *drv = bss->drv; + unsigned int i; if (!is_ap_interface(drv->nlmode)) return -1; - wpa_driver_nl80211_del_beacon_all(bss); + if (link_id == -1) { + 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; }