Browse Source

qcacld-3.0: Get proper channel after scan for SSID

If there is no scan cache available, csr_roam_connect
will trigger a scan and after scan complete csr will
call csr_roam_issue_connect to connect one of candidate BSS.
And driver only checks the first candidate BSS's channel
for HW mode change after scan complete.
The issue is if connect first candidate failed, the next
or other candidate BSS may require DBS in concurrency
condition and the check
policy_mgr_is_hwmode_set_for_given_chnl will be failed.
To avoid such the hw mode check failed, we need to change hw
mode early if any of BSS requires DBS mode before try to
connect the BSS candidate in list one by one.

Add API csr_scan_get_channel_for_hw_mode_change which returns
DBS required candidate channel in BSS list if available,
otherwise returns the first candidate's channel.

Change-Id: I42862f100ee56ada41d6397346937219d0e688df
CRs-Fixed: 2335075
Liangwei Dong 6 years ago
parent
commit
1ba994826c

+ 2 - 1
core/sme/inc/sme_api.h

@@ -1343,7 +1343,8 @@ void sme_register_hw_mode_trans_cb(tHalHandle hal,
 QDF_STATUS sme_nss_update_request(uint32_t vdev_id,
 				uint8_t  new_nss, policy_mgr_nss_update_cback cback,
 				uint8_t next_action, struct wlan_objmgr_psoc *psoc,
-				enum policy_mgr_conn_update_reason reason);
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t original_vdev_id);
 
 typedef void (*sme_peer_authorized_fp) (uint32_t vdev_id);
 QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,

+ 2 - 0
core/sme/inc/sme_inside.h

@@ -136,6 +136,7 @@ typedef struct s_tdls_cmd {
  * @context: Adapter context
  * @next_action: Action to be taken after nss update
  * @reason: reason for nss update
+ * @original_vdev_id: original request hwmode change vdev id
  */
 struct s_nss_update_cmd {
 	uint32_t new_nss;
@@ -144,6 +145,7 @@ struct s_nss_update_cmd {
 	void *context;
 	uint8_t next_action;
 	enum policy_mgr_conn_update_reason reason;
+	uint32_t original_vdev_id;
 };
 
 typedef struct tagSmeCmd {

+ 8 - 3
core/sme/src/common/sme_api.c

@@ -2455,7 +2455,8 @@ static QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg)
 				param->tx_status,
 				param->session_id,
 				command->u.nss_update_cmd.next_action,
-				command->u.nss_update_cmd.reason);
+				command->u.nss_update_cmd.reason,
+				command->u.nss_update_cmd.original_vdev_id);
 	} else {
 		sme_err("Callback does not exisit");
 	}
@@ -13179,6 +13180,7 @@ void sme_register_hw_mode_trans_cb(tHalHandle hal,
  * @new_nss: the new nss value
  * @cback: hdd callback
  * @next_action: next action to happen at policy mgr after beacon update
+ * @original_vdev_id: original request hwmode change vdev id
  *
  * Sends the command to CSR to send to PE
  * Return: QDF_STATUS_SUCCESS on successful posting
@@ -13186,7 +13188,8 @@ void sme_register_hw_mode_trans_cb(tHalHandle hal,
 QDF_STATUS sme_nss_update_request(uint32_t vdev_id,
 				uint8_t  new_nss, policy_mgr_nss_update_cback cback,
 				uint8_t next_action, struct wlan_objmgr_psoc *psoc,
-				enum policy_mgr_conn_update_reason reason)
+				enum policy_mgr_conn_update_reason reason,
+				uint32_t original_vdev_id)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	tpAniSirGlobal mac = sme_get_mac_context();
@@ -13213,8 +13216,10 @@ QDF_STATUS sme_nss_update_request(uint32_t vdev_id,
 		cmd->u.nss_update_cmd.context = psoc;
 		cmd->u.nss_update_cmd.next_action = next_action;
 		cmd->u.nss_update_cmd.reason = reason;
+		cmd->u.nss_update_cmd.original_vdev_id = original_vdev_id;
 
-		sme_debug("Queuing e_sme_command_nss_update to CSR");
+		sme_debug("Queuing e_sme_command_nss_update to CSR:vdev (%d %d) ss %d r %d",
+			  vdev_id, original_vdev_id, new_nss, reason);
 		csr_queue_sme_command(mac, cmd, false);
 		sme_release_global_lock(&mac->sme);
 	}

+ 41 - 2
core/sme/src/csr/csr_api_scan.c

@@ -1034,8 +1034,8 @@ static enum csr_scancomplete_nextcommand csr_scan_get_next_command_state(
 	switch (session->scan_info.scan_reason) {
 	case eCsrScanForSsid:
 		sme_debug("Resp for Scan For Ssid");
-		channel = policy_mgr_search_and_check_for_session_conc(
-				mac_ctx->psoc,
+		channel = csr_scan_get_channel_for_hw_mode_change(
+				mac_ctx,
 				session_id,
 				session->scan_info.profile);
 		if ((!channel) || scan_status) {
@@ -2175,6 +2175,45 @@ end:
 	return channel_id;
 }
 
+uint8_t
+csr_scan_get_channel_for_hw_mode_change(
+	tpAniSirGlobal mac_ctx, uint32_t session_id,
+	struct csr_roam_profile *profile)
+{
+	tScanResultHandle result_handle = NULL;
+	QDF_STATUS status;
+	uint8_t first_ap_ch = 0;
+	uint8_t candidate_chan;
+
+	status = sme_get_ap_channel_from_scan_cache(profile, &result_handle,
+						    &first_ap_ch);
+	if (status != QDF_STATUS_SUCCESS || !result_handle || !first_ap_ch) {
+		if (result_handle)
+			sme_scan_result_purge(result_handle);
+		sme_err("fail get scan result: status %d first ap ch %d",
+			status, first_ap_ch);
+		return 0;
+	}
+	if (!policy_mgr_check_for_session_conc(mac_ctx->psoc, session_id,
+					       first_ap_ch)) {
+		sme_scan_result_purge(result_handle);
+		sme_err("Conc not allowed for the session %d ch %d",
+			session_id, first_ap_ch);
+		return 0;
+	}
+
+	candidate_chan = csr_get_channel_for_hw_mode_change(mac_ctx,
+							    result_handle,
+							    session_id);
+	sme_scan_result_purge(result_handle);
+	if (!candidate_chan)
+		candidate_chan = first_ap_ch;
+	sme_debug("session %d hw mode check candidate_chan %d", session_id,
+		  candidate_chan);
+
+	return candidate_chan;
+}
+
 static enum wlan_auth_type csr_covert_auth_type_new(eCsrAuthType auth)
 {
 	switch (auth) {

+ 23 - 0
core/sme/src/csr/csr_inside_api.h

@@ -1123,4 +1123,27 @@ uint8_t
 csr_get_channel_for_hw_mode_change(tpAniSirGlobal mac_ctx,
 				   tScanResultHandle result_handle,
 				   uint32_t session_id);
+
+/**
+ * csr_scan_get_channel_for_hw_mode_change() - This function to find
+ *                                       out if HW mode change
+ *                                       is needed for any of
+ *                                       the candidate AP which
+ *                                       STA could join
+ * @mac_ctx: mac context
+ * @session_id: STA session ID
+ * @profile: profile
+ *
+ * This function is written to find out for any bss from scan
+ * handle a HW mode change to DBS will be needed or not.
+ * If there is no candidate AP which requires DBS, this function will return
+ * the first Candidate AP's chan.
+ *
+ * Return: AP channel for which HW mode change will be needed. 0
+ * means no candidate AP to connect.
+ */
+uint8_t
+csr_scan_get_channel_for_hw_mode_change(
+	tpAniSirGlobal mac_ctx, uint32_t session_id,
+	struct csr_roam_profile *profile);
 #endif /* CSR_INSIDE_API_H__ */