diff options
author | Arend van Spriel <arend@broadcom.com> | 2014-05-12 04:47:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-13 15:56:50 -0400 |
commit | 18d6c535cec18b8fc900fee9ce020ca0dd1d2da7 (patch) | |
tree | aeb9dc2e743ab9e4f2425a1959afc1373c2a783c /drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |
parent | 4439cbcd37a9dc2c4e976259cd2962956985d58d (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.c | 73 |
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 | ||
5316 | static 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 | |||
5332 | static __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 | |||
5343 | static 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 | |||
5316 | static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) | 5365 | static 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 | ||