Browse Source

qcacld-3.0: Merge extended capability IE in beacon/probe resp template

qcacld-2.0 to qcacld-3.0 propagation.

Merge extended capability coming from hostapd and remove it from
extra IE before sending beacon/probe response template to firmware.

Change-Id: Iae50bbf1f70fd280f3366a89e58ad8f2c729720c
CRs-Fixed: 943078
Krishna Kumaar Natarajan 9 years ago
parent
commit
164e6b0c7b
2 changed files with 94 additions and 42 deletions
  1. 34 21
      core/mac/src/pe/sch/sch_api.c
  2. 60 21
      core/mac/src/pe/sch/sch_beacon_gen.c

+ 34 - 21
core/mac/src/pe/sch/sch_api.c

@@ -55,6 +55,7 @@
 #include "sch_sys_params.h"
 #include "lim_trace.h"
 #include "lim_types.h"
+#include "lim_utils.h"
 
 #include "wma_types.h"
 
@@ -381,16 +382,18 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac,
 	uint32_t nPayload, nBytes, nStatus;
 	tpSirMacMgmtHdr pMacHdr;
 	uint32_t addnIEPresent = false;
-	uint32_t addnIELen = 0;
 	uint8_t *addIE = NULL;
 	uint8_t *addIeWoP2pIe = NULL;
 	uint32_t addnIELenWoP2pIe = 0;
 	uint32_t retStatus;
-
-	nStatus =
-		dot11f_get_packed_probe_response_size(pMac,
-						      &psessionEntry->probeRespFrame,
-						      &nPayload);
+	tDot11fIEExtCap extracted_extcap;
+	bool extcap_present = true;
+	tDot11fProbeResponse *prb_rsp_frm;
+	tSirRetStatus status;
+	uint16_t addn_ielen = 0;
+
+	nStatus = dot11f_get_packed_probe_response_size(pMac,
+			&psessionEntry->probeRespFrame, &nPayload);
 	if (DOT11F_FAILED(nStatus)) {
 		sch_log(pMac, LOGE, FL("Failed to calculate the packed size f"
 				       "or a Probe Response (0x%08x)."),
@@ -435,30 +438,34 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac,
 
 		/* Probe rsp IE available */
 		/*need to check the data length */
-		addIE =
-			qdf_mem_malloc(addnIELenWoP2pIe);
+		addIE = qdf_mem_malloc(addnIELenWoP2pIe);
 		if (NULL == addIE) {
 			sch_log(pMac, LOGE,
-				FL
-					("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length"));
+				FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length"));
 			qdf_mem_free(addIeWoP2pIe);
 			return eSIR_MEM_ALLOC_FAILED;
 		}
-		addnIELen = addnIELenWoP2pIe;
+		addn_ielen = addnIELenWoP2pIe;
 
-		if (addnIELen <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && addnIELen
-		    && (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE) {
+		if (addn_ielen <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN &&
+		    addn_ielen && (nBytes + addn_ielen) <= SIR_MAX_PACKET_SIZE)
+			qdf_mem_copy(addIE, addIeWoP2pIe, addnIELenWoP2pIe);
 
-			qdf_mem_copy(addIE,
-				     addIeWoP2pIe,
-				     addnIELenWoP2pIe);
-		}
 		qdf_mem_free(addIeWoP2pIe);
+
+		qdf_mem_zero((uint8_t *)&extracted_extcap,
+			     sizeof(tDot11fIEExtCap));
+		status = lim_strip_extcap_update_struct(pMac, addIE,
+				&addn_ielen, &extracted_extcap);
+		if (eSIR_SUCCESS != status) {
+			extcap_present = false;
+			sch_log(pMac, LOG1, FL("extcap not extracted"));
+		}
 	}
 
 	if (addnIEPresent) {
-		if ((nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE)
-			nBytes += addnIELen;
+		if ((nBytes + addn_ielen) <= SIR_MAX_PACKET_SIZE)
+			nBytes += addn_ielen;
 		else
 			addnIEPresent = false;  /* Dont include the IE. */
 	}
@@ -475,6 +482,12 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac,
 
 	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
 
+	/* merge extcap IE */
+	prb_rsp_frm = &psessionEntry->probeRespFrame;
+	if (extcap_present)
+		lim_merge_extcap_struct(&prb_rsp_frm->ExtCap,
+					&extracted_extcap);
+
 	/* That done, pack the Probe Response: */
 	nStatus =
 		dot11f_pack_probe_response(pMac, &psessionEntry->probeRespFrame,
@@ -494,8 +507,8 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac,
 	}
 
 	if (addnIEPresent) {
-		qdf_mem_copy(&pFrame2Hal[nBytes - addnIELen],
-			     &addIE[0], addnIELen);
+		qdf_mem_copy(&pFrame2Hal[nBytes - addn_ielen],
+			     &addIE[0], addn_ielen);
 	}
 
 	/* free the allocated Memory */

+ 60 - 21
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -94,41 +94,41 @@ tSirRetStatus sch_get_p2p_ie_offset(uint8_t *pExtraIe, uint32_t extraIeLen,
  * @frm:           frame where additional IE is to be added
  * @max_bcn_size:  max beacon size
  * @num_bytes:     final size
+ * @addn_ie:       pointer to additional IE
+ * @addn_ielen:    lenght of additional IE
  *
  * Return: status of operation
  */
 tSirRetStatus
 sch_append_addn_ie(tpAniSirGlobal mac_ctx, tpPESession session,
-		   uint8_t *frm, uint32_t max_bcn_size, uint32_t *num_bytes)
+		   uint8_t *frm, uint32_t max_bcn_size, uint32_t *num_bytes,
+		   uint8_t *addn_ie, uint16_t addn_ielen)
 {
 	tSirRetStatus status = eSIR_FAILURE;
-	uint32_t present, len;
 	uint8_t add_ie[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN];
 	uint8_t *p2p_ie = NULL;
 	uint8_t noa_len = 0;
 	uint8_t noa_strm[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+	bool valid_ie;
 
-	present = (session->addIeParams.probeRespBCNDataLen != 0);
-	if (!present)
-		return status;
+	valid_ie = (addn_ielen <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN &&
+		    addn_ielen && ((addn_ielen + *num_bytes) <= max_bcn_size));
 
-	len = session->addIeParams.probeRespBCNDataLen;
-	if (!(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
-	    ((len + *num_bytes) <= max_bcn_size)))
+	if (!valid_ie)
 		return status;
 
-	qdf_mem_copy(&add_ie[0], session->addIeParams.probeRespBCNData_buff,
-		     len);
+	qdf_mem_copy(&add_ie[0], addn_ie, addn_ielen);
 
-	p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0], len);
+	p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0], addn_ielen);
 	if ((p2p_ie != NULL) && !mac_ctx->beacon_offload) {
 		/* get NoA attribute stream P2P IE */
 		noa_len = lim_get_noa_attr_stream(mac_ctx, noa_strm, session);
 		if (noa_len) {
-			if ((noa_len + len) <=
+			if ((noa_len + addn_ielen) <=
 			    WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
-				qdf_mem_copy(&add_ie[len], noa_strm, noa_len);
-				len += noa_len;
+				qdf_mem_copy(&add_ie[addn_ielen], noa_strm,
+					     noa_len);
+				addn_ielen += noa_len;
 				p2p_ie[1] += noa_len;
 			} else {
 				sch_log(mac_ctx, LOGE,
@@ -136,13 +136,13 @@ sch_append_addn_ie(tpAniSirGlobal mac_ctx, tpPESession session,
 			}
 		}
 	}
-	if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
-		qdf_mem_copy(frm, &add_ie[0], len);
-		*num_bytes = *num_bytes + len;
+	if (addn_ielen <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
+		qdf_mem_copy(frm, &add_ie[0], addn_ielen);
+		*num_bytes = *num_bytes + addn_ielen;
 	} else {
 		sch_log(mac_ctx, LOGW,
 			FL("Not able to insert because of len constraint %d"),
-			len);
+			addn_ielen);
 	}
 	return status;
 }
@@ -176,6 +176,10 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
 	uint16_t p2p_ie_offset = 0;
 	tSirRetStatus status = eSIR_SUCCESS;
 	bool is_vht_enabled = false;
+	uint16_t addn_ielen = 0;
+	uint8_t *addn_ie = NULL;
+	tDot11fIEExtCap extracted_extcap;
+	bool extcap_present = true, addnie_present = false;
 
 	bcn_1 = qdf_mem_malloc(sizeof(tDot11fBeacon1));
 	if (NULL == bcn_1) {
@@ -474,6 +478,36 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
 
 	}
 
+	addnie_present = (session->addIeParams.probeRespBCNDataLen != 0);
+	if (addnie_present) {
+		addn_ielen = session->addIeParams.probeRespBCNDataLen;
+		addn_ie = qdf_mem_malloc(addn_ielen);
+		if (!addn_ie) {
+			sch_log(mac_ctx, LOGE, FL("addn_ie malloc failed"));
+			qdf_mem_free(bcn_1);
+			qdf_mem_free(bcn_2);
+			qdf_mem_free(wsc_prb_res);
+			return eSIR_MEM_ALLOC_FAILED;
+		}
+		qdf_mem_copy(addn_ie,
+			session->addIeParams.probeRespBCNData_buff,
+			addn_ielen);
+
+		qdf_mem_zero((uint8_t *)&extracted_extcap,
+			     sizeof(tDot11fIEExtCap));
+		status = lim_strip_extcap_update_struct(mac_ctx, addn_ie,
+				&addn_ielen, &extracted_extcap);
+		if (eSIR_SUCCESS != status) {
+			extcap_present = false;
+			sch_log(mac_ctx, LOG1, FL("extcap not extracted"));
+		}
+		/* merge extcap IE */
+		if (extcap_present)
+			lim_merge_extcap_struct(&bcn_2->ExtCap,
+						&extracted_extcap);
+
+	}
+
 	n_status = dot11f_pack_beacon2(mac_ctx, bcn_2,
 				      session->pSchBeaconFrameEnd,
 				      SCH_MAX_BEACON_SIZE, &n_bytes);
@@ -484,6 +518,7 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
 		qdf_mem_free(bcn_1);
 		qdf_mem_free(bcn_2);
 		qdf_mem_free(wsc_prb_res);
+		qdf_mem_free(addn_ie);
 		return eSIR_FAILURE;
 	} else if (DOT11F_WARNED(n_status)) {
 		sch_log(mac_ctx, LOGE,
@@ -493,10 +528,13 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
 
 	extra_ie = session->pSchBeaconFrameEnd + n_bytes;
 	extra_ie_offset = n_bytes;
+
 	/* TODO: Append additional IE here. */
-	sch_append_addn_ie(mac_ctx, session,
-			   session->pSchBeaconFrameEnd + n_bytes,
-			   SCH_MAX_BEACON_SIZE, &n_bytes);
+	if (addn_ielen > 0)
+		sch_append_addn_ie(mac_ctx, session,
+			session->pSchBeaconFrameEnd + n_bytes,
+			SCH_MAX_BEACON_SIZE, &n_bytes, addn_ie, addn_ielen);
+
 	session->schBeaconOffsetEnd = (uint16_t) n_bytes;
 	extra_ie_len = n_bytes - extra_ie_offset;
 	/* Get the p2p Ie Offset */
@@ -515,6 +553,7 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
 	qdf_mem_free(bcn_1);
 	qdf_mem_free(bcn_2);
 	qdf_mem_free(wsc_prb_res);
+	qdf_mem_free(addn_ie);
 	return eSIR_SUCCESS;
 }