Skip to content

Commit 42d98d9

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 10e5619 commit 42d98d9

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
@@ -7293,20 +7293,22 @@ static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
72937293
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
72947294
}
72957295

7296-
static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7296+
static __le16 brcmf_get_mcs_map(u32 nstreams,
7297+
enum ieee80211_vht_mcs_support supp)
72977298
{
72987299
u16 mcs_map;
72997300
int i;
73007301

7301-
for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7302+
for (i = 0, mcs_map = 0xFFFF; i < nstreams; i++)
73027303
mcs_map = (mcs_map << 2) | supp;
73037304

73047305
return cpu_to_le16(mcs_map);
73057306
}
73067307

73077308
static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7308-
u32 bw_cap[2], u32 nchain, u32 txstreams,
7309-
u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7309+
u32 bw_cap[2], u32 txstreams, u32 rxstreams,
7310+
u32 txbf_bfe_cap, u32 txbf_bfr_cap,
7311+
u32 ldpc_cap, u32 stbc_rx, u32 stbc_tx)
73107312
{
73117313
__le16 mcs_map;
73127314

@@ -7315,15 +7317,32 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
73157317
return;
73167318

73177319
band->vht_cap.vht_supported = true;
7320+
band->vht_cap.vht_mcs.tx_highest = cpu_to_le16(433 * txstreams);
7321+
band->vht_cap.vht_mcs.rx_highest = cpu_to_le16(433 * rxstreams);
7322+
7323+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
7324+
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
7325+
7326+
if (ldpc_cap)
7327+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
7328+
if (stbc_tx)
7329+
band->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
7330+
7331+
if (stbc_rx)
7332+
band->vht_cap.cap |=
7333+
(stbc_rx << IEEE80211_VHT_CAP_RXSTBC_SHIFT);
7334+
73187335
/* 80MHz is mandatory */
73197336
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
73207337
if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
73217338
band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
73227339
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
73237340
}
73247341
/* all support 256-QAM */
7325-
mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7342+
mcs_map = brcmf_get_mcs_map(rxstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
73267343
band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7344+
mcs_map = brcmf_get_mcs_map(txstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
7345+
73277346
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
73287347

73297348
/* Beamforming support information */
@@ -7339,11 +7358,15 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
73397358
if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
73407359
band->vht_cap.cap |=
73417360
(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7342-
band->vht_cap.cap |= ((txstreams - 1) <<
7343-
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7361+
band->vht_cap.cap |=
7362+
((txstreams - 1)
7363+
<< IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
73447364
band->vht_cap.cap |=
73457365
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
73467366
}
7367+
/* AMPDU length limit, support max 1MB (2 ^ (13 + 7)) */
7368+
band->vht_cap.cap |=
7369+
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
73477370
}
73487371

73497372
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
@@ -7360,10 +7383,17 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73607383
s32 i;
73617384
struct ieee80211_supported_band *band;
73627385
u32 txstreams = 0;
7386+
u32 rxstreams = 0;
73637387
u32 txbf_bfe_cap = 0;
73647388
u32 txbf_bfr_cap = 0;
7389+
u32 ldpc_cap = 0;
7390+
u32 stbc_rx = 0;
7391+
u32 stbc_tx = 0;
73657392

73667393
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7394+
(void)brcmf_fil_iovar_int_get(ifp, "ldpc_cap", &ldpc_cap);
7395+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_rx", &stbc_rx);
7396+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_tx", &stbc_tx);
73677397
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
73687398
if (err) {
73697399
bphy_err(drvr, "nmode error (%d)\n", err);
@@ -7396,6 +7426,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73967426
}
73977427

73987428
if (vhtmode) {
7429+
(void)brcmf_fil_iovar_int_get(ifp, "rxstreams", &rxstreams);
73997430
(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
74007431
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
74017432
&txbf_bfe_cap);
@@ -7411,8 +7442,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
74117442
if (nmode)
74127443
brcmf_update_ht_cap(band, bw_cap, nchain);
74137444
if (vhtmode)
7414-
brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7415-
txbf_bfe_cap, txbf_bfr_cap);
7445+
brcmf_update_vht_cap(band, bw_cap, txstreams, rxstreams,
7446+
txbf_bfe_cap, txbf_bfr_cap,
7447+
ldpc_cap, stbc_rx, stbc_tx);
74167448
}
74177449

74187450
return 0;

0 commit comments

Comments
 (0)