aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2014-05-12 04:47:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-05-13 15:56:50 -0400
commit18d6c535cec18b8fc900fee9ce020ca0dd1d2da7 (patch)
treeaeb9dc2e743ab9e4f2425a1959afc1373c2a783c /drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
parent4439cbcd37a9dc2c4e976259cd2962956985d58d (diff)
brcmfmac: provide VHT capability information to user-space
Although brcmfmac support several 11ac devices it did not advertise VHT related information to cfg80211. Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> Reviewed-by: Franky Lin <frankyl@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c73
1 files changed, 59 insertions, 14 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index c4c563e5c8b0..6bdbabb63d19 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -5313,13 +5313,63 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5313 } 5313 }
5314} 5314}
5315 5315
5316static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5317 u32 bw_cap[2], u32 nchain)
5318{
5319 band->ht_cap.ht_supported = true;
5320 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5321 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5322 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5323 }
5324 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5325 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5326 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5327 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5328 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5329 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5330}
5331
5332static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5333{
5334 u16 mcs_map;
5335 int i;
5336
5337 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5338 mcs_map = (mcs_map << 2) | supp;
5339
5340 return cpu_to_le16(mcs_map);
5341}
5342
5343static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5344 u32 bw_cap[2], u32 nchain)
5345{
5346 __le16 mcs_map;
5347
5348 /* not allowed in 2.4G band */
5349 if (band->band == IEEE80211_BAND_2GHZ)
5350 return;
5351
5352 band->vht_cap.vht_supported = true;
5353 /* 80MHz is mandatory */
5354 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5355 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5356 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5357 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5358 }
5359 /* all support 256-QAM */
5360 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5361 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5362 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5363}
5364
5316static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) 5365static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5317{ 5366{
5318 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 5367 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5319 struct wiphy *wiphy; 5368 struct wiphy *wiphy;
5320 s32 phy_list; 5369 s32 phy_list;
5321 u32 band_list[3]; 5370 u32 band_list[3];
5322 u32 nmode; 5371 u32 nmode = 0;
5372 u32 vhtmode = 0;
5323 u32 bw_cap[2] = { 0, 0 }; 5373 u32 bw_cap[2] = { 0, 0 };
5324 u32 rxchain; 5374 u32 rxchain;
5325 u32 nchain; 5375 u32 nchain;
@@ -5350,14 +5400,16 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5350 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n", 5400 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5351 band_list[0], band_list[1], band_list[2]); 5401 band_list[0], band_list[1], band_list[2]);
5352 5402
5403 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5353 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); 5404 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5354 if (err) { 5405 if (err) {
5355 brcmf_err("nmode error (%d)\n", err); 5406 brcmf_err("nmode error (%d)\n", err);
5356 } else { 5407 } else {
5357 brcmf_get_bwcap(ifp, bw_cap); 5408 brcmf_get_bwcap(ifp, bw_cap);
5358 } 5409 }
5359 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, 5410 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5360 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); 5411 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5412 bw_cap[IEEE80211_BAND_5GHZ]);
5361 5413
5362 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); 5414 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5363 if (err) { 5415 if (err) {
@@ -5388,17 +5440,10 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5388 else 5440 else
5389 continue; 5441 continue;
5390 5442
5391 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) { 5443 if (nmode)
5392 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; 5444 brcmf_update_ht_cap(band, bw_cap, nchain);
5393 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 5445 if (vhtmode)
5394 } 5446 brcmf_update_vht_cap(band, bw_cap, nchain);
5395 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5396 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5397 band->ht_cap.ht_supported = true;
5398 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5399 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5400 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5401 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5402 bands[band->band] = band; 5447 bands[band->band] = band;
5403 } 5448 }
5404 5449