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

qcacld-3.0: set roam offload only after sta connected

It set roam offload flag to FW when vdev type is sta in
wma_vdev_attach, FW team think this isn't reasonable since it wastes
FW memory if sta isn't disconnected. And required to set this flag
when connected to AP, remove this flag after disconnect from AP.

Change-Id: I5edfb8d5a2cec0e2ffdf34349c99d477860f1339
CRs-Fixed: 2367135
Wu Gao 6 жил өмнө
parent
commit
8cd2948ec0

+ 2 - 2
core/wma/inc/wma.h

@@ -804,6 +804,7 @@ struct roam_synch_frame_ind {
  * @vdev_stop_wakelock: wakelock to protect vdev stop op with firmware
  * @vdev_set_key_wakelock: wakelock to protect vdev set key op with firmware
  * @channel: channel
+ * @roam_offload_enabled: is roam offload enable/disable
  * @roam_scan_stats_req: cached roam scan stats request
  *
  * It stores parameters per vdev in wma.
@@ -894,6 +895,7 @@ struct wma_txrx_node {
 	qdf_wake_lock_t vdev_set_key_wakelock;
 	struct roam_synch_frame_ind roam_synch_frame_ind;
 	bool is_waiting_for_key;
+	bool roam_offload_enabled;
 	uint8_t channel;
 	struct sir_roam_scan_stats *roam_scan_stats_req;
 };
@@ -1004,7 +1006,6 @@ struct wma_valid_channels {
  * @get_sta_peer_info: Is a "get peer info" request active?
  * @peer_macaddr: When @get_one_peer_info is true, the peer's mac address
  * @thermal_mgmt_info: Thermal mitigation related info
- * @roam_offload_enabled: is roam offload enable/disable
  * @ssdp: ssdp flag
  * @enable_mc_list: To Check if Multicast list filtering is enabled in FW
  * @ibss_started: is IBSS started or not
@@ -1141,7 +1142,6 @@ typedef struct {
 	bool get_sta_peer_info;
 	struct qdf_mac_addr peer_macaddr;
 	t_thermal_mgmt thermal_mgmt_info;
-	bool roam_offload_enabled;
 	bool ssdp;
 	bool enable_mc_list;
 	uint8_t ibss_started;

+ 1 - 9
core/wma/src/wma_dev_if.c

@@ -2977,15 +2977,6 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
 	/* Initialize roaming offload state */
 	if ((self_sta_req->type == WMI_VDEV_TYPE_STA) &&
 	    (self_sta_req->sub_type == 0)) {
-		wma_handle->roam_offload_enabled = true;
-		ret = wma_vdev_set_param(wma_handle->wmi_handle,
-					self_sta_req->session_id,
-					WMI_VDEV_PARAM_ROAM_FW_OFFLOAD,
-					(WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG |
-					WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG));
-		if (QDF_IS_STATUS_ERROR(ret))
-			WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD");
-
 		/* Pass down enable/disable bcast probe rsp to FW */
 		ret = wma_vdev_set_param(
 				wma_handle->wmi_handle,
@@ -6196,6 +6187,7 @@ static void wma_wait_tx_complete(tp_wma_handle wma,
 		max_wait_iterations--;
 	}
 }
+
 /**
  * wma_delete_bss() - process delete bss request from upper layer
  * @wma: wma handle

+ 17 - 19
core/wma/src/wma_scan_roam.c

@@ -1558,7 +1558,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	if (!wma_handle->roam_offload_enabled) {
+	if (!wma_handle->interfaces[roam_req->sessionId].roam_offload_enabled) {
 		/* roam scan offload is not enabled in firmware.
 		 * Cannot initialize it in the middle of connection.
 		 */
@@ -1750,28 +1750,26 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
 		}
 
 		wma_handle->suitable_ap_hb_failure = false;
-		if (wma_handle->roam_offload_enabled) {
-			uint32_t mode;
 
-			wma_roam_scan_fill_scan_params(wma_handle, mac,
-						       NULL, &scan_params);
+		wma_roam_scan_fill_scan_params(wma_handle, mac,
+					       NULL, &scan_params);
 
-			if (roam_req->reason == REASON_ROAM_STOP_ALL ||
-			    roam_req->reason == REASON_DISCONNECTED ||
-			    roam_req->reason == REASON_ROAM_SYNCH_FAILED) {
+		if (roam_req->reason == REASON_ROAM_STOP_ALL ||
+		    roam_req->reason == REASON_DISCONNECTED ||
+		    roam_req->reason == REASON_ROAM_SYNCH_FAILED) {
+			mode = WMI_ROAM_SCAN_MODE_NONE;
+		} else {
+			if (csr_is_roam_offload_enabled(mac))
+				mode = WMI_ROAM_SCAN_MODE_NONE |
+				WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
+			else
 				mode = WMI_ROAM_SCAN_MODE_NONE;
-			} else {
-				if (csr_is_roam_offload_enabled(mac))
-					mode = WMI_ROAM_SCAN_MODE_NONE |
-						WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
-				else
-					mode = WMI_ROAM_SCAN_MODE_NONE;
-			}
-
-			qdf_status = wma_roam_scan_offload_mode(wma_handle,
-						&scan_params, NULL, mode,
-						roam_req->sessionId);
 		}
+
+		qdf_status = wma_roam_scan_offload_mode(
+					wma_handle,
+					&scan_params, NULL, mode,
+					roam_req->sessionId);
 		/*
 		 * After sending the roam scan mode because of a disconnect,
 		 * clear the scan bitmap client as well by sending

+ 104 - 2
core/wma/src/wma_utils.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -4383,6 +4383,106 @@ int wma_rcpi_event_handler(void *handle, uint8_t *cmd_param_info,
 	return 0;
 }
 
+/**
+ * wma_set_roam_offload_flag() -  Set roam offload flag to fw
+ * @wma:     wma handle
+ * @vdev_id: vdev id
+ * @is_set:  set or clear
+ *
+ * Return: none
+ */
+static void wma_set_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id,
+				      bool is_set)
+{
+	QDF_STATUS status;
+	uint32_t flag = 0;
+
+	if (is_set)
+		flag = WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG |
+		       WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG;
+
+	WMA_LOGD("%s: vdev_id:%d, is_set:%d, flag:%d, roam_offload_enabled:%d",
+		 __func__, vdev_id, is_set, flag,
+		  wma->interfaces[vdev_id].roam_offload_enabled);
+
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+				    WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, flag);
+	if (QDF_IS_STATUS_ERROR(status))
+		WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD");
+	else
+		wma->interfaces[vdev_id].roam_offload_enabled = is_set;
+}
+
+/**
+ * wma_update_roam_offload_flag() -  update roam offload flag to fw
+ * @wma:     wma handle
+ * @vdev_id: vdev id
+ * @is_connected: connected or disconnected
+ *
+ * Return: none
+ */
+static void wma_update_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id,
+					 bool is_connected)
+{
+	struct wma_txrx_node *iface;
+	uint8_t id;
+	uint8_t roam_offload_vdev_id = WMA_INVALID_VDEV_ID;
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t count;
+
+	WMA_LOGD("%s: vdev_id:%d, is_connected:%d", __func__,
+		 vdev_id, is_connected);
+
+	iface = &wma->interfaces[vdev_id];
+
+	if ((iface->type != WMI_VDEV_TYPE_STA) ||
+	    (iface->sub_type != 0)) {
+		WMA_LOGE("%s: this isn't a STA: %d",
+			 __func__, vdev_id);
+		return;
+	}
+
+	if (iface->roaming_in_progress || iface->roam_synch_in_progress) {
+		WMA_LOGE("%s: roaming in progress: %d",
+			 __func__, vdev_id);
+		return;
+	}
+
+	for (id = 0; id < wma->max_bssid; id++) {
+		if (wma->interfaces[id].roam_offload_enabled)
+			roam_offload_vdev_id = id;
+	}
+
+	/*
+	 * If sta connected, and no connected sta interface exist, then set
+	 * set roam offload flag to this sta interface
+	 */
+	if (is_connected && (roam_offload_vdev_id == WMA_INVALID_VDEV_ID))
+		wma_set_roam_offload_flag(wma, vdev_id, true);
+
+	if (!is_connected && roam_offload_vdev_id == vdev_id) {
+		/* If sta disconnected and roam offload enaled on this
+		 * interface, then clear roam offload flag
+		 */
+		wma_set_roam_offload_flag(wma, vdev_id, false);
+
+		count = policy_mgr_mode_specific_connection_count(
+				wma->psoc, PM_STA_MODE, list);
+		WMA_LOGD("%s: valid sta count:%d", __func__, count);
+		/*
+		 * If there is multi sta connection before this disconnection,
+		 * then set roam offload flag to other connected sta inferface.
+		 */
+		if (count > 1) {
+			for (id = 0; id < count; id++) {
+				if (list[id] != vdev_id)
+					wma_set_roam_offload_flag(wma, list[id],
+								  true);
+			}
+		}
+	}
+}
+
 #ifdef CONFIG_VDEV_SM
 QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma,
 				  struct vdev_up_params *params,
@@ -4395,6 +4495,7 @@ QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma,
 		WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id);
 		return QDF_STATUS_E_FAILURE;
 	}
+	wma_update_roam_offload_flag(wma, params->vdev_id, true);
 	vdev = &wma->interfaces[params->vdev_id];
 
 	status = wmi_unified_vdev_up_send(wma->wmi_handle, bssid, params);
@@ -4420,7 +4521,7 @@ QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma,
 			 params->vdev_id, bssid);
 		return QDF_STATUS_SUCCESS;
 	}
-
+	wma_update_roam_offload_flag(wma, params->vdev_id, true);
 	vdev = &wma->interfaces[params->vdev_id];
 
 	status = wmi_unified_vdev_up_send(wma->wmi_handle, bssid, params);
@@ -4440,6 +4541,7 @@ QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id)
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	wma_update_roam_offload_flag(wma, vdev_id, false);
 	vdev = &wma->interfaces[vdev_id];
 	wma->interfaces[vdev_id].roaming_in_progress = false;
 	status = wmi_unified_vdev_down_send(wma->wmi_handle, vdev_id);