mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
qcacmn: Add PNO changes for converged scan
Adds PNO related changes for converged scan Change-Id: Ia18e48645d511134698777b334348d68daf2dbee CRs-Fixed: 1095299
This commit is contained in:
parent
fa59ee7936
commit
8c6e82d763
19 changed files with 1268 additions and 215 deletions
|
|
@ -115,11 +115,34 @@ struct scan_req {
|
|||
uint8_t source;
|
||||
};
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
/**
|
||||
* wlan_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
|
||||
* @pdev: pdev pointer
|
||||
* @dev: Pointer network device
|
||||
* @request: Pointer to cfg80211 scheduled scan start request
|
||||
*
|
||||
* Return: 0 for success, non zero for failure
|
||||
*/
|
||||
int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_sched_scan_request *request);
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_sched_scan_stop() - cfg80211 scheduled scan(pno) stop
|
||||
* @pdev: pdev pointer
|
||||
* @dev: Pointer network device
|
||||
*
|
||||
* Return: 0 for success, non zero for failure
|
||||
*/
|
||||
int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_pdev *pdev,
|
||||
struct net_device *dev);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_scan_priv_init() - API to initialize cfg80211 scan
|
||||
* @pdev: Pointer to net device
|
||||
*
|
||||
*
|
||||
* API to initialize cfg80211 scan module.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
|
|
|
|||
|
|
@ -35,6 +35,351 @@
|
|||
#include <qdf_mem.h>
|
||||
#include <wlan_utility.h>
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \
|
||||
defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT))
|
||||
|
||||
/**
|
||||
* wlan_config_sched_scan_plan() - configures the sched scan plans
|
||||
* from the framework.
|
||||
* @pno_req: pointer to PNO scan request
|
||||
* @request: pointer to scan request from framework
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void wlan_config_sched_scan_plan(struct pno_scan_req_params *pno_req,
|
||||
struct cfg80211_sched_scan_request *request)
|
||||
{
|
||||
pno_req->delay_start_time = request->delay;
|
||||
/*
|
||||
* As of now max 2 scan plans were supported by firmware
|
||||
* if number of scan plan supported by firmware increased below logic
|
||||
* must change.
|
||||
*/
|
||||
if (request->n_scan_plans == SCAN_PNO_MAX_PLAN_REQUEST) {
|
||||
pno_req->fast_scan_period =
|
||||
request->scan_plans[0].interval * MSEC_PER_SEC;
|
||||
pno_req->fast_scan_max_cycles =
|
||||
request->scan_plans[0].iterations;
|
||||
pno_req->slow_scan_period =
|
||||
request->scan_plans[1].interval * MSEC_PER_SEC;
|
||||
} else if (request->n_scan_plans == 1) {
|
||||
pno_req->fast_scan_period =
|
||||
request->scan_plans[0].interval * MSEC_PER_SEC;
|
||||
/*
|
||||
* if only one scan plan is configured from framework
|
||||
* then both fast and slow scan should be configured with the
|
||||
* same value that is why fast scan cycles are hardcoded to one
|
||||
*/
|
||||
pno_req->fast_scan_max_cycles = 1;
|
||||
pno_req->slow_scan_period =
|
||||
request->scan_plans[0].interval * MSEC_PER_SEC;
|
||||
} else {
|
||||
cfg80211_err("Invalid number of scan plans %d !!",
|
||||
request->n_scan_plans);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void wlan_config_sched_scan_plan(struct pno_scan_req_params *pno_req,
|
||||
struct cfg80211_sched_scan_request *request)
|
||||
{
|
||||
pno_req->fast_scan_period = request->interval;
|
||||
pno_req->fast_scan_max_cycles = SCAN_PNO_DEF_SCAN_TIMER_REPEAT;
|
||||
pno_req->slow_scan_period =
|
||||
SCAN_PNO_DEF_SLOW_SCAN_MULTIPLIER *
|
||||
pno_req->fast_scan_period;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_pno_callback() - pno callback function to handle
|
||||
* pno events.
|
||||
* @vdev: vdev ptr
|
||||
* @event: scan events
|
||||
* @args: argument
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void wlan_cfg80211_pno_callback(struct wlan_objmgr_vdev *vdev,
|
||||
struct scan_event *event,
|
||||
void *args)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct pdev_osif_priv *pdev_ospriv;
|
||||
|
||||
if (event->type != SCAN_EVENT_TYPE_NLO_COMPLETE)
|
||||
return;
|
||||
|
||||
cfg80211_info("vdev id = %d", event->vdev_id);
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
pdev = wlan_vdev_get_pdev(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
if (!pdev) {
|
||||
cfg80211_err("pdev is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_pdev_obj_lock(pdev);
|
||||
pdev_ospriv = wlan_pdev_get_ospriv(pdev);
|
||||
wlan_pdev_obj_unlock(pdev);
|
||||
if (!pdev_ospriv) {
|
||||
cfg80211_err("pdev_osprivis NULL");
|
||||
return;
|
||||
}
|
||||
cfg80211_sched_scan_results(pdev_ospriv->wiphy);
|
||||
}
|
||||
|
||||
static void
|
||||
wlan_cfg80211_register_pno_cb(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
ucfg_scan_register_pno_cb(psoc,
|
||||
wlan_cfg80211_pno_callback, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_cfg80211_is_pno_allowed() - Check if PNO is allowed
|
||||
* @vdev: vdev ptr
|
||||
*
|
||||
* The PNO Start request is coming from upper layers.
|
||||
* It is to be allowed only for Infra STA device type
|
||||
* and the link should be in a disconnected state.
|
||||
*
|
||||
* Return: Success if PNO is allowed, Failure otherwise.
|
||||
*/
|
||||
static QDF_STATUS wlan_cfg80211_is_pno_allowed(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
enum wlan_vdev_state state;
|
||||
enum tQDF_ADAPTER_MODE vdev_opmode;
|
||||
uint8_t vdev_id;
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
state = wlan_vdev_mlme_get_state(vdev);
|
||||
vdev_id = wlan_vdev_get_id(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
|
||||
cfg80211_notice("dev_mode=%d, state=%d vdev id %d",
|
||||
vdev_opmode, state, vdev_id);
|
||||
|
||||
if ((vdev_opmode == QDF_STA_MODE) &&
|
||||
((state == WLAN_VDEV_S_INIT) ||
|
||||
(state == WLAN_VDEV_S_STOP)))
|
||||
return QDF_STATUS_SUCCESS;
|
||||
else
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_sched_scan_request *request)
|
||||
{
|
||||
struct pno_scan_req_params *req;
|
||||
int i, j, ret = 0;
|
||||
QDF_STATUS status;
|
||||
uint8_t num_chan = 0, channel;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
uint32_t valid_ch[SCAN_PNO_MAX_NETW_CHANNELS_EX] = {0};
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr,
|
||||
WLAN_OSIF_ID);
|
||||
if (!vdev) {
|
||||
cfg80211_err("vdev object is NULL");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
status = wlan_cfg80211_is_pno_allowed(vdev);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cfg80211_err("pno is not allowed");
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
ucfg_scan_flush_results(pdev, NULL);
|
||||
if (ucfg_scan_get_pdev_status(pdev) !=
|
||||
SCAN_NOT_IN_PROGRESS) {
|
||||
status = wlan_abort_scan(pdev,
|
||||
wlan_objmgr_pdev_get_pdev_id(pdev),
|
||||
INVAL_VDEV_ID, INVAL_SCAN_ID);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cfg80211_err("aborting the existing scan is unsuccessful");
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
req = qdf_mem_malloc(sizeof(*req));
|
||||
if (!req) {
|
||||
cfg80211_err("req malloc failed");
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
req->networks_cnt = request->n_match_sets;
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
req->vdev_id = wlan_vdev_get_id(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
|
||||
if ((!req->networks_cnt) ||
|
||||
(req->networks_cnt > SCAN_PNO_MAX_SUPP_NETWORKS)) {
|
||||
cfg80211_err("Network input is not correct %d",
|
||||
req->networks_cnt);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (request->n_channels > SCAN_PNO_MAX_NETW_CHANNELS_EX) {
|
||||
cfg80211_err("Incorrect number of channels %d",
|
||||
request->n_channels);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (request->n_channels) {
|
||||
char chl[(request->n_channels * 5) + 1];
|
||||
int len = 0;
|
||||
|
||||
for (i = 0; i < request->n_channels; i++) {
|
||||
channel = request->channels[i]->hw_value;
|
||||
if (wlan_is_dsrc_channel(wlan_chan_to_freq(channel)))
|
||||
continue;
|
||||
len += snprintf(chl + len, 5, "%d ", channel);
|
||||
valid_ch[num_chan++] = wlan_chan_to_freq(channel);
|
||||
}
|
||||
cfg80211_notice("No. of Scan Channels: %d", num_chan);
|
||||
cfg80211_notice("Channel-List: %s", chl);
|
||||
/* If all channels are DFS and dropped,
|
||||
* then ignore the PNO request
|
||||
*/
|
||||
if (!num_chan) {
|
||||
cfg80211_notice("Channel list empty due to filtering of DSRC");
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filling per profile params */
|
||||
for (i = 0; i < req->networks_cnt; i++) {
|
||||
req->networks_list[i].ssid.length =
|
||||
request->match_sets[i].ssid.ssid_len;
|
||||
|
||||
if ((!req->networks_list[i].ssid.length) ||
|
||||
(req->networks_list[i].ssid.length > WLAN_SSID_MAX_LEN)) {
|
||||
cfg80211_err(" SSID Len %d is not correct for network %d",
|
||||
req->networks_list[i].ssid.length, i);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
qdf_mem_copy(req->networks_list[i].ssid.ssid,
|
||||
request->match_sets[i].ssid.ssid,
|
||||
req->networks_list[i].ssid.length);
|
||||
req->networks_list[i].authentication = 0; /*eAUTH_TYPE_ANY */
|
||||
req->networks_list[i].encryption = 0; /*eED_ANY */
|
||||
req->networks_list[i].bc_new_type = 0; /*eBCAST_UNKNOWN */
|
||||
|
||||
cfg80211_notice("Received ssid:%.*s",
|
||||
req->networks_list[i].ssid.length,
|
||||
req->networks_list[i].ssid.ssid);
|
||||
|
||||
/*Copying list of valid channel into request */
|
||||
qdf_mem_copy(req->networks_list[i].channels, valid_ch,
|
||||
num_chan * sizeof(uint32_t));
|
||||
req->networks_list[i].channel_cnt = num_chan;
|
||||
req->networks_list[i].rssi_thresh =
|
||||
request->match_sets[i].rssi_thold;
|
||||
}
|
||||
|
||||
for (i = 0; i < request->n_ssids; i++) {
|
||||
j = 0;
|
||||
while (j < req->networks_cnt) {
|
||||
if ((req->networks_list[j].ssid.length ==
|
||||
request->ssids[i].ssid_len) &&
|
||||
(!qdf_mem_cmp(req->networks_list[j].ssid.ssid,
|
||||
request->ssids[i].ssid,
|
||||
req->networks_list[j].ssid.length))) {
|
||||
req->networks_list[j].bc_new_type =
|
||||
SSID_BC_TYPE_HIDDEN;
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
cfg80211_notice("Number of hidden networks being Configured = %d",
|
||||
request->n_ssids);
|
||||
|
||||
/*
|
||||
* Before Kernel 4.4
|
||||
* Driver gets only one time interval which is hard coded in
|
||||
* supplicant for 10000ms.
|
||||
*
|
||||
* After Kernel 4.4
|
||||
* User can configure multiple scan_plans, each scan would have
|
||||
* separate scan cycle and interval. (interval is in unit of second.)
|
||||
* For our use case, we would only have supplicant set one scan_plan,
|
||||
* and firmware also support only one as well, so pick up the first
|
||||
* index.
|
||||
*
|
||||
* Taking power consumption into account
|
||||
* firmware after gPNOScanTimerRepeatValue times fast_scan_period
|
||||
* switches slow_scan_period. This is less frequent scans and firmware
|
||||
* shall be in slow_scan_period mode until next PNO Start.
|
||||
*/
|
||||
wlan_config_sched_scan_plan(req, request);
|
||||
cfg80211_notice("Base scan interval: %d sec, scan cycles: %d, slow scan interval %d",
|
||||
req->fast_scan_period, req->fast_scan_max_cycles,
|
||||
req->slow_scan_period);
|
||||
|
||||
ucfg_scan_get_pno_def_params(vdev, req);
|
||||
status = ucfg_scan_pno_start(vdev, req);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cfg80211_err("Failed to enable PNO");
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
cfg80211_info("PNO scan request offloaded");
|
||||
|
||||
error:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
|
||||
qdf_mem_free(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_pdev *pdev,
|
||||
struct net_device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
QDF_STATUS status;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr,
|
||||
WLAN_OSIF_ID);
|
||||
if (!vdev) {
|
||||
cfg80211_err("vdev object is NULL");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
status = ucfg_scan_pno_stop(vdev);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cfg80211_err("Failed to disabled PNO");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
cfg80211_info("PNO scan disabled");
|
||||
}
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
wlan_cfg80211_register_pno_cb(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /*FEATURE_WLAN_SCAN_PNO */
|
||||
|
||||
/**
|
||||
* wlan_scan_request_enqueue() - enqueue Scan Request
|
||||
* @pdev: pointer to pdev object
|
||||
|
|
@ -352,6 +697,8 @@ QDF_STATUS wlan_cfg80211_scan_priv_init(struct wlan_objmgr_pdev *pdev)
|
|||
wlan_pdev_obj_lock(pdev);
|
||||
psoc = wlan_pdev_get_psoc(pdev);
|
||||
wlan_pdev_obj_unlock(pdev);
|
||||
|
||||
wlan_cfg80211_register_pno_cb(psoc);
|
||||
req_id = ucfg_scan_register_requester(psoc, "HDD",
|
||||
wlan_cfg80211_scan_done_callback, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -417,131 +417,6 @@ bool pmo_core_get_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx)
|
|||
return value;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
/**
|
||||
* pmo_core_is_nlo_scan_in_progress(): check if nlo scan is in progress
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* Return: TRUE/FALSE
|
||||
*/
|
||||
static inline
|
||||
bool pmo_core_is_nlo_scan_in_progress(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
bool nlo_in_progress;
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_get_vdev_priv_ctx(vdev);
|
||||
if (!vdev_ctx)
|
||||
return false;
|
||||
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
nlo_in_progress = vdev_ctx->nlo_in_progress;
|
||||
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
|
||||
return nlo_in_progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* pmo_core_is_nlo_scan_match_found(): check if a nlo scan match was found
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* Return: TRUE/FALSE
|
||||
*/
|
||||
static inline
|
||||
bool pmo_core_is_nlo_scan_match_found(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
bool nlo_match_received;
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_get_vdev_priv_ctx(vdev);
|
||||
if (!vdev_ctx)
|
||||
return false;
|
||||
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
nlo_match_received = vdev_ctx->nlo_match_received;
|
||||
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
|
||||
return nlo_match_received;
|
||||
}
|
||||
|
||||
/**
|
||||
* pmo_core_update_nlo_scan_in_progress(): update nlo scan is in progress flags
|
||||
* @vdev: objmgr vdev handle
|
||||
* @value:true if pno scan is in progress else false
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void pmo_core_update_nlo_scan_in_progress(struct wlan_objmgr_vdev *vdev,
|
||||
bool value)
|
||||
{
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_get_vdev_priv_ctx(vdev);
|
||||
if (!vdev_ctx)
|
||||
return;
|
||||
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
vdev_ctx->nlo_in_progress = value;
|
||||
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* pmo_core_update_nlo_match_found(): Update nlo scan match flag to value
|
||||
* @vdev: objmgr vdev handle
|
||||
* @value:true if nlo scan match event received else false
|
||||
*
|
||||
* Return: TRUE/FALSE
|
||||
*/
|
||||
static inline
|
||||
void pmo_core_update_nlo_match_found(struct wlan_objmgr_vdev *vdev,
|
||||
bool value)
|
||||
{
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_get_vdev_priv_ctx(vdev);
|
||||
if (!vdev_ctx)
|
||||
return;
|
||||
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
vdev_ctx->nlo_match_received = value;
|
||||
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* pmo_is_nlo_scan_in_progress(): dummy
|
||||
*
|
||||
* Return: False since no pnoscan cannot be in progress
|
||||
* when feature flag is not defined.
|
||||
*/
|
||||
static inline
|
||||
bool pmo_core_is_nlo_scan_in_progress(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* wma_is_pnoscan_match_found(): dummy
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* Return: False since no pnoscan cannot occur
|
||||
* when feature flag is not defined.
|
||||
*/
|
||||
static inline
|
||||
bool pmo_core_is_nlo_scan_match_found(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
void pmo_core_update_nlo_scan_in_progress(struct wlan_objmgr_vdev *vdev,
|
||||
bool value)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void pmo_core_update_nlo_match_found(struct wlan_objmgr_vdev *vdev,
|
||||
bool value)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_WLAN_EXTSCAN
|
||||
/**
|
||||
* pmo_core_is_extscan_in_progress(): check if a extscan is in progress
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "cdp_txrx_flow_ctrl_legacy.h"
|
||||
#include "htc_api.h"
|
||||
#include "wlan_pmo_obj_mgmt_api.h"
|
||||
#include <wlan_scan_ucfg_api.h>
|
||||
|
||||
|
||||
/**
|
||||
* pmo_core_calculate_listen_interval() - Calculate vdev listen interval
|
||||
|
|
@ -231,8 +233,8 @@ void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc)
|
|||
|
||||
enable_mask = 0;
|
||||
disable_mask = 0;
|
||||
if (pmo_core_is_nlo_scan_in_progress(vdev)) {
|
||||
if (pmo_core_is_nlo_scan_match_found(vdev))
|
||||
if (ucfg_scan_get_pno_in_progress(vdev)) {
|
||||
if (ucfg_scan_get_pno_match(vdev))
|
||||
enable_mask |=
|
||||
(1 << WOW_NLO_SCAN_COMPLETE_EVENT);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include "wlan_pmo_tgt_api.h"
|
||||
#include "wlan_pmo_main.h"
|
||||
#include "wlan_pmo_obj_mgmt_public_struct.h"
|
||||
#include <wlan_scan_ucfg_api.h>
|
||||
|
||||
|
||||
static inline int pmo_find_wow_ptrn_len(const char *ptrn)
|
||||
{
|
||||
|
|
@ -213,7 +215,7 @@ bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc)
|
|||
pmo_debug("STA is connected, enabling wow");
|
||||
is_wow_applicable = true;
|
||||
break;
|
||||
} else if (pmo_core_is_nlo_scan_in_progress(vdev)) {
|
||||
} else if (ucfg_scan_get_pno_in_progress(vdev)) {
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID);
|
||||
pmo_debug("NLO is in progress, enabling wow");
|
||||
is_wow_applicable = true;
|
||||
|
|
|
|||
|
|
@ -288,26 +288,6 @@ QDF_STATUS pmo_ucfg_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
|
|||
QDF_STATUS pmo_ucfg_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
|
||||
struct pmo_gtk_rsp_req *gtk_rsp_req);
|
||||
|
||||
/**
|
||||
* pmo_ucfg_update_nlo_scan_in_progress(): update nlo scan is in progress flags
|
||||
* @vdev: objmgr vdev handle
|
||||
* @value:true if pno scan is in progress else false
|
||||
*
|
||||
* Return: TRUE/FALSE
|
||||
*/
|
||||
void pmo_ucfg_update_nlo_scan_in_progress(struct wlan_objmgr_vdev *vdev,
|
||||
bool value);
|
||||
|
||||
/**
|
||||
* pmo_ucfg_update_nlo_match_found(): Update nlo scan match flag to value
|
||||
* @vdev: objmgr vdev handle
|
||||
* @value:true if nlo scan match event received else false
|
||||
*
|
||||
* Return: TRUE/FALSE
|
||||
*/
|
||||
void pmo_ucfg_update_nlo_match_found(struct wlan_objmgr_vdev *vdev,
|
||||
bool value);
|
||||
|
||||
/**
|
||||
* pmo_ucfg_update_extscan_in_progress(): update extscan is in progress flags
|
||||
* @vdev: objmgr vdev handle
|
||||
|
|
|
|||
|
|
@ -175,18 +175,6 @@ QDF_STATUS pmo_ucfg_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
|
|||
return pmo_core_get_gtk_rsp(vdev, gtk_rsp_req);
|
||||
}
|
||||
|
||||
void pmo_ucfg_update_nlo_scan_in_progress(struct wlan_objmgr_vdev *vdev,
|
||||
bool value)
|
||||
{
|
||||
pmo_core_update_nlo_scan_in_progress(vdev, value);
|
||||
}
|
||||
|
||||
void pmo_ucfg_update_nlo_match_found(struct wlan_objmgr_vdev *vdev,
|
||||
bool value)
|
||||
{
|
||||
pmo_core_update_nlo_match_found(vdev, value);
|
||||
}
|
||||
|
||||
void pmo_ucfg_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
|
||||
bool value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,10 +22,42 @@
|
|||
#ifndef __TARGET_SCAN_IF_H__
|
||||
#define __TARGET_SCAN_IF_H__
|
||||
|
||||
#include <wmi_unified_api.h>
|
||||
|
||||
struct scan_req_params;
|
||||
struct scan_cancel_param;
|
||||
struct wlan_objmgr_psoc;
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
/**
|
||||
* target_if_nlo_match_event_handler() - nlo match event handler
|
||||
* @scn: scn handle
|
||||
* @event: event data
|
||||
* @len: data length
|
||||
*
|
||||
* Record NLO match event comes from FW. It's a indication that
|
||||
* one of the profile is matched.
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
int target_if_nlo_match_event_handler(ol_scn_t scn, uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
/**
|
||||
* target_if_nlo_complete_handler() - nlo complete event handler
|
||||
* @scn: scn handle
|
||||
* @event: event data
|
||||
* @len: data length
|
||||
*
|
||||
* Record NLO match event comes from FW. It's a indication that
|
||||
* one of the profile is matched.
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
int target_if_nlo_complete_handler(ol_scn_t scn, uint8_t *data,
|
||||
uint32_t len);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* target_if_scan_register_event_handler() - lmac handler API
|
||||
* to register for scan events
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@
|
|||
|
||||
#include <qdf_mem.h>
|
||||
#include <qdf_status.h>
|
||||
#include <wmi_unified_api.h>
|
||||
#include <target_if_scan.h>
|
||||
#include <wmi_unified_priv.h>
|
||||
#include <wmi_unified_param.h>
|
||||
#include <wlan_objmgr_psoc_obj.h>
|
||||
#include <wlan_scan_tgt_api.h>
|
||||
#include <target_if.h>
|
||||
#include <target_if_scan.h>
|
||||
|
||||
|
||||
static inline struct wlan_lmac_if_scan_rx_ops *
|
||||
target_if_scan_get_rx_ops(struct wlan_objmgr_psoc *psoc)
|
||||
|
|
@ -82,19 +82,229 @@ target_if_scan_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
|
||||
int target_if_nlo_complete_handler(ol_scn_t scn, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
wmi_nlo_event *nlo_event;
|
||||
struct scan_event_info *event_info;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_lmac_if_scan_rx_ops *scan_rx_ops;
|
||||
WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf =
|
||||
(WMI_NLO_MATCH_EVENTID_param_tlvs *) data;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!scn || !data) {
|
||||
target_if_err("scn: 0x%p, data: 0x%p", scn, data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
psoc = target_if_get_psoc_from_scn_hdl(scn);
|
||||
if (!psoc) {
|
||||
target_if_err("null psoc");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
event_info = qdf_mem_malloc(sizeof(*event_info));
|
||||
if (!event_info) {
|
||||
target_if_err("unable to allocate scan_event");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nlo_event = param_buf->fixed_param;
|
||||
target_if_info("PNO complete event received for vdev %d",
|
||||
nlo_event->vdev_id);
|
||||
|
||||
event_info->event.type = SCAN_EVENT_TYPE_NLO_COMPLETE;
|
||||
event_info->event.vdev_id = nlo_event->vdev_id;
|
||||
|
||||
scan_rx_ops = target_if_scan_get_rx_ops(psoc);
|
||||
if (scan_rx_ops->scan_ev_handler) {
|
||||
status = scan_rx_ops->scan_ev_handler(psoc, event_info);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
qdf_mem_free(event_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_if_nlo_match_event_handler(ol_scn_t scn, uint8_t *data,
|
||||
uint32_t len)
|
||||
{
|
||||
wmi_nlo_event *nlo_event;
|
||||
struct scan_event_info *event_info;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_lmac_if_scan_rx_ops *scan_rx_ops;
|
||||
WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf =
|
||||
(WMI_NLO_MATCH_EVENTID_param_tlvs *) data;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!scn || !data) {
|
||||
target_if_err("scn: 0x%p, data: 0x%p", scn, data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
psoc = target_if_get_psoc_from_scn_hdl(scn);
|
||||
if (!psoc) {
|
||||
target_if_err("null psoc");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
event_info = qdf_mem_malloc(sizeof(*event_info));
|
||||
if (!event_info) {
|
||||
target_if_err("unable to allocate scan_event");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nlo_event = param_buf->fixed_param;
|
||||
target_if_info("PNO match event received for vdev %d",
|
||||
nlo_event->vdev_id);
|
||||
|
||||
event_info->event.type = SCAN_EVENT_TYPE_NLO_MATCH;
|
||||
event_info->event.vdev_id = nlo_event->vdev_id;
|
||||
|
||||
scan_rx_ops = target_if_scan_get_rx_ops(psoc);
|
||||
if (scan_rx_ops->scan_ev_handler) {
|
||||
status = scan_rx_ops->scan_ev_handler(psoc, event_info);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
qdf_mem_free(event_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_scan_register_pno_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
status = wmi_unified_register_event(psoc->tgt_if_handle,
|
||||
wmi_nlo_match_event_id,
|
||||
target_if_nlo_match_event_handler);
|
||||
if (status) {
|
||||
target_if_err("Failed to register nlo match event cb");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
status = wmi_unified_register_event(psoc->tgt_if_handle,
|
||||
wmi_nlo_scan_complete_event_id,
|
||||
target_if_nlo_complete_handler);
|
||||
if (status) {
|
||||
target_if_err("Failed to register nlo scan comp event cb");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_scan_unregister_pno_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
status = wmi_unified_unregister_event(psoc->tgt_if_handle,
|
||||
wmi_nlo_match_event_id);
|
||||
if (status) {
|
||||
target_if_err("Failed to unregister nlo match event cb");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
status = wmi_unified_unregister_event(psoc->tgt_if_handle,
|
||||
wmi_nlo_scan_complete_event_id);
|
||||
if (status) {
|
||||
target_if_err("Failed to unregister nlo scan comp event cb");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_pno_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct pno_scan_req_params *req)
|
||||
{
|
||||
return wmi_unified_pno_start_cmd(psoc->tgt_if_handle, req);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_pno_stop(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
return wmi_unified_pno_stop_cmd(psoc->tgt_if_handle, vdev_id);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline QDF_STATUS
|
||||
target_if_scan_register_pno_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
target_if_scan_unregister_pno_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
target_if_pno_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct pno_scan_req_params *req)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
target_if_pno_stop(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
QDF_STATUS
|
||||
target_if_scan_register_event_handler(struct wlan_objmgr_psoc *psoc, void *arg)
|
||||
{
|
||||
return wmi_unified_register_event(psoc->tgt_if_handle,
|
||||
QDF_STATUS status;
|
||||
|
||||
status = wmi_unified_register_event(psoc->tgt_if_handle,
|
||||
wmi_scan_event_id, target_if_scan_event_handler);
|
||||
if (status) {
|
||||
target_if_err("Failed to register Scan match event cb");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
status = target_if_scan_register_pno_event_handler(psoc, arg);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
target_if_scan_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg)
|
||||
{
|
||||
return wmi_unified_unregister_event(psoc->tgt_if_handle,
|
||||
QDF_STATUS status;
|
||||
|
||||
status = wmi_unified_unregister_event(psoc->tgt_if_handle,
|
||||
wmi_scan_event_id);
|
||||
if (status) {
|
||||
target_if_err("Failed to unregister Scan match event cb");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
status = target_if_scan_unregister_pno_event_handler(psoc, arg);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
|
|
@ -117,6 +327,8 @@ target_if_register_scan_tx_ops(struct wlan_lmac_if_scan_tx_ops *scan)
|
|||
{
|
||||
scan->scan_start = target_if_scan_start;
|
||||
scan->scan_cancel = target_if_scan_cancel;
|
||||
scan->pno_start = target_if_pno_start;
|
||||
scan->pno_stop = target_if_pno_stop;
|
||||
scan->scan_reg_ev_handler = target_if_scan_register_event_handler;
|
||||
scan->scan_unreg_ev_handler = target_if_scan_unregister_event_handler;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ struct wlan_lmac_if_mgmt_txrx_tx_ops {
|
|||
* struct wlan_lmac_if_scan_tx_ops - south bound tx function pointers for scan
|
||||
* @scan_start: function to start scan
|
||||
* @scan_cancel: function to cancel scan
|
||||
* @pno_start: start pno scan
|
||||
* @pno_stop: stop pno scan
|
||||
* @scan_reg_ev_handler: function to register for scan events
|
||||
* @scan_unreg_ev_handler: function to unregister for scan events
|
||||
*
|
||||
|
|
@ -74,6 +76,10 @@ struct wlan_lmac_if_scan_tx_ops {
|
|||
struct scan_start_request *req);
|
||||
QDF_STATUS (*scan_cancel)(struct wlan_objmgr_psoc *psoc,
|
||||
struct scan_cancel_param *req);
|
||||
QDF_STATUS (*pno_start)(struct wlan_objmgr_psoc *psoc,
|
||||
struct pno_scan_req_params *req);
|
||||
QDF_STATUS (*pno_stop)(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id);
|
||||
QDF_STATUS (*scan_reg_ev_handler)(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg);
|
||||
QDF_STATUS (*scan_unreg_ev_handler)(struct wlan_objmgr_psoc *psoc,
|
||||
|
|
|
|||
|
|
@ -70,3 +70,53 @@ QDF_STATUS wlan_scan_psoc_destroyed_notification(
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_scan_vdev_created_notification(struct wlan_objmgr_vdev *vdev,
|
||||
void *arg_list)
|
||||
{
|
||||
struct scan_vdev_obj *scan_vdev_obj;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
scan_vdev_obj = qdf_mem_malloc(sizeof(struct scan_vdev_obj));
|
||||
if (scan_vdev_obj == NULL) {
|
||||
scm_err("Failed to allocate memory");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
/* Attach scan private date to psoc */
|
||||
status = wlan_objmgr_vdev_component_obj_attach(vdev,
|
||||
WLAN_UMAC_COMP_SCAN, (void *)scan_vdev_obj,
|
||||
QDF_STATUS_SUCCESS);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
scm_err("Failed to attach vdev scan component");
|
||||
qdf_mem_free(scan_vdev_obj);
|
||||
} else {
|
||||
scm_info("vdev scan object attach successful");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_scan_vdev_destroyed_notification(
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
void *arg_list)
|
||||
{
|
||||
void *scan_vdev_obj = NULL;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
scan_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_SCAN);
|
||||
if (!scan_vdev_obj) {
|
||||
scm_err("Failed to detach scan in vdev ctx");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
status = wlan_objmgr_vdev_component_obj_detach(vdev,
|
||||
WLAN_UMAC_COMP_SCAN, scan_vdev_obj);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
scm_err("Failed to detach vdev scan component");
|
||||
|
||||
qdf_mem_free(scan_vdev_obj);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,6 +147,39 @@ struct pdev_scan_info {
|
|||
qdf_time_t last_scan_time;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct scan_vdev_obj - scan vdev obj
|
||||
* @pno_match_evt_received: pno match received
|
||||
* @pno_in_progress: pno in progress
|
||||
*/
|
||||
struct scan_vdev_obj {
|
||||
bool pno_match_evt_received;
|
||||
bool pno_in_progress;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pno_def_config - def configuration for PNO
|
||||
* @channel_prediction: config PNO channel prediction feature status
|
||||
* @top_k_num_of_channels: def top K number of channels are used for tanimoto
|
||||
* distance calculation.
|
||||
* @stationary_thresh: def threshold val to determine that STA is stationary.
|
||||
* @pnoscan_adaptive_dwell_mode: def adaptive dwelltime mode for pno scan
|
||||
* @channel_prediction_full_scan: def periodic timer upon which full scan needs
|
||||
* to be triggered.
|
||||
* @pno_wake_lock: pno wake lock
|
||||
* @pno_cb: callback to call on PNO completion
|
||||
*/
|
||||
struct pno_def_config {
|
||||
bool channel_prediction;
|
||||
uint8_t top_k_num_of_channels;
|
||||
uint8_t stationary_thresh;
|
||||
enum scan_dwelltime_adaptive_mode adaptive_dwell_mode;
|
||||
uint32_t channel_prediction_full_scan;
|
||||
qdf_wake_lock_t pno_wake_lock;
|
||||
struct cb_handler pno_cb;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct scan_default_params - default scan parameters to be used
|
||||
* @active_dwell: default active dwell time
|
||||
|
|
@ -310,6 +343,7 @@ struct wlan_scan_obj {
|
|||
struct scan_requester_info requesters[WLAN_MAX_REQUESTORS];
|
||||
struct global_scan_ev_handlers global_evhandlers;
|
||||
struct pdev_scan_info pdev_info[WLAN_UMAC_MAX_PDEVS];
|
||||
struct pno_def_config pno_cfg;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -354,6 +388,20 @@ wlan_vdev_get_scan_obj(struct wlan_objmgr_vdev *vdev)
|
|||
return wlan_pdev_get_scan_obj(pdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_get_vdev_scan_obj() - private API to get scan object vdev
|
||||
* @vdev: vdev object
|
||||
*
|
||||
* Return: scan object
|
||||
*/
|
||||
static inline struct scan_vdev_obj *
|
||||
wlan_get_vdev_scan_obj(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return (struct scan_vdev_obj *)
|
||||
wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_SCAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_scan_vdev_get_pdev_id)() - private API to get pdev id from vdev object
|
||||
* @vdev: vdev object
|
||||
|
|
@ -434,4 +482,25 @@ QDF_STATUS wlan_scan_psoc_created_notification(struct wlan_objmgr_psoc *psoc,
|
|||
*/
|
||||
QDF_STATUS wlan_scan_psoc_destroyed_notification(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg_list);
|
||||
|
||||
/**
|
||||
* wlan_scan_vdev_created_notification() - scan psoc create handler
|
||||
* @vdev: vdev object
|
||||
* @arg_list: Argument list
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_scan_vdev_created_notification(struct wlan_objmgr_vdev *vdev,
|
||||
void *arg_list);
|
||||
|
||||
/**
|
||||
* wlan_scan_vdev_destroyed_notification() - scan psoc delete handler
|
||||
* @vdev: vdev object
|
||||
* @arg_list: Argument list
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_scan_vdev_destroyed_notification(struct wlan_objmgr_vdev *vdev,
|
||||
void *arg_list);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@
|
|||
#include "wlan_scan_main.h"
|
||||
#include "wlan_scan_manager.h"
|
||||
#include "wlan_utility.h"
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
#include <host_diag_core_event.h>
|
||||
#endif
|
||||
|
||||
static QDF_STATUS
|
||||
scm_free_scan_request_mem(struct scan_start_request *req)
|
||||
|
|
@ -485,6 +488,64 @@ scm_scan_cancel_req(struct scheduler_msg *msg)
|
|||
return status;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
static QDF_STATUS
|
||||
scm_pno_event_handler(struct wlan_objmgr_vdev *vdev,
|
||||
struct scan_event *event)
|
||||
{
|
||||
struct scan_vdev_obj *scan_vdev_obj;
|
||||
struct wlan_scan_obj *scan_psoc_obj;
|
||||
scan_event_handler pno_cb;
|
||||
void *cb_arg;
|
||||
|
||||
scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
|
||||
scan_psoc_obj = wlan_vdev_get_scan_obj(vdev);
|
||||
if (!scan_vdev_obj || !scan_psoc_obj) {
|
||||
scm_err("null scan_vdev_obj %p scan_obj %p",
|
||||
scan_vdev_obj, scan_psoc_obj);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
case SCAN_EVENT_TYPE_NLO_COMPLETE:
|
||||
if (!scan_vdev_obj->pno_match_evt_received)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock,
|
||||
WIFI_POWER_EVENT_WAKELOCK_PNO);
|
||||
qdf_wake_lock_timeout_acquire(
|
||||
&scan_psoc_obj->pno_cfg.pno_wake_lock,
|
||||
SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT);
|
||||
scan_vdev_obj->pno_match_evt_received = false;
|
||||
break;
|
||||
case SCAN_EVENT_TYPE_NLO_MATCH:
|
||||
scan_vdev_obj->pno_match_evt_received = true;
|
||||
qdf_wake_lock_timeout_acquire(
|
||||
&scan_psoc_obj->pno_cfg.pno_wake_lock,
|
||||
SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
default:
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
qdf_spin_lock_bh(&scan_psoc_obj->lock);
|
||||
pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func;
|
||||
cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg;
|
||||
qdf_spin_unlock_bh(&scan_psoc_obj->lock);
|
||||
|
||||
if (pno_cb)
|
||||
pno_cb(vdev, event, cb_arg);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
|
||||
static QDF_STATUS
|
||||
scm_pno_event_handler(struct wlan_objmgr_vdev *vdev,
|
||||
struct scan_event *event)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS
|
||||
scm_scan_event_handler(struct scheduler_msg *msg)
|
||||
{
|
||||
|
|
@ -510,12 +571,17 @@ scm_scan_event_handler(struct scheduler_msg *msg)
|
|||
case SCAN_EVENT_TYPE_DEQUEUED:
|
||||
scm_release_serialization_command(vdev, event->scan_id);
|
||||
break;
|
||||
case SCAN_EVENT_TYPE_NLO_COMPLETE:
|
||||
case SCAN_EVENT_TYPE_NLO_MATCH:
|
||||
scm_pno_event_handler(vdev, event);
|
||||
goto exit;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Notify all interested parties */
|
||||
scm_scan_post_event(vdev, event);
|
||||
exit:
|
||||
/* free event info memory */
|
||||
qdf_mem_free(event_info);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
|
||||
|
|
|
|||
|
|
@ -692,6 +692,7 @@ struct mlme_update_info {
|
|||
* @SCAN_EVENT_TYPE_SUSPENDED: scan got suspended
|
||||
* @SCAN_EVENT_TYPE_RESUMED: scan resumed
|
||||
* @SCAN_EVENT_TYPE_NLO_COMPLETE: NLO completed
|
||||
* @SCAN_EVENT_TYPE_NLO_MATCH: NLO match event
|
||||
* @SCAN_EVENT_TYPE_INVALID: invalid request
|
||||
* @SCAN_EVENT_TYPE_GPIO_TIMEOUT: gpio timeout
|
||||
* @SCAN_EVENT_TYPE_RADIO_MEASUREMENT_START: radio measurement start
|
||||
|
|
@ -713,6 +714,7 @@ enum scan_event_type {
|
|||
SCAN_EVENT_TYPE_SUSPENDED,
|
||||
SCAN_EVENT_TYPE_RESUMED,
|
||||
SCAN_EVENT_TYPE_NLO_COMPLETE,
|
||||
SCAN_EVENT_TYPE_NLO_MATCH,
|
||||
SCAN_EVENT_TYPE_INVALID,
|
||||
SCAN_EVENT_TYPE_GPIO_TIMEOUT,
|
||||
SCAN_EVENT_TYPE_RADIO_MEASUREMENT_START,
|
||||
|
|
@ -819,10 +821,110 @@ enum scan_cb_type {
|
|||
SCAN_CB_TYPE_UPDATE_BCN,
|
||||
};
|
||||
|
||||
/* Set PNO */
|
||||
#define SCAN_PNO_MAX_PLAN_REQUEST 2
|
||||
#define SCAN_PNO_MAX_NETW_CHANNELS_EX 60
|
||||
#define SCAN_PNO_MAX_SUPP_NETWORKS 16
|
||||
#define SCAN_PNO_DEF_SLOW_SCAN_MULTIPLIER 6
|
||||
#define SCAN_PNO_DEF_SCAN_TIMER_REPEAT 20
|
||||
#define SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT (5 * 1000) /* in msec */
|
||||
#ifdef CONFIG_SLUB_DEBUG_ON
|
||||
#define SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT (2 * 1000) /* in msec */
|
||||
#else
|
||||
#define SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT (1 * 1000) /* in msec */
|
||||
#endif /* CONFIG_SLUB_DEBUG_ON */
|
||||
|
||||
#define SCAN_PNO_CHANNEL_PREDICTION 0
|
||||
#define SCAN_TOP_K_NUM_OF_CHANNELS 3
|
||||
#define SCAN_STATIONARY_THRESHOLD 10
|
||||
#define SCAN_CHANNEL_PREDICTION_FULL_SCAN_MS 60000
|
||||
#define SCAN_ADAPTIVE_PNOSCAN_DWELL_MODE 0
|
||||
|
||||
/**
|
||||
* struct pno_scan_req_params - forward declaration
|
||||
* enum ssid_bc_type - SSID broadcast type
|
||||
* @SSID_BC_TYPE_UNKNOWN: Broadcast unknown
|
||||
* @SSID_BC_TYPE_NORMAL: Broadcast normal
|
||||
* @SSID_BC_TYPE_HIDDEN: Broadcast hidden
|
||||
*/
|
||||
struct pno_scan_req_params;
|
||||
enum ssid_bc_type {
|
||||
SSID_BC_TYPE_UNKNOWN = 0,
|
||||
SSID_BC_TYPE_NORMAL = 1,
|
||||
SSID_BC_TYPE_HIDDEN = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pno_nw_type - pno nw type
|
||||
* @ssid: ssid
|
||||
* @authentication: authentication type
|
||||
* @encryption: encryption type
|
||||
* @bcastNetwType: broadcast nw type
|
||||
* @ucChannelCount: uc channel count
|
||||
* @aChannels: pno channel
|
||||
* @rssiThreshold: rssi threshold
|
||||
*/
|
||||
struct pno_nw_type {
|
||||
struct wlan_ssid ssid;
|
||||
uint32_t authentication;
|
||||
uint32_t encryption;
|
||||
uint32_t bc_new_type;
|
||||
uint8_t channel_cnt;
|
||||
uint32_t channels[SCAN_PNO_MAX_NETW_CHANNELS_EX];
|
||||
int32_t rssi_thresh;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pno_scan_req_params - PNO Scan request structure
|
||||
* @networks_cnt: Number of networks
|
||||
* @vdev_id: vdev id
|
||||
* @fast_scan_period: Fast Scan period
|
||||
* @slow_scan_period: Slow scan period
|
||||
* @delay_start_time: delay in seconds to use before starting the first scan
|
||||
* @fast_scan_max_cycles: Fast scan max cycles
|
||||
* @pno_channel_prediction: PNO channel prediction feature status
|
||||
* @uint32_t active_dwell_time: active dwell time
|
||||
* @uint32_t passive_dwell_time: passive dwell time
|
||||
* @top_k_num_of_channels: top K number of channels are used for tanimoto
|
||||
* distance calculation.
|
||||
* @stationary_thresh: threshold value to determine that the STA is stationary.
|
||||
* @adaptive_dwell_mode: adaptive dwelltime mode for pno scan
|
||||
* @channel_prediction_full_scan: periodic timer upon which a full scan needs
|
||||
* to be triggered.
|
||||
* @networks_list: Preferred network list
|
||||
*/
|
||||
struct pno_scan_req_params {
|
||||
uint32_t networks_cnt;
|
||||
uint32_t vdev_id;
|
||||
uint32_t fast_scan_period;
|
||||
uint32_t slow_scan_period;
|
||||
uint32_t delay_start_time;
|
||||
uint32_t fast_scan_max_cycles;
|
||||
uint32_t active_dwell_time;
|
||||
uint32_t passive_dwell_time;
|
||||
uint32_t pno_channel_prediction;
|
||||
uint32_t top_k_num_of_channels;
|
||||
uint32_t stationary_thresh;
|
||||
enum scan_dwelltime_adaptive_mode adaptive_dwell_mode;
|
||||
uint32_t channel_prediction_full_scan;
|
||||
struct pno_nw_type networks_list[SCAN_PNO_MAX_SUPP_NETWORKS];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pno_user_cfg - user configuration required for PNO
|
||||
* @channel_prediction: config PNO channel prediction feature status
|
||||
* @top_k_num_of_channels: def top K number of channels are used for tanimoto
|
||||
* distance calculation.
|
||||
* @stationary_thresh: def threshold val to determine that STA is stationary.
|
||||
* @pnoscan_adaptive_dwell_mode: def adaptive dwelltime mode for pno scan
|
||||
* @channel_prediction_full_scan: def periodic timer upon which full scan needs
|
||||
* to be triggered.
|
||||
*/
|
||||
struct pno_user_cfg {
|
||||
bool channel_prediction;
|
||||
uint8_t top_k_num_of_channels;
|
||||
uint8_t stationary_thresh;
|
||||
enum scan_dwelltime_adaptive_mode adaptive_dwell_mode;
|
||||
uint32_t channel_prediction_full_scan;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct scan_user_cfg - user configuration required for for scan
|
||||
|
|
@ -835,6 +937,7 @@ struct pno_scan_req_params;
|
|||
* @conc_idle_time: default concurrent idle time
|
||||
* @scan_cache_aging_time: default scan cache aging time
|
||||
* @scan_dwell_time_mode: Adaptive dweltime mode
|
||||
* @pno_cfg: Pno related config params
|
||||
*/
|
||||
struct scan_user_cfg {
|
||||
uint32_t active_dwell;
|
||||
|
|
@ -846,6 +949,7 @@ struct scan_user_cfg {
|
|||
uint32_t conc_idle_time;
|
||||
uint32_t scan_cache_aging_time;
|
||||
enum scan_dwelltime_adaptive_mode scan_dwell_time_mode;
|
||||
struct pno_user_cfg pno_cfg;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -48,37 +48,6 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc,
|
|||
struct mgmt_rx_event_params *rx_param,
|
||||
enum mgmt_frame_type frm_type);
|
||||
|
||||
/**
|
||||
* tgt_scan_nlo_complete_evt_handler() - The callbeack registered
|
||||
* to WMI for PNO complete
|
||||
* @handle: psoc handle
|
||||
* @event: event handler
|
||||
* @len: length of data
|
||||
*
|
||||
* This function handles NLO scan completion event.
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
|
||||
QDF_STATUS
|
||||
tgt_scan_nlo_complete_evt_handler(void *handle, uint8_t *event,
|
||||
uint32_t len);
|
||||
|
||||
/**
|
||||
* tgt_nlo_match_evt_handler() - nlo match event handler
|
||||
* @handle: psoc handle
|
||||
* @event: event data
|
||||
* @len: data length
|
||||
*
|
||||
* Record NLO match event comes from FW. It's a indication that
|
||||
* one of the profile is matched.
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
QDF_STATUS
|
||||
tgt_nlo_match_evt_handler(void *handle, uint8_t *event,
|
||||
uint32_t len);
|
||||
|
||||
/**
|
||||
* tgt_scan_event_handler() - The callbeack registered to WMI for scan events
|
||||
* @psoc: psoc handle
|
||||
|
|
@ -93,6 +62,30 @@ QDF_STATUS
|
|||
tgt_scan_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
struct scan_event_info *event_info);
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
|
||||
/**
|
||||
* tgt_scan_pno_start() - invoke lmac send PNO start req
|
||||
* @vdev: vdev pointer
|
||||
* @req: pno req params
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
QDF_STATUS tgt_scan_pno_start(struct wlan_objmgr_vdev *vdev,
|
||||
struct pno_scan_req_params *req);
|
||||
|
||||
/**
|
||||
* tgt_scan_pno_stop() - invoke lmac send PNO stop req
|
||||
* @vdev: vdev pointer
|
||||
* @vdev_id: pno req params
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
QDF_STATUS tgt_scan_pno_stop(struct wlan_objmgr_vdev *vdev,
|
||||
uint8_t vdev_id);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* tgt_scan_start() - invoke lmac scan start
|
||||
* @req: scan request object
|
||||
|
|
|
|||
|
|
@ -88,7 +88,79 @@ uint8_t *ucfg_get_scan_requester_name(struct wlan_objmgr_psoc *psoc,
|
|||
wlan_scan_id
|
||||
ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
/**
|
||||
* ucfg_scan_pno_start() - Public API to start PNO
|
||||
* @vdev: vdev pointer
|
||||
* @req: pno req params
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
|
||||
struct pno_scan_req_params *req);
|
||||
|
||||
/**
|
||||
* ucfg_scan_pno_stop() - Public API to stop PNO
|
||||
* @vdev: vdev pointer
|
||||
* @req: pno req params
|
||||
*
|
||||
* Return: 0 for success or error code.
|
||||
*/
|
||||
QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_scan_get_pno_in_progress() - Public API to check if pno is in progress
|
||||
* @vdev: vdev pointer
|
||||
*
|
||||
* Return: true if pno in progress else false.
|
||||
*/
|
||||
bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_scan_get_pno_match() - Public API to check if pno matched
|
||||
* @vdev: vdev pointer
|
||||
*
|
||||
* Return: true if pno matched else false.
|
||||
*/
|
||||
bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_scan_register_pno_cb() - register pno cb
|
||||
* @psoc: psoc object
|
||||
* @event_cb: callback function pointer
|
||||
* @arg: argument to @event_cb
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
|
||||
scan_event_handler event_cb, void *arg);
|
||||
|
||||
/**
|
||||
* ucfg_scan_get_pno_def_params() - get the defaults pno params
|
||||
* @vdev: vdev object
|
||||
* @req: pno request object
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS or error code
|
||||
*/
|
||||
QDF_STATUS
|
||||
ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
|
||||
struct pno_scan_req_params *req);
|
||||
|
||||
#else
|
||||
|
||||
static inline bool
|
||||
ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* FEATURE_WLAN_SCAN_PNO */
|
||||
/**
|
||||
* ucfg_scan_start() - Public API to start a scan
|
||||
* @req: start scan req params
|
||||
|
|
|
|||
|
|
@ -59,28 +59,39 @@ wlan_vdev_get_scan_rxops(struct wlan_objmgr_vdev *vdev)
|
|||
return &((psoc->soc_cb.rx_ops.scan));
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
tgt_scan_nlo_complete_evt_handler(void *handle, uint8_t *event,
|
||||
uint32_t len)
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
|
||||
QDF_STATUS tgt_scan_pno_start(struct wlan_objmgr_vdev *vdev,
|
||||
struct pno_scan_req_params *req)
|
||||
{
|
||||
/*
|
||||
* Convert the tlv/non tlv data to struct scan_event
|
||||
* (SCM_EVENT_NLO_COMPLETE) (same as WIN does by calling a win API) and
|
||||
* Post msg to target_if queue
|
||||
*/
|
||||
struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
|
||||
|
||||
scan_ops = wlan_vdev_get_scan_txops(vdev);
|
||||
/* invoke wmi_unified_pno_start_cmd() */
|
||||
QDF_ASSERT(scan_ops->pno_start);
|
||||
if (scan_ops->pno_start)
|
||||
return scan_ops->pno_start(psoc, req);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
tgt_nlo_match_evt_handler(void *handle, uint8_t *event,
|
||||
uint32_t len)
|
||||
QDF_STATUS tgt_scan_pno_stop(struct wlan_objmgr_vdev *vdev,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
/*
|
||||
* Convert the tlv/non tlv data to comman data
|
||||
* and set the pno match received flag in vdev scan info
|
||||
*/
|
||||
struct wlan_lmac_if_scan_tx_ops *scan_ops = NULL;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
|
||||
|
||||
scan_ops = wlan_vdev_get_scan_txops(vdev);
|
||||
|
||||
/* invoke wmi_unified_pno_stop_cmd() */
|
||||
QDF_ASSERT(scan_ops->pno_stop);
|
||||
if (scan_ops->pno_stop)
|
||||
return scan_ops->pno_stop(psoc, vdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS
|
||||
tgt_scan_start(struct scan_start_request *req)
|
||||
|
|
|
|||
|
|
@ -78,12 +78,33 @@ QDF_STATUS ucfg_scan_init(void)
|
|||
|
||||
status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_psoc_destroyed_notification, NULL);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
scm_err("Failed to create psoc delete handler");
|
||||
goto fail_psoc_destroy;
|
||||
}
|
||||
scm_info("scan psoc create and delete handler registered with objmgr");
|
||||
|
||||
status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_vdev_created_notification, NULL);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
scm_err("Failed to register vdev create handler");
|
||||
goto fail_pdev_create;
|
||||
}
|
||||
|
||||
status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_vdev_destroyed_notification, NULL);
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
scm_info("scan create and delete handler registered with objmgr");
|
||||
scm_info("scan vdev create and delete handler registered with objmgr");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
scm_err("Failed to create psoc delete handler");
|
||||
|
||||
scm_err("Failed to destroy vdev delete handler");
|
||||
wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_vdev_created_notification, NULL);
|
||||
fail_pdev_create:
|
||||
wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_psoc_destroyed_notification, NULL);
|
||||
fail_psoc_destroy:
|
||||
wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_psoc_created_notification, NULL);
|
||||
fail_create_psoc:
|
||||
|
|
@ -105,9 +126,206 @@ QDF_STATUS ucfg_scan_deinit(void)
|
|||
if (status != QDF_STATUS_SUCCESS)
|
||||
scm_err("Failed to unregister psoc delete handler");
|
||||
|
||||
status = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_vdev_created_notification, NULL);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
scm_err("Failed to unregister vdev create handler");
|
||||
|
||||
status = wlan_objmgr_unregister_vdev_destroy_handler(
|
||||
WLAN_UMAC_COMP_SCAN,
|
||||
wlan_scan_vdev_destroyed_notification, NULL);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
scm_err("Failed to unregister vdev delete handler");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
|
||||
QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev,
|
||||
struct pno_scan_req_params *req)
|
||||
{
|
||||
struct scan_vdev_obj *scan_vdev_obj;
|
||||
QDF_STATUS status;
|
||||
|
||||
scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
|
||||
if (!scan_vdev_obj) {
|
||||
scm_err("null scan_vdev_obj");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
if (scan_vdev_obj->pno_in_progress) {
|
||||
scm_err("pno already in progress");
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
|
||||
status = tgt_scan_pno_start(vdev, req);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
scm_err("pno start failed");
|
||||
else
|
||||
scan_vdev_obj->pno_in_progress = true;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct scan_vdev_obj *scan_vdev_obj;
|
||||
QDF_STATUS status;
|
||||
|
||||
scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
|
||||
if (!scan_vdev_obj) {
|
||||
scm_err("null scan_vdev_obj");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
if (!scan_vdev_obj->pno_in_progress) {
|
||||
scm_err("pno already stopped");
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
|
||||
status = tgt_scan_pno_stop(vdev, wlan_vdev_get_id(vdev));
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
scm_err("pno start failed");
|
||||
else
|
||||
scan_vdev_obj->pno_in_progress = false;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool ucfg_scan_get_pno_in_progress(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct scan_vdev_obj *scan_vdev_obj;
|
||||
|
||||
scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
|
||||
if (!scan_vdev_obj) {
|
||||
scm_err("null scan_vdev_obj");
|
||||
return false;
|
||||
}
|
||||
|
||||
return scan_vdev_obj->pno_in_progress;
|
||||
}
|
||||
|
||||
bool ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct scan_vdev_obj *scan_vdev_obj;
|
||||
|
||||
scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
|
||||
if (!scan_vdev_obj) {
|
||||
scm_err("null scan_vdev_obj");
|
||||
return false;
|
||||
}
|
||||
|
||||
return scan_vdev_obj->pno_match_evt_received;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
wlan_pno_global_init(struct pno_def_config *pno_def)
|
||||
{
|
||||
qdf_wake_lock_create(&pno_def->pno_wake_lock, "wlan_pno_wl");
|
||||
pno_def->channel_prediction = SCAN_PNO_CHANNEL_PREDICTION;
|
||||
pno_def->top_k_num_of_channels = SCAN_TOP_K_NUM_OF_CHANNELS;
|
||||
pno_def->stationary_thresh = SCAN_STATIONARY_THRESHOLD;
|
||||
pno_def->channel_prediction_full_scan =
|
||||
SCAN_CHANNEL_PREDICTION_FULL_SCAN_MS;
|
||||
pno_def->adaptive_dwell_mode = SCAN_ADAPTIVE_PNOSCAN_DWELL_MODE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
wlan_pno_global_deinit(struct pno_def_config *pno_def)
|
||||
{
|
||||
qdf_wake_lock_destroy(&pno_def->pno_wake_lock);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_scan_get_pno_def_params(struct wlan_objmgr_vdev *vdev,
|
||||
struct pno_scan_req_params *req)
|
||||
{
|
||||
struct scan_default_params *scan_def;
|
||||
struct wlan_scan_obj *scan = wlan_vdev_get_scan_obj(vdev);
|
||||
struct pno_def_config *pno_def;
|
||||
|
||||
if (!vdev | !req | !scan) {
|
||||
scm_err("vdev: 0x%p, req: 0x%p scan_obj: 0x%p",
|
||||
vdev, req, scan);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
scan_def = wlan_vdev_get_def_scan_params(vdev);
|
||||
pno_def = &scan->pno_cfg;
|
||||
|
||||
req->active_dwell_time = scan_def->active_dwell;
|
||||
req->passive_dwell_time = scan_def->passive_dwell;
|
||||
|
||||
req->adaptive_dwell_mode = pno_def->adaptive_dwell_mode;
|
||||
|
||||
req->pno_channel_prediction = pno_def->adaptive_dwell_mode;
|
||||
req->top_k_num_of_channels = pno_def->top_k_num_of_channels;
|
||||
req->stationary_thresh = pno_def->stationary_thresh;
|
||||
req->channel_prediction_full_scan =
|
||||
pno_def->channel_prediction_full_scan;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS ucfg_scan_update_pno_config(struct pno_def_config *pno,
|
||||
struct pno_user_cfg *pno_cfg)
|
||||
{
|
||||
pno->channel_prediction = pno_cfg->channel_prediction;
|
||||
pno->top_k_num_of_channels = pno_cfg->top_k_num_of_channels;
|
||||
pno->stationary_thresh = pno_cfg->stationary_thresh;
|
||||
pno->adaptive_dwell_mode = pno_cfg->adaptive_dwell_mode;
|
||||
pno->channel_prediction_full_scan =
|
||||
pno_cfg->channel_prediction_full_scan;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_scan_register_pno_cb(struct wlan_objmgr_psoc *psoc,
|
||||
scan_event_handler event_cb, void *arg)
|
||||
{
|
||||
struct wlan_scan_obj *scan;
|
||||
|
||||
if (!psoc) {
|
||||
scm_err("null psoc");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
scan = wlan_psoc_get_scan_obj(psoc);
|
||||
qdf_spin_lock_bh(&scan->lock);
|
||||
scan->pno_cfg.pno_cb.func = event_cb;
|
||||
scan->pno_cfg.pno_cb.arg = arg;
|
||||
qdf_spin_unlock_bh(&scan->lock);
|
||||
scm_info("event_cb: 0x%p, arg: 0x%p", event_cb, arg);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline QDF_STATUS
|
||||
wlan_pno_global_init(struct pno_def_config *pno_def)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
static inline QDF_STATUS
|
||||
wlan_pno_global_deinit(struct pno_def_config *pno_def)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
ucfg_scan_update_pno_config(struct pno_def_config *pno,
|
||||
struct pno_user_cfg *pno_cfg)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_scan_start(struct scan_start_request *req)
|
||||
{
|
||||
|
|
@ -378,7 +596,7 @@ wlan_scan_global_init(struct wlan_scan_obj *scan_obj)
|
|||
/* init scan id seed */
|
||||
qdf_atomic_init(&scan_obj->scan_ids);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
return wlan_pno_global_init(&scan_obj->pno_cfg);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
|
|
@ -713,7 +931,8 @@ QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
|
|||
scan_def->scan_cache_aging_time = scan_cfg->scan_cache_aging_time;
|
||||
scan_def->adaptive_dwell_time_mode = scan_cfg->scan_dwell_time_mode;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
return ucfg_scan_update_pno_config(&scan_obj->pno_cfg,
|
||||
&scan_cfg->pno_cfg);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
|
|
@ -754,6 +973,7 @@ ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc)
|
|||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
qdf_spinlock_destroy(&scan_obj->lock);
|
||||
wlan_pno_global_deinit(&scan_obj->pno_cfg);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ util_scan_get_ev_type_name(enum scan_event_type type)
|
|||
[SCAN_EVENT_TYPE_SUSPENDED] = "SUSPENDED",
|
||||
[SCAN_EVENT_TYPE_RESUMED] = "RESUMED",
|
||||
[SCAN_EVENT_TYPE_NLO_COMPLETE] = "NLO_COMPLETE",
|
||||
[SCAN_EVENT_TYPE_NLO_MATCH] = "NLO_MATCH",
|
||||
[SCAN_EVENT_TYPE_INVALID] = "INVALID",
|
||||
[SCAN_EVENT_TYPE_GPIO_TIMEOUT] = "GPIO_TIMEOUT",
|
||||
[SCAN_EVENT_TYPE_RADIO_MEASUREMENT_START] =
|
||||
|
|
|
|||
Loading…
Reference in a new issue