Skip to content

Commit 31ffd81

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 b822e0f commit 31ffd81

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
@@ -7243,20 +7243,22 @@ static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
72437243
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
72447244
}
72457245

7246-
static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7246+
static __le16 brcmf_get_mcs_map(u32 nstreams,
7247+
enum ieee80211_vht_mcs_support supp)
72477248
{
72487249
u16 mcs_map;
72497250
int i;
72507251

7251-
for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7252+
for (i = 0, mcs_map = 0xFFFF; i < nstreams; i++)
72527253
mcs_map = (mcs_map << 2) | supp;
72537254

72547255
return cpu_to_le16(mcs_map);
72557256
}
72567257

72577258
static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7258-
u32 bw_cap[2], u32 nchain, u32 txstreams,
7259-
u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7259+
u32 bw_cap[2], u32 txstreams, u32 rxstreams,
7260+
u32 txbf_bfe_cap, u32 txbf_bfr_cap,
7261+
u32 ldpc_cap, u32 stbc_rx, u32 stbc_tx)
72607262
{
72617263
__le16 mcs_map;
72627264

@@ -7265,15 +7267,32 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72657267
return;
72667268

72677269
band->vht_cap.vht_supported = true;
7270+
band->vht_cap.vht_mcs.tx_highest = cpu_to_le16(433 * txstreams);
7271+
band->vht_cap.vht_mcs.rx_highest = cpu_to_le16(433 * rxstreams);
7272+
7273+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
7274+
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
7275+
7276+
if (ldpc_cap)
7277+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
7278+
if (stbc_tx)
7279+
band->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
7280+
7281+
if (stbc_rx)
7282+
band->vht_cap.cap |=
7283+
(stbc_rx << IEEE80211_VHT_CAP_RXSTBC_SHIFT);
7284+
72687285
/* 80MHz is mandatory */
72697286
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
72707287
if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
72717288
band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
72727289
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
72737290
}
72747291
/* all support 256-QAM */
7275-
mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7292+
mcs_map = brcmf_get_mcs_map(rxstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
72767293
band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7294+
mcs_map = brcmf_get_mcs_map(txstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
7295+
72777296
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
72787297

72797298
/* Beamforming support information */
@@ -7289,11 +7308,15 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72897308
if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
72907309
band->vht_cap.cap |=
72917310
(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7292-
band->vht_cap.cap |= ((txstreams - 1) <<
7293-
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7311+
band->vht_cap.cap |=
7312+
((txstreams - 1)
7313+
<< IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
72947314
band->vht_cap.cap |=
72957315
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
72967316
}
7317+
/* AMPDU length limit, support max 1MB (2 ^ (13 + 7)) */
7318+
band->vht_cap.cap |=
7319+
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
72977320
}
72987321

72997322
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
@@ -7310,10 +7333,17 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73107333
s32 i;
73117334
struct ieee80211_supported_band *band;
73127335
u32 txstreams = 0;
7336+
u32 rxstreams = 0;
73137337
u32 txbf_bfe_cap = 0;
73147338
u32 txbf_bfr_cap = 0;
7339+
u32 ldpc_cap = 0;
7340+
u32 stbc_rx = 0;
7341+
u32 stbc_tx = 0;
73157342

73167343
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7344+
(void)brcmf_fil_iovar_int_get(ifp, "ldpc_cap", &ldpc_cap);
7345+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_rx", &stbc_rx);
7346+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_tx", &stbc_tx);
73177347
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
73187348
if (err) {
73197349
bphy_err(drvr, "nmode error (%d)\n", err);
@@ -7346,6 +7376,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73467376
}
73477377

73487378
if (vhtmode) {
7379+
(void)brcmf_fil_iovar_int_get(ifp, "rxstreams", &rxstreams);
73497380
(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
73507381
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
73517382
&txbf_bfe_cap);
@@ -7361,8 +7392,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73617392
if (nmode)
73627393
brcmf_update_ht_cap(band, bw_cap, nchain);
73637394
if (vhtmode)
7364-
brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7365-
txbf_bfe_cap, txbf_bfr_cap);
7395+
brcmf_update_vht_cap(band, bw_cap, txstreams, rxstreams,
7396+
txbf_bfe_cap, txbf_bfr_cap,
7397+
ldpc_cap, stbc_rx, stbc_tx);
73667398
}
73677399

73687400
return 0;

0 commit comments

Comments
 (0)