Skip to content

Commit 08ede9f

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 c3ed278 commit 08ede9f

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
@@ -7248,20 +7248,22 @@ static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
72487248
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
72497249
}
72507250

7251-
static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7251+
static __le16 brcmf_get_mcs_map(u32 nstreams,
7252+
enum ieee80211_vht_mcs_support supp)
72527253
{
72537254
u16 mcs_map;
72547255
int i;
72557256

7256-
for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7257+
for (i = 0, mcs_map = 0xFFFF; i < nstreams; i++)
72577258
mcs_map = (mcs_map << 2) | supp;
72587259

72597260
return cpu_to_le16(mcs_map);
72607261
}
72617262

72627263
static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7263-
u32 bw_cap[2], u32 nchain, u32 txstreams,
7264-
u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7264+
u32 bw_cap[2], u32 txstreams, u32 rxstreams,
7265+
u32 txbf_bfe_cap, u32 txbf_bfr_cap,
7266+
u32 ldpc_cap, u32 stbc_rx, u32 stbc_tx)
72657267
{
72667268
__le16 mcs_map;
72677269

@@ -7270,15 +7272,32 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72707272
return;
72717273

72727274
band->vht_cap.vht_supported = true;
7275+
band->vht_cap.vht_mcs.tx_highest = cpu_to_le16(433 * txstreams);
7276+
band->vht_cap.vht_mcs.rx_highest = cpu_to_le16(433 * rxstreams);
7277+
7278+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
7279+
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
7280+
7281+
if (ldpc_cap)
7282+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
7283+
if (stbc_tx)
7284+
band->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
7285+
7286+
if (stbc_rx)
7287+
band->vht_cap.cap |=
7288+
(stbc_rx << IEEE80211_VHT_CAP_RXSTBC_SHIFT);
7289+
72737290
/* 80MHz is mandatory */
72747291
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
72757292
if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
72767293
band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
72777294
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
72787295
}
72797296
/* all support 256-QAM */
7280-
mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7297+
mcs_map = brcmf_get_mcs_map(rxstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
72817298
band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7299+
mcs_map = brcmf_get_mcs_map(txstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
7300+
72827301
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
72837302

72847303
/* Beamforming support information */
@@ -7294,11 +7313,15 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72947313
if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
72957314
band->vht_cap.cap |=
72967315
(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7297-
band->vht_cap.cap |= ((txstreams - 1) <<
7298-
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7316+
band->vht_cap.cap |=
7317+
((txstreams - 1)
7318+
<< IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
72997319
band->vht_cap.cap |=
73007320
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
73017321
}
7322+
/* AMPDU length limit, support max 1MB (2 ^ (13 + 7)) */
7323+
band->vht_cap.cap |=
7324+
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
73027325
}
73037326

73047327
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
@@ -7315,10 +7338,17 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73157338
s32 i;
73167339
struct ieee80211_supported_band *band;
73177340
u32 txstreams = 0;
7341+
u32 rxstreams = 0;
73187342
u32 txbf_bfe_cap = 0;
73197343
u32 txbf_bfr_cap = 0;
7344+
u32 ldpc_cap = 0;
7345+
u32 stbc_rx = 0;
7346+
u32 stbc_tx = 0;
73207347

73217348
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7349+
(void)brcmf_fil_iovar_int_get(ifp, "ldpc_cap", &ldpc_cap);
7350+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_rx", &stbc_rx);
7351+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_tx", &stbc_tx);
73227352
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
73237353
if (err) {
73247354
bphy_err(drvr, "nmode error (%d)\n", err);
@@ -7351,6 +7381,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73517381
}
73527382

73537383
if (vhtmode) {
7384+
(void)brcmf_fil_iovar_int_get(ifp, "rxstreams", &rxstreams);
73547385
(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
73557386
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
73567387
&txbf_bfe_cap);
@@ -7366,8 +7397,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73667397
if (nmode)
73677398
brcmf_update_ht_cap(band, bw_cap, nchain);
73687399
if (vhtmode)
7369-
brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7370-
txbf_bfe_cap, txbf_bfr_cap);
7400+
brcmf_update_vht_cap(band, bw_cap, txstreams, rxstreams,
7401+
txbf_bfe_cap, txbf_bfr_cap,
7402+
ldpc_cap, stbc_rx, stbc_tx);
73717403
}
73727404

73737405
return 0;

0 commit comments

Comments
 (0)