qcacld-3.0: Update 11AX - Draft 1.4 MCS support - 2/2

Update driver to conform with Draft 1.4 MCS frame parser changes made
as part of Change-Id: I207db123d463f54ed6b148c9e957eb551d617ca2.

Change-Id: I4007ce0303b87c281b6fb2a94df576ee0da3f3e8
CRs-Fixed: 2130185
This commit is contained in:
Naveen Rawat 2017-10-16 16:55:31 -07:00 • committed by snandini
commit aeca1b93d6
13 changed files with 510 additions and 179 deletions

View file

@ -53,6 +53,7 @@ static int hdd_he_set_wni_cfg(struct hdd_context *hdd_ctx,
void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
struct wma_tgt_cfg *cfg)
{
uint8_t chan_width;
uint32_t ppet_size = sizeof(tDot11fIEppe_threshold);
QDF_STATUS status;
tDot11fIEhe_cap *he_cap = &cfg->he_cap;
@ -108,7 +109,12 @@ void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
he_cap->ops_supp);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DUAL_BAND, he_cap->dual_band);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CHAN_WIDTH, he_cap->chan_width);
chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
he_cap->chan_width_1, he_cap->chan_width_2,
he_cap->chan_width_3, he_cap->chan_width_4,
he_cap->chan_width_5, he_cap->chan_width_6);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CHAN_WIDTH, chan_width);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_PREAM_PUNC,
he_cap->rx_pream_puncturing);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CLASS_OF_DEVICE,
@ -165,8 +171,19 @@ void hdd_update_tgt_he_cap(struct hdd_context *hdd_ctx,
he_cap->stbc_gt_80mhz);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_ER_4x_LTF_GI,
he_cap->er_he_ltf_800_gi_4x);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NSS, he_cap->nss_supported);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MCS, he_cap->mcs_supported);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_MCS_MAP_LT_80,
he_cap->rx_he_mcs_map_lt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_MCS_MAP_LT_80,
he_cap->tx_he_mcs_map_lt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_MCS_MAP_160,
*((uint16_t *)he_cap->rx_he_mcs_map_160));
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_MCS_MAP_160,
*((uint16_t *)he_cap->tx_he_mcs_map_160));
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_MCS_MAP_80_80,
*((uint16_t *)he_cap->rx_he_mcs_map_80_80));
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TX_MCS_MAP_80_80,
*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
/* PPET can not be configured by user - Set values from FW */
status = sme_cfg_set_str(hdd_ctx->hHal, WNI_CFG_HE_PPET,

View file

@ -406,8 +406,12 @@ typedef struct sSirSupportedRates {
uint16_t vhtTxMCSMap;
uint16_t vhtTxHighestDataRate;
#ifdef WLAN_FEATURE_11AX
uint32_t he_rx_mcs;
uint32_t he_tx_mcs;
uint16_t rx_he_mcs_map_lt_80;
uint16_t tx_he_mcs_map_lt_80;
uint16_t rx_he_mcs_map_160;
uint16_t tx_he_mcs_map_160;
uint16_t rx_he_mcs_map_80_80;
uint16_t tx_he_mcs_map_80_80;
#endif
} tSirSupportedRates, *tpSirSupportedRates;
@ -7574,16 +7578,77 @@ struct wow_enable_params {
#define HE_MAX_PHY_CAP_SIZE 3
/*
* Three bits are used for each MCS
* For SS - 1; bits 0-2
* For SS - 2; bits 3-5
* MCS values are interpreted as in IEEE 11ax-D1.0 spec
*/
#define HE_MCS_1x1 0xFFFFFFF8
#define HE_MCS_2x2 0xFFFFFFC0
#define HE_CH_WIDTH_GET_BIT(ch_wd, bit) (((ch_wd) >> (bit)) & 1)
#define HE_CH_WIDTH_COMBINE(b0, b1, b2, b3, b4, b5, b6) \
((uint8_t)(b0) | ((b1) << 1) | ((b2) << 2) | ((b3) << 3) | \
((b4) << 4) | ((b5) << 5) | ((b6) << 6))
#define HEMCSSIZE 3
/*
* MCS values are interpreted as in IEEE 11ax-D1.4 spec onwards
* +-----------------------------------------------------+
* | SS8 | SS7 | SS6 | SS5 | SS4 | SS3 | SS2 | SS1 |
* +-----------------------------------------------------+
* | 15-14 | 13-12 | 11-10 | 9-8 | 7-6 | 5-4 | 3-2 | 1-0 |
* +-----------------------------------------------------+
*/
#define HE_MCS_NSS_SHIFT(nss) (((nss) - 1) << 1)
#define HE_MCS_MSK_4_NSS(nss) (3 << HE_MCS_NSS_SHIFT(nss))
#define HE_MCS_INV_MSK_4_NSS(nss) (~HE_MCS_MSK_4_NSS(nss))
#define HE_GET_MCS_4_NSS(mcs_set, nss) \
(((mcs_set) >> HE_MCS_NSS_SHIFT(nss)) & 3)
#define HE_SET_MCS_4_NSS(mcs_set, mcs, nss) \
(((mcs_set) & HE_MCS_INV_MSK_4_NSS(nss)) | \
((mcs) << HE_MCS_NSS_SHIFT(nss)))
#define HE_MCS_IS_NSS_ENABLED(mcs_set, nss) \
((HE_MCS_MSK_4_NSS(nss) & (mcs_set)) != HE_MCS_MSK_4_NSS(nss))
#define HE_MCS_ALL_DISABLED 0xFFFF
/*
* Following formuala has been arrived at using karnaugh map and unit tested
* with sample code. Take MCS for each NSS as 2 bit value first and solve for
* 2 bit intersection of NSS. Use following table/Matrix as guide for solving
* K-Maps
* MCS 1\MCS 2 00 01 10 11
* 00 00 00 00 11
* 01 00 01 01 11
* 10 00 01 10 11
* 11 11 11 11 11
* if output MCS is o1o0, then as per K-map reduction:
* o0 = m1.m0 | n1.n0 | (~m1).m0.(n1^n0) | (~n1).n0.(m1^m0)
* o1 = m1.m0 | n1.n0 | m1.(~m0).n1.(~n0)
*
* Please note: Calculating MCS intersection is 80211 protocol specific and
* should be implemented in PE. WMA can use this macro rather than calling any
* lim API to do the intersection.
*/
#define HE_INTERSECT_MCS_BITS_PER_NSS(m1, m0, n1, n0) \
(((m1 & m0) | (n1 & n0) | (((~m1) & m0) & (n1 ^ n0)) | \
(((~n1) & n0) & (m1 ^ m0))) | (((m1 & m0) | (n1 & n0) | \
(m1 & ~m0 & n1 & ~n0)) << 1))
/* following takes MCS as 2 bits */
#define HE_INTERSECT_MCS_PER_NSS(mcs_1, mcs_2) \
HE_INTERSECT_MCS_BITS_PER_NSS((mcs_1 >> 1), (mcs_1 & 1), \
(mcs_2 >> 1), (mcs_2 & 1))
/* following takes MCS as 16 bits */
#define HE_INTERSECT_MCS(mcs_1, mcs_2) ( \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 1), \
HE_GET_MCS_4_NSS(mcs_2, 1)) << HE_MCS_NSS_SHIFT(1) | \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 2), \
HE_GET_MCS_4_NSS(mcs_2, 2)) << HE_MCS_NSS_SHIFT(2) | \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 3), \
HE_GET_MCS_4_NSS(mcs_2, 3)) << HE_MCS_NSS_SHIFT(3) | \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 4), \
HE_GET_MCS_4_NSS(mcs_2, 4)) << HE_MCS_NSS_SHIFT(4) | \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 5), \
HE_GET_MCS_4_NSS(mcs_2, 5)) << HE_MCS_NSS_SHIFT(5) | \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 6), \
HE_GET_MCS_4_NSS(mcs_2, 6)) << HE_MCS_NSS_SHIFT(6) | \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 7), \
HE_GET_MCS_4_NSS(mcs_2, 7)) << HE_MCS_NSS_SHIFT(7) | \
HE_INTERSECT_MCS_PER_NSS(HE_GET_MCS_4_NSS(mcs_1, 8), \
HE_GET_MCS_4_NSS(mcs_2, 8)) << HE_MCS_NSS_SHIFT(8))
/**
* struct he_capability - to store 11ax HE capabilities
@ -7600,6 +7665,13 @@ struct he_capability {
};
#endif
#define HE_GET_NSS(mcs, nss) \
do { \
(nss) = 0; \
while ((((mcs) >> ((nss)*2)) & 3) != 3 && nss <= 8) \
(nss)++; \
} while (0)
/**
* struct sir_del_all_tdls_peers - delete all tdls peers
* @msg_type: type of message

View file

@ -2175,10 +2175,12 @@ struct he_capability_info {
uint8_t reserved2:3;
uint8_t er_he_ltf_800_gi_4x:1;
uint16_t rx_bw_bitmap:5;
uint16_t tx_bw_bitmap:5;
uint16_t mcs_supported:3;
uint16_t nss_supported:3;
uint16_t tx_he_mcs_map_80_80;
uint16_t rx_he_mcs_map_80_80;
uint16_t tx_he_mcs_map_160;
uint16_t rx_he_mcs_map_160;
uint16_t tx_he_mcs_map_lt_80;
uint16_t rx_he_mcs_map_lt_80;
#else
uint32_t htc_he:1;
uint32_t twt_request:1;
@ -2251,14 +2253,21 @@ struct he_capability_info {
uint8_t er_he_ltf_800_gi_4x:1;
uint8_t reserved3:7;
uint16_t nss_supported:3;
uint16_t mcs_supported:3;
uint16_t tx_bw_bitmap:5;
uint16_t rx_bw_bitmap:5;
uint16_t rx_he_mcs_map_lt_80;
uint16_t tx_he_mcs_map_lt_80;
uint16_t rx_he_mcs_map_160;
uint16_t tx_he_mcs_map_160;
uint16_t rx_he_mcs_map_80_80;
uint16_t tx_he_mcs_map_80_80;
#endif
} qdf_packed;
#endif
/*
* frame parser does not include optional 160 and 80+80 mcs set for MIN IE len
*/
#define SIR_MAC_HE_CAP_MIN_LEN (DOT11F_IE_HE_CAP_MIN_LEN + 8)
/* QOS action frame definitions */
/* max number of possible tclas elements in any frame */

View file

@ -315,8 +315,12 @@ enum {
WNI_CFG_HE_MAX_NC,
WNI_CFG_HE_STBC_GT80,
WNI_CFG_HE_ER_4x_LTF_GI,
WNI_CFG_HE_NSS,
WNI_CFG_HE_MCS,
WNI_CFG_HE_RX_MCS_MAP_LT_80,
WNI_CFG_HE_TX_MCS_MAP_LT_80,
WNI_CFG_HE_RX_MCS_MAP_160,
WNI_CFG_HE_TX_MCS_MAP_160,
WNI_CFG_HE_RX_MCS_MAP_80_80,
WNI_CFG_HE_TX_MCS_MAP_80_80,
WNI_CFG_HE_PPET,
WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT,
WNI_CFG_HE_STA_OBSSPD,
@ -1617,13 +1621,29 @@ enum {
#define WNI_CFG_HE_ER_4x_LTF_GI_STAMAX 1
#define WNI_CFG_HE_ER_4x_LTF_GI_STADEF 0
#define WNI_CFG_HE_NSS_STAMIN 0
#define WNI_CFG_HE_NSS_STAMAX 0x7
#define WNI_CFG_HE_NSS_STADEF 0
#define WNI_CFG_HE_RX_MCS_MAP_LT_80_MIN 0x0000
#define WNI_CFG_HE_RX_MCS_MAP_LT_80_MAX 0xFFFF
#define WNI_CFG_HE_RX_MCS_MAP_LT_80_DEF 0xFFF0
#define WNI_CFG_HE_MCS_STAMIN 0
#define WNI_CFG_HE_MCS_STAMAX 0x7
#define WNI_CFG_HE_MCS_STADEF 0
#define WNI_CFG_HE_TX_MCS_MAP_LT_80_MIN 0x0000
#define WNI_CFG_HE_TX_MCS_MAP_LT_80_MAX 0xFFFF
#define WNI_CFG_HE_TX_MCS_MAP_LT_80_DEF 0xFFF0
#define WNI_CFG_HE_RX_MCS_MAP_160_MIN 0x0000
#define WNI_CFG_HE_RX_MCS_MAP_160_MAX 0xFFFF
#define WNI_CFG_HE_RX_MCS_MAP_160_DEF 0xFFF0
#define WNI_CFG_HE_TX_MCS_MAP_160_MIN 0x0000
#define WNI_CFG_HE_TX_MCS_MAP_160_MAX 0xFFFF
#define WNI_CFG_HE_TX_MCS_MAP_160_DEF 0xFFF0
#define WNI_CFG_HE_RX_MCS_MAP_80_80_MIN 0x0000
#define WNI_CFG_HE_RX_MCS_MAP_80_80_MAX 0xFFFF
#define WNI_CFG_HE_RX_MCS_MAP_80_80_DEF 0xFFF0
#define WNI_CFG_HE_TX_MCS_MAP_80_80_MIN 0x0000
#define WNI_CFG_HE_TX_MCS_MAP_80_80_MAX 0xFFFF
#define WNI_CFG_HE_TX_MCS_MAP_80_80_DEF 0xFFF0
#define WNI_CFG_HE_STA_OBSSPD_STAMIN 0
#define WNI_CFG_HE_STA_OBSSPD_STAMAX 0xffffffff

View file

@ -324,8 +324,12 @@ const char *cfg_get_string(uint16_t cfg_id)
CASE_RETURN_STRING(WNI_CFG_HE_MAX_NC);
CASE_RETURN_STRING(WNI_CFG_HE_STBC_GT80);
CASE_RETURN_STRING(WNI_CFG_HE_ER_4x_LTF_GI);
CASE_RETURN_STRING(WNI_CFG_HE_NSS);
CASE_RETURN_STRING(WNI_CFG_HE_MCS);
CASE_RETURN_STRING(WNI_CFG_HE_RX_MCS_MAP_LT_80);
CASE_RETURN_STRING(WNI_CFG_HE_TX_MCS_MAP_LT_80);
CASE_RETURN_STRING(WNI_CFG_HE_RX_MCS_MAP_160);
CASE_RETURN_STRING(WNI_CFG_HE_TX_MCS_MAP_160);
CASE_RETURN_STRING(WNI_CFG_HE_RX_MCS_MAP_80_80);
CASE_RETURN_STRING(WNI_CFG_HE_TX_MCS_MAP_80_80);
CASE_RETURN_STRING(WNI_CFG_HE_PPET);
CASE_RETURN_STRING(WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT);
CASE_RETURN_STRING(WNI_CFG_HE_STA_OBSSPD);

View file

@ -1409,14 +1409,37 @@ cgstatic cfg_static[CFG_PARAM_MAX_NUM] = {
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_HE_ER_4x_LTF_GI_STAMIN, WNI_CFG_HE_ER_4x_LTF_GI_STAMAX,
WNI_CFG_HE_ER_4x_LTF_GI_STADEF},
{WNI_CFG_HE_NSS,
{WNI_CFG_HE_RX_MCS_MAP_LT_80,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_HE_NSS_STAMIN, WNI_CFG_HE_NSS_STAMAX,
WNI_CFG_HE_NSS_STADEF},
{WNI_CFG_HE_MCS,
WNI_CFG_HE_RX_MCS_MAP_LT_80_MIN, WNI_CFG_HE_RX_MCS_MAP_LT_80_MAX,
WNI_CFG_HE_RX_MCS_MAP_LT_80_DEF},
{WNI_CFG_HE_TX_MCS_MAP_LT_80,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_HE_MCS_STAMIN, WNI_CFG_HE_MCS_STAMAX,
WNI_CFG_HE_MCS_STADEF},
WNI_CFG_HE_TX_MCS_MAP_LT_80_MIN, WNI_CFG_HE_TX_MCS_MAP_LT_80_MAX,
WNI_CFG_HE_TX_MCS_MAP_LT_80_DEF},
{WNI_CFG_HE_RX_MCS_MAP_160,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_HE_RX_MCS_MAP_160_MIN, WNI_CFG_HE_RX_MCS_MAP_160_MAX,
WNI_CFG_HE_RX_MCS_MAP_160_DEF},
{WNI_CFG_HE_TX_MCS_MAP_160,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_HE_TX_MCS_MAP_160_MIN, WNI_CFG_HE_TX_MCS_MAP_160_MAX,
WNI_CFG_HE_TX_MCS_MAP_160_DEF},
{WNI_CFG_HE_RX_MCS_MAP_80_80,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_HE_RX_MCS_MAP_80_80_MIN, WNI_CFG_HE_RX_MCS_MAP_80_80_MAX,
WNI_CFG_HE_RX_MCS_MAP_80_80_DEF},
{WNI_CFG_HE_TX_MCS_MAP_80_80,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
WNI_CFG_HE_TX_MCS_MAP_80_80_MIN, WNI_CFG_HE_TX_MCS_MAP_80_80_MAX,
WNI_CFG_HE_TX_MCS_MAP_80_80_DEF},
{WNI_CFG_HE_PPET,
CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
0, 0, 0},

View file

@ -1778,7 +1778,7 @@ lim_populate_peer_rate_set(tpAniSirGlobal pMac,
psessionEntry, psessionEntry->nss);
if (IS_DOT11_MODE_HE(psessionEntry->dot11mode) && he_caps) {
psessionEntry->nss = he_caps->nss_supported;
HE_GET_NSS(he_caps->rx_he_mcs_map_lt_80, psessionEntry->nss);
} else if (IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) {
if ((pRates->vhtRxMCSMap & MCSMAPMASK2x2) == MCSMAPMASK2x2)
psessionEntry->nss = NSS_1x1_MODE;

View file

@ -1726,11 +1726,6 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
session->vht_config.su_beam_former);
}
if (IS_DOT11_MODE_HE(session->dot11mode)) {
lim_update_session_he_capable(mac_ctx, session);
lim_copy_join_req_he_cap(session, sme_join_req);
}
pe_debug("vhtCapability: %d su_beam_formee: %d txbf_csn_value: %d su_tx_bformer %d",
session->vhtCapability,
session->vht_config.su_beam_formee,
@ -1763,6 +1758,12 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
session->ch_width = CH_WIDTH_20MHZ;
}
if (IS_DOT11_MODE_HE(session->dot11mode)) {
lim_update_session_he_capable(mac_ctx, session);
lim_copy_join_req_he_cap(session, sme_join_req);
}
/* Record if management frames need to be protected */
#ifdef WLAN_FEATURE_11W
if (eSIR_ED_AES_128_CMAC == sme_join_req->MgmtEncryptionType)

View file

@ -7388,10 +7388,23 @@ void lim_copy_join_req_he_cap(tpPESession session,
{
qdf_mem_copy(&(session->he_config), &(sme_join_req->he_config),
sizeof(session->he_config));
if (session->ch_width <= CH_WIDTH_80MHZ) {
*(uint16_t *)session->he_config.rx_he_mcs_map_160 =
HE_MCS_ALL_DISABLED;
*(uint16_t *)session->he_config.tx_he_mcs_map_160 =
HE_MCS_ALL_DISABLED;
*(uint16_t *)session->he_config.rx_he_mcs_map_80_80 =
HE_MCS_ALL_DISABLED;
*(uint16_t *)session->he_config.tx_he_mcs_map_80_80 =
HE_MCS_ALL_DISABLED;
}
}
void lim_log_he_cap(tpAniSirGlobal mac, tDot11fIEhe_cap *he_cap)
{
uint8_t chan_width;
if (!he_cap->present)
return;
@ -7448,8 +7461,12 @@ void lim_log_he_cap(tpAniSirGlobal mac, tDot11fIEhe_cap *he_cap)
/* HE PHY capabilities */
pe_debug("\tDual band support: 0x%01x", he_cap->dual_band);
pe_debug("\tChannel width support: 0x%07x",
he_cap->chan_width);
chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
he_cap->chan_width_1, he_cap->chan_width_2,
he_cap->chan_width_3, he_cap->chan_width_4,
he_cap->chan_width_5, he_cap->chan_width_6);
pe_debug("\tChannel width support: 0x%07x", chan_width);
pe_debug("\tPreamble puncturing Rx: 0x%04x",
he_cap->rx_pream_puncturing);
pe_debug("\tClass of device: 0x%01x", he_cap->device_class);
@ -7501,12 +7518,18 @@ void lim_log_he_cap(tpAniSirGlobal mac, tDot11fIEhe_cap *he_cap)
pe_debug("\tMax Nc: 0x%03x", he_cap->max_nc);
pe_debug("\tER 4x HE LTF support: 0x%01x", he_cap->er_he_ltf_800_gi_4x);
pe_debug("\tHighest NSS supported: 0x%03x",
he_cap->nss_supported);
pe_debug("\tHighest MCS supported: 0x%03x",
he_cap->mcs_supported);
pe_debug("\tTX BW bitmap: 0x%05x", he_cap->tx_bw_bitmap);
pe_debug("\tRX BW bitmap: 0x%05x ", he_cap->rx_bw_bitmap);
pe_debug("\tRx MCS map for <= 80 Mhz: 0x%04x",
he_cap->rx_he_mcs_map_lt_80);
pe_debug("\tTx MCS map for <= 80 Mhz: 0x%04x",
he_cap->tx_he_mcs_map_lt_80);
pe_debug("\tRx MCS map for <= 160 Mhz: 0x%04x",
*((uint16_t *)he_cap->rx_he_mcs_map_160));
pe_debug("\tTx MCS map for <= 160 Mhz: 0x%04x",
*((uint16_t *)he_cap->tx_he_mcs_map_160));
pe_debug("\tRx MCS map for <= 80+80 Mhz: 0x%04x",
*((uint16_t *)he_cap->rx_he_mcs_map_80_80));
pe_debug("\tTx MCS map for <= 80+80 Mhz: 0x%04x",
*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
/* HE PPET */
if (!he_cap->ppet_present)
@ -7630,7 +7653,12 @@ void lim_set_he_caps(tpAniSirGlobal mac, tpPESession session, uint8_t *ie_start,
he_cap->reserved1 = dot11_cap.reserved1;
he_cap->dual_band = dot11_cap.dual_band;
he_cap->chan_width = dot11_cap.chan_width;
he_cap->chan_width = HE_CH_WIDTH_COMBINE(dot11_cap.chan_width_0,
dot11_cap.chan_width_1, dot11_cap.chan_width_2,
dot11_cap.chan_width_3, dot11_cap.chan_width_4,
dot11_cap.chan_width_5, dot11_cap.chan_width_6);
he_cap->rx_pream_puncturing = dot11_cap.rx_pream_puncturing;
he_cap->device_class = dot11_cap.device_class;
he_cap->ldpc_coding = dot11_cap.ldpc_coding;
@ -7667,40 +7695,46 @@ void lim_set_he_caps(tpAniSirGlobal mac, tpPESession session, uint8_t *ie_start,
he_cap->er_he_ltf_800_gi_4x = dot11_cap.er_he_ltf_800_gi_4x;
he_cap->reserved2 = dot11_cap.reserved2;
he_cap->nss_supported = dot11_cap.nss_supported;
he_cap->mcs_supported = dot11_cap.mcs_supported;
he_cap->tx_bw_bitmap = dot11_cap.tx_bw_bitmap;
he_cap->rx_bw_bitmap = dot11_cap.rx_bw_bitmap;
he_cap->rx_he_mcs_map_lt_80 = dot11_cap.rx_he_mcs_map_lt_80;
he_cap->tx_he_mcs_map_lt_80 = dot11_cap.tx_he_mcs_map_lt_80;
he_cap->rx_he_mcs_map_160 =
*((uint16_t *)dot11_cap.rx_he_mcs_map_160);
he_cap->tx_he_mcs_map_160 =
*((uint16_t *)dot11_cap.tx_he_mcs_map_160);
he_cap->rx_he_mcs_map_80_80 =
*((uint16_t *)dot11_cap.rx_he_mcs_map_80_80);
he_cap->tx_he_mcs_map_80_80 =
*((uint16_t *)dot11_cap.tx_he_mcs_map_80_80);
}
}
QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx, tpPESession session,
uint8_t vdev_id)
{
uint8_t he_caps[DOT11F_IE_HE_CAP_MIN_LEN + 3];
uint8_t he_caps[SIR_MAC_HE_CAP_MIN_LEN + 3];
struct he_capability_info *he_cap;
QDF_STATUS status_5g, status_2g;
/* Sending only minimal info(no PPET) to FW now, update if required */
qdf_mem_zero(he_caps, DOT11F_IE_HE_CAP_MIN_LEN + 3);
qdf_mem_zero(he_caps, SIR_MAC_HE_CAP_MIN_LEN + 3);
he_caps[0] = DOT11F_EID_HE_CAP;
he_caps[1] = DOT11F_IE_HE_CAP_MIN_LEN;
he_caps[1] = SIR_MAC_HE_CAP_MIN_LEN;
qdf_mem_copy(&he_caps[2], HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE);
lim_set_he_caps(mac_ctx, session, he_caps,
DOT11F_IE_HE_CAP_MIN_LEN + 3);
SIR_MAC_HE_CAP_MIN_LEN + 3);
he_cap = (struct he_capability_info *) (&he_caps[2 + HE_CAP_OUI_SIZE]);
he_cap->ppet_present = 0;
status_5g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HE_CAP,
CDS_BAND_5GHZ, &he_caps[2],
DOT11F_IE_HE_CAP_MIN_LEN + 1);
SIR_MAC_HE_CAP_MIN_LEN + 1);
if (QDF_IS_STATUS_ERROR(status_5g))
pe_err("Unable send HE Cap IE for 5GHZ band, status: %d",
status_5g);
status_2g = lim_send_ie(mac_ctx, vdev_id, DOT11F_EID_HE_CAP,
CDS_BAND_2GHZ, &he_caps[2],
DOT11F_IE_HE_CAP_MIN_LEN + 1);
SIR_MAC_HE_CAP_MIN_LEN + 1);
if (QDF_IS_STATUS_ERROR(status_2g))
pe_err("Unable send HE Cap IE for 2GHZ band, status: %d",
status_2g);
@ -7713,64 +7747,88 @@ QDF_STATUS lim_send_he_caps_ie(tpAniSirGlobal mac_ctx, tpPESession session,
}
/**
* MCS-NSS Map will be as follows - Each MCS is 3 bits
* - 0 indicates support for HE-MCS 0-7 for n spatial streams
* - 1 indicates support for HE-MCS 0-8 for n spatial streams
* - 2 indicates support for HE-MCS 0-9 for n spatial streams
* - 3 indicates support for HE-MCS 0-10 for n spatial streams
* - 4 indicates support for HE-MCS 0-11 for n spatial streams
* - 5-6 reserved
* - 7 indicates that n spatial streams is not supported
* +-----+-----+-----+-----+-----+-----+-----+-----+-----+-
* | SS | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
* +-----+-----+-----+-----+-----+-----+-----+-----+-----+
* | MCS | 7 | 7 | 7 | 7 | 7 | 7 | 4 | 4 |
* +-----+-----+-----+-----+-----+-----+-----+-----+-----+
* lim_populate_he_mcs_per_bw() - pouldate HE mcs set per BW (le 80, 160, 80+80)
* @mac_ctx: Global MAC context
* @self_rx: self rx mcs set
* @self_tx: self tx mcs set
* @peer_rx: peer rx mcs set
* @peer_tx: peer tx mcs set
* @nss: nss
* @cfg_rx_param: rx wni param to read
* @cfg_tx_param: tx wni param to read
*
* MCS values are interpreted as in IEEE 11ax-D1.4 spec onwards
* +-----------------------------------------------------+
* | SS8 | SS7 | SS6 | SS5 | SS4 | SS3 | SS2 | SS1 |
* +-----------------------------------------------------+
* | 15-14 | 13-12 | 11-10 | 9-8 | 7-6 | 5-4 | 3-2 | 1-0 |
* +-----------------------------------------------------+
*
* Return: status of operation
*/
static QDF_STATUS lim_populate_he_mcs_per_bw(tpAniSirGlobal mac_ctx,
uint16_t *self_rx, uint16_t *self_tx,
uint16_t peer_rx, uint16_t peer_tx, uint8_t nss,
uint32_t cfg_rx_param, uint32_t cfg_tx_param)
{
uint32_t val;
pe_debug("peer rates: rx_mcs - 0x%04x tx_mcs - 0x%04x",
peer_rx, peer_tx);
if (wlan_cfg_get_int(mac_ctx, cfg_rx_param, &val) != eSIR_SUCCESS) {
pe_err("could not retrieve HE_MCS");
return QDF_STATUS_E_FAILURE;
}
*self_rx = (uint16_t) val;
if (wlan_cfg_get_int(mac_ctx, cfg_tx_param, &val) != eSIR_SUCCESS) {
pe_err("could not retrieve HE_MCS");
return QDF_STATUS_E_FAILURE;
}
*self_tx = (uint16_t) val;
*self_rx = HE_INTERSECT_MCS(*self_rx, peer_tx);
*self_tx = HE_INTERSECT_MCS(*self_tx, peer_rx);
if (nss == NSS_1x1_MODE) {
*self_rx |= HE_MCS_INV_MSK_4_NSS(1);
*self_tx |= HE_MCS_INV_MSK_4_NSS(1);
}
/* if nss is 2, disable higher NSS */
if (nss == NSS_2x2_MODE) {
*self_rx |= (HE_MCS_INV_MSK_4_NSS(1) & HE_MCS_INV_MSK_4_NSS(2));
*self_tx |= (HE_MCS_INV_MSK_4_NSS(1) & HE_MCS_INV_MSK_4_NSS(2));
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
tpSirSupportedRates rates,
tDot11fIEhe_cap *peer_he_caps,
tpPESession session_entry, uint8_t nss)
{
uint32_t val;
uint32_t self_sta_dot11mode = 0;
uint8_t self_mcs, peer_mcs, negotiated_mcs;
uint32_t mcsmap = 0xFFFFFFFF;
bool support_2x2 = false;
uint32_t self_sta_dot11mode = 0;
wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
if (!IS_DOT11_MODE_HE(self_sta_dot11mode))
return QDF_STATUS_SUCCESS;
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_HE_MCS, &val) != eSIR_SUCCESS) {
pe_err("could not retrieve HE_MCS");
goto error;
}
self_mcs = (uint16_t) val;
if (NSS_1x1_MODE == nss) {
/* Add MCS for SS-1 */
mcsmap = self_mcs;
mcsmap |= HE_MCS_1x1;
} else if (NSS_2x2_MODE == nss) {
/* Add MCS for SS-1 */
mcsmap = self_mcs;
/* Add MCS for SS-2 */
mcsmap |= (self_mcs << HEMCSSIZE);
mcsmap |= HE_MCS_2x2;
}
rates->he_rx_mcs = rates->he_tx_mcs = mcsmap;
if ((peer_he_caps == NULL) || (!peer_he_caps->present)) {
pe_debug("self rate: nss %d he_rx_mcs - %x he_tx_mcs - %x",
nss, rates->he_rx_mcs, rates->he_tx_mcs);
pe_debug("peer not he capable or he_caps NULL");
return QDF_STATUS_SUCCESS;
}
pe_debug("peer rates: rx_mcs - %x tx_mcs - %x",
peer_he_caps->mcs_supported, peer_he_caps->mcs_supported);
pe_debug("peer rates lt 80: rx_mcs - 0x%04x tx_mcs - 0x%04x",
peer_he_caps->rx_he_mcs_map_lt_80,
peer_he_caps->tx_he_mcs_map_lt_80);
pe_debug("peer rates 160: rx_mcs - 0x%04x tx_mcs - 0x%04x",
(*(uint16_t *)peer_he_caps->rx_he_mcs_map_160),
(*(uint16_t *)peer_he_caps->tx_he_mcs_map_160));
pe_debug("peer rates 80+80: rx_mcs - 0x%04x tx_mcs - 0x%04x",
(*(uint16_t *)peer_he_caps->rx_he_mcs_map_80_80),
(*(uint16_t *)peer_he_caps->tx_he_mcs_map_80_80));
if (session_entry && session_entry->nss == NSS_2x2_MODE) {
if (mac_ctx->lteCoexAntShare &&
@ -7785,29 +7843,40 @@ QDF_STATUS lim_populate_he_mcs_set(tpAniSirGlobal mac_ctx,
}
}
peer_mcs = peer_he_caps->mcs_supported;
negotiated_mcs = QDF_MIN(peer_mcs, self_mcs);
if (support_2x2) {
/* Add MCS for SS-1 */
mcsmap = negotiated_mcs;
/* Add MCS for SS-2 */
mcsmap |= (negotiated_mcs << HEMCSSIZE);
mcsmap |= HE_MCS_2x2;
} else {
/* Add MCS for SS-1 */
mcsmap = negotiated_mcs;
mcsmap |= HE_MCS_1x1;
lim_populate_he_mcs_per_bw(mac_ctx,
&rates->rx_he_mcs_map_lt_80, &rates->tx_he_mcs_map_lt_80,
peer_he_caps->rx_he_mcs_map_lt_80,
peer_he_caps->tx_he_mcs_map_lt_80, nss,
WNI_CFG_HE_RX_MCS_MAP_LT_80, WNI_CFG_HE_TX_MCS_MAP_LT_80);
lim_populate_he_mcs_per_bw(mac_ctx,
&rates->rx_he_mcs_map_160, &rates->tx_he_mcs_map_160,
*((uint16_t *)peer_he_caps->rx_he_mcs_map_160),
*((uint16_t *)peer_he_caps->tx_he_mcs_map_160), nss,
WNI_CFG_HE_RX_MCS_MAP_160, WNI_CFG_HE_TX_MCS_MAP_160);
lim_populate_he_mcs_per_bw(mac_ctx,
&rates->rx_he_mcs_map_80_80, &rates->tx_he_mcs_map_80_80,
*((uint16_t *)peer_he_caps->rx_he_mcs_map_80_80),
*((uint16_t *)peer_he_caps->tx_he_mcs_map_80_80), nss,
WNI_CFG_HE_RX_MCS_MAP_80_80, WNI_CFG_HE_TX_MCS_MAP_80_80);
if (!support_2x2) {
/* disable 2 and higher NSS MCS sets */
rates->rx_he_mcs_map_lt_80 |= 0xFFFD;
rates->tx_he_mcs_map_lt_80 |= 0xFFFD;
rates->rx_he_mcs_map_160 |= 0xFFFD;
rates->tx_he_mcs_map_160 |= 0xFFFD;
rates->rx_he_mcs_map_80_80 |= 0xFFFD;
rates->tx_he_mcs_map_80_80 |= 0xFFFD;
}
rates->he_rx_mcs = rates->he_tx_mcs = mcsmap;
pe_debug("enable2x2 - %d nss %d he_rx_mcs - %x he_tx_mcs - %x",
mac_ctx->roam.configParam.enable2x2, nss,
rates->he_rx_mcs, rates->he_tx_mcs);
pe_debug("enable2x2 - %d nss %d",
mac_ctx->roam.configParam.enable2x2, nss);
pe_debug("he_rx_lt_80 - 0x%x he_tx_lt_80 0x%x",
rates->rx_he_mcs_map_lt_80, rates->tx_he_mcs_map_lt_80);
pe_debug("he_rx_160 - 0x%x he_tx_160 0x%x",
rates->rx_he_mcs_map_160, rates->tx_he_mcs_map_160);
pe_debug("he_rx_80_80 - 0x%x he_tx_80_80 0x%x",
rates->rx_he_mcs_map_80_80, rates->tx_he_mcs_map_80_80);
return QDF_STATUS_SUCCESS;
error:
return QDF_STATUS_E_FAILURE;
}
#endif

View file

@ -855,6 +855,7 @@ void lim_copy_bss_he_cap(tpPESession session,
/**
* lim_copy_join_req_he_cap() - Copy HE capability to PE session from Join req
* and update as per bandwidth supported
* @session: pointer to PE session
* @sme_join_req: pointer to SME join request
*

View file

@ -6118,7 +6118,14 @@ QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx, tpPESession session,
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DUAL_BAND, value);
he_cap->dual_band = value;
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CHAN_WIDTH, value);
he_cap->chan_width = value;
he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(value, 0);
he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(value, 1);
he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(value, 2);
he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(value, 3);
he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(value, 4);
he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(value, 5);
he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(value, 6);
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_PREAM_PUNC, value);
he_cap->rx_pream_puncturing = value;
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CLASS_OF_DEVICE, value);
@ -6183,10 +6190,23 @@ QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx, tpPESession session,
he_cap->stbc_gt_80mhz = value;
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ER_4x_LTF_GI, value);
he_cap->er_he_ltf_800_gi_4x = value;
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NSS, value);
he_cap->nss_supported = value;
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MCS, value);
he_cap->mcs_supported = value;
CFG_GET_INT(status, mac_ctx,
WNI_CFG_HE_RX_MCS_MAP_LT_80, value);
he_cap->rx_he_mcs_map_lt_80 = value;
CFG_GET_INT(status, mac_ctx,
WNI_CFG_HE_TX_MCS_MAP_LT_80, value);
he_cap->tx_he_mcs_map_lt_80 = value;
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_MCS_MAP_160, value);
*((uint16_t *)he_cap->rx_he_mcs_map_160) = value;
CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_MCS_MAP_160, value);
*((uint16_t *)he_cap->tx_he_mcs_map_160) = value;
CFG_GET_INT(status, mac_ctx,
WNI_CFG_HE_RX_MCS_MAP_80_80, value);
*((uint16_t *)he_cap->rx_he_mcs_map_80_80) = value;
CFG_GET_INT(status, mac_ctx,
WNI_CFG_HE_TX_MCS_MAP_80_80, value);
*((uint16_t *)he_cap->tx_he_mcs_map_80_80) = value;
if (he_cap->ppet_present) {
value = WNI_CFG_HE_PPET_LEN;

View file

@ -2329,7 +2329,14 @@ static void csr_update_session_he_cap(tpAniSirGlobal mac_ctx,
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_DUAL_BAND, &value);
he_cap->dual_band = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_CHAN_WIDTH, &value);
he_cap->chan_width = value;
he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(value, 0);
he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(value, 1);
he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(value, 2);
he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(value, 3);
he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(value, 4);
he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(value, 5);
he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(value, 6);
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_RX_PREAM_PUNC, &value);
he_cap->rx_pream_puncturing = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_CLASS_OF_DEVICE, &value);
@ -2394,10 +2401,19 @@ static void csr_update_session_he_cap(tpAniSirGlobal mac_ctx,
he_cap->stbc_gt_80mhz = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_ER_4x_LTF_GI, &value);
he_cap->er_he_ltf_800_gi_4x = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_NSS, &value);
he_cap->nss_supported = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_MCS, &value);
he_cap->mcs_supported = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_RX_MCS_MAP_LT_80, &value);
he_cap->rx_he_mcs_map_lt_80 = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_TX_MCS_MAP_LT_80, &value);
he_cap->tx_he_mcs_map_lt_80 = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_RX_MCS_MAP_160, &value);
*((uint16_t *)he_cap->rx_he_mcs_map_160) = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_TX_MCS_MAP_160, &value);
*((uint16_t *)he_cap->tx_he_mcs_map_160) = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_RX_MCS_MAP_80_80, &value);
*((uint16_t *)he_cap->rx_he_mcs_map_80_80) = value;
sme_cfg_get_int(mac_ctx, WNI_CFG_HE_TX_MCS_MAP_80_80, &value);
*((uint16_t *)he_cap->tx_he_mcs_map_80_80) = value;
if (he_cap->ppet_present) {
value = WNI_CFG_HE_PPET_LEN;

View file

@ -194,21 +194,14 @@ static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t mac_cap,
uint32_t supp_mcs, uint32_t tx_chain_mask,
uint32_t rx_chain_mask)
{
uint8_t nss, chan_width;
uint16_t rx_mcs_le_80, tx_mcs_le_80, rx_mcs_160, tx_mcs_160;
struct wmi_host_ppe_threshold *ppet = he_ppet;
uint8_t mcs, nss, k, mcs_temp;
nss = QDF_MAX(wma_get_num_of_setbits_from_bitmask(tx_chain_mask),
wma_get_num_of_setbits_from_bitmask(rx_chain_mask));
mcs = 0;
for (k = 1; k < nss; k++) {
mcs_temp = WMI_HE_MAX_MCS_4_SS_MASK(supp_mcs, k);
if (mcs_temp > mcs)
mcs = mcs_temp;
}
wma_get_num_of_setbits_from_bitmask(rx_chain_mask));
he_cap->present = true;
/* HE MAC capabilities */
he_cap->htc_he = WMI_HECAP_MAC_HECTRL_GET(mac_cap);
he_cap->twt_request = WMI_HECAP_MAC_TWTREQ_GET(mac_cap);
@ -242,7 +235,14 @@ static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t mac_cap,
/* HE PHY capabilities */
he_cap->dual_band = WMI_HECAP_PHY_DB_GET(phy_cap);
he_cap->chan_width = WMI_HECAP_PHY_CBW_GET(phy_cap);
chan_width = WMI_HECAP_PHY_CBW_GET(phy_cap);
he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(chan_width, 0);
he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(chan_width, 1);
he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(chan_width, 2);
he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(chan_width, 3);
he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(chan_width, 4);
he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(chan_width, 5);
he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(chan_width, 6);
he_cap->rx_pream_puncturing = WMI_HECAP_PHY_PREAMBLEPUNCRX_GET(phy_cap);
he_cap->device_class = WMI_HECAP_PHY_COD_GET(phy_cap);
he_cap->ldpc_coding = WMI_HECAP_PHY_LDPC_GET(phy_cap);
@ -287,12 +287,28 @@ static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t mac_cap,
he_cap->er_he_ltf_800_gi_4x =
WMI_HECAP_PHY_ERSU4X800NSECGI_GET(phy_cap);
he_cap->nss_supported = nss - 1;
he_cap->mcs_supported = mcs;
/* For Draft 1.0, following fields will be zero */
he_cap->tx_bw_bitmap = 0;
he_cap->rx_bw_bitmap = 0;
/*
* supp_mcs is split into 16 bits with lower indicating le_80 and
* upper indicating 160 and 80_80.
*/
WMA_LOGD(FL("supported_mcs: 0x%08x\n"), supp_mcs);
rx_mcs_le_80 = supp_mcs & 0xFFFF;
tx_mcs_le_80 = supp_mcs & 0xFFFF;
rx_mcs_160 = (supp_mcs & 0xFFFF0000) >> 16;
tx_mcs_160 = (supp_mcs & 0xFFFF0000) >> 16;
/* if FW indicated it is using 1x1 disable upper NSS-MCS sets */
if (nss == NSS_1x1_MODE) {
rx_mcs_le_80 |= HE_MCS_INV_MSK_4_NSS(1);
tx_mcs_le_80 |= HE_MCS_INV_MSK_4_NSS(1);
rx_mcs_160 |= HE_MCS_INV_MSK_4_NSS(1);
tx_mcs_160 |= HE_MCS_INV_MSK_4_NSS(1);
}
he_cap->rx_he_mcs_map_lt_80 = rx_mcs_le_80;
he_cap->tx_he_mcs_map_lt_80 = tx_mcs_le_80;
*((uint16_t *)he_cap->tx_he_mcs_map_160) = rx_mcs_160;
*((uint16_t *)he_cap->rx_he_mcs_map_160) = tx_mcs_160;
*((uint16_t *)he_cap->rx_he_mcs_map_80_80) = rx_mcs_160;
*((uint16_t *)he_cap->tx_he_mcs_map_80_80) = tx_mcs_160;
wma_convert_he_ppet(&he_cap->ppe_threshold, ppet);
}
@ -313,6 +329,8 @@ static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t mac_cap,
static void wma_derive_ext_he_cap(t_wma_handle *wma_handle,
tDot11fIEhe_cap *he_cap, tDot11fIEhe_cap *new_cap)
{
uint16_t mcs_1, mcs_2;
if (!he_cap->present) {
/* First time update, copy the capability as is */
qdf_mem_copy(he_cap, new_cap, sizeof(*he_cap));
@ -375,8 +393,22 @@ static void wma_derive_ext_he_cap(t_wma_handle *wma_handle,
he_cap->dual_band = QDF_MIN(he_cap->dual_band,
new_cap->dual_band);
he_cap->chan_width = QDF_MIN(he_cap->chan_width,
new_cap->chan_width);
he_cap->chan_width_0 = he_cap->chan_width_0 &
new_cap->chan_width_0;
he_cap->chan_width_1 = he_cap->chan_width_1 &
new_cap->chan_width_1;
he_cap->chan_width_2 = he_cap->chan_width_2 &
new_cap->chan_width_2;
he_cap->chan_width_3 = he_cap->chan_width_3 &
new_cap->chan_width_3;
he_cap->chan_width_4 = he_cap->chan_width_4 &
new_cap->chan_width_4;
he_cap->chan_width_5 = he_cap->chan_width_5 &
new_cap->chan_width_5;
he_cap->chan_width_6 = he_cap->chan_width_6 &
new_cap->chan_width_6;
he_cap->rx_pream_puncturing =
QDF_MIN(he_cap->rx_pream_puncturing,
new_cap->rx_pream_puncturing);
@ -438,20 +470,37 @@ static void wma_derive_ext_he_cap(t_wma_handle *wma_handle,
new_cap->he_ltf_800_gi_4x);
he_cap->reserved2 = QDF_MIN(he_cap->reserved2,
new_cap->reserved2);
he_cap->nss_supported = QDF_MIN(he_cap->nss_supported,
new_cap->nss_supported);
he_cap->mcs_supported = QDF_MIN(he_cap->mcs_supported,
new_cap->mcs_supported);
he_cap->tx_bw_bitmap = QDF_MIN(he_cap->tx_bw_bitmap,
new_cap->tx_bw_bitmap);
he_cap->rx_bw_bitmap = QDF_MIN(he_cap->rx_bw_bitmap,
new_cap->rx_bw_bitmap);
/* take intersection for MCS map */
mcs_1 = he_cap->rx_he_mcs_map_lt_80;
mcs_2 = new_cap->rx_he_mcs_map_lt_80;
he_cap->rx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(mcs_1, mcs_2);
mcs_1 = he_cap->tx_he_mcs_map_lt_80;
mcs_2 = new_cap->tx_he_mcs_map_lt_80;
he_cap->tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(mcs_1, mcs_2);
mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_160);
mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_160);
*((uint16_t *)he_cap->rx_he_mcs_map_160) =
HE_INTERSECT_MCS(mcs_1, mcs_2);
mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_160);
mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_160);
*((uint16_t *)he_cap->tx_he_mcs_map_160) =
HE_INTERSECT_MCS(mcs_1, mcs_2);
mcs_1 = *((uint16_t *)he_cap->rx_he_mcs_map_80_80);
mcs_2 = *((uint16_t *)new_cap->rx_he_mcs_map_80_80);
*((uint16_t *)he_cap->rx_he_mcs_map_80_80) =
HE_INTERSECT_MCS(mcs_1, mcs_2);
mcs_1 = *((uint16_t *)he_cap->tx_he_mcs_map_80_80);
mcs_2 = *((uint16_t *)new_cap->tx_he_mcs_map_80_80);
*((uint16_t *)he_cap->tx_he_mcs_map_80_80) =
HE_INTERSECT_MCS(mcs_1, mcs_2);
}
}
void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
{
uint8_t chan_width;
if (!he_cap->present) {
WMA_LOGI(FL("HE Capabilities not present"));
return;
@ -491,7 +540,12 @@ void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
/* HE PHY capabilities */
WMA_LOGD("\tDual band support: 0x%01x", he_cap->dual_band);
WMA_LOGD("\tChannel width support: 0x%07x", he_cap->chan_width);
chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
he_cap->chan_width_1, he_cap->chan_width_2,
he_cap->chan_width_3, he_cap->chan_width_4,
he_cap->chan_width_5, he_cap->chan_width_6);
WMA_LOGD("\tChannel width support: 0x%07x", chan_width);
WMA_LOGD("\tPreamble puncturing Rx: 0x%04x",
he_cap->rx_pream_puncturing);
WMA_LOGD("\tClass of device: 0x%01x", he_cap->device_class);
@ -532,10 +586,18 @@ void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
WMA_LOGD("\tPower boost factor: 0x%01x", he_cap->power_boost);
WMA_LOGD("\t4x HE LTF support: 0x%01x", he_cap->he_ltf_800_gi_4x);
WMA_LOGD("\tHighest NSS supported: 0x%03x", he_cap->nss_supported);
WMA_LOGD("\tHighest MCS supported: 0x%03x", he_cap->mcs_supported);
WMA_LOGD("\tTX BW bitmap: 0x%05x", he_cap->tx_bw_bitmap);
WMA_LOGD("\tRX BW bitmap: 0x%05x ", he_cap->rx_bw_bitmap);
WMA_LOGD("\tRx MCS MAP for BW <= 80 MHz: 0x%x",
he_cap->rx_he_mcs_map_lt_80);
WMA_LOGD("\tTx MCS MAP for BW <= 80 MHz: 0x%x",
he_cap->tx_he_mcs_map_lt_80);
WMA_LOGD("\tRx MCS MAP for BW = 160 MHz: 0x%x",
*((uint16_t *)he_cap->rx_he_mcs_map_160));
WMA_LOGD("\tTx MCS MAP for BW = 160 MHz: 0x%x",
*((uint16_t *)he_cap->tx_he_mcs_map_160));
WMA_LOGD("\tRx MCS MAP for BW = 80 + 80 MHz: 0x%x",
*((uint16_t *)he_cap->rx_he_mcs_map_80_80));
WMA_LOGD("\tTx MCS MAP for BW = 80 + 80 MHz: 0x%x",
*((uint16_t *)he_cap->tx_he_mcs_map_80_80));
/* HE PPET */
WMA_LOGD("\tNSS: %d", he_cap->ppe_threshold.nss_count + 1);
@ -934,7 +996,7 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
tDot11fIEhe_op *he_op = &params->he_op;
uint32_t *phy_cap = peer->peer_he_cap_phyinfo;
uint32_t mac_cap = 0, he_ops = 0;
uint8_t temp, i;
uint8_t temp, i, chan_width;
if (params->he_capable)
peer->peer_flags |= WMI_PEER_HE;
@ -975,7 +1037,11 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
/* HE PHY capabilities */
WMI_HECAP_PHY_DB_SET(phy_cap, he_cap->dual_band);
WMI_HECAP_PHY_CBW_SET(phy_cap, he_cap->chan_width);
chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
he_cap->chan_width_1, he_cap->chan_width_2,
he_cap->chan_width_3, he_cap->chan_width_4,
he_cap->chan_width_5, he_cap->chan_width_6);
WMI_HECAP_PHY_CBW_SET(phy_cap, chan_width);
WMI_HECAP_PHY_PREAMBLEPUNCRX_SET(phy_cap, he_cap->rx_pream_puncturing);
WMI_HECAP_PHY_COD_SET(phy_cap, he_cap->device_class);
WMI_HECAP_PHY_LDPC_SET(phy_cap, he_cap->ldpc_coding);
@ -1031,17 +1097,30 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
WMI_HECAP_PHY_ERSU4X800NSECGI_SET(phy_cap, he_cap->er_he_ltf_800_gi_4x);
/* until further update in standard */
peer->peer_he_mcs_count = WMI_HOST_MAX_HE_RATE_SET;
for (i = 0; i < peer->peer_he_mcs_count; i++) {
peer->peer_he_rx_mcs_set[i] = params->supportedRates.he_rx_mcs;
peer->peer_he_tx_mcs_set[i] = params->supportedRates.he_tx_mcs;
/* as per 11ax draft 1.4 */
peer->peer_he_mcs_count = 1;
peer->peer_he_rx_mcs_set[0] =
params->supportedRates.rx_he_mcs_map_lt_80;
peer->peer_he_tx_mcs_set[0] =
params->supportedRates.tx_he_mcs_map_lt_80;
WMA_LOGD(FL("[HE - MCS Map: %d] rx_mcs: %x, tx_mcs: %x"), i,
peer->peer_he_rx_mcs_set[i],
peer->peer_he_tx_mcs_set[i]);
if (params->ch_width > CH_WIDTH_80MHZ) {
peer->peer_he_mcs_count = WMI_HOST_MAX_HE_RATE_SET;
peer->peer_he_rx_mcs_set[1] =
params->supportedRates.rx_he_mcs_map_160;
peer->peer_he_tx_mcs_set[1] =
params->supportedRates.tx_he_mcs_map_160;
peer->peer_he_rx_mcs_set[2] =
params->supportedRates.rx_he_mcs_map_80_80;
peer->peer_he_tx_mcs_set[2] =
params->supportedRates.tx_he_mcs_map_80_80;
}
for (i = 0; i < peer->peer_he_mcs_count; i++)
WMA_LOGD(FL("[HE - MCS Map: %d] rx_mcs: 0x%x, tx_mcs: 0x%x"), i,
peer->peer_he_rx_mcs_set[i],
peer->peer_he_tx_mcs_set[i]);
WMI_HEOPS_COLOR_SET(he_ops, he_op->bss_color);
WMI_HEOPS_DEFPE_SET(he_ops, he_op->default_pe);
WMI_HEOPS_TWT_SET(he_ops, he_op->twt_required);