qcacld-3.0: Add wow user pattern support in PMO

Add wow user pattern support in PMO.

Change-Id: I186e650e3a165ea0aeaada4bba880005c5be8b5f
CRs-Fixed: 2135644
这个提交包含在:
Mukul Sharma
2017-11-02 17:08:23 +05:30
提交者 snandini
父节点 29b81c20aa
当前提交 0c1c379514
修改 18 个文件,包含 277 行新增230 行删除

查看文件

@@ -175,6 +175,54 @@ static inline void pmo_decrement_wow_default_ptrn(
}
}
/**
* pmo_get_wow_default_ptrn() -Get wow default ptrn
* @vdev_ctx: pmo vdev priv ctx
*
* API to get wow default ptrn
*
* Return: current wow default ptrn count
*/
static inline uint8_t pmo_get_wow_default_ptrn(
struct pmo_vdev_priv_obj *vdev_ctx)
{
uint8_t count;
if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.ptrn_id_per_vdev) {
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
count = vdev_ctx->num_wow_default_patterns;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
} else {
qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def;
qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
}
return count;
}
/**
* pmo_get_wow_default_ptrn() -Set wow default ptrn
* @vdev_ctx: pmo vdev priv ctx
*
* API to set wow default ptrn
*
* Return: Set wow default ptrn count
*/
static inline void pmo_set_wow_default_ptrn(
struct pmo_vdev_priv_obj *vdev_ctx, uint8_t value)
{
if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.ptrn_id_per_vdev) {
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
vdev_ctx->num_wow_default_patterns = value;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
} else {
qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def = value;
qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
}
}
/**
* pmo_increment_wow_user_ptrn() -increment wow user ptrn
* @vdev_ctx: pmo vdev priv ctx
@@ -219,6 +267,32 @@ static inline void pmo_decrement_wow_user_ptrn(
}
}
/**
* pmo_get_wow_user_ptrn() -Get wow user ptrn
* @vdev_ctx: pmo vdev priv ctx
*
* API to Get wow user ptrn
*
* Return: None
*/
static inline uint8_t pmo_get_wow_user_ptrn(
struct pmo_vdev_priv_obj *vdev_ctx)
{
uint8_t count;
if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.ptrn_id_per_vdev) {
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
count = vdev_ctx->num_wow_user_patterns;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
} else {
qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_usr;
qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
}
return count;
}
void pmo_dump_wow_ptrn(struct pmo_wow_add_pattern *ptrn);
/**
@@ -229,18 +303,18 @@ void pmo_dump_wow_ptrn(struct pmo_wow_add_pattern *ptrn);
*
* Return: false if any errors encountered, QDF_STATUS_SUCCESS otherwise
*/
QDF_STATUS pmo_core_add_wow_pattern(struct wlan_objmgr_vdev *vdev,
const char *ptrn);
QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
struct pmo_wow_add_pattern *ptrn);
/**
* pmo_core_del_wow_pattern() - Function which will delete the WoWL pattern
* @vdev: pointer to the vdev
* @ptrn: pointer to the pattern string to be added
* @ptrn: pointer to the pattern string to be delete
*
* Return: error if any errors encountered, QDF_STATUS_SUCCESS otherwise
*/
QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev,
const char *ptrn);
QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
uint8_t pattern_id);
/**
* pmo_core_wow_enter() - store enable/disable status for pattern

查看文件

@@ -27,29 +27,104 @@
#include "wlan_pmo_static_config.h"
#include "wlan_reg_services_api.h"
static inline int pmo_find_wow_ptrn_len(const char *ptrn)
QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
struct pmo_wow_add_pattern *ptrn)
{
int len = 0;
QDF_STATUS status;
uint8_t id;
uint8_t bit_to_check, pos;
uint8_t new_mask[PMO_WOWL_BCAST_PATTERN_MAX_SIZE];
struct pmo_vdev_priv_obj *vdev_ctx;
while (*ptrn != '\0' && *ptrn != PMO_WOW_INTER_PTRN_TOKENIZER) {
len++;
ptrn++;
status = pmo_vdev_get_ref(vdev);
if (QDF_IS_STATUS_ERROR(status))
goto out;
vdev_ctx = pmo_vdev_get_priv(vdev);
/* clear all default patterns cofigured by pmo */
for (id = 0; id < pmo_get_wow_default_ptrn(vdev_ctx); id++)
pmo_tgt_del_wow_pattern(vdev, id, false);
pmo_set_wow_default_ptrn(vdev_ctx, 0);
pmo_debug("Add user passed wow pattern id %d vdev id %d",
ptrn->pattern_id, ptrn->session_id);
/*
* Convert received pattern mask value from bit representation
* to byte representation.
*
* For example, received value from umac,
*
* Mask value : A1 (equivalent binary is "1010 0001")
* Pattern value : 12:00:13:00:00:00:00:44
*
* The value which goes to FW after the conversion from this
* function (1 in mask value will become FF and 0 will
* become 00),
*
* Mask value : FF:00:FF:00:0:00:00:FF
* Pattern value : 12:00:13:00:00:00:00:44
*/
qdf_mem_zero(new_mask, sizeof(new_mask));
for (pos = 0; pos < ptrn->pattern_size; pos++) {
bit_to_check = (PMO_NUM_BITS_IN_BYTE - 1) -
(pos % PMO_NUM_BITS_IN_BYTE);
bit_to_check = 0x1 << bit_to_check;
if (ptrn->pattern_mask[pos / PMO_NUM_BITS_IN_BYTE] &
bit_to_check)
new_mask[pos] = PMO_WOW_PTRN_MASK_VALID;
}
return len;
status = pmo_tgt_send_wow_patterns_to_fw(vdev,
ptrn->pattern_id,
ptrn->pattern, ptrn->pattern_size,
ptrn->pattern_byte_offset, new_mask,
ptrn->pattern_size, true);
if (status != QDF_STATUS_SUCCESS)
pmo_err("Failed to add wow pattern %d", ptrn->pattern_id);
pmo_vdev_put_ref(vdev);
out:
PMO_EXIT();
return status;
}
QDF_STATUS pmo_core_add_wow_pattern(struct wlan_objmgr_vdev *vdev,
const char *ptrn)
QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
uint8_t pattern_id)
{
return QDF_STATUS_SUCCESS;
QDF_STATUS status;
struct pmo_vdev_priv_obj *vdev_ctx;
status = pmo_vdev_get_ref(vdev);
if (QDF_IS_STATUS_ERROR(status))
goto out;
vdev_ctx = pmo_vdev_get_priv(vdev);
if (pmo_get_wow_user_ptrn(vdev_ctx) <= 0) {
pmo_err("No valid user pattern. Num user pattern %u",
pmo_get_wow_user_ptrn(vdev_ctx));
status = QDF_STATUS_E_INVAL;
goto rel_ref;
}
pmo_debug("Delete user passed wow pattern id %d total user pattern %d",
pattern_id, pmo_get_wow_user_ptrn(vdev_ctx));
pmo_tgt_del_wow_pattern(vdev, pattern_id, true);
/* configure default patterns once all user patterns are deleted */
if (!pmo_get_wow_user_ptrn(vdev_ctx))
pmo_register_wow_default_patterns(vdev);
rel_ref:
pmo_vdev_put_ref(vdev);
out:
PMO_EXIT();
return status;
}
QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev,
const char *ptrn)
{
return QDF_STATUS_SUCCESS;
}
QDF_STATUS pmo_core_wow_enter(struct wlan_objmgr_vdev *vdev,
struct pmo_wow_enter_params *wow_enter_param)

查看文件

@@ -74,6 +74,7 @@ int (*pmo_pld_auto_resume_cb)(void);
* @send_enable_wakeup_event_req: fp to send enable wow wakeup events req
* @send_disable_wakeup_event_req: fp to send disable wow wakeup events req
* @send_add_wow_pattern: fp to send wow pattern request
* @del_wow_pattern: fp to delete wow pattern from firmware
* @send_enhance_mc_offload_req: fp to send enhanced multicast offload request
* @send_set_mc_filter_req: fp to send set mc filter request
* @send_clear_mc_filter_req: fp to send clear mc filter request
@@ -128,6 +129,8 @@ struct wlan_pmo_tx_ops {
uint8_t ptrn_id, const uint8_t *ptrn, uint8_t ptrn_len,
uint8_t ptrn_offset, const uint8_t *mask,
uint8_t mask_len, bool user);
QDF_STATUS (*del_wow_pattern)(
struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id);
QDF_STATUS (*send_enhance_mc_offload_req)(
struct wlan_objmgr_vdev *vdev, bool enable);
QDF_STATUS (*send_set_mc_filter_req)(

查看文件

@@ -150,6 +150,10 @@ QDF_STATUS pmo_tgt_send_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
uint8_t ptrn_offset, const uint8_t *mask,
uint8_t mask_len, bool user);
QDF_STATUS pmo_tgt_del_wow_pattern(
struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id,
bool user);
/**
* pmo_tgt_set_mc_filter_req() - Set mcast filter command to fw
* @vdev: objmgr vdev

查看文件

@@ -529,6 +529,12 @@ QDF_STATUS pmo_ucfg_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
QDF_STATUS pmo_ucfg_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
int disable_target_intr);
QDF_STATUS pmo_ucfg_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
struct pmo_wow_add_pattern *ptrn);
QDF_STATUS pmo_ucfg_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
uint8_t pattern_id);
/**
* pmo_ucfg_psoc_bus_resume() -handle bus resume request for psoc
* @psoc: objmgr psoc handle

查看文件

@@ -36,6 +36,9 @@
#define PMO_WOW_INTER_PTRN_TOKENIZER ';'
#define PMO_WOW_INTRA_PTRN_TOKENIZER ':'
#define PMO_WOW_PTRN_MASK_VALID 0xFF
#define PMO_NUM_BITS_IN_BYTE 8
/* Action frame categories */

查看文件

@@ -107,7 +107,7 @@ QDF_STATUS pmo_tgt_send_wow_patterns_to_fw(
if (status != QDF_STATUS_SUCCESS) {
if (!user)
pmo_decrement_wow_default_ptrn(vdev_ctx);
pmo_err("Failed to sen wow pattern event");
pmo_err("Failed to send wow pattern event");
goto out;
}
@@ -119,3 +119,36 @@ out:
return status;
}
QDF_STATUS pmo_tgt_del_wow_pattern(
struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id,
bool user)
{
QDF_STATUS status;
struct pmo_vdev_priv_obj *vdev_ctx;
struct wlan_objmgr_psoc *psoc;
struct wlan_pmo_tx_ops pmo_tx_ops;
PMO_ENTER();
psoc = pmo_vdev_get_psoc(vdev);
vdev_ctx = pmo_vdev_get_priv(vdev);
pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
if (!pmo_tx_ops.del_wow_pattern) {
pmo_err("del_wow_pattern is null");
status = QDF_STATUS_E_NULL_VALUE;
goto out;
}
status = pmo_tx_ops.del_wow_pattern(vdev, ptrn_id);
if (status) {
status = QDF_STATUS_E_FAILURE;
goto out;
}
if (user)
pmo_decrement_wow_user_ptrn(vdev_ctx);
out:
PMO_EXIT();
return status;
}

查看文件

@@ -298,6 +298,18 @@ QDF_STATUS pmo_ucfg_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
return pmo_core_psoc_suspend_target(psoc, disable_target_intr);
}
QDF_STATUS pmo_ucfg_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
struct pmo_wow_add_pattern *ptrn)
{
return pmo_core_add_wow_user_pattern(vdev, ptrn);
}
QDF_STATUS pmo_ucfg_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
uint8_t pattern_id)
{
return pmo_core_del_wow_user_pattern(vdev, pattern_id);
}
QDF_STATUS pmo_ucfg_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
enum qdf_suspend_type type)
{