Browse Source

qcacld-3.0: Add support to parse new vht op IE definition

VHT channel width definition is changed in latest draft. Add
support to parse the new definition of VHT channel width in
VHT operation IE.

Change-Id: I1b9ece6ad490cc158df87d86035a0a338008c539
CRs-Fixed: 1022680
Kiran Kumar Lokere 8 years ago
parent
commit
02b9aa4bba
3 changed files with 175 additions and 108 deletions
  1. 168 103
      core/mac/src/pe/lim/lim_prop_exts_utils.c
  2. 4 2
      core/wma/src/wma_dev_if.c
  3. 3 3
      core/wma/src/wma_utils.c

+ 168 - 103
core/mac/src/pe/lim/lim_prop_exts_utils.c

@@ -81,6 +81,12 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
 	uint32_t enable_txbf_20mhz;
 	tSirRetStatus cfg_set_status = eSIR_FAILURE;
 	tSirRetStatus cfg_get_status = eSIR_FAILURE;
+	uint8_t ap_bcon_ch_width;
+	bool new_ch_width_dfn = false;
+	tDot11fIEVHTOperation *vht_op;
+	uint8_t fw_vht_ch_wd;
+	uint8_t vht_ch_wd;
+	uint8_t center_freq_diff;
 
 	beacon_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
 	if (NULL == beacon_struct) {
@@ -96,123 +102,182 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
 		FL("In lim_extract_ap_capability: The IE's being received:"));
 	sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG3, p_ie, ie_len);
 	if (sir_parse_beacon_ie(mac_ctx, beacon_struct, p_ie,
-		(uint32_t) ie_len) == eSIR_SUCCESS) {
-		if (beacon_struct->wmeInfoPresent
-		    || beacon_struct->wmeEdcaPresent
-		    || beacon_struct->HTCaps.present)
-			LIM_BSS_CAPS_SET(WME, *qos_cap);
-		if (LIM_BSS_CAPS_GET(WME, *qos_cap)
-		    && beacon_struct->wsmCapablePresent)
-			LIM_BSS_CAPS_SET(WSM, *qos_cap);
-		if (beacon_struct->propIEinfo.capabilityPresent)
-			*prop_cap = beacon_struct->propIEinfo.capability;
-		if (beacon_struct->HTCaps.present)
-			mac_ctx->lim.htCapabilityPresentInBeacon = 1;
-		else
-			mac_ctx->lim.htCapabilityPresentInBeacon = 0;
+		(uint32_t) ie_len) != eSIR_SUCCESS) {
+		lim_log(mac_ctx, LOGE, FL(
+			"sir_parse_beacon_ie failed to parse beacon"));
+		qdf_mem_free(beacon_struct);
+		return;
+	}
+	if (beacon_struct->wmeInfoPresent ||
+	    beacon_struct->wmeEdcaPresent ||
+	    beacon_struct->HTCaps.present)
+		LIM_BSS_CAPS_SET(WME, *qos_cap);
+	if (LIM_BSS_CAPS_GET(WME, *qos_cap)
+			&& beacon_struct->wsmCapablePresent)
+		LIM_BSS_CAPS_SET(WSM, *qos_cap);
+	if (beacon_struct->propIEinfo.capabilityPresent)
+		*prop_cap = beacon_struct->propIEinfo.capability;
+	if (beacon_struct->HTCaps.present)
+		mac_ctx->lim.htCapabilityPresentInBeacon = 1;
+	else
+		mac_ctx->lim.htCapabilityPresentInBeacon = 0;
 
-		lim_log(mac_ctx, LOG1,
-			FL("Beacon : VHTCaps.present: %d SU Beamformer: %d, IS_BSS_VHT_CAPABLE: %d"),
-			beacon_struct->VHTCaps.present,
-			beacon_struct->VHTCaps.suBeamFormerCap,
-			IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps));
+	lim_log(mac_ctx, LOG1, FL(
+		"Bcon: VHTCap.present %d SU Beamformer %d BSS_VHT_CAPABLE %d"),
+		beacon_struct->VHTCaps.present,
+		beacon_struct->VHTCaps.suBeamFormerCap,
+		IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps));
 
-		if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) &&
-			beacon_struct->VHTOperation.present &&
+	vht_op = &beacon_struct->VHTOperation;
+	if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) &&
+			vht_op->present &&
 			session->vhtCapability) {
-			session->vhtCapabilityPresentInBeacon = 1;
-			if (((beacon_struct->Vendor1IEPresent &&
-				beacon_struct->vendor2_ie.present &&
-				beacon_struct->Vendor3IEPresent)) &&
-				(((beacon_struct->VHTCaps.txMCSMap &
-				    VHT_MCS_3x3_MASK) == VHT_MCS_3x3_MASK) &&
-				  ((beacon_struct->VHTCaps.txMCSMap &
-				    VHT_MCS_2x2_MASK) != VHT_MCS_2x2_MASK))) {
-				session->txBFIniFeatureEnabled = 0;
-			}
-		} else {
-			session->vhtCapabilityPresentInBeacon = 0;
-		}
+		session->vhtCapabilityPresentInBeacon = 1;
+		if (((beacon_struct->Vendor1IEPresent &&
+		      beacon_struct->vendor2_ie.present &&
+		      beacon_struct->Vendor3IEPresent)) &&
+		      (((beacon_struct->VHTCaps.txMCSMap & VHT_MCS_3x3_MASK) ==
+			VHT_MCS_3x3_MASK) &&
+		      ((beacon_struct->VHTCaps.txMCSMap & VHT_MCS_2x2_MASK) !=
+		       VHT_MCS_2x2_MASK)))
+			session->txBFIniFeatureEnabled = 0;
+	} else {
+		session->vhtCapabilityPresentInBeacon = 0;
+	}
 
-		if (session->vhtCapabilityPresentInBeacon == 1 &&
-		    session->txBFIniFeatureEnabled == 0) {
-			cfg_set_status = cfg_set_int(mac_ctx,
-						WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
-						0);
-			if (cfg_set_status != eSIR_SUCCESS)
-				lim_log(mac_ctx, LOGP,
-					FL("Set VHT_SU_BEAMFORMEE_CAP Fail"));
+	if (session->vhtCapabilityPresentInBeacon == 1 &&
+			session->txBFIniFeatureEnabled == 0) {
+		cfg_set_status = cfg_set_int(mac_ctx,
+				WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
+				0);
+		if (cfg_set_status != eSIR_SUCCESS)
+			lim_log(mac_ctx, LOGP, FL(
+					"Set VHT_SU_BEAMFORMEE_CAP Fail"));
+	}
+	if (session->vhtCapabilityPresentInBeacon == 1 &&
+			!session->htSupportedChannelWidthSet) {
+		cfg_get_status = wlan_cfg_get_int(mac_ctx,
+				WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
+				&enable_txbf_20mhz);
+		if ((IS_SIR_STATUS_SUCCESS(cfg_get_status)) &&
+				(false == enable_txbf_20mhz))
+			session->txBFIniFeatureEnabled = 0;
+	} else if (session->vhtCapabilityPresentInBeacon &&
+			vht_op->chanWidth) {
+		/* If VHT is supported min 80 MHz support is must */
+		ap_bcon_ch_width = vht_op->chanWidth;
+		if ((ap_bcon_ch_width == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
+		     vht_op->chanCenterFreqSeg2) {
+			new_ch_width_dfn = true;
+			if (vht_op->chanCenterFreqSeg2 >
+			    vht_op->chanCenterFreqSeg1)
+			    center_freq_diff = vht_op->chanCenterFreqSeg2 -
+				    vht_op->chanCenterFreqSeg1;
+			else
+			    center_freq_diff = vht_op->chanCenterFreqSeg1 -
+				    vht_op->chanCenterFreqSeg2;
+			if (center_freq_diff == 8)
+				ap_bcon_ch_width =
+					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+			else if (center_freq_diff > 16)
+				ap_bcon_ch_width =
+					WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ;
 		}
-		if (session->vhtCapabilityPresentInBeacon == 1 &&
-		    !session->htSupportedChannelWidthSet) {
-			cfg_get_status = wlan_cfg_get_int(mac_ctx,
-						WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
-						&enable_txbf_20mhz);
-			if ((IS_SIR_STATUS_SUCCESS(cfg_get_status)) &&
-			    (false == enable_txbf_20mhz))
-				session->txBFIniFeatureEnabled = 0;
-		} else if (session->vhtCapabilityPresentInBeacon == 1 &&
-			   beacon_struct->VHTOperation.chanWidth) {
-			/* If VHT is supported min 80 MHz support is must */
-			uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();
-			uint32_t vht_ch_wd = QDF_MIN(fw_vht_ch_wd,
-					beacon_struct->VHTOperation.chanWidth);
-			if (vht_ch_wd == beacon_struct->VHTOperation.chanWidth
-			    || vht_ch_wd >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {
-				/*
-				 * This block covers 2 cases:
-				 * 1) AP and STA both have same vht capab
-				 * 2) AP is 160 (80+80), we are 160 only
-				 */
-				session->ch_center_freq_seg0 =
-				 beacon_struct->VHTOperation.chanCenterFreqSeg1;
-				session->ch_center_freq_seg1 =
-				 beacon_struct->VHTOperation.chanCenterFreqSeg2;
+
+		fw_vht_ch_wd = wma_get_vht_ch_width();
+		vht_ch_wd = QDF_MIN(fw_vht_ch_wd, ap_bcon_ch_width);
+		/*
+		 * VHT OP IE old definition:
+		 * vht_op->chanCenterFreqSeg1: center freq of 80MHz/160MHz/
+		 * primary 80 in 80+80MHz.
+		 *
+		 * vht_op->chanCenterFreqSeg2: center freq of secondary 80
+		 * in 80+80MHz.
+		 *
+		 * VHT OP IE NEW definition:
+		 * vht_op->chanCenterFreqSeg1: center freq of 80MHz/primary
+		 * 80 in 80+80MHz/center freq of the 80 MHz channel segment
+		 * that contains the primary channel in 160MHz mode.
+		 *
+		 * vht_op->chanCenterFreqSeg2: center freq of secondary 80
+		 * in 80+80MHz/center freq of 160MHz.
+		 */
+		session->ch_center_freq_seg0 = vht_op->chanCenterFreqSeg1;
+		session->ch_center_freq_seg1 = vht_op->chanCenterFreqSeg2;
+		if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {
+			/* DUT or AP supports only 160MHz */
+			if (ap_bcon_ch_width ==
+					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {
+				/* AP is in 160MHz mode */
+				if (!new_ch_width_dfn) {
+					session->ch_center_freq_seg1 =
+						vht_op->chanCenterFreqSeg1;
+					session->ch_center_freq_seg0 =
+						lim_get_80Mhz_center_channel(
+						beacon_struct->channelNumber);
+				}
 			} else {
-				/* when AP was 160 but we were 80 only */
+				/* DUT supports only 160MHz and AP is
+				 * in 80+80 mode
+				 */
+				vht_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+				session->ch_center_freq_seg1 = 0;
+			}
+		} else if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
+			/* DUT or AP supports only 80MHz */
+			if (ap_bcon_ch_width ==
+					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ &&
+					!new_ch_width_dfn)
+				/* AP is in 160MHz mode */
 				session->ch_center_freq_seg0 =
 					lim_get_80Mhz_center_channel(
 						beacon_struct->channelNumber);
-			}
-			session->ch_width = vht_ch_wd + 1;
-			if (CH_WIDTH_80MHZ < session->ch_width) {
-				session->enable_su_tx_bformer = 0;
-				session->nss = 1;
-			}
+			else
+				session->ch_center_freq_seg1 = 0;
 		}
-		if (session->vhtCapabilityPresentInBeacon == 1 &&
-		    !session->htSupportedChannelWidthSet &&
-		    session->txBFIniFeatureEnabled == 0) {
-			cfg_set_status = cfg_set_int(mac_ctx,
-						WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
-						0);
-			if (cfg_set_status != eSIR_SUCCESS)
-				lim_log(mac_ctx, LOGP,
-					FL("Set VHT_SU_BEAMFORMEE_CAP Fail"));
+		session->ch_width = vht_ch_wd + 1;
+		lim_log(mac_ctx, LOGE, FL(
+				"cntr_freq0 %d, cntr_freq1 %d, width %d"),
+				session->ch_center_freq_seg0,
+				session->ch_center_freq_seg1,
+				session->ch_width);
+		if (CH_WIDTH_80MHZ < session->ch_width) {
+			session->enable_su_tx_bformer = 0;
+			session->nss = 1;
 		}
-		/* Extract the UAPSD flag from WMM Parameter element */
-		if (beacon_struct->wmeEdcaPresent)
-			*uapsd = beacon_struct->edcaParams.qosInfo.uapsd;
+	}
+	if (session->vhtCapabilityPresentInBeacon == 1 &&
+			!session->htSupportedChannelWidthSet &&
+			session->txBFIniFeatureEnabled == 0) {
+		cfg_set_status = cfg_set_int(mac_ctx,
+				WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
+				0);
+		if (cfg_set_status != eSIR_SUCCESS)
+			lim_log(mac_ctx, LOGP,
+					FL("Set VHT_SU_BEAMFORMEE_CAP Fail"));
+	}
+	/* Extract the UAPSD flag from WMM Parameter element */
+	if (beacon_struct->wmeEdcaPresent)
+		*uapsd = beacon_struct->edcaParams.qosInfo.uapsd;
 #if defined FEATURE_WLAN_ESE
-		/* If there is Power Constraint Element specifically,
-		 * adapt to it. Hence there is else condition check
-		 * for this if statement.
-		 */
-		if (beacon_struct->eseTxPwr.present)
-			*local_constraint = beacon_struct->eseTxPwr.power_limit;
-		session->is_ese_version_ie_present =
-			beacon_struct->is_ese_ver_ie_present;
+	/* If there is Power Constraint Element specifically,
+	 * adapt to it. Hence there is else condition check
+	 * for this if statement.
+	 */
+	if (beacon_struct->eseTxPwr.present)
+		*local_constraint = beacon_struct->eseTxPwr.power_limit;
+	session->is_ese_version_ie_present =
+		beacon_struct->is_ese_ver_ie_present;
 #endif
-		if (beacon_struct->powerConstraintPresent) {
-			*local_constraint -=
-				beacon_struct->localPowerConstraint.
-				localPowerConstraints;
-		}
-		session->country_info_present = false;
-		/* Initializing before first use */
-		if (beacon_struct->countryInfoPresent)
-			session->country_info_present = true;
+	if (beacon_struct->powerConstraintPresent) {
+		*local_constraint -=
+			beacon_struct->localPowerConstraint.
+			localPowerConstraints;
 	}
+	session->country_info_present = false;
+	/* Initializing before first use */
+	if (beacon_struct->countryInfoPresent)
+		session->country_info_present = true;
 	/* Check if Extended caps are present in probe resp or not */
 	if (beacon_struct->ext_cap.present)
 		session->is_ext_caps_present = true;

+ 4 - 2
core/wma/src/wma_dev_if.c

@@ -1729,6 +1729,7 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma,
 	uint32_t temp_chan_info = 0;
 	uint32_t temp_reg_info_1 = 0;
 	uint32_t temp_reg_info_2 = 0;
+	uint16_t bw_val;
 
 	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
 	if (mac_ctx == NULL) {
@@ -1773,10 +1774,11 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma,
 
 	params.band_center_freq1 = params.chan_freq;
 
-	if (CH_WIDTH_20MHZ != req->chan_width)
+	bw_val = cds_bw_value(req->chan_width);
+	if (20 < bw_val)
 		params.band_center_freq1 =
 			cds_chan_to_freq(req->ch_center_freq_seg0);
-	if (CH_WIDTH_80P80MHZ == req->chan_width)
+	if (80 < bw_val)
 		params.band_center_freq2 =
 			cds_chan_to_freq(req->ch_center_freq_seg1);
 	else

+ 3 - 3
core/wma/src/wma_utils.c

@@ -3374,10 +3374,10 @@ uint32_t wma_get_vht_ch_width(void)
 	if (NULL == wm_hdl)
 		return fw_ch_wd;
 
-	if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ)
-		fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
-	else if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ)
+	if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ)
 		fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ;
+	else if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ)
+		fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
 
 	return fw_ch_wd;
 }