diff options
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c')
-rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 141 |
1 files changed, 103 insertions, 38 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index d5c2a27573b4..d0631b6cfd53 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -144,7 +144,7 @@ static struct ieee80211_rate __wl_rates[] = { #define wl_a_rates_size (wl_g_rates_size - 4) #define CHAN2G(_channel, _freq) { \ - .band = IEEE80211_BAND_2GHZ, \ + .band = NL80211_BAND_2GHZ, \ .center_freq = (_freq), \ .hw_value = (_channel), \ .flags = IEEE80211_CHAN_DISABLED, \ @@ -153,7 +153,7 @@ static struct ieee80211_rate __wl_rates[] = { } #define CHAN5G(_channel) { \ - .band = IEEE80211_BAND_5GHZ, \ + .band = NL80211_BAND_5GHZ, \ .center_freq = 5000 + (5 * (_channel)), \ .hw_value = (_channel), \ .flags = IEEE80211_CHAN_DISABLED, \ @@ -181,13 +181,13 @@ static struct ieee80211_channel __wl_5ghz_channels[] = { * above is added to the band during setup. */ static const struct ieee80211_supported_band __wl_band_2ghz = { - .band = IEEE80211_BAND_2GHZ, + .band = NL80211_BAND_2GHZ, .bitrates = wl_g_rates, .n_bitrates = wl_g_rates_size, }; static const struct ieee80211_supported_band __wl_band_5ghz = { - .band = IEEE80211_BAND_5GHZ, + .band = NL80211_BAND_5GHZ, .bitrates = wl_a_rates, .n_bitrates = wl_a_rates_size, }; @@ -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) { @@ -292,13 +306,13 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, WARN_ON_ONCE(1); } switch (ch->chan->band) { - case IEEE80211_BAND_2GHZ: + case NL80211_BAND_2GHZ: ch_inf.band = BRCMU_CHAN_BAND_2G; break; - case IEEE80211_BAND_5GHZ: + case NL80211_BAND_5GHZ: ch_inf.band = BRCMU_CHAN_BAND_5G; break; - case IEEE80211_BAND_60GHZ: + case NL80211_BAND_60GHZ: default: WARN_ON_ONCE(1); } @@ -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); @@ -2679,9 +2739,9 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, channel = bi->ctl_ch; if (channel <= CH_MAX_2G_CHANNEL) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; + band = wiphy->bands[NL80211_BAND_2GHZ]; else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; + band = wiphy->bands[NL80211_BAND_5GHZ]; freq = ieee80211_channel_to_frequency(channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); @@ -2788,9 +2848,9 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, cfg->d11inf.decchspec(&ch); if (ch.band == BRCMU_CHAN_BAND_2G) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; + band = wiphy->bands[NL80211_BAND_2GHZ]; else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; + band = wiphy->bands[NL80211_BAND_5GHZ]; freq = ieee80211_channel_to_frequency(ch.chnum, band->band); cfg->channel = freq; @@ -3608,7 +3668,8 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg, if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) wowl_config |= BRCMF_WOWL_UNASSOC; - brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear")); + brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", + sizeof(struct brcmf_wowl_wakeind_le)); brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config); brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1); brcmf_bus_wowl_config(cfg->pub->bus_if, true); @@ -5215,9 +5276,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, cfg->d11inf.decchspec(&ch); if (ch.band == BRCMU_CHAN_BAND_2G) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; + band = wiphy->bands[NL80211_BAND_2GHZ]; else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; + band = wiphy->bands[NL80211_BAND_5GHZ]; freq = ieee80211_channel_to_frequency(ch.chnum, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); @@ -5707,11 +5768,11 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, } wiphy = cfg_to_wiphy(cfg); - band = wiphy->bands[IEEE80211_BAND_2GHZ]; + band = wiphy->bands[NL80211_BAND_2GHZ]; if (band) for (i = 0; i < band->n_channels; i++) band->channels[i].flags = IEEE80211_CHAN_DISABLED; - band = wiphy->bands[IEEE80211_BAND_5GHZ]; + band = wiphy->bands[NL80211_BAND_5GHZ]; if (band) for (i = 0; i < band->n_channels; i++) band->channels[i].flags = IEEE80211_CHAN_DISABLED; @@ -5722,9 +5783,9 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, cfg->d11inf.decchspec(&ch); if (ch.band == BRCMU_CHAN_BAND_2G) { - band = wiphy->bands[IEEE80211_BAND_2GHZ]; + band = wiphy->bands[NL80211_BAND_2GHZ]; } else if (ch.band == BRCMU_CHAN_BAND_5G) { - band = wiphy->bands[IEEE80211_BAND_5GHZ]; + band = wiphy->bands[NL80211_BAND_5GHZ]; } else { brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); continue; @@ -5839,7 +5900,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) return err; } - band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ]; + band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ]; list = (struct brcmf_chanspec_list *)pbuf; num_chan = le32_to_cpu(list->count); for (i = 0; i < num_chan; i++) { @@ -5871,11 +5932,11 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) band = WLC_BAND_2G; err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); if (!err) { - bw_cap[IEEE80211_BAND_2GHZ] = band; + bw_cap[NL80211_BAND_2GHZ] = band; band = WLC_BAND_5G; err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); if (!err) { - bw_cap[IEEE80211_BAND_5GHZ] = band; + bw_cap[NL80211_BAND_5GHZ] = band; return; } WARN_ON(1); @@ -5890,14 +5951,14 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) switch (mimo_bwcap) { case WLC_N_BW_40ALL: - bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT; + bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT; /* fall-thru */ case WLC_N_BW_20IN2G_40IN5G: - bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT; + bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT; /* fall-thru */ case WLC_N_BW_20ALL: - bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT; - bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT; + bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT; + bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT; break; default: brcmf_err("invalid mimo_bw_cap value\n"); @@ -5938,7 +5999,7 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band, __le16 mcs_map; /* not allowed in 2.4G band */ - if (band->band == IEEE80211_BAND_2GHZ) + if (band->band == NL80211_BAND_2GHZ) return; band->vht_cap.vht_supported = true; @@ -5997,8 +6058,8 @@ static int brcmf_setup_wiphybands(struct wiphy *wiphy) brcmf_get_bwcap(ifp, bw_cap); } brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n", - nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ], - bw_cap[IEEE80211_BAND_5GHZ]); + nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ], + bw_cap[NL80211_BAND_5GHZ]); err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); if (err) { @@ -6279,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; @@ -6321,7 +6386,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) } band->n_channels = ARRAY_SIZE(__wl_2ghz_channels); - wiphy->bands[IEEE80211_BAND_2GHZ] = band; + wiphy->bands[NL80211_BAND_2GHZ] = band; } if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) { band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz), @@ -6338,7 +6403,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) } band->n_channels = ARRAY_SIZE(__wl_5ghz_channels); - wiphy->bands[IEEE80211_BAND_5GHZ] = band; + wiphy->bands[NL80211_BAND_5GHZ] = band; } } err = brcmf_setup_wiphybands(wiphy); @@ -6604,13 +6669,13 @@ static void brcmf_free_wiphy(struct wiphy *wiphy) kfree(wiphy->iface_combinations[i].limits); } kfree(wiphy->iface_combinations); - if (wiphy->bands[IEEE80211_BAND_2GHZ]) { - kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); - kfree(wiphy->bands[IEEE80211_BAND_2GHZ]); + if (wiphy->bands[NL80211_BAND_2GHZ]) { + kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels); + kfree(wiphy->bands[NL80211_BAND_2GHZ]); } - if (wiphy->bands[IEEE80211_BAND_5GHZ]) { - kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels); - kfree(wiphy->bands[IEEE80211_BAND_5GHZ]); + if (wiphy->bands[NL80211_BAND_5GHZ]) { + kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels); + kfree(wiphy->bands[NL80211_BAND_5GHZ]); } wiphy_free(wiphy); } @@ -6698,8 +6763,8 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, * cfg80211 here that we do and have it decide we can enable * it. But first check if device does support 2G operation. */ - if (wiphy->bands[IEEE80211_BAND_2GHZ]) { - cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap; + if (wiphy->bands[NL80211_BAND_2GHZ]) { + cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap; *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; } err = wiphy_register(wiphy); |