Skip to content

Commit feb6945

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 95ad86d commit feb6945

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
@@ -7273,20 +7273,22 @@ static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
72737273
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
72747274
}
72757275

7276-
static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7276+
static __le16 brcmf_get_mcs_map(u32 nstreams,
7277+
enum ieee80211_vht_mcs_support supp)
72777278
{
72787279
u16 mcs_map;
72797280
int i;
72807281

7281-
for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7282+
for (i = 0, mcs_map = 0xFFFF; i < nstreams; i++)
72827283
mcs_map = (mcs_map << 2) | supp;
72837284

72847285
return cpu_to_le16(mcs_map);
72857286
}
72867287

72877288
static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7288-
u32 bw_cap[2], u32 nchain, u32 txstreams,
7289-
u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7289+
u32 bw_cap[2], u32 txstreams, u32 rxstreams,
7290+
u32 txbf_bfe_cap, u32 txbf_bfr_cap,
7291+
u32 ldpc_cap, u32 stbc_rx, u32 stbc_tx)
72907292
{
72917293
__le16 mcs_map;
72927294

@@ -7295,15 +7297,32 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72957297
return;
72967298

72977299
band->vht_cap.vht_supported = true;
7300+
band->vht_cap.vht_mcs.tx_highest = cpu_to_le16(433 * txstreams);
7301+
band->vht_cap.vht_mcs.rx_highest = cpu_to_le16(433 * rxstreams);
7302+
7303+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
7304+
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
7305+
7306+
if (ldpc_cap)
7307+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
7308+
if (stbc_tx)
7309+
band->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
7310+
7311+
if (stbc_rx)
7312+
band->vht_cap.cap |=
7313+
(stbc_rx << IEEE80211_VHT_CAP_RXSTBC_SHIFT);
7314+
72987315
/* 80MHz is mandatory */
72997316
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
73007317
if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
73017318
band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
73027319
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
73037320
}
73047321
/* all support 256-QAM */
7305-
mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7322+
mcs_map = brcmf_get_mcs_map(rxstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
73067323
band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7324+
mcs_map = brcmf_get_mcs_map(txstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
7325+
73077326
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
73087327

73097328
/* Beamforming support information */
@@ -7319,11 +7338,15 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
73197338
if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
73207339
band->vht_cap.cap |=
73217340
(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7322-
band->vht_cap.cap |= ((txstreams - 1) <<
7323-
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7341+
band->vht_cap.cap |=
7342+
((txstreams - 1)
7343+
<< IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
73247344
band->vht_cap.cap |=
73257345
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
73267346
}
7347+
/* AMPDU length limit, support max 1MB (2 ^ (13 + 7)) */
7348+
band->vht_cap.cap |=
7349+
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
73277350
}
73287351

73297352
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
@@ -7340,10 +7363,17 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73407363
s32 i;
73417364
struct ieee80211_supported_band *band;
73427365
u32 txstreams = 0;
7366+
u32 rxstreams = 0;
73437367
u32 txbf_bfe_cap = 0;
73447368
u32 txbf_bfr_cap = 0;
7369+
u32 ldpc_cap = 0;
7370+
u32 stbc_rx = 0;
7371+
u32 stbc_tx = 0;
73457372

73467373
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7374+
(void)brcmf_fil_iovar_int_get(ifp, "ldpc_cap", &ldpc_cap);
7375+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_rx", &stbc_rx);
7376+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_tx", &stbc_tx);
73477377
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
73487378
if (err) {
73497379
bphy_err(drvr, "nmode error (%d)\n", err);
@@ -7376,6 +7406,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73767406
}
73777407

73787408
if (vhtmode) {
7409+
(void)brcmf_fil_iovar_int_get(ifp, "rxstreams", &rxstreams);
73797410
(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
73807411
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
73817412
&txbf_bfe_cap);
@@ -7391,8 +7422,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73917422
if (nmode)
73927423
brcmf_update_ht_cap(band, bw_cap, nchain);
73937424
if (vhtmode)
7394-
brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7395-
txbf_bfe_cap, txbf_bfr_cap);
7425+
brcmf_update_vht_cap(band, bw_cap, txstreams, rxstreams,
7426+
txbf_bfe_cap, txbf_bfr_cap,
7427+
ldpc_cap, stbc_rx, stbc_tx);
73967428
}
73977429

73987430
return 0;

0 commit comments

Comments
 (0)