Skip to content

Commit db9c02f

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 7a1875d commit db9c02f

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
@@ -7235,20 +7235,22 @@ static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
72357235
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
72367236
}
72377237

7238-
static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7238+
static __le16 brcmf_get_mcs_map(u32 nstreams,
7239+
enum ieee80211_vht_mcs_support supp)
72397240
{
72407241
u16 mcs_map;
72417242
int i;
72427243

7243-
for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7244+
for (i = 0, mcs_map = 0xFFFF; i < nstreams; i++)
72447245
mcs_map = (mcs_map << 2) | supp;
72457246

72467247
return cpu_to_le16(mcs_map);
72477248
}
72487249

72497250
static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7250-
u32 bw_cap[2], u32 nchain, u32 txstreams,
7251-
u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7251+
u32 bw_cap[2], u32 txstreams, u32 rxstreams,
7252+
u32 txbf_bfe_cap, u32 txbf_bfr_cap,
7253+
u32 ldpc_cap, u32 stbc_rx, u32 stbc_tx)
72527254
{
72537255
__le16 mcs_map;
72547256

@@ -7257,15 +7259,32 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72577259
return;
72587260

72597261
band->vht_cap.vht_supported = true;
7262+
band->vht_cap.vht_mcs.tx_highest = cpu_to_le16(433 * txstreams);
7263+
band->vht_cap.vht_mcs.rx_highest = cpu_to_le16(433 * rxstreams);
7264+
7265+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
7266+
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
7267+
7268+
if (ldpc_cap)
7269+
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
7270+
if (stbc_tx)
7271+
band->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
7272+
7273+
if (stbc_rx)
7274+
band->vht_cap.cap |=
7275+
(stbc_rx << IEEE80211_VHT_CAP_RXSTBC_SHIFT);
7276+
72607277
/* 80MHz is mandatory */
72617278
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
72627279
if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
72637280
band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
72647281
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
72657282
}
72667283
/* all support 256-QAM */
7267-
mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7284+
mcs_map = brcmf_get_mcs_map(rxstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
72687285
band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7286+
mcs_map = brcmf_get_mcs_map(txstreams, IEEE80211_VHT_MCS_SUPPORT_0_9);
7287+
72697288
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
72707289

72717290
/* Beamforming support information */
@@ -7281,11 +7300,15 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
72817300
if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
72827301
band->vht_cap.cap |=
72837302
(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7284-
band->vht_cap.cap |= ((txstreams - 1) <<
7285-
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7303+
band->vht_cap.cap |=
7304+
((txstreams - 1)
7305+
<< IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
72867306
band->vht_cap.cap |=
72877307
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
72887308
}
7309+
/* AMPDU length limit, support max 1MB (2 ^ (13 + 7)) */
7310+
band->vht_cap.cap |=
7311+
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
72897312
}
72907313

72917314
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
@@ -7302,10 +7325,17 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73027325
s32 i;
73037326
struct ieee80211_supported_band *band;
73047327
u32 txstreams = 0;
7328+
u32 rxstreams = 0;
73057329
u32 txbf_bfe_cap = 0;
73067330
u32 txbf_bfr_cap = 0;
7331+
u32 ldpc_cap = 0;
7332+
u32 stbc_rx = 0;
7333+
u32 stbc_tx = 0;
73077334

73087335
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7336+
(void)brcmf_fil_iovar_int_get(ifp, "ldpc_cap", &ldpc_cap);
7337+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_rx", &stbc_rx);
7338+
(void)brcmf_fil_iovar_int_get(ifp, "stbc_tx", &stbc_tx);
73097339
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
73107340
if (err) {
73117341
bphy_err(drvr, "nmode error (%d)\n", err);
@@ -7338,6 +7368,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73387368
}
73397369

73407370
if (vhtmode) {
7371+
(void)brcmf_fil_iovar_int_get(ifp, "rxstreams", &rxstreams);
73417372
(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
73427373
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
73437374
&txbf_bfe_cap);
@@ -7353,8 +7384,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
73537384
if (nmode)
73547385
brcmf_update_ht_cap(band, bw_cap, nchain);
73557386
if (vhtmode)
7356-
brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7357-
txbf_bfe_cap, txbf_bfr_cap);
7387+
brcmf_update_vht_cap(band, bw_cap, txstreams, rxstreams,
7388+
txbf_bfe_cap, txbf_bfr_cap,
7389+
ldpc_cap, stbc_rx, stbc_tx);
73587390
}
73597391

73607392
return 0;

0 commit comments

Comments
 (0)