mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
qcacld-3.0: Fix incorrect phymode in 6GHz connection
Add support to parse 6GHz operation information from AP beacon for connection. Change-Id: I67d167cd982163e28b3bbe7dc81747d8289a1513 CRs-Fixed: 2567849
This commit is contained in:
parent
8e36da41ba
commit
5abc59e4bf
8 changed files with 209 additions and 60 deletions
|
|
@ -1761,6 +1761,8 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac,
|
|||
tSirMacRateSet tempRateSet2;
|
||||
uint32_t i, j, val, min, isArate = 0;
|
||||
qdf_size_t val_len;
|
||||
uint8_t aRateIndex = 0;
|
||||
uint8_t bRateIndex = 0;
|
||||
|
||||
/* copy operational rate set from pe_session */
|
||||
if (pe_session->rateSet.numRates <= WLAN_SUPPORTED_RATES_IE_MAX_LEN) {
|
||||
|
|
@ -1806,42 +1808,31 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac,
|
|||
* Sort rates in tempRateSet (they are likely to be already sorted)
|
||||
* put the result in pSupportedRates
|
||||
*/
|
||||
{
|
||||
uint8_t aRateIndex = 0;
|
||||
uint8_t bRateIndex = 0;
|
||||
|
||||
qdf_mem_zero(pRates, sizeof(*pRates));
|
||||
for (i = 0; i < tempRateSet.numRates; i++) {
|
||||
min = 0;
|
||||
val = 0xff;
|
||||
isArate = 0;
|
||||
for (j = 0;
|
||||
(j < tempRateSet.numRates)
|
||||
&& (j < WLAN_SUPPORTED_RATES_IE_MAX_LEN); j++) {
|
||||
if ((uint32_t) (tempRateSet.rate[j] & 0x7f) <
|
||||
val) {
|
||||
val = tempRateSet.rate[j] & 0x7f;
|
||||
min = j;
|
||||
}
|
||||
qdf_mem_zero(pRates, sizeof(*pRates));
|
||||
for (i = 0; i < tempRateSet.numRates; i++) {
|
||||
min = 0;
|
||||
val = 0xff;
|
||||
isArate = 0;
|
||||
for (j = 0; (j < tempRateSet.numRates) &&
|
||||
(j < WLAN_SUPPORTED_RATES_IE_MAX_LEN); j++) {
|
||||
if ((uint32_t)(tempRateSet.rate[j] & 0x7f) <
|
||||
val) {
|
||||
val = tempRateSet.rate[j] & 0x7f;
|
||||
min = j;
|
||||
}
|
||||
if (sirIsArate(tempRateSet.rate[min] & 0x7f))
|
||||
isArate = 1;
|
||||
/*
|
||||
* HAL needs to know whether the rate is basic rate or not, as it needs to
|
||||
* update the response rate table accordingly. e.g. if one of the 11a rates is
|
||||
* basic rate, then that rate can be used for sending control frames.
|
||||
* HAL updates the response rate table whenever basic rate set is changed.
|
||||
*/
|
||||
if (basicOnly) {
|
||||
if (tempRateSet.rate[min] & 0x80) {
|
||||
if (isArate)
|
||||
pRates->llaRates[aRateIndex++] =
|
||||
tempRateSet.rate[min];
|
||||
else
|
||||
pRates->llbRates[bRateIndex++] =
|
||||
tempRateSet.rate[min];
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if (sirIsArate(tempRateSet.rate[min] & 0x7f))
|
||||
isArate = 1;
|
||||
/*
|
||||
* HAL needs to know whether the rate is basic rate or not,
|
||||
* as it needs to update the response rate table accordingly.
|
||||
* e.g. if one of the 11a rates is basic rate, then that rate
|
||||
* can be used for sending control frames. HAL updates the
|
||||
* response rate table whenever basic rate set is changed.
|
||||
*/
|
||||
if (basicOnly) {
|
||||
if (tempRateSet.rate[min] & 0x80) {
|
||||
if (isArate)
|
||||
pRates->llaRates[aRateIndex++] =
|
||||
tempRateSet.rate[min];
|
||||
|
|
@ -1849,11 +1840,19 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac,
|
|||
pRates->llbRates[bRateIndex++] =
|
||||
tempRateSet.rate[min];
|
||||
}
|
||||
tempRateSet.rate[min] = 0xff;
|
||||
} else {
|
||||
if (isArate)
|
||||
pRates->llaRates[aRateIndex++] =
|
||||
tempRateSet.rate[min];
|
||||
else
|
||||
pRates->llbRates[bRateIndex++] =
|
||||
tempRateSet.rate[min];
|
||||
}
|
||||
tempRateSet.rate[min] = 0xff;
|
||||
}
|
||||
|
||||
if (IS_DOT11_MODE_HT(pe_session->dot11mode)) {
|
||||
if (IS_DOT11_MODE_HT(pe_session->dot11mode) &&
|
||||
!lim_is_he_6ghz_band(pe_session)) {
|
||||
val_len = SIZE_OF_SUPPORTED_MCS_SET;
|
||||
if (wlan_mlme_get_cfg_str(
|
||||
pRates->supportedMCSSet,
|
||||
|
|
@ -3667,6 +3666,8 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp
|
|||
(pAssocRsp->he_cap.present)) {
|
||||
lim_add_bss_he_cap(pAddBssParams, pAssocRsp);
|
||||
lim_add_bss_he_cfg(pAddBssParams, pe_session);
|
||||
lim_update_he_6gop_assoc_resp(pAddBssParams, &pAssocRsp->he_op,
|
||||
pe_session);
|
||||
}
|
||||
/*
|
||||
* Populate the STA-related parameters here
|
||||
|
|
@ -3876,6 +3877,16 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp
|
|||
pAddBssParams->staContext.htLdpcCapable,
|
||||
pAddBssParams->staContext.vhtLdpcCapable);
|
||||
}
|
||||
if (lim_is_he_6ghz_band(pe_session)) {
|
||||
if (lim_is_session_he_capable(pe_session) &&
|
||||
pAssocRsp->he_cap.present) {
|
||||
lim_intersect_ap_he_caps(pe_session,
|
||||
pAddBssParams,
|
||||
NULL,
|
||||
pAssocRsp);
|
||||
lim_update_he_stbc_capable(&pAddBssParams->staContext);
|
||||
}
|
||||
}
|
||||
pAddBssParams->staContext.smesessionId =
|
||||
pe_session->smeSessionId;
|
||||
pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
|
||||
|
|
|
|||
|
|
@ -519,9 +519,20 @@ lim_handle_assoc_reject_status(struct mac_context *mac_ctx,
|
|||
* Return: nss advertised by AP in beacon
|
||||
*/
|
||||
static uint8_t lim_get_nss_supported_by_ap(tDot11fIEVHTCaps *vht_caps,
|
||||
tDot11fIEHTCaps *ht_caps)
|
||||
tDot11fIEHTCaps *ht_caps,
|
||||
tDot11fIEhe_cap *he_caps)
|
||||
{
|
||||
if (vht_caps->present) {
|
||||
|
||||
if (he_caps->present) {
|
||||
if ((he_caps->rx_he_mcs_map_lt_80 & 0xC0) != 0xC0)
|
||||
return NSS_4x4_MODE;
|
||||
|
||||
if ((he_caps->rx_he_mcs_map_lt_80 & 0x30) != 0x30)
|
||||
return NSS_3x3_MODE;
|
||||
|
||||
if ((he_caps->rx_he_mcs_map_lt_80 & 0x0C) != 0x0C)
|
||||
return NSS_2x2_MODE;
|
||||
} else if (vht_caps->present) {
|
||||
if ((vht_caps->rxMCSMap & 0xC0) != 0xC0)
|
||||
return NSS_4x4_MODE;
|
||||
|
||||
|
|
@ -859,7 +870,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx,
|
|||
QDF_STATUS_SUCCESS), assoc_rsp->status_code);
|
||||
|
||||
ap_nss = lim_get_nss_supported_by_ap(&assoc_rsp->VHTCaps,
|
||||
&assoc_rsp->HTCaps);
|
||||
&assoc_rsp->HTCaps,
|
||||
&assoc_rsp->he_cap);
|
||||
|
||||
if (subtype == LIM_REASSOC) {
|
||||
pe_debug("Successfully Reassociated with BSS");
|
||||
|
|
|
|||
|
|
@ -772,6 +772,7 @@ __lim_handle_sme_start_bss_request(struct mac_context *mac_ctx, uint32_t *msg_bu
|
|||
sme_start_bss_req->center_freq_seg0;
|
||||
session->ch_center_freq_seg1 =
|
||||
sme_start_bss_req->center_freq_seg1;
|
||||
lim_update_he_bw_cap_mcs(session);
|
||||
}
|
||||
|
||||
pe_debug("vht su tx bformer %d",
|
||||
|
|
|
|||
|
|
@ -102,11 +102,61 @@ static inline void get_ese_version_ie_probe_response(struct mac_context *mac_ctx
|
|||
static void lim_extract_he_op(struct pe_session *session,
|
||||
tSirProbeRespBeacon *beacon_struct)
|
||||
{
|
||||
if (session->he_capable && beacon_struct->he_op.present) {
|
||||
qdf_mem_copy(&session->he_op, &beacon_struct->he_op,
|
||||
sizeof(session->he_op));
|
||||
pe_debug("he_op.bss_color %d", session->he_op.bss_color);
|
||||
pe_debug("he_op.default_pe %d", session->he_op.default_pe);
|
||||
uint8_t fw_vht_ch_wd;
|
||||
uint8_t ap_bcon_ch_width;
|
||||
uint8_t center_freq_diff;
|
||||
|
||||
if (!session->he_capable)
|
||||
return;
|
||||
if (!beacon_struct->he_op.present) {
|
||||
pe_debug("HE op not present in beacon");
|
||||
return;
|
||||
}
|
||||
qdf_mem_copy(&session->he_op, &beacon_struct->he_op,
|
||||
sizeof(session->he_op));
|
||||
pe_debug("he_op.bss_color %d", session->he_op.bss_color);
|
||||
pe_debug("he_op.default_pe %d", session->he_op.default_pe);
|
||||
if (!session->he_6ghz_band)
|
||||
return;
|
||||
if (!session->he_op.oper_info_6g_present) {
|
||||
pe_debug("6GHz op not present in 6G beacon");
|
||||
return;
|
||||
}
|
||||
session->ch_width = session->he_op.oper_info_6g.info.ch_width;
|
||||
session->ch_center_freq_seg0 =
|
||||
session->he_op.oper_info_6g.info.center_freq_seg0;
|
||||
session->ch_center_freq_seg1 =
|
||||
session->he_op.oper_info_6g.info.center_freq_seg1;
|
||||
|
||||
pe_debug("6G op info: ch_wd %d cntr_freq_seg0 %d cntr_freq_seg1 %d",
|
||||
session->ch_width, session->ch_center_freq_seg0,
|
||||
session->ch_center_freq_seg1);
|
||||
|
||||
if (!session->ch_center_freq_seg1)
|
||||
return;
|
||||
|
||||
fw_vht_ch_wd = wma_get_vht_ch_width();
|
||||
if (fw_vht_ch_wd <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
|
||||
session->ch_width = CH_WIDTH_80MHZ;
|
||||
session->ch_center_freq_seg1 = 0;
|
||||
return;
|
||||
}
|
||||
center_freq_diff = abs(session->ch_center_freq_seg1 -
|
||||
session->ch_center_freq_seg0);
|
||||
if (center_freq_diff == 8) {
|
||||
ap_bcon_ch_width = CH_WIDTH_160MHZ;
|
||||
} else if (center_freq_diff > 16) {
|
||||
ap_bcon_ch_width = CH_WIDTH_80P80MHZ;
|
||||
} else {
|
||||
session->ch_width = CH_WIDTH_80MHZ;
|
||||
session->ch_center_freq_seg1 = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ap_bcon_ch_width == CH_WIDTH_80P80MHZ) &&
|
||||
(fw_vht_ch_wd != WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)) {
|
||||
session->ch_width = CH_WIDTH_80MHZ;
|
||||
session->ch_center_freq_seg1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +201,7 @@ static void lim_check_he_ldpc_cap(struct pe_session *session,
|
|||
}
|
||||
}
|
||||
|
||||
static void lim_update_he_bw_cap_mcs(struct pe_session *session)
|
||||
void lim_update_he_bw_cap_mcs(struct pe_session *session)
|
||||
{
|
||||
if (!session->he_capable)
|
||||
return;
|
||||
|
|
@ -192,9 +242,6 @@ static inline void lim_extract_he_op(struct pe_session *session,
|
|||
static void lim_check_he_ldpc_cap(struct pe_session *session,
|
||||
tSirProbeRespBeacon *beacon_struct)
|
||||
{}
|
||||
|
||||
static void lim_update_he_bw_cap_mcs(struct pe_session *session)
|
||||
{}
|
||||
#endif
|
||||
|
||||
void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
|
||||
|
|
|
|||
|
|
@ -6718,6 +6718,27 @@ void lim_add_bss_he_cfg(struct bss_params *add_bss, struct pe_session *session)
|
|||
add_bss->he_sta_obsspd = session->he_sta_obsspd;
|
||||
}
|
||||
|
||||
void lim_update_he_6gop_assoc_resp(struct bss_params *pAddBssParams,
|
||||
tDot11fIEhe_op *he_op,
|
||||
struct pe_session *pe_session)
|
||||
{
|
||||
if (!pe_session->he_6ghz_band)
|
||||
return;
|
||||
|
||||
if (!he_op->oper_info_6g_present) {
|
||||
pe_debug("6G operation info not present in beacon");
|
||||
return;
|
||||
}
|
||||
if (!pe_session->ch_width)
|
||||
return;
|
||||
|
||||
pAddBssParams->ch_width = QDF_MIN(he_op->oper_info_6g.info.ch_width,
|
||||
pe_session->ch_width);
|
||||
|
||||
if (pAddBssParams->ch_width == CH_WIDTH_160MHZ)
|
||||
pAddBssParams->ch_width = pe_session->ch_width;
|
||||
}
|
||||
|
||||
void lim_update_stads_he_caps(tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
|
||||
struct pe_session *session_entry)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1029,6 +1029,17 @@ void lim_add_bss_he_cfg(struct bss_params *add_bss, struct pe_session *session);
|
|||
void lim_copy_bss_he_cap(struct pe_session *session,
|
||||
struct start_bss_req *sme_start_bss_req);
|
||||
|
||||
/**
|
||||
* lim_update_he_6gop_assoc_resp() - Update HE 6GHz op info to BSS params
|
||||
* @add_bss: pointer to add bss params
|
||||
* @he_op: Pointer to HE operation info IE
|
||||
* @session: Pointer to Session entry struct
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void lim_update_he_6gop_assoc_resp(struct bss_params *pAddBssParams,
|
||||
tDot11fIEhe_op *he_op,
|
||||
struct pe_session *pe_session);
|
||||
/**
|
||||
* lim_copy_join_req_he_cap() - Copy HE capability to PE session from Join req
|
||||
* and update as per bandwidth supported
|
||||
|
|
@ -1143,6 +1154,19 @@ static inline bool lim_is_session_he_capable(struct pe_session *session)
|
|||
return session->he_capable;
|
||||
}
|
||||
|
||||
/**
|
||||
* lim_update_he_bw_cap_mcs(): Update he mcs map per bandwidth
|
||||
* @session_entry: pointer to PE session
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void lim_update_he_bw_cap_mcs(struct pe_session *session);
|
||||
|
||||
static inline bool lim_is_he_6ghz_band(struct pe_session *session)
|
||||
{
|
||||
return session->he_6ghz_band;
|
||||
}
|
||||
|
||||
/**
|
||||
* lim_get_session_he_frag_cap(): Get session HE fragmentation cap
|
||||
* @session: pointer to session
|
||||
|
|
@ -1252,6 +1276,13 @@ static inline void lim_add_bss_he_cfg(struct bss_params *add_bss,
|
|||
{
|
||||
}
|
||||
|
||||
static inline void lim_update_he_6gop_assoc_resp(
|
||||
struct bss_params *pAddBssParams,
|
||||
tDot11fIEhe_op *he_op,
|
||||
struct pe_session *pe_session)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void lim_intersect_ap_he_caps(struct pe_session *session,
|
||||
struct bss_params *add_bss, tSchBeaconStruct *pBeaconStruct,
|
||||
tpSirAssocRsp assoc_rsp)
|
||||
|
|
@ -1313,6 +1344,15 @@ static inline bool lim_is_session_he_capable(struct pe_session *session)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline void lim_update_he_bw_cap_mcs(struct pe_session *session)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool lim_is_he_6ghz_band(struct pe_session *session)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline uint8_t lim_get_session_he_frag_cap(struct pe_session *session)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -15423,34 +15423,45 @@ static inline void csr_update_sae_config(struct join_req *csr_join_req,
|
|||
*/
|
||||
static uint8_t csr_get_nss_supported_by_sta_and_ap(tDot11fIEVHTCaps *vht_caps,
|
||||
tDot11fIEHTCaps *ht_caps,
|
||||
tDot11fIEhe_cap *he_cap,
|
||||
uint32_t dot11_mode)
|
||||
{
|
||||
bool vht_capability, ht_capability;
|
||||
bool vht_capability, ht_capability, he_capability;
|
||||
|
||||
vht_capability = IS_DOT11_MODE_VHT(dot11_mode);
|
||||
ht_capability = IS_DOT11_MODE_HT(dot11_mode);
|
||||
he_capability = IS_DOT11_MODE_HE(dot11_mode);
|
||||
|
||||
if (vht_capability && vht_caps->present) {
|
||||
if (he_capability && he_cap->present) {
|
||||
if ((he_cap->rx_he_mcs_map_lt_80 & 0xC0) != 0xC0)
|
||||
return NSS_4x4_MODE;
|
||||
|
||||
if ((he_cap->rx_he_mcs_map_lt_80 & 0x30) != 0x30)
|
||||
return NSS_3x3_MODE;
|
||||
|
||||
if ((he_cap->rx_he_mcs_map_lt_80 & 0x0C) != 0x0C)
|
||||
return NSS_2x2_MODE;
|
||||
} else if (vht_capability && vht_caps->present) {
|
||||
if ((vht_caps->rxMCSMap & 0xC0) != 0xC0)
|
||||
return 4;
|
||||
return NSS_4x4_MODE;
|
||||
|
||||
if ((vht_caps->rxMCSMap & 0x30) != 0x30)
|
||||
return 3;
|
||||
return NSS_3x3_MODE;
|
||||
|
||||
if ((vht_caps->rxMCSMap & 0x0C) != 0x0C)
|
||||
return 2;
|
||||
return NSS_2x2_MODE;
|
||||
} else if (ht_capability && ht_caps->present) {
|
||||
if (ht_caps->supportedMCSSet[3])
|
||||
return 4;
|
||||
return NSS_4x4_MODE;
|
||||
|
||||
if (ht_caps->supportedMCSSet[2])
|
||||
return 3;
|
||||
return NSS_3x3_MODE;
|
||||
|
||||
if (ht_caps->supportedMCSSet[1])
|
||||
return 2;
|
||||
return NSS_2x2_MODE;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return NSS_1x1_MODE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -15785,7 +15796,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
|
|||
vendor_ap_search_attr.mac_addr = &pBssDescription->bssId[0];
|
||||
vendor_ap_search_attr.nss = csr_get_nss_supported_by_sta_and_ap(
|
||||
&pIes->VHTCaps, &pIes->HTCaps,
|
||||
dot11mode);
|
||||
&pIes->he_cap, dot11mode);
|
||||
vendor_ap_search_attr.ht_cap = pIes->HTCaps.present;
|
||||
vendor_ap_search_attr.vht_cap = pIes->VHTCaps.present;
|
||||
vendor_ap_search_attr.enable_2g =
|
||||
|
|
@ -15816,7 +15827,9 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
|
|||
if (!force_max_nss)
|
||||
ap_nss = csr_get_nss_supported_by_sta_and_ap(
|
||||
&pIes->VHTCaps,
|
||||
&pIes->HTCaps, dot11mode);
|
||||
&pIes->HTCaps,
|
||||
&pIes->he_cap,
|
||||
dot11mode);
|
||||
if (!force_max_nss && pSession->nss > ap_nss) {
|
||||
pSession->nss = ap_nss;
|
||||
pSession->vdev_nss = pSession->nss;
|
||||
|
|
|
|||
|
|
@ -1264,6 +1264,10 @@ void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
|
|||
params->supportedRates.tx_he_mcs_map_80_80;
|
||||
}
|
||||
|
||||
#define HE2x2MCSMASK 0xc
|
||||
|
||||
peer->peer_nss = ((params->supportedRates.rx_he_mcs_map_lt_80 &
|
||||
HE2x2MCSMASK) == HE2x2MCSMASK) ? 1 : 2;
|
||||
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],
|
||||
|
|
|
|||
Loading…
Reference in a new issue