qcacld-3.0: Move rso related process to connection manager [PART 1]
Add macro ROAM_OFFLOAD_V1 for new code and implement below functions for connection manager roam part: csr_handle_roam_state_change() roam offload state related handler. Filling WMI_ROAM_SCAN_RSSI_THRESHOLD cmd parameters related process. Change-Id: I0351155ca5a3d68ade6568c7527c5708582ccf1a CRs-Fixed: 2730826
此提交包含在:
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2020 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
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOC: wlan_cm_roam_offload.c
|
||||
*
|
||||
* Implementation for the common roaming offload api interfaces.
|
||||
*/
|
||||
|
||||
#include "wlan_cm_roam_offload.h"
|
||||
#include "wlan_cm_tgt_if_tx_api.h"
|
||||
#include "wlan_cm_roam_api.h"
|
||||
|
||||
/**
|
||||
* cm_roam_init_req() - roam init request handling
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_init_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
bool enable)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_roam_start_req() - roam start request handling
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_start_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
struct wlan_roam_start_config *start_req;
|
||||
QDF_STATUS status;
|
||||
|
||||
start_req = qdf_mem_malloc(sizeof(*start_req));
|
||||
if (!start_req)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
/* fill from legacy through this API */
|
||||
wlan_cm_roam_fill_start_req(psoc, vdev_id, start_req, reason);
|
||||
|
||||
status = wlan_cm_tgt_send_roam_start_req(psoc, vdev_id, start_req);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
mlme_debug("fail to send roam start");
|
||||
|
||||
qdf_mem_free(start_req);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_roam_update_config_req() - roam update config request handling
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* similar to csr_roam_offload_scan, will be used from many legacy
|
||||
* process directly, generate a new function wlan_cm_roam_send_rso_cmd
|
||||
* for external usage.
|
||||
*/
|
||||
QDF_STATUS cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t rso_command,
|
||||
uint8_t reason)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||
|
||||
status = wlan_cm_roam_cmd_allowed(psoc, vdev_id, rso_command, reason);
|
||||
|
||||
if (status == QDF_STATUS_E_NOSUPPORT)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
mlme_debug("ROAM: not allowed");
|
||||
return status;
|
||||
}
|
||||
if (rso_command == ROAM_SCAN_OFFLOAD_START)
|
||||
status = cm_roam_start_req(psoc, vdev_id, reason);
|
||||
else if (rso_command == ROAM_SCAN_OFFLOAD_UPDATE_CFG)
|
||||
status = cm_roam_update_config_req(psoc, vdev_id, reason);
|
||||
// else if (rso_command == ROAM_SCAN_OFFLOAD_RESTART)
|
||||
/* RESTART API */
|
||||
// else
|
||||
/* ABORT SCAN API */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_roam_stop_req() - roam stop request handling
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_stop_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
/* do the filling as csr_post_rso_stop */
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_roam_switch_to_rso_stop() - roam state handling for rso stop
|
||||
* @pdev: pdev pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* This function is used for WLAN_ROAM_RSO_STOPPED roam state handling
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
enum roam_offload_state cur_state;
|
||||
QDF_STATUS status;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
|
||||
|
||||
cur_state = mlme_get_roam_state(psoc, vdev_id);
|
||||
switch (cur_state) {
|
||||
case WLAN_ROAM_RSO_ENABLED:
|
||||
status = cm_roam_stop_req(psoc, vdev_id, reason);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
mlme_err("ROAM: Unable to switch to RSO STOP State");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WLAN_ROAM_DEINIT:
|
||||
case WLAN_ROAM_RSO_STOPPED:
|
||||
case WLAN_ROAM_INIT:
|
||||
/*
|
||||
* Already the roaming module is initialized at fw,
|
||||
* nothing to do here
|
||||
*/
|
||||
default:
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_roam_switch_to_deinit() - roam state handling for roam deinit
|
||||
* @pdev: pdev pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* This function is used for WLAN_ROAM_DEINIT roam state handling
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_switch_to_deinit(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
|
||||
enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id);
|
||||
|
||||
switch (cur_state) {
|
||||
case WLAN_ROAM_RSO_ENABLED:
|
||||
cm_roam_switch_to_rso_stop(pdev, vdev_id, reason);
|
||||
break;
|
||||
case WLAN_ROAM_RSO_STOPPED:
|
||||
case WLAN_ROAM_INIT:
|
||||
break;
|
||||
|
||||
case WLAN_ROAM_DEINIT:
|
||||
/*
|
||||
* Already the roaming module is de-initialized at fw,
|
||||
* do nothing here
|
||||
*/
|
||||
default:
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = cm_roam_init_req(psoc, vdev_id, false);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT);
|
||||
|
||||
if (reason != REASON_SUPPLICANT_INIT_ROAMING)
|
||||
wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_roam_switch_to_init() - roam state handling for roam init
|
||||
* @pdev: pdev pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* This function is used for WLAN_ROAM_INIT roam state handling
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_switch_to_init(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
enum roam_offload_state cur_state;
|
||||
uint8_t temp_vdev_id, roam_enabled_vdev_id;
|
||||
uint32_t roaming_bitmap;
|
||||
bool dual_sta_roam_active;
|
||||
QDF_STATUS status;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
|
||||
|
||||
dual_sta_roam_active =
|
||||
wlan_mlme_get_dual_sta_roaming_enabled(psoc);
|
||||
|
||||
cur_state = mlme_get_roam_state(psoc, vdev_id);
|
||||
switch (cur_state) {
|
||||
case WLAN_ROAM_DEINIT:
|
||||
roaming_bitmap = mlme_get_roam_trigger_bitmap(psoc, vdev_id);
|
||||
if (!roaming_bitmap) {
|
||||
mlme_info("ROAM: Cannot change to INIT state for vdev[%d]",
|
||||
vdev_id);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (dual_sta_roam_active)
|
||||
break;
|
||||
/*
|
||||
* Disable roaming on the enabled sta if supplicant wants to
|
||||
* enable roaming on this vdev id
|
||||
*/
|
||||
temp_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(
|
||||
psoc, vdev_id);
|
||||
if (temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
|
||||
/*
|
||||
* Roam init state can be requested as part of
|
||||
* initial connection or due to enable from
|
||||
* supplicant via vendor command. This check will
|
||||
* ensure roaming does not get enabled on this STA
|
||||
* vdev id if it is not an explicit enable from
|
||||
* supplicant.
|
||||
*/
|
||||
if (reason != REASON_SUPPLICANT_INIT_ROAMING) {
|
||||
mlme_info("ROAM: Roam module already initialized on vdev:[%d]",
|
||||
temp_vdev_id);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
cm_roam_state_change(pdev, temp_vdev_id,
|
||||
WLAN_ROAM_DEINIT, reason);
|
||||
}
|
||||
break;
|
||||
|
||||
case WLAN_ROAM_INIT:
|
||||
case WLAN_ROAM_RSO_STOPPED:
|
||||
case WLAN_ROAM_RSO_ENABLED:
|
||||
/*
|
||||
* Already the roaming module is initialized at fw,
|
||||
* just return from here
|
||||
*/
|
||||
default:
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = cm_roam_init_req(psoc, vdev_id, true);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_INIT);
|
||||
|
||||
roam_enabled_vdev_id =
|
||||
policy_mgr_get_roam_enabled_sta_session_id(psoc, vdev_id);
|
||||
|
||||
/* Send PDEV pcl command if only one STA is in connected state
|
||||
* If there is another STA connection exist, then set the
|
||||
* PCL type to vdev level
|
||||
*/
|
||||
if (roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX &&
|
||||
dual_sta_roam_active)
|
||||
wlan_cm_roam_activate_pcl_per_vdev(psoc, vdev_id, true);
|
||||
|
||||
/* Set PCL before sending RSO start */
|
||||
policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, vdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_roam_switch_to_rso_start() - roam state handling for rso started
|
||||
* @pdev: pdev pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* This function is used for WLAN_ROAM_RSO_ENABLED roam state handling
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS cm_roam_switch_to_rso_start(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
enum roam_offload_state cur_state;
|
||||
QDF_STATUS status;
|
||||
uint8_t control_bitmap;
|
||||
bool sup_disabled_roaming;
|
||||
bool rso_allowed;
|
||||
uint8_t rso_command = ROAM_SCAN_OFFLOAD_START;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
|
||||
|
||||
wlan_mlme_get_roam_scan_offload_enabled(psoc, &rso_allowed);
|
||||
|
||||
cur_state = mlme_get_roam_state(psoc, vdev_id);
|
||||
switch (cur_state) {
|
||||
case WLAN_ROAM_INIT:
|
||||
case WLAN_ROAM_RSO_STOPPED:
|
||||
break;
|
||||
|
||||
case WLAN_ROAM_DEINIT:
|
||||
status = cm_roam_switch_to_init(pdev, vdev_id, reason);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
break;
|
||||
case WLAN_ROAM_RSO_ENABLED:
|
||||
/*
|
||||
* Send RSO update config if roaming already enabled
|
||||
*/
|
||||
rso_command = ROAM_SCAN_OFFLOAD_UPDATE_CFG;
|
||||
break;
|
||||
default:
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!rso_allowed) {
|
||||
mlme_debug("ROAM: RSO disabled via INI");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id);
|
||||
if (control_bitmap) {
|
||||
mlme_debug("ROAM: RSO Disabled internaly: vdev[%d] bitmap[0x%x]",
|
||||
vdev_id, control_bitmap);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
status = cm_roam_send_rso_cmd(psoc, vdev_id, rso_command, reason);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
mlme_debug("ROAM: RSO start failed");
|
||||
return status;
|
||||
}
|
||||
mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_ENABLED);
|
||||
|
||||
/*
|
||||
* If supplicant disabled roaming, driver does not send
|
||||
* RSO cmd to fw. This causes roam invoke to fail in FW
|
||||
* since RSO start never happened at least once to
|
||||
* configure roaming engine in FW.
|
||||
*/
|
||||
sup_disabled_roaming = mlme_get_supplicant_disabled_roaming(psoc,
|
||||
vdev_id);
|
||||
if (!sup_disabled_roaming)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
mlme_debug("ROAM: RSO disabled by Supplicant on vdev[%d]", vdev_id);
|
||||
return cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_STOPPED,
|
||||
REASON_SUPPLICANT_DISABLED_ROAMING);
|
||||
}
|
||||
|
||||
QDF_STATUS cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
enum roam_offload_state requested_state,
|
||||
uint8_t reason)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
bool is_up;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
|
||||
WLAN_MLME_NB_ID);
|
||||
if (!vdev)
|
||||
return status;
|
||||
|
||||
is_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev));
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
|
||||
|
||||
if (requested_state != WLAN_ROAM_DEINIT && !is_up) {
|
||||
mlme_debug("ROAM: roam state change requested in disconnected state");
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (requested_state) {
|
||||
case WLAN_ROAM_DEINIT:
|
||||
status = cm_roam_switch_to_deinit(pdev, vdev_id, reason);
|
||||
break;
|
||||
case WLAN_ROAM_INIT:
|
||||
status = cm_roam_switch_to_init(pdev, vdev_id, reason);
|
||||
break;
|
||||
case WLAN_ROAM_RSO_ENABLED:
|
||||
status = cm_roam_switch_to_rso_start(pdev, vdev_id, reason);
|
||||
break;
|
||||
case WLAN_ROAM_RSO_STOPPED:
|
||||
status = cm_roam_switch_to_rso_stop(pdev, vdev_id, reason);
|
||||
break;
|
||||
default:
|
||||
mlme_debug("ROAM: Invalid roam state %d", requested_state);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2020 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
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOC: wlan_cm_roam_offload.h
|
||||
*
|
||||
* Implementation for the common roaming offload api interfaces.
|
||||
*/
|
||||
|
||||
#ifndef _WLAN_CM_ROAM_OFFLOAD_H_
|
||||
#define _WLAN_CM_ROAM_OFFLOAD_H_
|
||||
|
||||
#include "wlan_cm_roam_public_srtuct.h"
|
||||
|
||||
#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
/**
|
||||
* cm_roam_send_rso_cmd() - Send rso command
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @rso_command: roam scan offload command
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* This function is used to send rso command
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t rso_command,
|
||||
uint8_t reason);
|
||||
|
||||
/**
|
||||
* cm_roam_state_change() - Post roam state change to roam state machine
|
||||
* @pdev: pdev pointer
|
||||
* @vdev_id: vdev id
|
||||
* @requested_state: roam state to be set
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* This function posts roam state change to roam state machine handling
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
enum roam_offload_state requested_state,
|
||||
uint8_t reason);
|
||||
#endif
|
||||
#endif
|
@@ -31,6 +31,111 @@
|
||||
/* Default value of reason code */
|
||||
#define DISABLE_VENDOR_BTM_CONFIG 2
|
||||
|
||||
#ifdef ROAM_OFFLOAD_V1
|
||||
#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
/**
|
||||
* wlan_cm_enable_roaming_on_connected_sta() - Enable roaming on other connected
|
||||
* sta vdev
|
||||
* @pdev: pointer to pdev object
|
||||
* @vdev_id: vdev id on which roaming should not be enabled
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id);
|
||||
|
||||
/**
|
||||
* wlan_cm_start_roaming() - start roaming
|
||||
* @pdev: pdev pointer
|
||||
* @vdev_id: vdev id
|
||||
* @reason: reason to roam
|
||||
*
|
||||
* This function gets called to start roaming
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
wlan_cm_start_roaming(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason);
|
||||
|
||||
/**
|
||||
* wlan_cm_roam_cmd_allowed() - check roam cmd is allowed or not
|
||||
* @psoc: pointer to psoc object
|
||||
* @vdev_id: vdev id
|
||||
* @rso_command: roam scan offload command
|
||||
* @reason: reason to roam
|
||||
*
|
||||
* This function gets called to check roam cmd is allowed or not
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
wlan_cm_roam_cmd_allowed(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t rso_command,
|
||||
uint8_t reason);
|
||||
|
||||
/**
|
||||
* wlan_cm_roam_fill_start_req() - fill start request structure content
|
||||
* @psoc: pointer to psoc object
|
||||
* @vdev_id: vdev id
|
||||
* @req: roam start config pointer
|
||||
* @reason: reason to roam
|
||||
*
|
||||
* This function gets called to fill start request structure content
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
wlan_cm_roam_fill_start_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
struct wlan_roam_start_config *req,
|
||||
uint8_t reason);
|
||||
|
||||
/**
|
||||
* wlan_cm_roam_send_rso_cmd() - Send rso command
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @rso_command: roam scan offload command
|
||||
* @reason: reason for changing roam state for the requested vdev id
|
||||
*
|
||||
* This function is used to send rso command
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t rso_command,
|
||||
uint8_t reason);
|
||||
#else
|
||||
static inline QDF_STATUS
|
||||
wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
wlan_cm_start_roaming(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
uint8_t reason)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
wlan_cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t rso_command,
|
||||
uint8_t reason);
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
||||
/**
|
||||
* wlan_cm_roam_extract_btm_response() - Extract BTM rsp stats
|
||||
|
@@ -26,6 +26,144 @@
|
||||
#include "wmi_unified_param.h"
|
||||
#include "wmi_unified_sta_param.h"
|
||||
|
||||
#define ROAM_SCAN_OFFLOAD_START 1
|
||||
#define ROAM_SCAN_OFFLOAD_STOP 2
|
||||
#define ROAM_SCAN_OFFLOAD_RESTART 3
|
||||
#define ROAM_SCAN_OFFLOAD_UPDATE_CFG 4
|
||||
#define ROAM_SCAN_OFFLOAD_ABORT_SCAN 5
|
||||
|
||||
#define REASON_CONNECT 1
|
||||
#define REASON_CHANNEL_LIST_CHANGED 2
|
||||
#define REASON_LOOKUP_THRESH_CHANGED 3
|
||||
#define REASON_DISCONNECTED 4
|
||||
#define REASON_RSSI_DIFF_CHANGED 5
|
||||
#define REASON_ESE_INI_CFG_CHANGED 6
|
||||
#define REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED 7
|
||||
#define REASON_VALID_CHANNEL_LIST_CHANGED 8
|
||||
#define REASON_FLUSH_CHANNEL_LIST 9
|
||||
#define REASON_EMPTY_SCAN_REF_PERIOD_CHANGED 10
|
||||
#define REASON_PREAUTH_FAILED_FOR_ALL 11
|
||||
#define REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW 12
|
||||
#define REASON_NPROBES_CHANGED 13
|
||||
#define REASON_HOME_AWAY_TIME_CHANGED 14
|
||||
#define REASON_OS_REQUESTED_ROAMING_NOW 15
|
||||
#define REASON_SCAN_CH_TIME_CHANGED 16
|
||||
#define REASON_SCAN_HOME_TIME_CHANGED 17
|
||||
#define REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED 18
|
||||
#define REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED 19
|
||||
#define REASON_ROAM_BMISS_FIRST_BCNT_CHANGED 20
|
||||
#define REASON_ROAM_BMISS_FINAL_BCNT_CHANGED 21
|
||||
#define REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED 22
|
||||
#define REASON_ROAM_DFS_SCAN_MODE_CHANGED 23
|
||||
#define REASON_ROAM_ABORT_ROAM_SCAN 24
|
||||
#define REASON_ROAM_EXT_SCAN_PARAMS_CHANGED 25
|
||||
#define REASON_ROAM_SET_SSID_ALLOWED 26
|
||||
#define REASON_ROAM_SET_FAVORED_BSSID 27
|
||||
#define REASON_ROAM_GOOD_RSSI_CHANGED 28
|
||||
#define REASON_ROAM_SET_BLACKLIST_BSSID 29
|
||||
#define REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED 30
|
||||
#define REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED 31
|
||||
#define REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED 32
|
||||
#define REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED 33
|
||||
#define REASON_CONNECT_IES_CHANGED 34
|
||||
#define REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED 35
|
||||
#define REASON_ROAM_SYNCH_FAILED 36
|
||||
#define REASON_ROAM_PSK_PMK_CHANGED 37
|
||||
#define REASON_ROAM_STOP_ALL 38
|
||||
#define REASON_SUPPLICANT_DISABLED_ROAMING 39
|
||||
#define REASON_CTX_INIT 40
|
||||
#define REASON_FILS_PARAMS_CHANGED 41
|
||||
#define REASON_SME_ISSUED 42
|
||||
#define REASON_DRIVER_ENABLED 43
|
||||
#define REASON_ROAM_FULL_SCAN_PERIOD_CHANGED 44
|
||||
#define REASON_SCORING_CRITERIA_CHANGED 45
|
||||
#define REASON_SUPPLICANT_INIT_ROAMING 46
|
||||
#define REASON_SUPPLICANT_DE_INIT_ROAMING 47
|
||||
#define REASON_DRIVER_DISABLED 48
|
||||
#define REASON_ROAM_CONTROL_CONFIG_CHANGED 49
|
||||
#define REASON_ROAM_CONTROL_CONFIG_ENABLED 50
|
||||
#define REASON_ROAM_CANDIDATE_FOUND 51
|
||||
#define REASON_ROAM_HANDOFF_DONE 52
|
||||
#define REASON_ROAM_ABORT 53
|
||||
|
||||
#ifdef ROAM_OFFLOAD_V1
|
||||
#define NOISE_FLOOR_DBM_DEFAULT (-96)
|
||||
#define RSSI_MIN_VALUE (-128)
|
||||
#define RSSI_MAX_VALUE (127)
|
||||
|
||||
/**
|
||||
* struct wlan_roam_offload_scan_rssi_params - structure containing
|
||||
* parameters for roam offload scan based on RSSI
|
||||
* @rssi_thresh: rssi threshold
|
||||
* @rssi_thresh_diff: difference in rssi threshold
|
||||
* @hi_rssi_scan_max_count: 5G scan max count
|
||||
* @hi_rssi_scan_rssi_delta: 5G scan rssi change threshold value
|
||||
* @hi_rssi_scan_rssi_ub: 5G scan upper bound
|
||||
* @raise_rssi_thresh_5g: flag to determine penalty and boost thresholds
|
||||
* @vdev_id: vdev id
|
||||
* @penalty_threshold_5g: RSSI threshold below which 5GHz RSSI is penalized
|
||||
* @boost_threshold_5g: RSSI threshold above which 5GHz RSSI is favored
|
||||
* @raise_factor_5g: factor by which 5GHz RSSI is boosted
|
||||
* @drop_factor_5g: factor by which 5GHz RSSI is penalized
|
||||
* @max_raise_rssi_5g: maximum boost that can be applied to a 5GHz RSSI
|
||||
* @max_drop_rssi_5g: maximum penalty that can be applied to a 5GHz RSSI
|
||||
* @good_rssi_threshold: RSSI below which roam is kicked in by background
|
||||
* scan although rssi is still good
|
||||
* @early_stop_scan_enable: early stop scan enable
|
||||
* @roam_earlystop_thres_min: Minimum RSSI threshold value for early stop,
|
||||
* unit is dB above NF
|
||||
* @roam_earlystop_thres_max: Maximum RSSI threshold value for early stop,
|
||||
* unit is dB above NF
|
||||
* @dense_rssi_thresh_offset: dense roam RSSI threshold difference
|
||||
* @dense_min_aps_cnt: dense roam minimum APs
|
||||
* @initial_dense_status: dense status detected by host
|
||||
* @traffic_threshold: dense roam RSSI threshold
|
||||
* @bg_scan_bad_rssi_thresh: Bad RSSI threshold to perform bg scan
|
||||
* @roam_bad_rssi_thresh_offset_2g: Offset from Bad RSSI threshold for 2G
|
||||
* to 5G Roam
|
||||
* @bg_scan_client_bitmap: Bitmap used to identify the client scans to snoop
|
||||
*/
|
||||
struct wlan_roam_offload_scan_rssi_params {
|
||||
int8_t rssi_thresh;
|
||||
uint8_t rssi_thresh_diff;
|
||||
uint32_t hi_rssi_scan_max_count;
|
||||
uint32_t hi_rssi_scan_rssi_delta;
|
||||
int32_t hi_rssi_scan_rssi_ub;
|
||||
int raise_rssi_thresh_5g;
|
||||
int drop_rssi_thresh_5g;
|
||||
uint8_t vdev_id;
|
||||
uint32_t penalty_threshold_5g;
|
||||
uint32_t boost_threshold_5g;
|
||||
uint8_t raise_factor_5g;
|
||||
uint8_t drop_factor_5g;
|
||||
int max_raise_rssi_5g;
|
||||
int max_drop_rssi_5g;
|
||||
uint32_t good_rssi_threshold;
|
||||
bool early_stop_scan_enable;
|
||||
uint32_t roam_earlystop_thres_min;
|
||||
uint32_t roam_earlystop_thres_max;
|
||||
int dense_rssi_thresh_offset;
|
||||
int dense_min_aps_cnt;
|
||||
int initial_dense_status;
|
||||
int traffic_threshold;
|
||||
int32_t rssi_thresh_offset_5g;
|
||||
int8_t bg_scan_bad_rssi_thresh;
|
||||
uint8_t roam_bad_rssi_thresh_offset_2g;
|
||||
uint32_t bg_scan_client_bitmap;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_roam_start_config - structure containing parameters for
|
||||
* roam start config
|
||||
* @rssi_params: roam scan rssi threshold parameters
|
||||
*/
|
||||
struct wlan_roam_start_config {
|
||||
struct wlan_roam_offload_scan_rssi_params rssi_params;
|
||||
/* other wmi cmd structures */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
/**
|
||||
* enum roam_offload_state - Roaming module state for each STA vdev.
|
||||
@@ -121,10 +259,16 @@ struct set_pcl_req {
|
||||
* roaming related commands
|
||||
* @send_vdev_set_pcl_cmd: TX ops function pointer to send set vdev PCL
|
||||
* command
|
||||
* @send_roam_start_req: TX ops function pointer to send roam start related
|
||||
* commands
|
||||
*/
|
||||
struct wlan_cm_roam_tx_ops {
|
||||
QDF_STATUS (*send_vdev_set_pcl_cmd) (struct wlan_objmgr_vdev *vdev,
|
||||
struct set_pcl_req *req);
|
||||
#ifdef ROAM_OFFLOAD_V1
|
||||
QDF_STATUS (*send_roam_start_req)(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_roam_start_config *req);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOC: wlan_cm_roam_ucfg_api.h
|
||||
*
|
||||
* Implementation for roaming public ucfg API interfaces.
|
||||
*/
|
||||
|
||||
#ifndef _WLAN_CM_ROAM_UCFG_API_H_
|
||||
#define _WLAN_CM_ROAM_UCFG_API_H_
|
||||
|
||||
#endif
|
@@ -47,4 +47,20 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc,
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
|
||||
|
||||
#ifdef ROAM_OFFLOAD_V1
|
||||
#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
/**
|
||||
* wlan_cm_tgt_send_roam_start_req - Send roam start command to firmware
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @req: roam start config parameter
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_cm_tgt_send_roam_start_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
struct wlan_roam_start_config *req);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CM_TGT_IF_TX_API_H__ */
|
||||
|
@@ -25,6 +25,73 @@
|
||||
#include "wlan_mlme_main.h"
|
||||
#include "wlan_policy_mgr_api.h"
|
||||
#include <wmi_unified_priv.h>
|
||||
#include "../../core/src/wlan_cm_roam_offload.h"
|
||||
|
||||
#ifdef ROAM_OFFLOAD_V1
|
||||
#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
QDF_STATUS
|
||||
wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
|
||||
uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
|
||||
uint32_t sta_vdev_id = WLAN_INVALID_VDEV_ID;
|
||||
uint32_t count;
|
||||
uint32_t idx;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
|
||||
|
||||
sta_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(psoc, vdev_id);
|
||||
if (sta_vdev_id != WLAN_UMAC_VDEV_ID_MAX)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
count = policy_mgr_get_mode_specific_conn_info(psoc,
|
||||
op_ch_freq_list,
|
||||
vdev_id_list,
|
||||
PM_STA_MODE);
|
||||
|
||||
if (!count)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
/*
|
||||
* Loop through all connected STA vdevs and roaming will be enabled
|
||||
* on the STA that has a different vdev id from the one passed as
|
||||
* input and has non zero roam trigger value.
|
||||
*/
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
if (vdev_id_list[idx] != vdev_id &&
|
||||
mlme_get_roam_trigger_bitmap(psoc, vdev_id_list[idx])) {
|
||||
sta_vdev_id = vdev_id_list[idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sta_vdev_id == WLAN_INVALID_VDEV_ID)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
mlme_debug("ROAM: Enabling roaming on vdev[%d]", sta_vdev_id);
|
||||
|
||||
return cm_roam_state_change(pdev,
|
||||
sta_vdev_id,
|
||||
WLAN_ROAM_RSO_ENABLED,
|
||||
REASON_CTX_INIT);
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_cm_start_roaming(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id, uint8_t reason)
|
||||
{
|
||||
return cm_roam_state_change(pdev, vdev_id,
|
||||
WLAN_ROAM_RSO_ENABLED, reason);
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t rso_command,
|
||||
uint8_t reason)
|
||||
{
|
||||
return cm_roam_send_rso_cmd(psoc, vdev_id, rso_command, reason);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
||||
QDF_STATUS
|
||||
|
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOC: wlan_cm_roam_ucfg_api.c
|
||||
*
|
||||
* Implementation for roaming ucfg public functionality.
|
||||
*/
|
||||
|
||||
#include "wlan_cm_roam_ucfg_api.h"
|
||||
|
@@ -127,3 +127,35 @@ end:
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ROAM_OFFLOAD_V1
|
||||
#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
||||
QDF_STATUS wlan_cm_tgt_send_roam_start_req(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id,
|
||||
struct wlan_roam_start_config *req)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct wlan_cm_roam_tx_ops roam_tx_ops;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||
WLAN_MLME_NB_ID);
|
||||
if (!vdev)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
roam_tx_ops = GET_CM_ROAM_TX_OPS_FROM_VDEV(vdev);
|
||||
if (!roam_tx_ops.send_roam_start_req) {
|
||||
mlme_err("send_roam_start_req is NULL");
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
status = roam_tx_ops.send_roam_start_req(vdev, req);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
mlme_debug("fail to send roam start");
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
新增問題並參考
封鎖使用者