summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}