Browse Source

qcacld-3.0: Take care of hw mode change in Connection mgr

Set hw mode before initiating connection request
and send vdev start to FW.

Change-Id: I76e17465b3e40762df62d6c08deb9066ff98a6a7
CRs-Fixed: 2763362
gaurank kathpalia 4 years ago
parent
commit
249f7a6467

+ 17 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -990,6 +990,23 @@ policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
 				      enum policy_mgr_conn_update_reason,
 				      uint32_t request_id);
 
+/**
+ * policy_mgr_change_hw_mode_sta_connect() - Change HW mode for STA connect
+ * @psoc: psoc object
+ * @scan_list: candidates for conenction
+ * @vdev_id: vdev id for STA/CLI
+ * @connect_id: connect id of the conenct request
+ *
+ * When a new connection is about to come up, change hw mode for STA/CLI
+ * based upon the scan results and hw type.
+ *
+ * Return: status ifset HW mode is fail or already taken care of.
+ */
+QDF_STATUS
+policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
+				      qdf_list_t *scan_list, uint8_t vdev_id,
+				      uint32_t connect_id);
+
 /**
  * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
  * concurreny

+ 2 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h

@@ -905,6 +905,7 @@ enum policy_mgr_band {
  *        to the other DBS mode. This reason code indicates such condition.
  * @POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY: NAN Discovery related
  * @POLICY_MGR_UPDATE_REASON_NDP_UPDATE: NAN Datapath related update
+ * @POLICY_MGR_UPDATE_REASON_STA_CONNECT: STA/CLI connection to peer
  */
 enum policy_mgr_conn_update_reason {
 	POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN,
@@ -922,6 +923,7 @@ enum policy_mgr_conn_update_reason {
 	POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY,
 	POLICY_MGR_UPDATE_REASON_NDP_UPDATE,
 	POLICY_MGR_UPDATE_REASON_LFR2_ROAM,
+	POLICY_MGR_UPDATE_REASON_STA_CONNECT,
 };
 
 /**

+ 110 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -907,6 +907,116 @@ policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+static bool
+policy_mgr_is_hw_mode_change_required(struct wlan_objmgr_psoc *psoc,
+				      uint32_t ch_freq, uint8_t vdev_id)
+{
+	if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G)) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
+			return true;
+	} else {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
+		    policy_mgr_is_any_mode_active_on_band_along_with_session
+			(psoc, vdev_id, POLICY_MGR_BAND_5))
+			return true;
+
+		if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
+		    policy_mgr_is_any_mode_active_on_band_along_with_session
+			(psoc, vdev_id, POLICY_MGR_BAND_24))
+			return true;
+	}
+
+	return false;
+}
+
+static uint32_t
+policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
+				    qdf_list_t *scan_list, uint8_t vdev_id)
+{
+
+	struct scan_cache_node *scan_node = NULL;
+	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
+	uint32_t ch_freq = 0;
+	struct scan_cache_entry *entry;
+
+	if (!scan_list || !qdf_list_size(scan_list)) {
+		policy_mgr_debug("Scan list is NULL or No BSSIDs present");
+		goto end;
+	}
+
+	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_debug("Driver isn't DBS capable");
+		goto end;
+	}
+
+	if (!policy_mgr_is_dbs_allowed_for_concurrency(psoc, QDF_STA_MODE)) {
+		policy_mgr_debug("DBS not allowed for concurrency combo");
+		goto end;
+	}
+
+	if (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
+	    !policy_mgr_is_hw_dbs_required_for_band(psoc,
+						    HW_MODE_MAC_BAND_2G) &&
+	    !policy_mgr_get_connection_count(psoc)) {
+		policy_mgr_debug("1x1 DBS with no existing connection, HW mode change not required");
+		goto end;
+	}
+
+	qdf_list_peek_front(scan_list, &cur_node);
+
+	while (cur_node) {
+		qdf_list_peek_next(scan_list, cur_node, &next_node);
+
+		scan_node = qdf_container_of(cur_node, struct scan_cache_node,
+					     node);
+		entry = scan_node->entry;
+		ch_freq = entry->channel.chan_freq;
+
+		if (policy_mgr_is_hw_mode_change_required(psoc, ch_freq,
+							  vdev_id)) {
+			policy_mgr_debug("Scan list has BSS of freq %d hw mode required",
+					 ch_freq);
+			break;
+		}
+
+		cur_node = next_node;
+		next_node = NULL;
+	}
+
+end:
+	return ch_freq;
+}
+
+QDF_STATUS
+policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
+				      qdf_list_t *scan_list, uint8_t vdev_id,
+				      uint32_t connect_id)
+{
+	QDF_STATUS status;
+	uint32_t ch_freq;
+
+	ch_freq = policy_mgr_check_for_hw_mode_change(psoc, scan_list, vdev_id);
+
+	if (!ch_freq)
+		return QDF_STATUS_E_ALREADY;
+
+	status = policy_mgr_current_connections_update(psoc, vdev_id, ch_freq,
+			POLICY_MGR_UPDATE_REASON_STA_CONNECT, connect_id);
+
+	/*
+	 * If status is success then the callback of policy mgr hw mode change
+	 * would be called.
+	 * If status is no support then the DUT is already in required HW mode.
+	 */
+
+	if (status == QDF_STATUS_E_FAILURE)
+		policy_mgr_err("Hw mode change failed");
+	else if (status == QDF_STATUS_E_NOSUPPORT)
+		status = QDF_STATUS_E_ALREADY;
+
+	return status;
+}
+
 QDF_STATUS
 policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
 				      uint32_t session_id, uint32_t ch_freq,

+ 15 - 0
core/sme/src/common/sme_api.c

@@ -67,6 +67,7 @@
 #include "mac_init_api.h"
 #include "wlan_cm_roam_api.h"
 #include "wlan_cm_tgt_if_tx_api.h"
+#include "wlan_cm_api.h"
 
 static QDF_STATUS init_sme_cmd_list(struct mac_context *mac);
 
@@ -161,6 +162,7 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t
 	enum policy_mgr_conn_update_reason reason;
 	struct csr_roam_session *session;
 	uint32_t session_id;
+	uint32_t request_id;
 
 	param = (struct sir_set_hw_mode_resp *)msg;
 	if (!param) {
@@ -190,6 +192,7 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t
 	callback = command->u.set_hw_mode_cmd.set_hw_mode_cb;
 	reason = command->u.set_hw_mode_cmd.reason;
 	session_id = command->u.set_hw_mode_cmd.session_id;
+	request_id = command->u.set_hw_mode_cmd.request_id;
 
 	sme_debug("reason: %d session: %d",
 		command->u.set_hw_mode_cmd.reason,
@@ -257,6 +260,18 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t
 	if (reason == POLICY_MGR_UPDATE_REASON_LFR2_ROAM)
 		csr_continue_lfr2_connect(mac, session_id);
 
+	if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT) {
+		QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+		sme_info("Continue connect on vdev %d", session_id);
+		if (param->status == SET_HW_MODE_STATUS_OK ||
+		    param->status == SET_HW_MODE_STATUS_ALREADY)
+			status = QDF_STATUS_SUCCESS;
+
+		wlan_cm_hw_mode_change_resp(mac->pdev, session_id, request_id,
+					    status);
+	}
+
 end:
 	found = csr_nonscan_active_ll_remove_entry(mac, entry,
 			LL_ACCESS_LOCK);