Эх сурвалжийг харах

qcacld-3.0: Handle bss color change IE coming from AP

If AP changes its color code for 11AX mode then it will announce
through bss color change IE. Connected STA needs to honor that IE
and update its internal table.
Along with color change IE, he ops can also be changed by AP.
STA needs to honor that as well.

CRs-Fixed: 2039284
Change-Id: I4f6767d0a6a814f56448dc6d647e045c852e2750
Krunal Soni 8 жил өмнө
parent
commit
b7f2043b99

+ 9 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -126,6 +126,15 @@ static const int beacon_filter_table[] = {
 	SIR_MAC_HT_INFO_EID,
 	SIR_MAC_VHT_OPMODE_EID,
 	SIR_MAC_VHT_OPERATION_EID,
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+	/*
+	 * EID: 221 vendor IE is being used temporarily by 11AX
+	 * bss-color-change IE till it gets any fixed number. This
+	 * vendor EID needs to be replaced with bss-color-change IE
+	 * number.
+	 */
+	SIR_MAC_EID_VENDOR,
+#endif
 };
 
 /**

+ 37 - 0
core/mac/src/pe/lim/lim_utils.c

@@ -59,6 +59,9 @@
 #include "nan_datapath.h"
 #include "wma.h"
 #include "wlan_reg_services_api.h"
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+#include "wma_he.h"
+#endif
 
 #ifdef WLAN_FEATURE_11W
 #include "wni_cfg.h"
@@ -5852,6 +5855,40 @@ bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac, tpPESession psessionEntry
 	return true;
 }
 
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+bool lim_send_he_ie_update(tpAniSirGlobal mac_ctx, tpPESession pe_session)
+{
+	uint32_t he_ops = 0;
+	tDot11fIEvendor_he_op *he_op = &pe_session->he_op;
+	QDF_STATUS status;
+
+	WMI_HEOPS_COLOR_SET(he_ops, he_op->bss_color);
+	WMI_HEOPS_DEFPE_SET(he_ops, he_op->default_pe);
+	WMI_HEOPS_TWT_SET(he_ops, he_op->twt_required);
+	WMI_HEOPS_RTSTHLD_SET(he_ops, he_op->rts_threshold);
+	WMI_HEOPS_PARTBSSCOLOR_SET(he_ops, he_op->partial_bss_col);
+	WMI_HEOPS_MAXBSSID_SET(he_ops, he_op->maxbssid_ind);
+	WMI_HEOPS_TXBSSID_SET(he_ops, he_op->tx_bssid_ind);
+	WMI_HEOPS_BSSCOLORDISABLE_SET(he_ops, he_op->bss_col_disabled);
+	WMI_HEOPS_DUALBEACON_SET(he_ops, he_op->dual_beacon);
+	status = wma_update_he_ops_ie(cds_get_context(QDF_MODULE_ID_WMA),
+				      pe_session->smeSessionId, he_ops);
+	if (status != QDF_STATUS_SUCCESS)  {
+		lim_log(mac_ctx, LOGE,
+			FL("Can't send for vdev_id[%d] he_ops[0x%x]"),
+			pe_session->smeSessionId, he_ops);
+		return false;
+	} else {
+		lim_log(mac_ctx, LOGD,
+			FL("successfully sent for vdev_id[%d] he_ops[0x%x]"),
+			pe_session->smeSessionId, he_ops);
+	}
+
+	return true;
+
+}
+#endif
+
 bool lim_set_nss_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
 			uint8_t rxNss, uint8_t staId, uint8_t *peerMac)
 {

+ 3 - 0
core/mac/src/pe/lim/lim_utils.h

@@ -465,6 +465,9 @@ bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac,
 		tpPESession psessionEntry,
 		uint8_t chanWidth, uint8_t staId,
 		uint8_t *peerMac);
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+bool lim_send_he_ie_update(tpAniSirGlobal mac_ctx, tpPESession pe_session);
+#endif
 bool lim_set_nss_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
 		uint8_t rxNss, uint8_t staId, uint8_t *peerMac);
 bool lim_check_membership_user_position(tpAniSirGlobal pMac,

+ 138 - 85
core/mac/src/pe/sch/sch_beacon_process.c

@@ -489,106 +489,114 @@ static void update_nss(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
 	}
 }
 
-/*
- * sch_bcn_process_sta_ibss() - Process the received beacon frame
- * for sta, bt_amp_sta and ibss
- *
- * @mac_ctx:        mac_ctx
- * @bcn:            beacon struct
- * @rx_pkt_info:    received packet info
- * @session:        pe session pointer
- * @bssIdx:         bss index
- * @beaconParams:   update beacon params
- * @sendProbeReq:   out flag to indicate if probe rsp is to be sent
- * @pMh:            mac header
- *
- * Process the received beacon frame for sta and ibss
- *
- * Return: void
- */
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
 static void
-sch_bcn_process_sta_ibss(tpAniSirGlobal mac_ctx,
-				    tpSchBeaconStruct bcn,
-				    uint8_t *rx_pkt_info,
-				    tpPESession session, uint8_t *bssIdx,
-				    tUpdateBeaconParams *beaconParams,
-				    uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
+sch_bcn_update_he_ies(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+				tpPESession session, tpSchBeaconStruct bcn,
+				tpSirMacMgmtHdr mac_hdr)
 {
-	tpDphHashNode pStaDs = NULL;
-	uint16_t aid;
-	uint8_t operMode;
-	uint8_t chWidth = 0;
-	uint8_t cb_mode;
-	uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();
-	bool skip_opmode_update = false;
+	uint8_t session_bss_col_disabled_flag;
+	bool anything_changed = false;
+
+	if (session->he_op.present && bcn->vendor_he_op.present) {
+		if (bcn->vendor_he_bss_color_change.present &&
+				(session->he_op.bss_color !=
+				 bcn->vendor_he_bss_color_change.new_color)) {
+			pe_debug("bss color changed from [%d] to [%d]",
+				session->he_op.bss_color,
+				bcn->vendor_he_bss_color_change.new_color);
+			session->he_op.bss_color =
+				bcn->vendor_he_bss_color_change.new_color;
+			anything_changed = true;
+		}
+		session_bss_col_disabled_flag = session->he_op.bss_col_disabled;
+		if (session_bss_col_disabled_flag !=
+				bcn->vendor_he_op.bss_col_disabled) {
+			pe_debug("color disable flag changed from [%d] to [%d]",
+				session->he_op.bss_col_disabled,
+				bcn->vendor_he_op.bss_col_disabled);
+			session->he_op.bss_col_disabled =
+				bcn->vendor_he_op.bss_col_disabled;
+			anything_changed = true;
+		}
+	}
+	if (anything_changed)
+		lim_send_he_ie_update(mac_ctx, session);
+}
+#else
+static void
+sch_bcn_update_he_ies(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+				tpPESession session, tpSchBeaconStruct bcn,
+				tpSirMacMgmtHdr mac_hdr)
+{
+	return;
+}
+#endif
 
-	if (CHAN_ENUM_14 >= session->currentOperChannel)
-		cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
-	else
-		cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
-	/* check for VHT capability */
-	pStaDs = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid,
-			&session->dph.dphHashTable);
-	if ((NULL == pStaDs) ||
-	  (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) ||
-	  ((NULL != pStaDs) &&
-	   (STA_INVALID_IDX == pStaDs->staIndex)))
-		return;
+static void
+sch_bcn_update_opmode_change(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+				tpPESession session, tpSchBeaconStruct bcn,
+				tpSirMacMgmtHdr mac_hdr)
+{
+	bool skip_opmode_update = false;
+	uint8_t oper_mode;
+	uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();
+	uint8_t ch_width = 0;
 
 	if (session->vhtCapability && bcn->OperatingMode.present) {
-		operMode = get_operating_channel_width(pStaDs);
-		if ((operMode == eHT_CHANNEL_WIDTH_80MHZ) &&
+		oper_mode = get_operating_channel_width(sta_ds);
+		if ((oper_mode == eHT_CHANNEL_WIDTH_80MHZ) &&
 		    (bcn->OperatingMode.chanWidth > eHT_CHANNEL_WIDTH_80MHZ))
 			skip_opmode_update = true;
 
 		if (!skip_opmode_update &&
-			((operMode != bcn->OperatingMode.chanWidth) ||
-			(pStaDs->vhtSupportedRxNss !=
+			((oper_mode != bcn->OperatingMode.chanWidth) ||
+			(sta_ds->vhtSupportedRxNss !=
 			(bcn->OperatingMode.rxNSS + 1)))) {
 			pe_debug("received OpMode Chanwidth %d, staIdx = %d",
-			       bcn->OperatingMode.chanWidth, pStaDs->staIndex);
+			       bcn->OperatingMode.chanWidth, sta_ds->staIndex);
 			pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x",
-			       pMh->sa[0], pMh->sa[1],
-			       pMh->sa[2], pMh->sa[3],
-			       pMh->sa[4], pMh->sa[5]);
+			       mac_hdr->sa[0], mac_hdr->sa[1],
+			       mac_hdr->sa[2], mac_hdr->sa[3],
+			       mac_hdr->sa[4], mac_hdr->sa[5]);
 
 			if ((bcn->OperatingMode.chanWidth >=
 				eHT_CHANNEL_WIDTH_160MHZ) &&
 				(fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) {
 				pe_debug("Updating the CH Width to 160MHz");
-				pStaDs->vhtSupportedChannelWidthSet =
+				sta_ds->vhtSupportedChannelWidthSet =
 					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
-				pStaDs->htSupportedChannelWidthSet =
+				sta_ds->htSupportedChannelWidthSet =
 					eHT_CHANNEL_WIDTH_40MHZ;
-				chWidth = eHT_CHANNEL_WIDTH_160MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_160MHZ;
 			} else if (bcn->OperatingMode.chanWidth >=
 				eHT_CHANNEL_WIDTH_80MHZ) {
 				pe_debug("Updating the CH Width to 80MHz");
-				pStaDs->vhtSupportedChannelWidthSet =
+				sta_ds->vhtSupportedChannelWidthSet =
 					WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
-				pStaDs->htSupportedChannelWidthSet =
+				sta_ds->htSupportedChannelWidthSet =
 					eHT_CHANNEL_WIDTH_40MHZ;
-				chWidth = eHT_CHANNEL_WIDTH_80MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_80MHZ;
 			} else if (bcn->OperatingMode.chanWidth ==
 				eHT_CHANNEL_WIDTH_40MHZ) {
 				pe_debug("Updating the CH Width to 40MHz");
-				pStaDs->vhtSupportedChannelWidthSet =
+				sta_ds->vhtSupportedChannelWidthSet =
 					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
-				pStaDs->htSupportedChannelWidthSet =
+				sta_ds->htSupportedChannelWidthSet =
 					eHT_CHANNEL_WIDTH_40MHZ;
-				chWidth = eHT_CHANNEL_WIDTH_40MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_40MHZ;
 			} else if (bcn->OperatingMode.chanWidth ==
 				eHT_CHANNEL_WIDTH_20MHZ) {
 				pe_debug("Updating the CH Width to 20MHz");
-				pStaDs->vhtSupportedChannelWidthSet =
+				sta_ds->vhtSupportedChannelWidthSet =
 					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
-				pStaDs->htSupportedChannelWidthSet =
+				sta_ds->htSupportedChannelWidthSet =
 					eHT_CHANNEL_WIDTH_20MHZ;
-				chWidth = eHT_CHANNEL_WIDTH_20MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_20MHZ;
 			}
 			lim_check_vht_op_mode_change(mac_ctx, session,
-					chWidth, pStaDs->staIndex, pMh->sa);
-			update_nss(mac_ctx, pStaDs, bcn, session, pMh);
+				ch_width, sta_ds->staIndex, mac_hdr->sa);
+			update_nss(mac_ctx, sta_ds, bcn, session, mac_hdr);
 		}
 		return;
 	}
@@ -596,56 +604,101 @@ sch_bcn_process_sta_ibss(tpAniSirGlobal mac_ctx,
 	if (!(session->vhtCapability && bcn->VHTOperation.present))
 		return;
 
-	operMode = pStaDs->vhtSupportedChannelWidthSet;
-	if ((operMode == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
-	    (operMode < bcn->VHTOperation.chanWidth))
+	oper_mode = sta_ds->vhtSupportedChannelWidthSet;
+	if ((oper_mode == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
+	    (oper_mode < bcn->VHTOperation.chanWidth))
 		skip_opmode_update = true;
 
 	if (!skip_opmode_update &&
-	    (operMode != bcn->VHTOperation.chanWidth)) {
+	    (oper_mode != bcn->VHTOperation.chanWidth)) {
 		pe_debug("received VHTOP CHWidth %d staIdx = %d",
-		       bcn->VHTOperation.chanWidth, pStaDs->staIndex);
+		       bcn->VHTOperation.chanWidth, sta_ds->staIndex);
 		pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x",
-		       pMh->sa[0], pMh->sa[1],
-		       pMh->sa[2], pMh->sa[3],
-		       pMh->sa[4], pMh->sa[5]);
+		       mac_hdr->sa[0], mac_hdr->sa[1],
+		       mac_hdr->sa[2], mac_hdr->sa[3],
+		       mac_hdr->sa[4], mac_hdr->sa[5]);
 
 		if ((bcn->VHTOperation.chanWidth >=
 			WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) &&
 			(fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) {
 			pe_debug("Updating the CH Width to 160MHz");
-			pStaDs->vhtSupportedChannelWidthSet =
+			sta_ds->vhtSupportedChannelWidthSet =
 				bcn->VHTOperation.chanWidth;
-			pStaDs->htSupportedChannelWidthSet =
+			sta_ds->htSupportedChannelWidthSet =
 				eHT_CHANNEL_WIDTH_40MHZ;
-			chWidth = eHT_CHANNEL_WIDTH_160MHZ;
+			ch_width = eHT_CHANNEL_WIDTH_160MHZ;
 		} else if (bcn->VHTOperation.chanWidth >=
 			WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
 			pe_debug("Updating the CH Width to 80MHz");
-			pStaDs->vhtSupportedChannelWidthSet =
+			sta_ds->vhtSupportedChannelWidthSet =
 				WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
-			pStaDs->htSupportedChannelWidthSet =
+			sta_ds->htSupportedChannelWidthSet =
 				eHT_CHANNEL_WIDTH_40MHZ;
-			chWidth = eHT_CHANNEL_WIDTH_80MHZ;
+			ch_width = eHT_CHANNEL_WIDTH_80MHZ;
 		} else if (bcn->VHTOperation.chanWidth ==
 			WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
-			pStaDs->vhtSupportedChannelWidthSet =
+			sta_ds->vhtSupportedChannelWidthSet =
 				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
 			if (bcn->HTCaps.supportedChannelWidthSet) {
 				pe_debug("Updating the CH Width to 40MHz");
-				pStaDs->htSupportedChannelWidthSet =
+				sta_ds->htSupportedChannelWidthSet =
 					eHT_CHANNEL_WIDTH_40MHZ;
-				chWidth = eHT_CHANNEL_WIDTH_40MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_40MHZ;
 			} else {
 				pe_debug("Updating the CH Width to 20MHz");
-				pStaDs->htSupportedChannelWidthSet =
+				sta_ds->htSupportedChannelWidthSet =
 					eHT_CHANNEL_WIDTH_20MHZ;
-				chWidth = eHT_CHANNEL_WIDTH_20MHZ;
+				ch_width = eHT_CHANNEL_WIDTH_20MHZ;
 			}
 		}
-		lim_check_vht_op_mode_change(mac_ctx, session, chWidth,
-						pStaDs->staIndex, pMh->sa);
+		lim_check_vht_op_mode_change(mac_ctx, session, ch_width,
+						sta_ds->staIndex, mac_hdr->sa);
 	}
+}
+
+/*
+ * sch_bcn_process_sta_ibss() - Process the received beacon frame
+ * for sta, bt_amp_sta and ibss
+ *
+ * @mac_ctx:        mac_ctx
+ * @bcn:            beacon struct
+ * @rx_pkt_info:    received packet info
+ * @session:        pe session pointer
+ * @bssIdx:         bss index
+ * @beaconParams:   update beacon params
+ * @sendProbeReq:   out flag to indicate if probe rsp is to be sent
+ * @pMh:            mac header
+ *
+ * Process the received beacon frame for sta and ibss
+ *
+ * Return: void
+ */
+static void
+sch_bcn_process_sta_ibss(tpAniSirGlobal mac_ctx,
+				    tpSchBeaconStruct bcn,
+				    uint8_t *rx_pkt_info,
+				    tpPESession session, uint8_t *bssIdx,
+				    tUpdateBeaconParams *beaconParams,
+				    uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
+{
+	tpDphHashNode pStaDs = NULL;
+	uint16_t aid;
+	uint8_t cb_mode;
+
+	if (CHAN_ENUM_14 >= session->currentOperChannel)
+		cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
+	else
+		cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
+	/* check for VHT capability */
+	pStaDs = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid,
+			&session->dph.dphHashTable);
+	if ((NULL == pStaDs) ||
+	  (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) ||
+	  ((NULL != pStaDs) &&
+	   (STA_INVALID_IDX == pStaDs->staIndex)))
+		return;
+	sch_bcn_update_opmode_change(mac_ctx, pStaDs, session, bcn, pMh);
+	sch_bcn_update_he_ies(mac_ctx, pStaDs, session, bcn, pMh);
 	return;
 }
 

+ 20 - 0
core/wma/inc/wma_he.h

@@ -170,6 +170,20 @@ static inline bool wma_is_peer_he_capable(tpAddStaParams params)
 void wma_update_vdev_he_capable(struct wma_vdev_start_req *req,
 		tpSwitchChannelParams params);
 
+/**
+ * wma_update_he_ops_ie() - update the HE OPS IE to firmware
+ * @wma: pointer to wma context
+ * @vdev_id: vdev id
+ * @he_ops: 32bit value of HE ops
+ *
+ * This API is used to send updated HE operational IE to firmware, so that
+ * firmware can be in sync with host
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma, uint8_t vdev_id,
+					   uint32_t he_ops);
+
 /**
  * wma_get_he_capabilities() - Get HE capabilities from WMA
  * @he_cap: Pointer to HE capabilities
@@ -256,6 +270,12 @@ static inline void wma_copy_vdev_start_he_ops(struct vdev_start_params *params,
 {
 }
 
+static inline  QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma,
+			uint8_t vdev_id, uint32_t he_ops)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 static inline void wma_vdev_set_he_bss_params(tp_wma_handle wma,
 				uint8_t vdev_id, struct wma_vdev_start_req *req)
 {

+ 21 - 0
core/wma/src/wma_he.c

@@ -1092,6 +1092,27 @@ void wma_update_vdev_he_capable(struct wma_vdev_start_req *req,
 	req->he_capable = params->he_capable;
 }
 
+QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma, uint8_t vdev_id,
+					   uint32_t he_ops)
+{
+	QDF_STATUS ret;
+
+	if (!wma) {
+		WMA_LOGE(FL("wrong wma_handle...."));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_HEOPS_0_31, he_ops);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		WMA_LOGE(FL("Failed to set HE OPs"));
+	else
+		WMA_LOGD(FL("Succesfully send he_ops[0x%x]"), he_ops);
+
+	return ret;
+}
+
 QDF_STATUS wma_get_he_capabilities(struct he_capability *he_cap)
 {
 	tp_wma_handle wma_handle;