Sfoglia il codice sorgente

qcacld-3.0: Connection manager add ucfg API for sme roam operations

Add changes to handle north bound roaming operations/
configurations in connection manager. Add equivalent connection
manager api for userspace triggered roaming operations & driver
internally triggered roaming offload operations:
sme_enable_roaming() - ucfg_cm_rso_init_deinit : Driver
internally triggered
sme_config_fast_roaming() - ucfg_user_space_enable_disable_rso:
Userspace triggered
sme_start_roaming() - ucfg_cm_enable_rso() - Driver internally
triggered
sme_stop_roaming() - ucfg_cm_disable_rso() - Driver internally
triggered
sme_abort_roam_scan() - ucfg_user_space_abort_roam_scan() -User
space triggered

Change-Id: I65130f69f2afff61b9ef7334ec365d3ce7519930
CRs-Fixed: 2741055
Pragaspathi Thilagaraj 4 anni fa
parent
commit
5fb48b5750

+ 23 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -134,6 +134,29 @@ wlan_cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_E_NOSUPPORT;
 }
 #endif
+
+/**
+ * cm_roam_acquire_lock  - Wrapper for sme_acquire_global_lock.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cm_roam_acquire_lock(void);
+
+/**
+ * cm_roam_release_lock  - Wrapper for sme_release_global_lock()
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cm_roam_release_lock(void);
+
+/**
+ * cm_roam_get_requestor_string  - RSO control requestor to string api
+ * @requestor: Requestor of type enum wlan_cm_rso_control_requestor
+ *
+ * Return: Pointer to converted string
+ */
+char
+*cm_roam_get_requestor_string(enum wlan_cm_rso_control_requestor requestor);
 #endif
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD

+ 56 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h

@@ -23,4 +23,60 @@
 #ifndef _WLAN_CM_ROAM_UCFG_API_H_
 #define _WLAN_CM_ROAM_UCFG_API_H_
 
+#ifdef ROAM_OFFLOAD_V1
+/**
+ * ucfg_user_space_enable_disable_rso  - Enable/Disable Roam Scan offload
+ * to firmware.
+ * @pdev: Pointer to pdev
+ * @vdev_id: vdev id
+ * @is_fast_roam_enabled: Value provided by userspace.
+ * is_fast_roam_enabled - true: enable RSO if FastRoamEnabled ini is enabled
+ *                        false: disable RSO
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ucfg_user_space_enable_disable_rso(struct wlan_objmgr_pdev *pdev,
+				   uint8_t vdev_id,
+				   const bool is_fast_roam_enabled);
+
+/**
+ * ucfg_cm_rso_init_deinit  - Init or Deinit roaming module at firmware
+ * @pdev: Pointer to pdev
+ * @vdev_id: vdev id
+ * @enable: true: Send RSO init and RSO enable
+ *          false: Send RSO stop
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ucfg_cm_rso_init_deinit(struct wlan_objmgr_pdev *pdev,
+			uint8_t vdev_id, bool enable);
+
+/**
+ * ucfg_cm_disable_rso  - Disable roam scan offload to firmware
+ * @pdev: Pointer to pdev
+ * @vdev_id: vdev id
+ * @requestor: RSO disable requestor
+ * @reason: Reason for RSO disable
+ *
+ * Return:  QDF_STATUS
+ */
+QDF_STATUS ucfg_cm_disable_rso(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id,
+			       enum wlan_cm_rso_control_requestor requestor,
+			       uint8_t reason);
+
+/**
+ * ucfg_cm_enable_rso  - Enable roam scan offload to firmware
+ * @pdev: Pointer to pdev
+ * @vdev_id: vdev id
+ * @requestor: RSO disable requestor
+ * @reason: Reason for RSO disable
+ *
+ * Return:  QDF_STATUS
+ */
+QDF_STATUS ucfg_cm_enable_rso(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id,
+			      enum wlan_cm_rso_control_requestor requestor,
+			      uint8_t reason);
+#endif
 #endif

+ 23 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -329,3 +329,26 @@ wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc,
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
 }
 #endif
+
+#ifdef ROAM_OFFLOAD_V1
+char *cm_roam_get_requestor_string(enum wlan_cm_rso_control_requestor requestor)
+{
+	switch (requestor) {
+	case RSO_INVALID_REQUESTOR:
+	default:
+		return "No requestor";
+	case RSO_START_BSS:
+		return "SAP start";
+	case RSO_CHANNEL_SWITCH:
+		return "CSA";
+	case RSO_CONNECT_START:
+		return "STA connection";
+	case RSO_SAP_CHANNEL_CHANGE:
+		return "SAP Ch switch";
+	case RSO_NDP_CON_ON_NDI:
+		return "NDP connection";
+	case RSO_SET_PCL:
+		return "Set PCL";
+	}
+}
+#endif

+ 124 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c

@@ -22,3 +22,127 @@
 
 #include "wlan_cm_roam_ucfg_api.h"
 
+#ifdef ROAM_OFFLOAD_V1
+QDF_STATUS
+ucfg_user_space_enable_disable_rso(struct wlan_objmgr_pdev *pdev,
+				   uint8_t vdev_id,
+				   const bool is_fast_roam_enabled)
+{
+	bool supplicant_disabled_roaming;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	QDF_STATUS status;
+
+	/*
+	 * If the ini "FastRoamEnabled" is disabled, don't allow the
+	 * userspace to enable roam offload
+	 */
+	ucfg_mlme_is_lfr_enabled(psoc, &lfr_enabled);
+	if (!lfr_enabled) {
+		mlme_legacy_debug("ROAM_CONFIG: Fast roam ini is disabled");
+		if (!is_fast_roam_enabled)
+			return QDF_STATUS_SUCCESS;
+
+		return  QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Supplicant_disabled_roaming flag is the global flag to control
+	 * roam offload from supplicant. Driver cannot enable roaming if
+	 * supplicant disabled roaming is set.
+	 * is_fast_roam_enabled: true - enable RSO if not disabled by driver
+	 *                       false - Disable RSO. Send RSO stop if false
+	 *                       is set.
+	 */
+	supplicant_disabled_roaming =
+		mlme_get_supplicant_disabled_roaming(psoc, vdev_id);
+	if (!is_fast_roam_enabled && supplicant_disabled_roaming) {
+		mlme_legacy_debug("ROAM_CONFIG: RSO already disabled by supplicant");
+		return QDF_STATUS_E_ALREADY;
+	}
+
+	mlme_set_supplicant_disabled_roaming(psoc, vdev_id,
+					     !is_fast_roam_enabled);
+
+	state = (is_fast_roam_enabled) ?
+		WLAN_ROAM_RSO_ENABLED : WLAN_ROAM_RSO_STOPPED;
+	status = cm_roam_state_change(pdev, vdev_id, state,
+				      REASON_SUPPLICANT_DISABLED_ROAMING);
+
+	return status;
+}
+
+/*
+ * Driver internally invoked RSO operation/configuration APIs.
+ */
+QDF_STATUS
+ucfg_cm_rso_init_deinit(struct wlan_objmgr_pdev *pdev,
+			uint8_t vdev_id, bool enable)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	uint8_t reason = REASON_SUPPLICANT_DE_INIT_ROAMING;
+	QDF_STATUS status;
+
+	status = cm_roam_acquire_lock();
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_FAILURE;
+
+	if (enable)
+		reason = REASON_SUPPLICANT_INIT_ROAMING;
+
+	status = cm_roam_state_change(
+			pdev, vdev_id,
+			enable ? WLAN_ROAM_RSO_ENABLED : WLAN_ROAM_DEINIT,
+			reason);
+	cm_roam_release_lock();
+
+	return status;
+}
+
+QDF_STATUS ucfg_cm_disable_rso(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id,
+			       enum wlan_cm_rso_control_requestor requestor,
+			       uint8_t reason)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	QDF_STATUS status;
+
+	status = cm_roam_acquire_lock();
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_FAILURE;
+
+	if (reason == REASON_DRIVER_DISABLED && requestor)
+		mlme_set_operations_bitmap(psoc, vdev_id, requestor, false);
+
+	mlme_legacy_debug("ROAM_CONFIG: vdev[%d] Disable roaming - requestor:%s",
+			  vdev_id, cm_roam_get_requestor_string(requestor));
+
+	status = cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_STOPPED,
+				      REASON_DRIVER_DISABLED);
+	cm_roam_release_lock();
+
+	return status;
+}
+
+QDF_STATUS ucfg_cm_enable_rso(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id,
+			      enum wlan_cm_rso_control_requestor requestor,
+			      uint8_t reason)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	QDF_STATUS status;
+
+	if (reason == REASON_DRIVER_DISABLED && requestor)
+		mlme_set_operations_bitmap(mac->psoc, vdev_id, requestor, true);
+
+	status = cm_roam_acquire_lock();
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_FAILURE;
+
+	mlme_legacy_debug("ROAM_CONFIG: vdev[%d] Enable roaming - requestor:%s",
+			  vdev_id, cm_roam_get_requestor_string(requestor));
+
+	status = cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_STARTED,
+				      REASON_DRIVER_ENABLED);
+	cm_roam_release_lock();
+
+	return status;
+}
+#endif

+ 94 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -13026,6 +13026,99 @@ void wlan_hdd_rso_cmd_status_cb(hdd_handle_t hdd_handle,
 	complete(&adapter->lfr_fw_status.disable_lfr_event);
 }
 
+#ifdef ROAM_OFFLOAD_V1
+/**
+ * __wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * This function is used to enable/disable roaming using vendor commands
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data, int data_len)
+{
+	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
+	uint32_t is_fast_roam_enabled;
+	int ret;
+	QDF_STATUS qdf_status;
+	unsigned long rc;
+	struct hdd_station_ctx *hdd_sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	mac_handle_t mac_handle;
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_cfg80211_nla_parse(tb,
+				      QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
+				      qca_wlan_vendor_attr);
+	if (ret) {
+		hdd_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	/* Parse and fetch Enable flag */
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
+		hdd_err("attr enable failed");
+		return -EINVAL;
+	}
+
+	is_fast_roam_enabled = nla_get_u32(
+				tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
+	hdd_debug("ROAM_CONFIG: isFastRoamEnabled %d", is_fast_roam_enabled);
+
+	/* Update roaming */
+	mac_handle = hdd_ctx->mac_handle;
+	qdf_status = ucfg_user_space_enable_disable_rso(hdd_ctx->pdev,
+							adapter->vdev_id,
+							is_fast_roam_enabled);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		hdd_err("ROAM_CONFIG: sme_config_fast_roaming failed with status=%d",
+			qdf_status);
+
+	ret = qdf_status_to_os_return(qdf_status);
+
+	if (eConnectionState_Associated == hdd_sta_ctx->conn_info.conn_state &&
+	    QDF_IS_STATUS_SUCCESS(qdf_status) && !is_fast_roam_enabled) {
+		INIT_COMPLETION(adapter->lfr_fw_status.disable_lfr_event);
+		/*
+		 * 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;
+		}
+	}
+
+	hdd_exit();
+	return ret;
+}
+#else
 /**
  * __wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
  * @wiphy: Pointer to wireless phy
@@ -13116,6 +13209,7 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
 	hdd_exit();
 	return ret;
 }
+#endif
 
 /**
  * wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming

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

@@ -191,6 +191,7 @@
 #include "wlan_global_lmac_if_api.h"
 #include "wlan_coex_ucfg_api.h"
 #include "wlan_cm_roam_api.h"
+#include "wlan_cm_roam_ucfg_api.h"
 
 #ifdef MODULE
 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
@@ -5293,6 +5294,114 @@ hdd_vdev_destroy_procedure:
 	return errno;
 }
 
+#ifdef ROAM_OFFLOAD_V1
+QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx = &adapter->session.station;
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+	int ret_val;
+	mac_handle_t mac_handle;
+	bool bval = false;
+	uint8_t enable_sifs_burst = 0;
+	uint32_t fine_time_meas_cap = 0, roam_triggers;
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	mac_handle = hdd_ctx->mac_handle;
+	sme_set_curr_device_mode(mac_handle, adapter->device_mode);
+	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("unable to get vht_enable2x2");
+	sme_set_pdev_ht_vht_ies(mac_handle, bval);
+
+	sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id);
+
+	hdd_roam_profile_init(adapter);
+	hdd_register_wext(adapter->dev);
+
+	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
+	sme_roam_reset_configs(mac_handle, adapter->vdev_id);
+
+	/* set fast roaming capability in sme session */
+	status = ucfg_user_space_enable_disable_rso(hdd_ctx->pdev,
+						    adapter->vdev_id,
+						    true);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("ROAM_CONFIG: sme_config_fast_roaming failed with status=%d",
+			status);
+
+	/* Set the default operation channel freq*/
+	sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq;
+
+	/* Make the default Auth Type as OPEN */
+	sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+
+	status = hdd_init_tx_rx(adapter);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
+			status, status);
+		goto error_init_txrx;
+	}
+
+	set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
+
+	status = hdd_wmm_adapter_init(adapter);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
+			status, status);
+		goto error_wmm_init;
+	}
+
+	set_bit(WMM_INIT_DONE, &adapter->event_flags);
+
+	status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("Failed to get sifs burst value, use default");
+
+	ret_val = sme_cli_set_command(adapter->vdev_id,
+				      WMI_PDEV_PARAM_BURST_ENABLE,
+				      enable_sifs_burst,
+				      PDEV_CMD);
+	if (ret_val)
+		hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
+
+	hdd_set_netdev_flags(adapter);
+
+	/* rcpi info initialization */
+	qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
+
+	if (adapter->device_mode == QDF_STA_MODE) {
+		roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc);
+		mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, adapter->vdev_id,
+					     roam_triggers);
+		wlan_cm_roam_disable_vendor_btm(hdd_ctx->psoc,
+						adapter->vdev_id);
+		ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
+						 &fine_time_meas_cap);
+		sme_cli_set_command(
+			adapter->vdev_id,
+			WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
+			(bool)(fine_time_meas_cap & WMI_FW_STA_RTT_RESPR),
+			VDEV_CMD);
+		sme_cli_set_command(
+			adapter->vdev_id,
+			WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_ROLE,
+			(bool)(fine_time_meas_cap & WMI_FW_STA_RTT_INITR),
+			VDEV_CMD);
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+error_wmm_init:
+	clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
+	hdd_deinit_tx_rx(adapter);
+error_init_txrx:
+	hdd_unregister_wext(adapter->dev);
+	QDF_BUG(!hdd_vdev_destroy(adapter));
+
+	return status;
+}
+#else
 QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
 {
 	struct hdd_station_ctx *sta_ctx = &adapter->session.station;
@@ -5395,6 +5504,7 @@ error_init_txrx:
 
 	return status;
 }
+#endif
 
 /**
  * hdd_deinit_station_mode() - De-initialize the station adapter

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

@@ -103,6 +103,28 @@ QDF_STATUS sme_release_global_lock(struct sme_context *sme)
 	return qdf_mutex_release(&sme->sme_global_lock);
 }
 
+#ifdef ROAM_OFFLOAD_V1
+QDF_STATUS cm_roam_acquire_lock(void)
+{
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_SME);
+
+	if (!mac)
+		return QDF_STATUS_E_FAILURE;
+
+	return sme_acquire_global_lock(&mac->sme);
+}
+
+QDF_STATUS cm_roam_release_lock(void)
+{
+	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_SME);
+
+	if (!mac)
+		return QDF_STATUS_E_FAILURE;
+
+	return sme_release_global_lock(&mac->sme);
+}
+#endif
+
 struct mac_context *sme_get_mac_context(void)
 {
 	struct mac_context *mac_ctx;