mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 22:02:02 +00:00
brcmfmac: add support for nl80211 BSS_SELECT feature
Announce support for nl80211 feature BSS_SELECT and process BSS selection behaviour provided in .connect() callback. Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Lei Zhang <leizh@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
005a425b24
commit
7705ba6f7b
4 changed files with 89 additions and 15 deletions
|
@ -250,6 +250,20 @@ struct parsed_vndr_ies {
|
|||
struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
|
||||
};
|
||||
|
||||
static u8 nl80211_band_to_fwil(enum nl80211_band band)
|
||||
{
|
||||
switch (band) {
|
||||
case NL80211_BAND_2GHZ:
|
||||
return WLC_BAND_2G;
|
||||
case NL80211_BAND_5GHZ:
|
||||
return WLC_BAND_5G;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
|
||||
struct cfg80211_chan_def *ch)
|
||||
{
|
||||
|
@ -1796,6 +1810,50 @@ enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
|
|||
return type;
|
||||
}
|
||||
|
||||
static void brcmf_set_join_pref(struct brcmf_if *ifp,
|
||||
struct cfg80211_bss_selection *bss_select)
|
||||
{
|
||||
struct brcmf_join_pref_params join_pref_params[2];
|
||||
enum nl80211_band band;
|
||||
int err, i = 0;
|
||||
|
||||
join_pref_params[i].len = 2;
|
||||
join_pref_params[i].rssi_gain = 0;
|
||||
|
||||
if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
|
||||
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
|
||||
|
||||
switch (bss_select->behaviour) {
|
||||
case __NL80211_BSS_SELECT_ATTR_INVALID:
|
||||
brcmf_c_set_joinpref_default(ifp);
|
||||
return;
|
||||
case NL80211_BSS_SELECT_ATTR_BAND_PREF:
|
||||
join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
|
||||
band = bss_select->param.band_pref;
|
||||
join_pref_params[i].band = nl80211_band_to_fwil(band);
|
||||
i++;
|
||||
break;
|
||||
case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
|
||||
join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
|
||||
band = bss_select->param.adjust.band;
|
||||
join_pref_params[i].band = nl80211_band_to_fwil(band);
|
||||
join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
|
||||
i++;
|
||||
break;
|
||||
case NL80211_BSS_SELECT_ATTR_RSSI:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
|
||||
join_pref_params[i].len = 2;
|
||||
join_pref_params[i].rssi_gain = 0;
|
||||
join_pref_params[i].band = 0;
|
||||
err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
|
||||
sizeof(join_pref_params));
|
||||
if (err)
|
||||
brcmf_err("Set join_pref error (%d)\n", err);
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
||||
struct cfg80211_connect_params *sme)
|
||||
|
@ -1952,6 +2010,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
|||
ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
|
||||
}
|
||||
|
||||
brcmf_set_join_pref(ifp, &sme->bss_select);
|
||||
|
||||
err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
|
||||
join_params_size);
|
||||
kfree(ext_join_params);
|
||||
|
@ -6280,6 +6340,10 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
|
|||
wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
|
||||
if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
|
||||
wiphy->n_cipher_suites--;
|
||||
wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
|
||||
BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
|
||||
BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
|
||||
|
||||
wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
|
||||
WIPHY_FLAG_OFFCHAN_TX |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
||||
|
|
|
@ -38,7 +38,7 @@ const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
|||
#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
|
||||
#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
|
||||
|
||||
/* boost value for RSSI_DELTA in preferred join selection */
|
||||
/* default boost value for RSSI_DELTA in preferred join selection */
|
||||
#define BRCMF_JOIN_PREF_RSSI_BOOST 8
|
||||
|
||||
#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
|
||||
|
@ -83,11 +83,31 @@ MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
|
|||
static struct brcmfmac_platform_data *brcmfmac_pdata;
|
||||
struct brcmf_mp_global_t brcmf_mp_global;
|
||||
|
||||
void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
|
||||
{
|
||||
struct brcmf_join_pref_params join_pref_params[2];
|
||||
int err;
|
||||
|
||||
/* Setup join_pref to select target by RSSI (boost on 5GHz) */
|
||||
join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
|
||||
join_pref_params[0].len = 2;
|
||||
join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
|
||||
join_pref_params[0].band = WLC_BAND_5G;
|
||||
|
||||
join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
|
||||
join_pref_params[1].len = 2;
|
||||
join_pref_params[1].rssi_gain = 0;
|
||||
join_pref_params[1].band = 0;
|
||||
err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
|
||||
sizeof(join_pref_params));
|
||||
if (err)
|
||||
brcmf_err("Set join_pref error (%d)\n", err);
|
||||
}
|
||||
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
{
|
||||
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
|
||||
u8 buf[BRCMF_DCMD_SMLEN];
|
||||
struct brcmf_join_pref_params join_pref_params[2];
|
||||
struct brcmf_rev_info_le revinfo;
|
||||
struct brcmf_rev_info *ri;
|
||||
char *ptr;
|
||||
|
@ -154,19 +174,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Setup join_pref to select target by RSSI(with boost on 5GHz) */
|
||||
join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
|
||||
join_pref_params[0].len = 2;
|
||||
join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
|
||||
join_pref_params[0].band = WLC_BAND_5G;
|
||||
join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
|
||||
join_pref_params[1].len = 2;
|
||||
join_pref_params[1].rssi_gain = 0;
|
||||
join_pref_params[1].band = 0;
|
||||
err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
|
||||
sizeof(join_pref_params));
|
||||
if (err)
|
||||
brcmf_err("Set join_pref error (%d)\n", err);
|
||||
brcmf_c_set_joinpref_default(ifp);
|
||||
|
||||
/* Setup event_msgs, enable E_IF */
|
||||
err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
|
||||
|
|
|
@ -223,6 +223,7 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
|||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||
void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
|
||||
int __init brcmf_core_init(void);
|
||||
void __exit brcmf_core_exit(void);
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
|
||||
#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
|
||||
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
|
||||
#define BRCMF_C_SET_ASSOC_PREFER 205
|
||||
#define BRCMF_C_GET_VALID_CHANNELS 217
|
||||
#define BRCMF_C_GET_KEY_PRIMARY 235
|
||||
#define BRCMF_C_SET_KEY_PRIMARY 236
|
||||
|
|
Loading…
Reference in a new issue