Commit 98027769 authored by Arend van Spriel's avatar Arend van Spriel Committed by Kalle Valo

brcmfmac: enable 802.11d support in firmware

When the driver gets beacon info containing a country IE from user-space
upon .start_ap() callback, it will enable regulatory 802.11d support.
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 6b89dcb3
......@@ -3966,6 +3966,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
const struct brcmf_tlv *ssid_ie;
const struct brcmf_tlv *country_ie;
struct brcmf_ssid_le ssid_le;
s32 err = -EPERM;
const struct brcmf_tlv *rsn_ie;
......@@ -3975,6 +3976,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_fil_bss_enable_le bss_enable;
u16 chanspec;
bool mbss;
int is_11d;
brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
settings->chandef.chan->hw_value,
......@@ -3986,6 +3988,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
dev_role = ifp->vif->wdev.iftype;
mbss = ifp->vif->mbss;
/* store current 11d setting */
brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
settings->beacon.tail_len,
WLAN_EID_COUNTRY);
is_11d = country_ie ? 1 : 0;
memset(&ssid_le, 0, sizeof(ssid_le));
if (settings->ssid == NULL || settings->ssid_len == 0) {
ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
......@@ -4051,6 +4060,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
if (is_11d != ifp->vif->is_11d) {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
is_11d);
if (err < 0) {
brcmf_err("Regulatory Set Error, %d\n", err);
goto exit;
}
}
if (settings->beacon_interval) {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
settings->beacon_interval);
......@@ -4083,6 +4100,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
brcmf_err("SET INFRA error %d\n", err);
goto exit;
}
} else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
/* Multiple-BSS should use same 11d configuration */
err = -EINVAL;
goto exit;
}
if (dev_role == NL80211_IFTYPE_AP) {
if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
......@@ -4178,6 +4199,11 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
brcmf_err("setting INFRA mode failed %d\n", err);
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
brcmf_fil_iovar_int_set(ifp, "mbss", 0);
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
ifp->vif->is_11d);
if (err < 0)
brcmf_err("restoring REGULATORY setting failed %d\n",
err);
/* Bring device back up so it can be used again */
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
if (err < 0)
......
......@@ -200,6 +200,7 @@ struct brcmf_cfg80211_vif {
struct list_head list;
u16 mgmt_rx_reg;
bool mbss;
int is_11d;
};
/* association inform */
......
......@@ -43,6 +43,8 @@
#define BRCMF_C_SET_RADIO 38
#define BRCMF_C_GET_PHYTYPE 39
#define BRCMF_C_SET_KEY 45
#define BRCMF_C_GET_REGULATORY 46
#define BRCMF_C_SET_REGULATORY 47
#define BRCMF_C_SET_PASSIVE_SCAN 49
#define BRCMF_C_SCAN 50
#define BRCMF_C_SCAN_RESULTS 51
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment