Przeglądaj źródła

qcacld-3.0: Add support to get the status for Roam Scan Offload command

Add support to handle the event for the Roam Scan Offload[RSO] command
status. Inform the same to user space.

Change-Id: I2758103e8ca3c49c0fecd3323b619542dbbabf0c
CRs-Fixed: 1111809
Sreelakshmi Konamki 8 lat temu
rodzic
commit
88a2a41bbf

+ 4 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -167,6 +167,9 @@
 
 #define WLAN_WAIT_TIME_BPF     1000
 
+/* Maximum time(ms) to wait for RSO CMD status event */
+#define WAIT_TIME_RSO_CMD_STATUS 2000
+
 #define MAX_NUMBER_OF_ADAPTERS 4
 
 #define MAX_CFG_STRING_LEN  255
@@ -1143,6 +1146,7 @@ struct hdd_adapter_s {
 	 * disconnect is being deferred.
 	 */
 	uint8_t cfg80211_disconnect_reason;
+	struct lfr_firmware_status lfr_fw_status;
 };
 
 /*

+ 39 - 3
core/hdd/src/wlan_hdd_cfg80211.c

@@ -9177,6 +9177,21 @@ nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
 						 .len = QDF_MAC_ADDR_SIZE},
 };
 
+void wlan_hdd_rso_cmd_status_cb(void *ctx, struct rso_cmd_status *rso_status)
+{
+	hdd_context_t *hdd_ctx = (hdd_context_t *)ctx;
+	hdd_adapter_t *adapter;
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, rso_status->vdev_id);
+	if (!adapter) {
+		hdd_err("adapter NULL");
+		return;
+	}
+
+	adapter->lfr_fw_status.is_disabled = rso_status->status;
+	complete(&adapter->lfr_fw_status.disable_lfr_event);
+}
+
 /**
  * __wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
  * @wiphy: Pointer to wireless phy
@@ -9196,9 +9211,10 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
 	struct net_device *dev = wdev->netdev;
 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
-	uint32_t is_fast_roam_enabled;
+	uint32_t is_fast_roam_enabled, enable_lfr_fw;
 	int ret;
 	QDF_STATUS qdf_status;
+	unsigned long rc;
 
 	ENTER_DEV(dev);
 
@@ -9235,14 +9251,34 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
 		return -EINVAL;
 	}
 	/* Update roaming */
+	enable_lfr_fw = (is_fast_roam_enabled && adapter->fast_roaming_allowed);
 	qdf_status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->sessionId,
-				      (is_fast_roam_enabled &&
-				       adapter->fast_roaming_allowed));
+					     enable_lfr_fw);
 	if (qdf_status != QDF_STATUS_SUCCESS)
 		hdd_err("sme_config_fast_roaming failed with status=%d",
 				qdf_status);
 	ret = qdf_status_to_os_return(qdf_status);
 
+	INIT_COMPLETION(adapter->lfr_fw_status.disable_lfr_event);
+	if (QDF_IS_STATUS_SUCCESS(qdf_status) && !enable_lfr_fw) {
+		/*
+		 * wait only for LFR disable in fw as LFR enable
+		 * is always success
+		 */
+		rc = wait_for_completion_timeout(
+				&adapter->lfr_fw_status.disable_lfr_event,
+				msecs_to_jiffies(WAIT_TIME_RSO_CMD_STATUS));
+		if (!rc) {
+			hdd_err("Timed out waiting for RSO CMD status");
+			return -ETIMEDOUT;
+		}
+
+		if (!adapter->lfr_fw_status.is_disabled) {
+			hdd_err("Roam disable attempt in FW fails");
+			return -EBUSY;
+		}
+	}
+
 	EXIT();
 	return ret;
 }

+ 12 - 0
core/hdd/src/wlan_hdd_cfg80211.h

@@ -297,6 +297,18 @@ void wlan_hdd_cfg80211_extscan_callback(void *ctx,
 					const uint16_t evType, void *pMsg);
 #endif /* FEATURE_WLAN_EXTSCAN */
 
+/**
+ * wlan_hdd_rso_cmd_status_cb() - HDD callback to read RSO command status
+ * @ctx: void pointer to hdd context
+ * @rso_status: rso command status
+ *
+ * This callback function is invoked by firmware to update
+ * the RSO(ROAM SCAN OFFLOAD) command status.
+ *
+ * Return: None
+ */
+void wlan_hdd_rso_cmd_status_cb(void *ctx, struct rso_cmd_status *rso_status);
+
 void hdd_rssi_threshold_breached(void *hddctx,
 				 struct rssi_breach_event *data);
 

+ 3 - 0
core/hdd/src/wlan_hdd_main.c

@@ -2816,6 +2816,7 @@ static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx,
 
 
 		init_completion(&adapter->scan_info.abortscan_event_var);
+		init_completion(&adapter->lfr_fw_status.disable_lfr_event);
 
 		adapter->offloads_configured = false;
 		adapter->isLinkUpSvcNeeded = false;
@@ -9350,6 +9351,8 @@ int hdd_register_cb(hdd_context_t *hdd_ctx)
 	sme_set_link_layer_stats_ind_cb(hdd_ctx->hHal,
 				wlan_hdd_cfg80211_link_layer_stats_callback);
 
+	sme_rso_cmd_status_cb(hdd_ctx->hHal, wlan_hdd_rso_cmd_status_cb);
+
 	status = sme_set_lost_link_info_cb(hdd_ctx->hHal,
 					   hdd_lost_link_info_cb);
 	/* print error and not block the startup process */

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

@@ -4617,6 +4617,26 @@ struct power_stats_response {
 };
 #endif
 
+/**
+ * struct lfr_firmware_status - LFR status in firmware
+ * @is_disabled: Is LFR disabled in FW
+ * @disable_lfr_event: Disable attempt done in FW
+ */
+struct lfr_firmware_status {
+	uint32_t is_disabled;
+	struct completion disable_lfr_event;
+};
+
+/**
+ * struct rso_cmd_status - RSO Command status
+ * @vdev_id: Vdev ID for which RSO command sent
+ * @status: Status of RSO command sent to FW
+ */
+struct rso_cmd_status {
+	uint32_t vdev_id;
+	bool status;
+};
+
 typedef struct {
 	uint8_t oui[WIFI_SCANNING_MAC_OUI_LENGTH];
 } tSirScanMacOui, *tpSirScanMacOui;

+ 1 - 0
core/mac/inc/wni_api.h

@@ -256,6 +256,7 @@ enum eWniMsgTypes {
 	eWNI_SME_ROAM_SCAN_OFFLOAD_REQ,
 	eWNI_SME_LOST_LINK_INFO_IND,
 	eWNI_SME_DEL_ALL_TDLS_PEERS,
+	eWNI_SME_RSO_CMD_STATUS_IND,
 	eWNI_SME_MSG_TYPES_END
 };
 

+ 1 - 0
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -415,6 +415,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
 		CASE_RETURN_STRING(eWNI_SME_DEFAULT_SCAN_IE);
 		CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_REQ);
 		CASE_RETURN_STRING(eWNI_SME_LOST_LINK_INFO_IND);
+		CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND);
 		CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
 	default:
 		return (uint8_t *) "UNKNOWN";

+ 12 - 0
core/sme/inc/sme_api.h

@@ -1437,6 +1437,18 @@ QDF_STATUS sme_get_beacon_frm(tHalHandle hal, tCsrRoamProfile *profile,
 
 QDF_STATUS sme_delete_all_tdls_peers(tHalHandle hal, uint8_t session_id);
 
+/**
+ * sme_rso_cmd_status_cb() - Set RSO cmd status callback
+ * @hal: HAL Handle
+ * @cb: HDD Callback to rso comman status read
+ *
+ * This function is used to save HDD RSO Command status callback in MAC
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_rso_cmd_status_cb(tHalHandle hal,
+		void (*cb)(void *, struct rso_cmd_status *));
+
 /**
  * sme_register_set_connection_info_cb() - Register connection
  * info callback

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

@@ -244,6 +244,8 @@ typedef struct tagSmeStruct {
 	bool (*set_connection_info_cb)(bool);
 	bool (*get_connection_info_cb)(uint8_t *session_id,
 			enum scan_reject_states *reason);
+	void (*rso_cmd_status_cb)(void *hdd_context,
+			struct rso_cmd_status *rso_status);
 } tSmeStruct, *tpSmeStruct;
 
 #endif /* #if !defined( __SMEINTERNAL_H ) */

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

@@ -2630,6 +2630,11 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, struct scheduler_msg *pMsg)
 				(struct sir_lost_link_info *)pMsg->bodyptr);
 		qdf_mem_free(pMsg->bodyptr);
 		break;
+	case eWNI_SME_RSO_CMD_STATUS_IND:
+		if (pMac->sme.rso_cmd_status_cb)
+			pMac->sme.rso_cmd_status_cb(pMac->hHdd, pMsg->bodyptr);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
 	default:
 
 		if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
@@ -16093,3 +16098,14 @@ QDF_STATUS sme_register_set_connection_info_cb(tHalHandle hHal,
 	}
 	return status;
 }
+
+QDF_STATUS sme_rso_cmd_status_cb(tHalHandle hal,
+		void (*cb)(void *, struct rso_cmd_status *))
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	mac->sme.rso_cmd_status_cb = cb;
+	sms_log(mac, LOG1, FL("Registered RSO command status callback"));
+	return status;
+}

+ 10 - 0
core/wma/inc/wma_internal.h

@@ -840,6 +840,16 @@ void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus,
 int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info,
 				  uint32_t len);
 
+/**
+ * wma_rso_cmd_status_event_handler() - RSO Command status event handler
+ * @wmi_event: WMI event
+ *
+ * This function is used to send RSO command status to upper layer
+ *
+ * Return: 0 for success
+ */
+int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event);
+
 int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
 			    uint32_t len);
 

+ 3 - 0
core/wma/src/wma_scan_roam.c

@@ -5432,6 +5432,9 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
 				roam_synch_data, NULL, op_code);
 		qdf_mem_free(roam_synch_data);
 		break;
+	case WMI_ROAM_REASON_RSO_STATUS:
+		wma_rso_cmd_status_event_handler(wmi_event);
+		break;
 	default:
 		WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__,
 			 wmi_event->reason, wmi_event->vdev_id);

+ 30 - 0
core/wma/src/wma_utils.c

@@ -1750,6 +1750,36 @@ int wma_link_status_event_handler(void *handle, uint8_t *cmd_param_info,
 	return 0;
 }
 
+int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event)
+{
+	struct rso_cmd_status *rso_status;
+	struct scheduler_msg sme_msg;
+	QDF_STATUS qdf_status;
+
+	rso_status = qdf_mem_malloc(sizeof(*rso_status));
+	if (!rso_status) {
+		WMA_LOGE("%s: malloc fails for rso cmd status", __func__);
+		return -ENOMEM;
+	}
+
+	rso_status->vdev_id = wmi_event->vdev_id;
+	if (WMI_ROAM_NOTIF_SCAN_MODE_SUCCESS == wmi_event->notif)
+		rso_status->status = true;
+	else if (WMI_ROAM_NOTIF_SCAN_MODE_FAIL == wmi_event->notif)
+		rso_status->status = false;
+	sme_msg.type = eWNI_SME_RSO_CMD_STATUS_IND;
+	sme_msg.bodyptr = rso_status;
+	sme_msg.bodyval = 0;
+	WMA_LOGI("%s: Post RSO cmd status to SME",  __func__);
+
+	qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		WMA_LOGE("%s: fail to post RSO cmd status to SME", __func__);
+		qdf_mem_free(rso_status);
+	}
+	return 0;
+}
+
 /**
  * wma_stats_event_handler() - stats event handler
  * @handle: wma handle