Browse Source

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
Hu Wang 8 years ago
parent
commit
fbd279de9d

+ 1 - 1
core/mac/src/pe/lim/lim_api.c

@@ -2397,7 +2397,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);

+ 33 - 4
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -376,7 +376,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);
@@ -778,7 +778,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)) {
@@ -1370,7 +1371,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);
@@ -1657,6 +1659,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"));
@@ -1906,7 +1913,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)) {

+ 23 - 6
core/mac/src/pe/lim/lim_utils.c

@@ -6647,7 +6647,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 */
@@ -6855,26 +6855,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;
 }
 
 /**

+ 2 - 1
core/mac/src/pe/lim/lim_utils.h

@@ -608,7 +608,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,

+ 2 - 1
core/mac/src/pe/sch/sch_api.c

@@ -414,7 +414,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);

+ 2 - 1
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -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);
 
 	}