qcacmn: Add user stats and callback of DCS

Add user stats and callback to indicate DCS stats to userspace.

Change-Id: If841f9cad72ce2303046316d4c16ebf7efd9c3ec
CRs-Fixed: 2773531
This commit is contained in:
Min Liu
2020-09-09 17:34:48 +08:00
committed by snandini
parent cee83b8a96
commit ffddaeaf60
6 changed files with 268 additions and 7 deletions

View File

@@ -243,6 +243,7 @@ wlan_dcs_wlan_interference_process(
uint32_t cycle_count_delta = 0;
uint32_t tx_frame_delta = 0;
uint32_t rx_frame_delta = 0;
uint32_t my_bss_rx_delta = 0;
uint32_t reg_total_cu = 0;
uint32_t reg_tx_cu = 0;
uint32_t reg_rx_cu = 0;
@@ -314,10 +315,13 @@ wlan_dcs_wlan_interference_process(
cycle_count_delta = curr_stats->mib_stats.reg_cycle_cnt -
prev_stats->mib_stats.reg_cycle_cnt;
my_bss_rx_delta = curr_stats->my_bss_rx_cycle_count -
prev_stats->my_bss_rx_cycle_count;
if (unlikely(dcs_host_params.dcs_debug >= DCS_DEBUG_VERBOSE))
dcs_debug("rxclr_delta: %u, rxclr_ext_delta: %u, tx_frame_delta: %u, rx_frame_delta: %u, cycle_count_delta: %u",
rxclr_delta, rxclr_ext_delta,
tx_frame_delta, rx_frame_delta, cycle_count_delta);
dcs_debug("rxclr_delta: %u, rxclr_ext_delta: %u, tx_frame_delta: %u, rx_frame_delta: %u, cycle_count_delta: %u, my_bss_rx_delta: %u",
rxclr_delta, rxclr_ext_delta, tx_frame_delta,
rx_frame_delta, cycle_count_delta, my_bss_rx_delta);
if (0 == (cycle_count_delta >> 8)) {
if (unlikely(dcs_host_params.dcs_debug >= DCS_DEBUG_VERBOSE))
@@ -325,6 +329,34 @@ wlan_dcs_wlan_interference_process(
goto copy_stats;
}
/* Update user stats */
wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
if (dcs_pdev_priv->dcs_host_params.user_request_count) {
struct wlan_host_dcs_im_user_stats *p_user_stats =
&p_dcs_im_stats->user_dcs_im_stats;
p_user_stats->cycle_count += cycle_count_delta;
p_user_stats->rxclr_count += rxclr_delta;
p_user_stats->rx_frame_count += rx_frame_delta;
p_user_stats->my_bss_rx_cycle_count += my_bss_rx_delta;
if (0 == p_user_stats->max_rssi &&
0 == p_user_stats->min_rssi) {
p_user_stats->max_rssi = curr_stats->last_ack_rssi;
p_user_stats->min_rssi = curr_stats->last_ack_rssi;
} else {
if (curr_stats->last_ack_rssi > p_user_stats->max_rssi)
p_user_stats->max_rssi =
curr_stats->last_ack_rssi;
if (curr_stats->last_ack_rssi < p_user_stats->min_rssi)
p_user_stats->min_rssi =
curr_stats->last_ack_rssi;
}
dcs_pdev_priv->dcs_host_params.user_request_count--;
if (0 == dcs_pdev_priv->dcs_host_params.user_request_count)
dcs_pdev_priv->dcs_host_params.notify_user = 1;
}
wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
/*
* For below scenario, will ignore dcs event data and won't do
* interference detection algorithm calculation:
@@ -672,6 +704,13 @@ wlan_dcs_process(struct wlan_objmgr_psoc *psoc, struct dcs_stats_event *event)
wlan_dcs_wlan_interference_process(
&event->wlan_stat,
dcs_pdev_priv);
if (dcs_pdev_priv->user_cb &&
dcs_pdev_priv->dcs_host_params.notify_user) {
dcs_pdev_priv->dcs_host_params.notify_user = 0;
dcs_pdev_priv->user_cb(dcs_pdev_priv->requestor_vdev_id,
&dcs_pdev_priv->dcs_im_stats.user_dcs_im_stats,
0);
}
if (start_dcs_cbk_handler)
wlan_dcs_frequency_control(psoc,
dcs_pdev_priv,

View File

@@ -54,12 +54,14 @@ enum wlan_dcs_debug_level {
* struct pdev_dcs_im_stats - define dcs interference mitigation
* stats in pdev object
* @prev_dcs_im_stats: previous statistics at last time
* @user_dcs_im_stats: statistics requested from userspace
* @im_intfr_cnt: number of times the interference is
* detected within detection window
* @im_sample_cnt: sample counter
*/
struct pdev_dcs_im_stats {
struct wlan_host_dcs_im_tgt_stats prev_dcs_im_stats;
struct wlan_host_dcs_im_user_stats user_dcs_im_stats;
uint8_t im_intfr_cnt;
uint8_t im_samp_cnt;
};
@@ -78,6 +80,8 @@ struct pdev_dcs_im_stats {
* @intfr_detection_threshold: interference detection threshold
* @intfr_detection_window: interference sampling window
* @tx_err_threshold: transmission failure rate threshold
* @user_request_count: counter of stats requested from userspace
* @notify_user: whether to notify userspace
*/
struct pdev_dcs_params {
uint8_t dcs_enable_cfg;
@@ -92,6 +96,8 @@ struct pdev_dcs_params {
uint32_t intfr_detection_threshold;
uint32_t intfr_detection_window;
uint32_t tx_err_threshold;
uint32_t user_request_count;
uint8_t notify_user;
};
/**
@@ -140,6 +146,9 @@ struct psoc_dcs_cbk {
* @dcs_freq_ctrl_params: dcs frequency control parameter
* @dcs_disable_timer: dcs disable timer
* @dcs_timer_args: dcs disable timer args
* @lock: lock to protect dcs pdev priv
* @requestor_vdev_id: user request vdev id
* @user_cb: user request callback
*/
struct dcs_pdev_priv_obj {
struct pdev_dcs_params dcs_host_params;
@@ -147,6 +156,11 @@ struct dcs_pdev_priv_obj {
struct pdev_dcs_freq_ctrl_params dcs_freq_ctrl_params;
qdf_timer_t dcs_disable_timer;
struct pdev_dcs_timer_args dcs_timer_args;
qdf_spinlock_t lock;
uint8_t requestor_vdev_id;
void (*user_cb)(uint8_t vdev_id,
struct wlan_host_dcs_im_user_stats *stats,
int status);
};
/**
@@ -255,4 +269,26 @@ void wlan_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
void wlan_dcs_set_algorithm_process(struct wlan_objmgr_psoc *psoc,
uint32_t pdev_id,
bool dcs_algorithm_process);
/*
* wlan_dcs_pdev_obj_lock() - private API to acquire spinlock at pdev
* @dcs_pdev: pointer to dcs pdev object
*
* Return: void
*/
static inline void wlan_dcs_pdev_obj_lock(struct dcs_pdev_priv_obj *dcs_pdev)
{
qdf_spin_lock_bh(&dcs_pdev->lock);
}
/**
* wlan_dcs_pdev_obj_unlock() - private api to release spinlock at pdev
* @dcs_pdev: pointer to dcs pdev object
*
* Return: void
*/
static inline void wlan_dcs_pdev_obj_unlock(struct dcs_pdev_priv_obj *dcs_pdev)
{
qdf_spin_unlock_bh(&dcs_pdev->lock);
}
#endif /* _WLAN_DCS_H_ */

View File

@@ -83,4 +83,22 @@ struct wlan_host_dcs_im_tgt_stats {
uint32_t reg_rxclr_ext80_cnt;
};
/**
* struct wlan_host_dcs_im_user_stats - DCS IM stats requested by userspace
* @max_rssi: max rssi of the bss traffic
* @min_rssi: min rssi of the bss traffic
* @cycle_count: cycle count
* @rxclr_count: rx clear count
* @rx_frame_count: rx frame count
* @my_bss_rx_cycle_count: BSS rx cycle count
*/
struct wlan_host_dcs_im_user_stats {
uint32_t max_rssi;
uint32_t min_rssi;
uint32_t cycle_count;
uint32_t rxclr_count;
uint32_t rx_frame_count;
uint32_t my_bss_rx_cycle_count;
};
#endif

View File

@@ -23,6 +23,7 @@
#include <qdf_status.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_dcs_public_structs.h>
/**
* @brief List of DCS capabilities that can be set or unset
@@ -47,6 +48,7 @@ typedef void (*dcs_callback)(
uint8_t interference_type,
void *arg);
#ifdef DCS_INTERFERENCE_DETECTION
/**
* ucfg_dcs_register_cb() - API to register dcs callback
* @psoc: pointer to psoc object
@@ -62,6 +64,21 @@ void ucfg_dcs_register_cb(
dcs_callback cbk,
void *arg);
/**
* ucfg_dcs_register_user_cb() - API to register dcs user callback
* @psoc: pointer to psoc object
* @pdev_id: pdev id
* @vdev_id: vdev id
* @cb: dcs user callback to be registered
*
* Return: None
*/
void ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
uint8_t pdev_id, uint8_t vdev_id,
void (*cb)(uint8_t vdev_id,
struct wlan_host_dcs_im_user_stats *stats,
int status));
/**
* ucfg_wlan_dcs_cmd(): API to send dcs command
* @psoc: pointer to psoc object
@@ -115,7 +132,7 @@ void ucfg_config_dcs_disable(struct wlan_objmgr_psoc *psoc,
*
* Return: WLANIM/CWIM enable status
*/
uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id);
/**
* ucfg_dcs_clear() - API to clear dcs related information
@@ -142,4 +159,86 @@ void ucfg_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
*/
void ucfg_config_dcs_event_data(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
bool dcs_algorithm_process);
/*
* ucfg_dcs_reset_user_stats() - API to reset dcs user stats
* @psoc: pointer to psoc object
* @pdev_id: pdev id
*
* Return: None
*/
void ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id);
/**
* ucfg_dcs_set_user_request() - API to set dcs user stats request counter
* @psoc: pointer to psoc object
* @pdev_id: pdev id
* @user_request_count: user stats request counter
*
* Return: None
*/
void ucfg_dcs_set_user_request(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
uint32_t user_request_count);
#else
static inline void
ucfg_dcs_register_cb(struct wlan_objmgr_psoc *psoc, dcs_callback cbk, void *arg)
{
}
static inline void
ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
uint8_t pdev_id, uint8_t vdev_id,
void (*cb)(uint8_t vdev_id,
struct wlan_host_dcs_im_user_stats *stats,
int status))
{
}
static inline QDF_STATUS
ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
bool is_host_pdev_id)
{
return QDF_STATUS_SUCCESS;
}
static inline void
ucfg_config_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
uint8_t interference_type)
{
}
static inline void
ucfg_config_dcs_disable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
uint8_t interference_type)
{
}
static inline uint8_t
ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
{
return 0;
}
static inline void
ucfg_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
{
}
static inline void
ucfg_config_dcs_event_data(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
bool dcs_algorithm_process)
{
}
static inline void
ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
{
}
static inline void
ucfg_dcs_set_user_request(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
uint32_t user_request_count)
{
}
#endif
#endif /* _WLAN_DCS_UCFG_API_H_ */

View File

@@ -36,12 +36,16 @@ wlan_dcs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
{
QDF_STATUS status;
struct dcs_psoc_priv_obj *dcs_psoc_obj;
uint8_t loop;
dcs_psoc_obj = qdf_mem_malloc(sizeof(*dcs_psoc_obj));
if (!dcs_psoc_obj)
return QDF_STATUS_E_NOMEM;
for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++)
qdf_spinlock_create(&dcs_psoc_obj->dcs_pdev_priv[loop].lock);
status = wlan_objmgr_psoc_component_obj_attach(psoc,
WLAN_UMAC_COMP_DCS,
dcs_psoc_obj,
@@ -82,9 +86,11 @@ wlan_dcs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
status = wlan_objmgr_psoc_component_obj_detach(psoc,
WLAN_UMAC_COMP_DCS,
dcs_psoc_obj);
for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++)
for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++) {
qdf_timer_free(&dcs_psoc_obj->dcs_pdev_priv[loop].
dcs_disable_timer);
qdf_spinlock_destroy(&dcs_psoc_obj->dcs_pdev_priv[loop].lock);
}
qdf_mem_free(dcs_psoc_obj);
return status;

View File

@@ -41,6 +41,25 @@ void ucfg_dcs_register_cb(
dcs_psoc_priv->dcs_cbk.arg = arg;
}
void
ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
uint8_t pdev_id, uint8_t vdev_id,
void (*cb)(uint8_t vdev_id,
struct wlan_host_dcs_im_user_stats *stats,
int status))
{
struct dcs_pdev_priv_obj *dcs_pdev_priv;
dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
if (!dcs_pdev_priv) {
dcs_err("dcs pdev private object is null");
return;
}
dcs_pdev_priv->requestor_vdev_id = vdev_id;
dcs_pdev_priv->user_cb = cb;
}
QDF_STATUS
ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc,
uint32_t pdev_id,
@@ -79,9 +98,10 @@ void ucfg_config_dcs_disable(struct wlan_objmgr_psoc *psoc,
dcs_pdev_priv->dcs_host_params.dcs_enable &= (~interference_type);
}
uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
{
struct dcs_pdev_priv_obj *dcs_pdev_priv;
uint8_t enable = 0;
dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
if (!dcs_pdev_priv) {
@@ -89,7 +109,10 @@ uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
return 0;
}
return dcs_pdev_priv->dcs_host_params.dcs_enable;
if (dcs_pdev_priv->dcs_host_params.dcs_enable_cfg)
enable = dcs_pdev_priv->dcs_host_params.dcs_enable;
return enable;
}
void ucfg_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
@@ -102,3 +125,43 @@ void ucfg_config_dcs_event_data(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
{
wlan_dcs_set_algorithm_process(psoc, pdev_id, dcs_algorithm_process);
}
void ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
{
struct dcs_pdev_priv_obj *dcs_pdev_priv;
struct wlan_host_dcs_im_user_stats *user_stats;
dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
if (!dcs_pdev_priv) {
dcs_err("dcs pdev private object is null");
return;
}
wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
dcs_pdev_priv->dcs_host_params.user_request_count = 0;
dcs_pdev_priv->dcs_host_params.notify_user = 0;
user_stats = &dcs_pdev_priv->dcs_im_stats.user_dcs_im_stats;
user_stats->cycle_count = 0;
user_stats->rxclr_count = 0;
user_stats->rx_frame_count = 0;
user_stats->my_bss_rx_cycle_count = 0;
user_stats->max_rssi = 0;
user_stats->min_rssi = 0;
wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
}
void ucfg_dcs_set_user_request(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
uint32_t user_request_count)
{
struct dcs_pdev_priv_obj *dcs_pdev_priv;
dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
if (!dcs_pdev_priv) {
dcs_err("dcs pdev private object is null");
return;
}
wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
dcs_pdev_priv->dcs_host_params.user_request_count = user_request_count;
wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
}