aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index a54db9185747..00bd1e16c3ce 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
21#include <linux/module.h>
21#include <net/cfg80211.h> 22#include <net/cfg80211.h>
22#include <net/netlink.h> 23#include <net/netlink.h>
23 24
@@ -251,6 +252,10 @@ struct parsed_vndr_ies {
251 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT]; 252 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
252}; 253};
253 254
255static int brcmf_roamoff;
256module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
257MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
258
254/* Quarter dBm units to mW 259/* Quarter dBm units to mW
255 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 260 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
256 * Table is offset so the last entry is largest mW value that fits in 261 * Table is offset so the last entry is largest mW value that fits in
@@ -4444,7 +4449,9 @@ static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4444 u32 event = e->event_code; 4449 u32 event = e->event_code;
4445 u16 flags = e->flags; 4450 u16 flags = e->flags;
4446 4451
4447 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { 4452 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4453 (event == BRCMF_E_DISASSOC_IND) ||
4454 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4448 brcmf_dbg(CONN, "Processing link down\n"); 4455 brcmf_dbg(CONN, "Processing link down\n");
4449 return true; 4456 return true;
4450 } 4457 }
@@ -4688,6 +4695,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4688 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 4695 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4689 struct ieee80211_channel *chan; 4696 struct ieee80211_channel *chan;
4690 s32 err = 0; 4697 s32 err = 0;
4698 u16 reason;
4691 4699
4692 if (ifp->vif->mode == WL_MODE_AP) { 4700 if (ifp->vif->mode == WL_MODE_AP) {
4693 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); 4701 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
@@ -4709,9 +4717,15 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4709 if (!brcmf_is_ibssmode(ifp->vif)) { 4717 if (!brcmf_is_ibssmode(ifp->vif)) {
4710 brcmf_bss_connect_done(cfg, ndev, e, false); 4718 brcmf_bss_connect_done(cfg, ndev, e, false);
4711 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, 4719 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4712 &ifp->vif->sme_state)) 4720 &ifp->vif->sme_state)) {
4713 cfg80211_disconnected(ndev, 0, NULL, 0, 4721 reason = 0;
4722 if (((e->event_code == BRCMF_E_DEAUTH_IND) ||
4723 (e->event_code == BRCMF_E_DISASSOC_IND)) &&
4724 (e->reason != WLAN_REASON_UNSPECIFIED))
4725 reason = e->reason;
4726 cfg80211_disconnected(ndev, reason, NULL, 0,
4714 GFP_KERNEL); 4727 GFP_KERNEL);
4728 }
4715 } 4729 }
4716 brcmf_link_down(ifp->vif); 4730 brcmf_link_down(ifp->vif);
4717 brcmf_init_prof(ndev_to_prof(ndev)); 4731 brcmf_init_prof(ndev_to_prof(ndev));
@@ -4905,11 +4919,8 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4905 4919
4906 cfg->scan_request = NULL; 4920 cfg->scan_request = NULL;
4907 cfg->pwr_save = true; 4921 cfg->pwr_save = true;
4908 cfg->roam_on = true; /* roam on & off switch. 4922 cfg->active_scan = true; /* we do active scan per default */
4909 we enable roam per default */ 4923 cfg->dongle_up = false; /* dongle is not up yet */
4910 cfg->active_scan = true; /* we do active scan for
4911 specific scan per default */
4912 cfg->dongle_up = false; /* dongle is not up yet */
4913 err = brcmf_init_priv_mem(cfg); 4924 err = brcmf_init_priv_mem(cfg);
4914 if (err) 4925 if (err)
4915 return err; 4926 return err;
@@ -5029,7 +5040,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5029} 5040}
5030 5041
5031static s32 5042static s32
5032brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout) 5043brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5033{ 5044{
5034 s32 err = 0; 5045 s32 err = 0;
5035 __le32 roamtrigger[2]; 5046 __le32 roamtrigger[2];
@@ -5039,7 +5050,7 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5039 * Setup timeout if Beacons are lost and roam is 5050 * Setup timeout if Beacons are lost and roam is
5040 * off to report link down 5051 * off to report link down
5041 */ 5052 */
5042 if (roamvar) { 5053 if (brcmf_roamoff) {
5043 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout); 5054 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5044 if (err) { 5055 if (err) {
5045 brcmf_err("bcn_timeout error (%d)\n", err); 5056 brcmf_err("bcn_timeout error (%d)\n", err);
@@ -5051,8 +5062,9 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5051 * Enable/Disable built-in roaming to allow supplicant 5062 * Enable/Disable built-in roaming to allow supplicant
5052 * to take care of roaming 5063 * to take care of roaming
5053 */ 5064 */
5054 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On"); 5065 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5055 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar); 5066 brcmf_roamoff ? "Off" : "On");
5067 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5056 if (err) { 5068 if (err) {
5057 brcmf_err("roam_off error (%d)\n", err); 5069 brcmf_err("roam_off error (%d)\n", err);
5058 goto dongle_rom_out; 5070 goto dongle_rom_out;
@@ -5294,6 +5306,8 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5294 u32 band_list[3]; 5306 u32 band_list[3];
5295 u32 nmode; 5307 u32 nmode;
5296 u32 bw_cap[2] = { 0, 0 }; 5308 u32 bw_cap[2] = { 0, 0 };
5309 u32 rxchain;
5310 u32 nchain;
5297 s8 phy; 5311 s8 phy;
5298 s32 err; 5312 s32 err;
5299 u32 nband; 5313 u32 nband;
@@ -5330,6 +5344,16 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5330 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, 5344 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
5331 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); 5345 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
5332 5346
5347 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5348 if (err) {
5349 brcmf_err("rxchain error (%d)\n", err);
5350 nchain = 1;
5351 } else {
5352 for (nchain = 0; rxchain; nchain++)
5353 rxchain = rxchain & (rxchain - 1);
5354 }
5355 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5356
5333 err = brcmf_construct_reginfo(cfg, bw_cap); 5357 err = brcmf_construct_reginfo(cfg, bw_cap);
5334 if (err) { 5358 if (err) {
5335 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err); 5359 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
@@ -5358,10 +5382,7 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5358 band->ht_cap.ht_supported = true; 5382 band->ht_cap.ht_supported = true;
5359 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 5383 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5360 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; 5384 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5361 /* An HT shall support all EQM rates for one spatial 5385 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5362 * stream
5363 */
5364 band->ht_cap.mcs.rx_mask[0] = 0xff;
5365 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 5386 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5366 bands[band->band] = band; 5387 bands[band->band] = band;
5367 } 5388 }
@@ -5408,7 +5429,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5408 brcmf_dbg(INFO, "power save set to %s\n", 5429 brcmf_dbg(INFO, "power save set to %s\n",
5409 (power_mode ? "enabled" : "disabled")); 5430 (power_mode ? "enabled" : "disabled"));
5410 5431
5411 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); 5432 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5412 if (err) 5433 if (err)
5413 goto default_conf_out; 5434 goto default_conf_out;
5414 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, 5435 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,