Browse Source

qcacld-3.0: Add support for OUI framework during join request in CSR

Add support to use the action OUI framework to identify vendor APs from
the ini and apply vendor AP specific WARs during CSR join request.

Change-Id: Icb6742bfeb9515c11d61034b795b95b92e833b64
CRs-Fixed: 2254532
Vignesh Viswanathan 6 years ago
parent
commit
d5a5f2e278

+ 4 - 0
core/mac/inc/sir_api.h

@@ -1078,6 +1078,10 @@ typedef struct sSirSmeJoinReq {
 	/* Pls make this as last variable in struct */
 	bool force_24ghz_in_ht20;
 	bool force_rsne_override;
+	bool supported_nss_1x1;
+	uint8_t vdev_nss;
+	uint8_t nss;
+	bool nss_forced_1x1;
 	tSirBssDescription bssDescription;
 	/*
 	 * WARNING: Pls make bssDescription as last variable in struct

+ 0 - 7
core/mac/inc/sir_mac_prot_def.h

@@ -633,13 +633,6 @@
 #define SIR_MAC_VENDOR_AP_1_OUI             "\x00\x0C\x43"
 #define SIR_MAC_VENDOR_AP_1_OUI_LEN         3
 
-#define SIR_MAC_VENDOR_AP_2_OUI             "\x00\x10\x18"
-#define SIR_MAC_VENDOR_AP_2_OUI_LEN         3
-
-#define SIR_MAC_VENDOR_AP_2_DATA            "\x02\xFF\xF0\x2C\x00\x00"
-#define SIR_MAC_VENDOR_AP_2_DATA_2          "\x02\xFF\x04\x0C\x00\x00"
-#define SIR_MAC_VENDOR_AP_2_DATA_LEN        6
-
 #define SIR_MAC_VENDOR_AP_3_OUI             "\x00\x03\x7F"
 #define SIR_MAC_VENDOR_AP_3_OUI_LEN         3
 

+ 1 - 0
core/mac/src/pe/include/lim_session.h

@@ -499,6 +499,7 @@ typedef struct sPESession       /* Added to Support BT-AMP */
 	/* flag to indicate country code in beacon */
 	uint8_t country_info_present;
 	uint8_t nss;
+	bool nss_forced_1x1;
 	bool add_bss_failed;
 	/* To hold OBSS Scan IE Parameters */
 	struct obss_scanparam obss_ht40_scanparam;

+ 16 - 12
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -1227,7 +1227,6 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
 	uint16_t ie_len;
 	const uint8_t *vendor_ie;
 	tSirBssDescription *bss_desc;
-	struct vdev_type_nss *vdev_type_nss;
 
 	if (!mac_ctx || !msg_buf) {
 		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
@@ -1427,17 +1426,7 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
 
 		/* Copy The channel Id to the session Table */
 		session->currentOperChannel = bss_desc->channelId;
-		if (IS_5G_CH(session->currentOperChannel))
-			vdev_type_nss = &mac_ctx->vdev_type_nss_5g;
-		else
-			vdev_type_nss = &mac_ctx->vdev_type_nss_2g;
-		if (session->pePersona == QDF_P2P_CLIENT_MODE)
-			session->vdev_nss = vdev_type_nss->p2p_cli;
-		else
-			session->vdev_nss = vdev_type_nss->sta;
-		session->nss = session->vdev_nss;
-		if (!mac_ctx->roam.configParam.enable2x2)
-			session->nss = 1;
+
 		session->vhtCapability =
 			IS_DOT11_MODE_VHT(session->dot11mode);
 		if (session->vhtCapability) {
@@ -1591,6 +1580,16 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
 
 		session->encryptType = sme_join_req->UCEncryptionType;
 
+		session->supported_nss_1x1 = sme_join_req->supported_nss_1x1;
+		session->vdev_nss = sme_join_req->vdev_nss;
+		session->nss = sme_join_req->nss;
+		session->nss_forced_1x1 = sme_join_req->nss_forced_1x1;
+
+		pe_debug("nss %d, vdev_nss %d, supported_nss_1x1 %d",
+			 session->nss,
+			 session->vdev_nss,
+			 session->supported_nss_1x1);
+
 		mlm_join_req->bssDescription.length =
 			session->pLimJoinReq->bssDescription.length;
 
@@ -1844,6 +1843,11 @@ static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
 		pe_debug("vht su bformer [%d]", session_entry->vht_config.su_beam_former);
 	}
 
+	session_entry->supported_nss_1x1 = reassoc_req->supported_nss_1x1;
+	session_entry->vdev_nss = reassoc_req->vdev_nss;
+	session_entry->nss = reassoc_req->nss;
+	session_entry->nss_forced_1x1 = reassoc_req->nss_forced_1x1;
+
 	pe_debug("vhtCapability: %d su_beam_formee: %d su_tx_bformer %d",
 		session_entry->vhtCapability,
 		session_entry->vht_config.su_beam_formee,

+ 0 - 188
core/mac/src/pe/lim/lim_prop_exts_utils.c

@@ -101,168 +101,6 @@ static inline void get_ese_version_ie_probe_response(tpAniSirGlobal mac_ctx,
 }
 #endif
 
-/**
- * lim_get_nss_supported_by_beacon() - finds out nss from beacom
- * @bcn: beacon structure pointer
- * @session: pointer to pe session
- *
- * Return: number of nss advertised by beacon
- */
-static uint8_t lim_get_nss_supported_by_beacon(tpSchBeaconStruct bcn,
-						tpPESession session)
-{
-	if (session->vhtCapability && bcn->VHTCaps.present) {
-		if ((bcn->VHTCaps.rxMCSMap & 0xC0) != 0xC0)
-			return 4;
-
-		if ((bcn->VHTCaps.rxMCSMap & 0x30) != 0x30)
-			return 3;
-
-		if ((bcn->VHTCaps.rxMCSMap & 0x0C) != 0x0C)
-			return 2;
-	} else if (session->htCapability && bcn->HTCaps.present) {
-		if (bcn->HTCaps.supportedMCSSet[3])
-			return 4;
-
-		if (bcn->HTCaps.supportedMCSSet[2])
-			return 3;
-
-		if (bcn->HTCaps.supportedMCSSet[1])
-			return 2;
-	}
-
-	return 1;
-}
-
-/**
- * lim_dump_vendor_ies() - Dumps all the vendor IEs
- * @ie:         ie buffer
- * @ie_len:     length of ie buffer
- *
- * This function dumps the vendor IEs present in the AP's IE buffer
- *
- * Return: none
- */
-static
-void lim_dump_vendor_ies(uint8_t *ie, uint16_t ie_len)
-{
-	int32_t left = ie_len;
-	uint8_t *ptr = ie;
-	uint8_t elem_id, elem_len;
-
-	while (left >= 2) {
-		elem_id  = ptr[0];
-		elem_len = ptr[1];
-		left -= 2;
-		if (elem_len > left) {
-			pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
-					elem_id, elem_len, left);
-			return;
-		}
-		if (SIR_MAC_EID_VENDOR == elem_id) {
-			pe_debug("Dumping Vendor IE of len %d", elem_len);
-			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
-					   QDF_TRACE_LEVEL_DEBUG,
-					   &ptr[2], elem_len);
-		}
-
-		left -= elem_len;
-		ptr += (elem_len + 2);
-	}
-}
-
-/**
- * lim_check_vendor_ap_present() - checks if the Vendor OUIs are present
- * in the IE buffer
- *
- * @ie:            ie buffer
- * @ie_len:        length of ie buffer
- * @beacon_struct: pointer to beacon structure
- * @session:       pointer to pe session
- *
- * This function parses the IE buffer and finds if any of the vendor OUI
- * is present in it.
- *
- * Return: true if the vendor OUI is present, else false
- */
-static bool
-lim_check_vendor_ap_present(uint8_t *ie, uint16_t ie_len,
-			    tpSchBeaconStruct beacon_struct,
-			    tpPESession session)
-{
-	uint8_t nss;
-	const uint8_t *ptr = NULL;
-	uint8_t elem_len;
-	uint8_t elem_data[SIR_MAC_VENDOR_AP_2_DATA_LEN];
-
-	nss = lim_get_nss_supported_by_beacon(beacon_struct, session);
-	lim_dump_vendor_ies(ie, ie_len);
-	/*
-	 * for SIR_MAC_VENDOR_AP_1_OUI, check for Vendor OUI and if it is 2x2
-	 */
-	if ((wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_1_OUI,
-	    SIR_MAC_VENDOR_AP_1_OUI_LEN, ie, ie_len)) &&
-	    (nss == 2)) {
-		pe_debug("In lim_check_vendor_ap_present match Vendor AP 1");
-		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
-				SIR_MAC_VENDOR_AP_1_OUI,
-				SIR_MAC_VENDOR_AP_1_OUI_LEN);
-		return true;
-	}
-
-	/*
-	 * for SIR_MAC_VENDOR_AP_2_OUI check for Vendor OUI, Vendor IE Data
-	 * and if it is 2x2
-	 */
-	ptr = wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_2_OUI,
-					      SIR_MAC_VENDOR_AP_2_OUI_LEN,
-					      ie, ie_len);
-	if (!ptr)
-		goto vendor3;
-
-	elem_len = ptr[1];
-	qdf_mem_copy(&elem_data, &ptr[2 + SIR_MAC_VENDOR_AP_2_OUI_LEN],
-			SIR_MAC_VENDOR_AP_2_DATA_LEN);
-	/*
-	 * Byte 2 of Vendor IE data might change dynamically, masking it
-	 */
-	elem_data[1] |= 0xFF;
-
-	if ((nss == 2) && (elem_len == (SIR_MAC_VENDOR_AP_2_OUI_LEN +
-	     SIR_MAC_VENDOR_AP_2_DATA_LEN)) &&
-	     ((qdf_mem_cmp(&elem_data, SIR_MAC_VENDOR_AP_2_DATA,
-	     SIR_MAC_VENDOR_AP_2_DATA_LEN) == 0) ||
-	     (qdf_mem_cmp(&elem_data, SIR_MAC_VENDOR_AP_2_DATA_2,
-	     SIR_MAC_VENDOR_AP_2_DATA_LEN) == 0))) {
-		pe_debug("In lim_check_vendor_ap_present match Vendor AP 2");
-		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
-				SIR_MAC_VENDOR_AP_2_OUI,
-				SIR_MAC_VENDOR_AP_2_OUI_LEN);
-		pe_debug("Verifying vendor IE Data "MAC_ADDRESS_STR,
-			MAC_ADDR_ARRAY(&ptr[2 + SIR_MAC_VENDOR_AP_2_OUI_LEN]));
-		return true;
-	}
-
-vendor3:
-	/*
-	 * for SIR_MAC_VENDOR_AP_3_OUI, check if VENDOR AP 3 IE is present and
-	 * if Vendor AP 4 IE is not present and if it is 4x4 11ac
-	 */
-	if (beacon_struct->VHTCaps.present &&
-	    (nss == 4 || nss == 3) &&
-	    (wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_3_OUI,
-	    SIR_MAC_VENDOR_AP_3_OUI_LEN, ie, ie_len)) &&
-	    !(wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_4_OUI,
-	    SIR_MAC_VENDOR_AP_4_OUI_LEN, ie, ie_len))) {
-		pe_debug("In lim_check_vendor_ap_present match Vendor AP 3");
-		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
-					SIR_MAC_VENDOR_AP_3_OUI,
-					SIR_MAC_VENDOR_AP_3_OUI_LEN);
-		return true;
-	}
-
-	return false;
-}
 #ifdef WLAN_FEATURE_11AX
 static void lim_extract_he_op(tpPESession session,
 		tSirProbeRespBeacon *beacon_struct)
@@ -366,7 +204,6 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
 	QDF_STATUS cfg_get_status = QDF_STATUS_E_FAILURE;
 	uint8_t ap_bcon_ch_width;
 	bool new_ch_width_dfn = false;
-	bool is_vendor_ap_present;
 	tDot11fIEVHTOperation *vht_op;
 	uint8_t fw_vht_ch_wd;
 	uint8_t vht_ch_wd;
@@ -392,31 +229,6 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
 		return;
 	}
 
-	is_vendor_ap_present = lim_check_vendor_ap_present(p_ie,
-							   ie_len,
-							   beacon_struct,
-							   session);
-
-	if (mac_ctx->roam.configParam.is_force_1x1 &&
-	    is_vendor_ap_present &&
-	    mac_ctx->lteCoexAntShare &&
-	    IS_24G_CH(session->currentOperChannel)) {
-		session->supported_nss_1x1 = true;
-		session->vdev_nss = 1;
-		session->nss = 1;
-		pe_debug("For special ap, NSS: %d", session->nss);
-	}
-
-	if (session->nss > lim_get_nss_supported_by_beacon(beacon_struct,
-	    session)) {
-		session->nss = lim_get_nss_supported_by_beacon(beacon_struct,
-							       session);
-		session->vdev_nss = session->nss;
-	}
-
-	if (session->nss == 1)
-		session->supported_nss_1x1 = true;
-
 	if (beacon_struct->wmeInfoPresent ||
 	    beacon_struct->wmeEdcaPresent ||
 	    beacon_struct->HTCaps.present)

+ 4 - 0
core/mac/src/pe/sch/sch_beacon_process.c

@@ -475,6 +475,10 @@ static void update_nss(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
 		       tpSirMacMgmtHdr mgmt_hdr)
 {
 	if (sta_ds->vhtSupportedRxNss != (beacon->OperatingMode.rxNSS + 1)) {
+		if (session_entry->nss_forced_1x1) {
+			pe_debug("Not Updating NSS for special AP");
+			return;
+		}
 		sta_ds->vhtSupportedRxNss =
 			beacon->OperatingMode.rxNSS + 1;
 		lim_set_nss_change(mac_ctx, session_entry,

+ 3 - 0
core/sme/inc/csr_internal.h

@@ -935,6 +935,9 @@ struct csr_roam_session {
 	bool ch_switch_in_progress;
 	bool roam_synch_in_progress;
 	bool supported_nss_1x1;
+	uint8_t vdev_nss;
+	uint8_t nss;
+	bool nss_forced_1x1;
 	bool disable_hi_rssi;
 	bool dhcp_done;
 	uint8_t disconnect_reason;

+ 222 - 3
core/sme/src/csr/csr_api_roam.c

@@ -52,6 +52,8 @@
 #include <wlan_tdls_tgt_api.h>
 #include <wlan_cfg80211_scan.h>
 #include <wlan_scan_public_structs.h>
+#include <wlan_action_oui_public_struct.h>
+#include <wlan_action_oui_ucfg_api.h>
 #include <wlan_utility.h>
 
 #define MAX_PWR_FCC_CHAN_12 8
@@ -15371,6 +15373,114 @@ static void csr_update_sae_config(tSirSmeJoinReq *csr_join_req,
 { }
 #endif
 
+/**
+ * csr_get_nss_supported_by_sta_and_ap() - finds out nss from session
+ * and beacon from AP
+ * @vht_caps: VHT capabilities
+ * @ht_caps: HT capabilities
+ * @dot11_mode: dot11 mode
+ *
+ * Return: number of nss advertised by beacon
+ */
+static uint8_t csr_get_nss_supported_by_sta_and_ap(tDot11fIEVHTCaps *vht_caps,
+						   tDot11fIEHTCaps *ht_caps,
+						   uint32_t dot11_mode)
+{
+	bool vht_capability, ht_capability;
+
+	vht_capability = IS_DOT11_MODE_VHT(dot11_mode);
+	ht_capability = IS_DOT11_MODE_HT(dot11_mode);
+
+	if (vht_capability && vht_caps->present) {
+		if ((vht_caps->rxMCSMap & 0xC0) != 0xC0)
+			return 4;
+
+		if ((vht_caps->rxMCSMap & 0x30) != 0x30)
+			return 3;
+
+		if ((vht_caps->rxMCSMap & 0x0C) != 0x0C)
+			return 2;
+	} else if (ht_capability && ht_caps->present) {
+		if (ht_caps->supportedMCSSet[3])
+			return 4;
+
+		if (ht_caps->supportedMCSSet[2])
+			return 3;
+
+		if (ht_caps->supportedMCSSet[1])
+			return 2;
+	}
+
+	return 1;
+}
+
+/**
+ * csr_dump_vendor_ies() - Dumps all the vendor IEs
+ * @ie:         ie buffer
+ * @ie_len:     length of ie buffer
+ *
+ * This function dumps the vendor IEs present in the AP's IE buffer
+ *
+ * Return: none
+ */
+static
+void csr_dump_vendor_ies(uint8_t *ie, uint16_t ie_len)
+{
+	int32_t left = ie_len;
+	uint8_t *ptr = ie;
+	uint8_t elem_id, elem_len;
+
+	while (left >= 2) {
+		elem_id  = ptr[0];
+		elem_len = ptr[1];
+		left -= 2;
+		if (elem_len > left) {
+			pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
+			       elem_id, elem_len, left);
+			return;
+		}
+		if (elem_id == SIR_MAC_EID_VENDOR) {
+			pe_debug("Dumping Vendor IE of len %d", elem_len);
+			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
+					   QDF_TRACE_LEVEL_DEBUG,
+					   &ptr[2], elem_len);
+		}
+
+		left -= elem_len;
+		ptr += (elem_len + 2);
+	}
+}
+
+/**
+ * csr_check_vendor_ap_3_present() - Check if Vendor AP 3 is present
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ie: Pointer to starting IE in Beacon/Probe Response
+ * @ie_len: Length of all IEs combined
+ *
+ * For Vendor AP 3, the condition is that Vendor AP 3 IE should be present
+ * and Vendor AP 4 IE should not be present.
+ * If Vendor AP 3 IE is present and Vendor AP 4 IE is also present,
+ * return false, else return true.
+ *
+ * Return: true or false
+ */
+static bool
+csr_check_vendor_ap_3_present(tpAniSirGlobal mac_ctx, uint8_t *ie,
+			      uint16_t ie_len)
+{
+	bool ret = true;
+
+	if ((wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_3_OUI,
+	    SIR_MAC_VENDOR_AP_3_OUI_LEN, ie, ie_len)) &&
+	    (wlan_get_vendor_ie_ptr_from_oui(SIR_MAC_VENDOR_AP_4_OUI,
+	    SIR_MAC_VENDOR_AP_4_OUI_LEN, ie, ie_len))) {
+		pe_debug("Vendor OUI 3 and Vendor OUI 4 found");
+		ret = false;
+	}
+
+	return ret;
+}
+
 /**
  * The communication between HDD and LIM is thru mailbox (MB).
  * Both sides will access the data structure "tSirSmeJoinReq".
@@ -15406,6 +15516,9 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
 	tpCsrNeighborRoamControlInfo neigh_roam_info;
 	uint32_t value = 0, value1 = 0;
 	QDF_STATUS packetdump_timer_status;
+	bool is_vendor_ap_present;
+	struct vdev_type_nss *vdev_type_nss;
+	struct action_oui_search_attr vendor_ap_search_attr;
 
 	if (!pSession) {
 		sme_err("session %d not found", sessionId);
@@ -15522,10 +15635,116 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
 			/* Need to disable VHT operation in 2.4 GHz band */
 			ucDot11Mode = WNI_CFG_DOT11_MODE_11N;
 		}
+
+		if (IS_5G_CH(pBssDescription->channelId))
+			vdev_type_nss = &pMac->vdev_type_nss_5g;
+		else
+			vdev_type_nss = &pMac->vdev_type_nss_2g;
+		if (pSession->pCurRoamProfile->csrPersona ==
+		    QDF_P2P_CLIENT_MODE)
+			pSession->vdev_nss = vdev_type_nss->p2p_cli;
+		else
+			pSession->vdev_nss = vdev_type_nss->sta;
+		pSession->nss = pSession->vdev_nss;
+
+		if (pSession->nss > csr_get_nss_supported_by_sta_and_ap(
+						&pIes->VHTCaps,
+						&pIes->HTCaps, ucDot11Mode)) {
+			pSession->nss = csr_get_nss_supported_by_sta_and_ap(
+						&pIes->VHTCaps, &pIes->HTCaps,
+						ucDot11Mode);
+			pSession->vdev_nss = pSession->nss;
+		}
+
+		if (!pMac->roam.configParam.enable2x2)
+			pSession->nss = 1;
+
+		if (pSession->nss == 1)
+			pSession->supported_nss_1x1 = true;
+
+		ieLen = csr_get_ielen_from_bss_description(pBssDescription);
+
+		/* Dump the Vendor Specific IEs*/
+		csr_dump_vendor_ies((uint8_t *)&pBssDescription->ieFields[0],
+				    ieLen);
+
+		/* Fill the Vendor AP search params */
+		vendor_ap_search_attr.ie_data =
+				(uint8_t *)&pBssDescription->ieFields[0];
+		vendor_ap_search_attr.ie_length = ieLen;
+		vendor_ap_search_attr.mac_addr = &pBssDescription->bssId[0];
+		vendor_ap_search_attr.nss = csr_get_nss_supported_by_sta_and_ap(
+						&pIes->VHTCaps, &pIes->HTCaps,
+						ucDot11Mode);
+		vendor_ap_search_attr.ht_cap = pIes->HTCaps.present;
+		vendor_ap_search_attr.vht_cap = pIes->VHTCaps.present;
+		vendor_ap_search_attr.enable_2g =
+					IS_24G_CH(pBssDescription->channelId);
+		vendor_ap_search_attr.enable_5g =
+					IS_5G_CH(pBssDescription->channelId);
+
+		is_vendor_ap_present =
+				ucfg_action_oui_search(pMac->psoc,
+						       &vendor_ap_search_attr,
+						       ACTION_OUI_CONNECT_1X1);
+
+		if (is_vendor_ap_present) {
+			is_vendor_ap_present = csr_check_vendor_ap_3_present(
+						pMac, (uint8_t *)pIes, ieLen);
+		}
+
+		if (pMac->roam.configParam.is_force_1x1 &&
+		    pMac->lteCoexAntShare &&
+		    is_vendor_ap_present) {
+			pSession->supported_nss_1x1 = true;
+			pSession->vdev_nss = 1;
+			pSession->nss = 1;
+			pSession->nss_forced_1x1 = true;
+			sme_debug("For special ap, NSS: %d", pSession->nss);
+		}
+
+		/*
+		 * If CCK WAR is set for current AP, update to firmware via
+		 * WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM
+		 */
+		is_vendor_ap_present =
+				ucfg_action_oui_search(pMac->psoc,
+						       &vendor_ap_search_attr,
+						       ACTION_OUI_CCKM_1X1);
+		if (is_vendor_ap_present) {
+			pe_debug("vdev: %d WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM 1",
+				 pSession->sessionId);
+			wma_cli_set_command(
+				pSession->sessionId,
+				(int)WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM, 1,
+				VDEV_CMD);
+		}
+
+		/*
+		 * If Switch to 11N WAR is set for current AP, change dot11
+		 * mode to 11N.
+		 */
+		is_vendor_ap_present =
+			ucfg_action_oui_search(pMac->psoc,
+					       &vendor_ap_search_attr,
+					       ACTION_OUI_SWITCH_TO_11N_MODE);
+		if (pMac->roam.configParam.is_force_1x1 &&
+		    pMac->lteCoexAntShare &&
+		    is_vendor_ap_present &&
+		    (ucDot11Mode == WNI_CFG_DOT11_MODE_ALL ||
+		     ucDot11Mode == WNI_CFG_DOT11_MODE_11AC ||
+		     ucDot11Mode == WNI_CFG_DOT11_MODE_11AC_ONLY))
+			ucDot11Mode = WNI_CFG_DOT11_MODE_11N;
+
+		csr_join_req->supported_nss_1x1 = pSession->supported_nss_1x1;
+		csr_join_req->vdev_nss = pSession->vdev_nss;
+		csr_join_req->nss = pSession->nss;
+		csr_join_req->nss_forced_1x1 = pSession->nss_forced_1x1;
 		csr_join_req->dot11mode = (uint8_t) ucDot11Mode;
-		sme_debug("dot11mode=%d, uCfgDot11Mode=%d",
-			csr_join_req->dot11mode,
-			pSession->bssParams.uCfgDot11Mode);
+		sme_debug("dot11mode=%d, uCfgDot11Mode=%d nss=%d",
+			  csr_join_req->dot11mode,
+			  pSession->bssParams.uCfgDot11Mode,
+			  csr_join_req->nss);
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 		csr_join_req->cc_switch_mode =
 			pMac->roam.configParam.cc_switch_mode;