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
This commit is contained in:
Pragaspathi Thilagaraj 2020-07-26 23:36:11 +05:30 • committed by snandini
commit 5fb48b5750
7 changed files with 452 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;