Skip to content

Commit 92dc56f

Browse files
dberlinjannau
authored andcommitted
[brcmfmac] Dynamically configure VHT settings to match firmware
1. Correct VHT MCS settings to support as many tx/rx streams as chip does. 2. Correct VHT capabilities to support what all chips do. 3. Correct max AMPDU capabilities for VHT. 4. Support LDPC and STBC in VHT where available. Signed-off-by: Daniel Berlin <dberlin@dberlin.org>
1 parent 056df6b commit 92dc56f

1 file changed

Lines changed: 41 additions & 9 deletions

File tree

  • drivers/net/wireless/broadcom/brcm80211/brcmfmac

drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7228,20 +7228,22 @@ static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
72287228
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
72297229
}
72307230

7231-
static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7231+
static __le16 brcmf_get_mcs_map(u32 nstreams,
7232+
enum ieee80211_vht_mcs_support supp)
72327233
{
72337234
u16 mcs_map;
72347235
int i;
72357236

7236-
for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7237+
for (i = 0, mcs_map = 0xFFFF; i < nstreams; i++)
72377238
mcs_map = (mcs_map << 2) | supp;
72387239

72397240
return cpu_to_le16(mcs_map);
72407241
}
72417242

72427243
static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7243-
u32 bw_cap[2], u32 nchain, u32 txstreams,
7244-
u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7244+
u32 bw_cap[2], u32 txstreams, u32 rxstreams,
7245+
u32 txbf_bfe_cap, u32 txbf_bfr_cap,
7246+
u32 ldpc_cap, u32 stbc_rx, u32 stbc_tx)
72457247
{
72467248
__le16 mcs_map;
72477249

@@ -7250,15 +7252,32 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72507252
return;
72517253

72527254
band->vht_cap.vht_supported = true;
7255+
band->vht_cap.vht_mcs.tx_highest = cpu_to_le16(433 * txstreams);
7256+
band->vht_cap.vht_mcs.rx_highest = cpu_to_le16(433 * rxstreams);
7257+
7258+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
7259+
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
7260+
7261+
if (ldpc_cap)
7262+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
7263+
if (stbc_tx)
7264+
band->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
7265+
7266+
if (stbc_rx)
7267+
band->vht_cap.cap |=
7268+
(stbc_rx << IEEE80211_VHT_CAP_RXSTBC_SHIFT);
7269+
72537270
/* 80MHz is mandatory */
72547271
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
72557272
if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
72567273
band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
72577274
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
72587275
}
72597276
/* all support 256-QAM */
7260-
mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7277+
mcs_map = brcmf_get_mcs_map(rxstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
72617278
band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7279+
mcs_map = brcmf_get_mcs_map(txstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
7280+
72627281
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
72637282

72647283
/* Beamforming support information */
@@ -7274,11 +7293,15 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72747293
if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
72757294
band->vht_cap.cap |=
72767295
(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7277-
band->vht_cap.cap |= ((txstreams - 1) <<
7278-
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7296+
band->vht_cap.cap |=
7297+
((txstreams - 1)
7298+
<< IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
72797299
band->vht_cap.cap |=
72807300
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
72817301
}
7302+
/* AMPDU length limit, support max 1MB (2 ^ (13 + 7)) */
7303+
band->vht_cap.cap |=
7304+
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
72827305
}
72837306

72847307
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
@@ -7295,10 +7318,17 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
72957318
s32 i;
72967319
struct ieee80211_supported_band *band;
72977320
u32 txstreams = 0;
7321+
u32 rxstreams = 0;
72987322
u32 txbf_bfe_cap = 0;
72997323
u32 txbf_bfr_cap = 0;
7324+
u32 ldpc_cap = 0;
7325+
u32 stbc_rx = 0;
7326+
u32 stbc_tx = 0;
73007327

73017328
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7329+
(void)brcmf_fil_iovar_int_get(ifp, "ldpc_cap", &ldpc_cap);
7330+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_rx", &stbc_rx);
7331+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_tx", &stbc_tx);
73027332
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
73037333
if (err) {
73047334
bphy_err(drvr, "nmode error (%d)\n", err);
@@ -7331,6 +7361,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73317361
}
73327362

73337363
if (vhtmode) {
7364+
(void)brcmf_fil_iovar_int_get(ifp, "rxstreams", &rxstreams);
73347365
(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
73357366
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
73367367
&txbf_bfe_cap);
@@ -7346,8 +7377,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73467377
if (nmode)
73477378
brcmf_update_ht_cap(band, bw_cap, nchain);
73487379
if (vhtmode)
7349-
brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7350-
txbf_bfe_cap, txbf_bfr_cap);
7380+
brcmf_update_vht_cap(band, bw_cap, txstreams, rxstreams,
7381+
txbf_bfe_cap, txbf_bfr_cap,
7382+
ldpc_cap, stbc_rx, stbc_tx);
73517383
}
73527384

73537385
return 0;

0 commit comments

Comments
 (0)