summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHu Wang <huw@codeaurora.org>2016-10-31 18:24:34 +0800
committerqcabuildsw <qcabuildsw@localhost>2017-02-08 21:28:31 -0800
commit3083b7e3a0e1c22d71134b1c19eb9230ca84a006 (patch)
tree947dae5b1bef4dfe4e03fc481e9ea6fb9cde245c
parentf79fb521bc0546b7d95710cf92bccab7d01801e7 (diff)
qcacld-3.0: Clear the bits in Ext Cap IE if AP not support
qcacld-2.0 to qcacld-3.0 propagation Some specific AP will send assoc reject if DUT set the bits in Ext Cap IE which AP not advertise in beacon or probe response. To avoid the IoT issue, clear the bits in Ext Cap IE if AP not support. Change-Id: I632f5474331abf51257cacdcce412d7a110d2433 CRs-Fixed: 1052140
-rw-r--r--core/mac/src/pe/lim/lim_api.c2
-rw-r--r--core/mac/src/pe/lim/lim_send_management_frames.c37
-rw-r--r--core/mac/src/pe/lim/lim_utils.c29
-rw-r--r--core/mac/src/pe/lim/lim_utils.h3
-rw-r--r--core/mac/src/pe/sch/sch_api.c3
-rw-r--r--core/mac/src/pe/sch/sch_beacon_gen.c5
6 files changed, 64 insertions, 15 deletions
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index e6885d88c2f9..dbdffa54655d 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -2327,7 +2327,7 @@ QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx,
(*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN;
return QDF_STATUS_SUCCESS;
}
- lim_merge_extcap_struct(&driver_ext_cap, &default_scan_ext_cap);
+ lim_merge_extcap_struct(&driver_ext_cap, &default_scan_ext_cap, true);
qdf_mem_copy(local_ie_buf + (*local_ie_len),
driver_ext_cap.bytes, DOT11F_IE_EXTCAP_MAX_LEN);
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index 3611f1f8dbc2..c161fe1e93ed 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -375,7 +375,7 @@ lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
* dot11f get packed payload size.
*/
if (extracted_ext_cap_flag)
- lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap);
+ lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
/* That's it-- now we pack it. First, how much space are we going to */
status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
@@ -777,7 +777,8 @@ lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
* dot11f get packed payload size.
*/
if (extracted_ext_cap_flag)
- lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap);
+ lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
+ true);
status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
if (DOT11F_FAILED(status)) {
@@ -1369,7 +1370,8 @@ lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
* dot11f get packed payload size.
*/
if (extracted_flag)
- lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap);
+ lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
+ true);
/* Allocate a buffer for this frame: */
status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
@@ -1656,6 +1658,11 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
tDot11fIEExtCap extr_ext_cap;
bool extr_ext_flag = true;
tpSirMacMgmtHdr mac_hdr;
+ uint32_t ie_offset = 0;
+ uint8_t *p_ext_cap = NULL;
+ tDot11fIEExtCap bcn_ext_cap;
+ uint8_t *bcn_ie = NULL;
+ uint32_t bcn_ie_len = 0;
if (NULL == pe_session) {
lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
@@ -1908,7 +1915,29 @@ lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
* dot11f get packed payload size.
*/
if (extr_ext_flag)
- lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap);
+ lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
+
+ /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
+ if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
+ ie_offset = DOT11F_FF_TIMESTAMP_LEN +
+ DOT11F_FF_BEACONINTERVAL_LEN +
+ DOT11F_FF_CAPABILITIES_LEN;
+
+ qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
+ if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
+ bcn_ie = pe_session->beacon + ie_offset;
+ bcn_ie_len = pe_session->bcnLen - ie_offset;
+ p_ext_cap = lim_get_ie_ptr_new(mac_ctx,
+ bcn_ie,
+ bcn_ie_len,
+ DOT11F_EID_EXTCAP,
+ ONE_BYTE);
+ lim_update_extcap_struct(mac_ctx, p_ext_cap,
+ &bcn_ext_cap);
+ lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
+ false);
+ }
+ }
status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
if (DOT11F_FAILED(status)) {
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index 2f1409329763..283d5c29b76c 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -6646,7 +6646,7 @@ QDF_STATUS lim_send_ext_cap_ie(tpAniSirGlobal mac_ctx,
if (merge && NULL != extra_extcap && extra_extcap->num_bytes > 0) {
if (extra_extcap->num_bytes > ext_cap_data.num_bytes)
num_bytes = extra_extcap->num_bytes;
- lim_merge_extcap_struct(&ext_cap_data, extra_extcap);
+ lim_merge_extcap_struct(&ext_cap_data, extra_extcap, true);
}
/* Allocate memory for the WMI request, and copy the parameter */
@@ -6854,26 +6854,43 @@ tSirRetStatus lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
* lim_merge_extcap_struct() - merge extended capabilities info
* @dst: destination extended capabilities
* @src: source extended capabilities
+ * @add: true if add the capabilites, false if strip the capabilites.
*
- * This function is used to take @src info and merge it with @dst
- * extended capabilities info.
+ * This function is used to take @src info and add/strip it to/from
+ * @dst extended capabilities info.
*
* Return: None
*/
void lim_merge_extcap_struct(tDot11fIEExtCap *dst,
- tDot11fIEExtCap *src)
+ tDot11fIEExtCap *src,
+ bool add)
{
uint8_t *tempdst = (uint8_t *)dst->bytes;
uint8_t *tempsrc = (uint8_t *)src->bytes;
uint8_t structlen = member_size(tDot11fIEExtCap, bytes);
+ /* Return if @src not present */
+ if (!src->present)
+ return;
+
+ /* Return if strip the capabilites from @dst which not present */
+ if (!dst->present && !add)
+ return;
+
+ /* Merge the capabilites info in other cases */
while (tempdst && tempsrc && structlen--) {
- *tempdst |= *tempsrc;
+ if (add)
+ *tempdst |= *tempsrc;
+ else
+ *tempdst &= *tempsrc;
tempdst++;
tempsrc++;
}
- dst->present |= src->present;
dst->num_bytes = lim_compute_ext_cap_ie_length(dst);
+ if (dst->num_bytes == 0)
+ dst->present = 0;
+ else
+ dst->present = 1;
}
/**
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index 6e3d214aaf17..c6f66a209c87 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -603,7 +603,8 @@ void lim_update_extcap_struct(tpAniSirGlobal mac_ctx, uint8_t *buf,
tDot11fIEExtCap *ext_cap);
tSirRetStatus lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
uint8_t *addn_ie, uint16_t *addn_ielen, tDot11fIEExtCap *dst);
-void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src);
+void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src,
+ bool add);
uint8_t lim_get_80Mhz_center_channel(uint8_t primary_channel);
void lim_update_obss_scanparams(tpPESession session,
diff --git a/core/mac/src/pe/sch/sch_api.c b/core/mac/src/pe/sch/sch_api.c
index efed2ffb4a16..5ecf8a24d557 100644
--- a/core/mac/src/pe/sch/sch_api.c
+++ b/core/mac/src/pe/sch/sch_api.c
@@ -419,7 +419,8 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac,
prb_rsp_frm = &psessionEntry->probeRespFrame;
if (extcap_present)
lim_merge_extcap_struct(&prb_rsp_frm->ExtCap,
- &extracted_extcap);
+ &extracted_extcap,
+ true);
nStatus = dot11f_get_packed_probe_response_size(pMac,
&psessionEntry->probeRespFrame, &nPayload);
diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c
index 22c5738be6b4..2f06cbd2dea2 100644
--- a/core/mac/src/pe/sch/sch_beacon_gen.c
+++ b/core/mac/src/pe/sch/sch_beacon_gen.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -493,7 +493,8 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
if (extcap_present &&
session->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
lim_merge_extcap_struct(&bcn_2->ExtCap,
- &extracted_extcap);
+ &extracted_extcap,
+ true);
}