Bläddra i källkod

qcacld-3.0: Enhance TDLS antenna switch operation

qcacld-2.0 to qcacld-3.0 propagation

Remove TDLS teardown wait event for antenna switch 1x1 -> 2x2 and
avoid band specific validation.

Change-Id: If29c102e59ba0f9df528e988e9d5e517a9849c55
CRs-Fixed: 961949
Archana Ramachandran 9 år sedan
förälder
incheckning
2ad7de2b2d
3 ändrade filer med 71 tillägg och 23 borttagningar
  1. 16 2
      core/hdd/inc/wlan_hdd_tdls.h
  2. 2 1
      core/hdd/src/wlan_hdd_ioctl.c
  3. 53 20
      core/hdd/src/wlan_hdd_tdls.c

+ 16 - 2
core/hdd/inc/wlan_hdd_tdls.h

@@ -134,6 +134,16 @@ typedef enum {
 	eTDLS_SUPPORT_EXTERNAL_CONTROL,
 } eTDLSSupportMode;
 
+/**
+ * enum tdls_spatial_streams - TDLS spatial streams
+ * @TDLS_NSS_1x1_MODE: TDLS tx/rx spatial streams = 1
+ * @TDLS_NSS_2x2_MODE: TDLS tx/rx spatial streams = 2
+ */
+enum tdls_spatial_streams {
+	TDLS_NSS_1x1_MODE = 0,
+	TDLS_NSS_2x2_MODE = 0xff,
+};
+
 /**
  * enum tTDLSCapType - tdls capability type
  *
@@ -369,6 +379,7 @@ typedef struct {
  * @op_class_for_pref_off_chan_is_set: op class for preferred off channel set
  * @peer_idle_timer: time to check idle traffic in tdls peers
  * @is_peer_idle_timer_initialised: Flag to check idle timer init
+ * @spatial_streams: Number of TX/RX spatial streams for TDLS
  * @reason: reason
  * @state_change_notification: state change notification
  */
@@ -400,6 +411,7 @@ typedef struct _hddTdlsPeer_t {
 	uint8_t op_class_for_pref_off_chan_is_set;
 	qdf_mc_timer_t peer_idle_timer;
 	bool is_peer_idle_timer_initialised;
+	uint8_t spatial_streams;
 	tTDLSLinkReason reason;
 	cfg80211_exttdls_callback state_change_notification;
 } hddTdlsPeer_t;
@@ -670,7 +682,8 @@ int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val);
 void hdd_tdls_context_init(hdd_context_t *hdd_ctx);
 void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx);
 int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx,
-				 hdd_adapter_t *adapter);
+				 hdd_adapter_t *adapter,
+				 uint32_t mode);
 
 #else
 static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter,
@@ -696,7 +709,8 @@ static inline void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { }
 static inline void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) { }
 
 static inline int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx,
-					       hdd_adapter_t *adapter)
+					       hdd_adapter_t *adapter,
+					       uint32_t mode)
 {
 	return 0;
 }

+ 2 - 1
core/hdd/src/wlan_hdd_ioctl.c

@@ -6615,7 +6615,8 @@ static int drv_cmd_set_antenna_mode(hdd_adapter_t *adapter,
 	if ((QDF_STA_MODE == adapter->device_mode) &&
 	    cds_is_sta_active_connection_exists() &&
 	    (hdd_ctx->connected_peer_count > 0)) {
-		ret = wlan_hdd_tdls_antenna_switch(hdd_ctx, adapter);
+		ret = wlan_hdd_tdls_antenna_switch(hdd_ctx, adapter,
+						   mode);
 		if (0 != ret)
 			goto exit;
 	}

+ 53 - 20
core/hdd/src/wlan_hdd_tdls.c

@@ -32,6 +32,7 @@
  */
 
 #include <wlan_hdd_includes.h>
+#include <ani_global.h>
 #include <wlan_hdd_hostapd.h>
 #include <wlan_hdd_trace.h>
 #include <net/cfg80211.h>
@@ -3774,6 +3775,16 @@ int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
 
 	INIT_COMPLETION(pAdapter->tdls_add_station_comp);
 
+	/* Update the number of stream for each peer */
+	if ((NULL != StaParams) && (StaParams->htcap_present)) {
+		hddTdlsPeer_t *tdls_peer;
+
+		tdls_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, true);
+		if (NULL != tdls_peer)
+			tdls_peer->spatial_streams =
+			StaParams->HTCap.suppMcsSet[1];
+	}
+
 	if (!update) {
 		status = sme_add_tdls_peer_sta(WLAN_HDD_GET_HAL_CTX(pAdapter),
 					       pAdapter->sessionId, mac);
@@ -5764,22 +5775,24 @@ int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val)
  *
  * Return: 0 if success else non zero
  */
-static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx)
+static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx,
+					uint32_t mode)
 {
 	uint16_t connected_tdls_peers = 0;
 	uint8_t staidx;
 	hddTdlsPeer_t *curr_peer;
 	hdd_adapter_t *adapter;
+	int ret = 0;
 
 	if (eTDLS_SUPPORT_NOT_ENABLED == hddctx->tdls_mode) {
-		hdd_log(LOG1, "TDLS mode is disabled OR not enabled in FW");
+		hdd_info("TDLS mode is disabled OR not enabled in FW");
 		return 0;
 	}
 
 	adapter = hdd_get_adapter(hddctx, QDF_STA_MODE);
 
 	if (adapter == NULL) {
-		hdd_log(LOGE, "Station Adapter Not Found");
+		hdd_info("Station Adapter Not Found");
 		return 0;
 	}
 
@@ -5794,13 +5807,17 @@ static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx)
 			continue;
 
 		curr_peer = wlan_hdd_tdls_find_all_peer(hddctx,
-				hddctx->tdlsConnInfo[staidx].peerMac.bytes);
+			hddctx->tdlsConnInfo[staidx].peerMac.bytes);
 
 		if (!curr_peer)
 			continue;
 
-		hdd_log(LOG1, "indicate TDLS teardown (staId %d)",
-			curr_peer->staId);
+		/* Check if connected peer supports more than one stream */
+		if (curr_peer->spatial_streams == TDLS_NSS_1x1_MODE)
+			continue;
+
+		hdd_info("Indicate TDLS teardown (staId %d)",
+			 curr_peer->staId);
 
 		wlan_hdd_tdls_indicate_teardown(
 					curr_peer->pHddTdlsCtx->pAdapter,
@@ -5811,13 +5828,20 @@ static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx)
 		mutex_unlock(&hddctx->tdls_lock);
 	}
 	mutex_lock(&hddctx->tdls_lock);
-	if (hddctx->tdls_teardown_peers_cnt >= 1)
+	if (hddctx->tdls_teardown_peers_cnt >= 1) {
 		hddctx->tdls_nss_switch_in_progress = true;
-	hdd_log(LOGE, "TDLS peers to be torn down = %d",
-		hddctx->tdls_teardown_peers_cnt);
+		hdd_info("TDLS peers to be torn down = %d",
+			 hddctx->tdls_teardown_peers_cnt);
+		/*  Antenna switch 2x2 to 1x1 */
+		if (mode == HDD_ANTENNA_MODE_1X1)
+			ret = -EAGAIN;
+		else
+		/*  Antenna switch 1x1 to 2x2 */
+			ret = 0;
+		hdd_info("TDLS teardown for antenna switch operation starts");
+	}
 	mutex_unlock(&hddctx->tdls_lock);
-	hdd_log(LOGE, "TDLS teardown for antenna switch operation starts");
-	return -EAGAIN;
+	return ret;
 }
 
 /**
@@ -5829,15 +5853,16 @@ static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx)
  * Return: 0 if success else non zero
  */
 int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx,
-				 hdd_adapter_t *adapter)
+					hdd_adapter_t *adapter, uint32_t mode)
 {
 	uint8_t tdls_peer_cnt;
+	uint32_t vdev_nss;
 	hdd_station_ctx_t *sta_ctx =
 		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 
 	/* Check whether TDLS antenna switch is in progress */
 	if (hdd_ctx->tdls_nss_switch_in_progress) {
-		hdd_log(LOGE, "TDLS antenna switch is in progress");
+		hdd_err("TDLS antenna switch is in progress");
 		return -EAGAIN;
 	}
 
@@ -5845,19 +5870,27 @@ int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx,
 	mutex_lock(&hdd_ctx->tdls_lock);
 	tdls_peer_cnt = hdd_ctx->connected_peer_count;
 	mutex_unlock(&hdd_ctx->tdls_lock);
-	if (tdls_peer_cnt <= 0)
+	if (tdls_peer_cnt <= 0) {
+		hdd_info("No TDLS connection established");
 		goto tdls_ant_sw_done;
+	}
 
-	/* Check the current operating band */
-	if (!IS_5G_CH(sta_ctx->conn_info.operationChannel)) {
-		hdd_log(LOGE, "TDLS is in 2.4G, Ant switch not needed");
-		return 0;
+	/* Check the supported nss for TDLS */
+	if (IS_5G_CH(sta_ctx->conn_info.operationChannel))
+		vdev_nss = CFG_TDLS_NSS(
+			hdd_ctx->config->vdev_type_nss_5g);
+	else
+		vdev_nss = CFG_TDLS_NSS(
+			hdd_ctx->config->vdev_type_nss_2g);
+
+	if (vdev_nss == HDD_ANTENNA_MODE_1X1) {
+		hdd_info("Supported NSS is 1X1, no need to teardown TDLS links");
+		goto tdls_ant_sw_done;
 	}
 
 	/* teardown all the tdls connections */
-	return wlan_hdd_tdls_teardown_links(hdd_ctx);
+	return wlan_hdd_tdls_teardown_links(hdd_ctx, mode);
 
 tdls_ant_sw_done:
-	hdd_log(LOGE, "No TDLS connection established");
 	return 0;
 }