diff mbox series

[wireless-next,v3,2/5] wifi: brcmfmac: support AP isolation to restrict reachability between stations

Message ID 20250603161057.19101-3-gokulkumar.sivakumar@infineon.com
State Superseded
Headers show
Series wifi: cfg80211: Add support to indicate changed AP BSS parameters to drivers | expand

Commit Message

Gokul Sivakumar June 3, 2025, 4:10 p.m. UTC
From: Wright Feng <wright.feng@cypress.com>

hostapd & wpa_supplicant userspace daemons exposes an AP mode specific
config file parameter "ap_isolate" to the user, which is used to control
low-level bridging of frames between the stations associated in the BSS.

In driver, handle this user setting in the newly defined cfg80211_ops
function brcmf_cfg80211_change_bss() by enabling "ap_isolate" IOVAR in
the firmware.

In AP mode, the "ap_isolate" value from the cfg80211 layer represents,
 0 = allow low-level bridging of frames between associated stations
 1 = restrict low-level bridging of frames to isolate associated stations

The userspace can change more than one AP BSS Parameter in the SET_BSS
operation. Incase if any BSS param other than the currently supported
"ap_isolate" is passed by userspace, reject the entire SET_BSS operation
instead of misleading the userspace that the operation is fully successful.

Also add an individual check for the CFG80211_BSS_PARAM_CHANGED_AP_ISOLATE
flag, before handling "ap_isolate" value from the userspace. This addresses
case where driver unnecessarily checks the value of ap_isolate, even if the
userspace did not pass this param in the SET_BSS request.

Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Gokul Sivakumar <gokulkumar.sivakumar@infineon.com>
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
diff mbox series

Patch

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index dc2383faddd1..276d08048cbb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5933,6 +5933,52 @@  static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
 	return brcmf_set_pmk(ifp, NULL, 0);
 }
 
+static int brcmf_set_ap_bssparam_isolate(struct brcmf_if *ifp, int param_ap_isolate)
+{
+	int ret = 0, cur_ap_isolate = 0;
+
+	/* In cfg80211, for AP mode, the "param_ap_isolate" value represents
+	 *  0 = allow low-level bridging of frames between associated stations
+	 *  1 = restrict low-level bridging of frames to isolate associated stations
+	 */
+	ret = brcmf_fil_iovar_int_get(ifp, "ap_isolate", &cur_ap_isolate);
+	if (ret < 0)
+		return ret;
+
+	if (cur_ap_isolate != param_ap_isolate) {
+		ret = brcmf_fil_iovar_int_set(ifp, "ap_isolate", param_ap_isolate);
+		if (ret < 0) {
+			brcmf_err("ap_isolate iovar failed: ret=%d\n", ret);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
+				     struct bss_parameters *params)
+{
+	struct brcmf_if *ifp = netdev_priv(dev);
+	int ret = 0;
+
+	/* Reject the operation if any of the AP BSS params that got changed are not
+	 * supported by the driver for explicit configuration.
+	 */
+	if (params->changed &
+	    ~(CFG80211_BSS_PARAM_CHANGED_AP_ISOLATE))
+		return -EOPNOTSUPP;
+
+	if (params->changed &
+	    CFG80211_BSS_PARAM_CHANGED_AP_ISOLATE) {
+		ret = brcmf_set_ap_bssparam_isolate(ifp, params->ap_isolate);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
 static struct cfg80211_ops brcmf_cfg80211_ops = {
 	.add_virtual_intf = brcmf_cfg80211_add_iface,
 	.del_virtual_intf = brcmf_cfg80211_del_iface,
@@ -5980,6 +6026,7 @@  static struct cfg80211_ops brcmf_cfg80211_ops = {
 	.update_connect_params = brcmf_cfg80211_update_conn_params,
 	.set_pmk = brcmf_cfg80211_set_pmk,
 	.del_pmk = brcmf_cfg80211_del_pmk,
+	.change_bss = brcmf_cfg80211_change_bss,
 };
 
 struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)