qcacmn: Add ucfg and wmi changes for green ap low latency ps mode

Add ucfg and wmi changes to support for green ap low latency
power mode enable/disable command.

Change-Id: Ib9112e384c8354f1eff0f15610301225d51ef3ac
CRs-Fixed: 3265649
This commit is contained in:
Vijay Raj
2022-11-08 03:03:01 -08:00
committed by Madan Koyyalamudi
parent 4dfe160bf8
commit f0578f5bdb
12 changed files with 308 additions and 11 deletions

View File

@@ -55,7 +55,7 @@ QDF_STATUS target_if_green_ap_register_egap_event_handler(
* @pdev: pdev pointer
* @egap_params: enhanced green ap params
*
* @Return: QDF_STATUS_SUCCESS in case of success
* Return: QDF_STATUS_SUCCESS in case of success
*/
QDF_STATUS target_if_green_ap_enable_egap(
struct wlan_objmgr_pdev *pdev,
@@ -67,7 +67,7 @@ QDF_STATUS target_if_green_ap_enable_egap(
* @value: Value to send PS on/off to FW
* @pdev_id: pdev id
*
* @Return: QDF_STATUS_SUCCESS in case of success
* Return: QDF_STATUS_SUCCESS in case of success
*/
QDF_STATUS target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev *pdev,
bool value, uint8_t pdev_id);
@@ -76,7 +76,7 @@ QDF_STATUS target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev *pdev,
* target_if_green_ap_get_current_channel() - Get current channel
* @pdev: pdev pointer
*
* @Return: current channel freq
* Return: current channel freq
*/
uint16_t target_if_green_ap_get_current_channel(struct wlan_objmgr_pdev *pdev);
@@ -84,7 +84,7 @@ uint16_t target_if_green_ap_get_current_channel(struct wlan_objmgr_pdev *pdev);
* target_if_green_ap_get_current_channel_flags() - Get current channel flags
* @pdev: pdev pointer
*
* @Return: current channel flags
* Return: current channel flags
*/
uint64_t target_if_green_ap_get_current_channel_flags(
struct wlan_objmgr_pdev *pdev);
@@ -93,7 +93,7 @@ uint64_t target_if_green_ap_get_current_channel_flags(
* target_if_green_ap_reset_dev() - Reset dev
* @pdev: pdev pointer
*
* @Return: QDF_STATUS_SUCCESS if device reset
* Return: QDF_STATUS_SUCCESS if device reset
*/
QDF_STATUS target_if_green_ap_reset_dev(struct wlan_objmgr_pdev *pdev);

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -26,6 +27,49 @@
#include <target_if.h>
#include <wmi_unified_api.h>
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
/**
* target_if_green_ap_ll_ps_cmd() - Green AP low latency power save mode
* cmd api
* @vdev: vdev object
* @ll_ps_params: low latency power save command parameter
*
* Return: QDF_STATUS_SUCCESS for success, otherwise appropriate failure reason
*/
static QDF_STATUS
target_if_green_ap_ll_ps_cmd(struct wlan_objmgr_vdev *vdev,
struct green_ap_ll_ps_cmd_param *ll_ps_params)
{
struct wlan_objmgr_pdev *pdev;
wmi_unified_t wmi_hdl;
pdev = wlan_vdev_get_pdev(vdev);
if (!pdev) {
green_ap_err("pdev context passed is NULL");
return QDF_STATUS_E_INVAL;
}
wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
if (!wmi_hdl) {
green_ap_err("null wmi_hdl");
return QDF_STATUS_E_FAILURE;
}
return wmi_unified_green_ap_ll_ps_send(wmi_hdl, ll_ps_params);
}
static inline void target_if_register_ll_ps_tx_ops(
struct wlan_lmac_if_green_ap_tx_ops *tx_ops)
{
tx_ops->ll_ps = target_if_green_ap_ll_ps_cmd;
}
#else
static inline void target_if_register_ll_ps_tx_ops(
struct wlan_lmac_if_green_ap_tx_ops *tx_ops)
{
}
#endif
QDF_STATUS target_if_register_green_ap_tx_ops(
struct wlan_lmac_if_tx_ops *tx_ops)
{
@@ -45,6 +89,8 @@ QDF_STATUS target_if_register_green_ap_tx_ops(
green_ap_tx_ops->get_current_channel_flags = NULL;
green_ap_tx_ops->get_capab = NULL;
target_if_register_ll_ps_tx_ops(green_ap_tx_ops);
return QDF_STATUS_SUCCESS;
}

View File

@@ -1252,11 +1252,34 @@ struct wlan_lmac_if_offchan_txrx_ops {
#ifdef WLAN_SUPPORT_GREEN_AP
struct wlan_green_ap_egap_params;
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
/**
* struct green_ap_ll_ps_cmd_param - structure of the parameter of
* green AP low latency power save mode command
* @state: SAP low power state.(0 = disable, 1 = enable)
* @bcn_interval: beacon interval (in ms)
* @cookie: Cookie ID. Unique identifier to track power save command.
* The value is generated by wlan_green_ap_get_cookie_id().
*/
struct green_ap_ll_ps_cmd_param {
uint8_t state;
uint16_t bcn_interval;
uint32_t cookie;
};
#endif
/**
* struct wlan_lmac_if_green_ap_tx_ops - structure of tx function
* pointers for green ap component
* @enable_egap: function pointer to send enable egap indication to fw
* @ps_on_off_send: function pointer to send enable/disable green ap ps to fw
* @reset_dev: Function pointer to reset device
* @get_current_channel: function pointer to get current channel
* @get_current_channel_flag: function pointer to get current channel flag
* @get_capab: function pointer to get green ap capabilities
* @ll_ps: function pointer to send low latency power save command
*/
struct wlan_lmac_if_green_ap_tx_ops {
QDF_STATUS (*enable_egap)(struct wlan_objmgr_pdev *pdev,
@@ -1267,6 +1290,11 @@ struct wlan_lmac_if_green_ap_tx_ops {
uint16_t (*get_current_channel)(struct wlan_objmgr_pdev *pdev);
uint64_t (*get_current_channel_flags)(struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*get_capab)(struct wlan_objmgr_pdev *pdev);
#if defined(WLAN_SUPPORT_GAP_LL_PS_MODE)
QDF_STATUS (*ll_ps)(struct wlan_objmgr_vdev *vdev,
struct green_ap_ll_ps_cmd_param *ll_ps_params);
#endif
};
#endif

View File

@@ -400,3 +400,40 @@ void wlan_green_ap_check_mode(struct wlan_objmgr_pdev *pdev,
wlan_vdev_obj_unlock(vdev);
}
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
#define LOW_LATENCY_MAX_CMDID 0x00000080
uint32_t wlan_green_ap_get_cookie_id(struct wlan_pdev_green_ap_ctx *green_ap_ctx,
enum wlan_green_ap_ll_ps_state state)
{
uint32_t id;
qdf_atomic_t *cmd_cnt;
qdf_spin_lock_bh(&green_ap_ctx->lock);
if (!state)
cmd_cnt = &green_ap_ctx->ps_dis_cmd_cnt;
else
cmd_cnt = &green_ap_ctx->ps_en_cmd_cnt;
id = qdf_atomic_read(cmd_cnt);
if (id >= LOW_LATENCY_MAX_CMDID) {
green_ap_debug("Cookie id Max limit reached");
if (!state)
qdf_atomic_set(cmd_cnt, 0);
else
qdf_atomic_set(cmd_cnt, 1);
id = qdf_atomic_read(cmd_cnt);
}
qdf_atomic_add(2, cmd_cnt);
qdf_spin_unlock_bh(&green_ap_ctx->lock);
green_ap_debug("Cookie id : %x", id);
return id;
}
#endif

View File

@@ -100,6 +100,16 @@ enum wlan_green_ap_ps_event {
WLAN_GREEN_AP_PS_WAIT_EVENT,
};
/**
* enum wlan_green_ap_ll_ps_state - PS state
* @WLAN_GREEN_AP_LL_PS_DISABLE - Disable PS
* @WLAN_GREEN_AP_LL_PS_ENABLE - Enable PS
*/
enum wlan_green_ap_ll_ps_state {
WLAN_GREEN_AP_LL_PS_DISABLE = 0,
WLAN_GREEN_AP_LL_PS_ENABLE,
};
/**
* struct wlan_pdev_green_ap_ctx - green ap context
* @pdev: Pdev pointer
@@ -135,6 +145,7 @@ struct wlan_pdev_green_ap_ctx {
uint32_t bcn_mult;
qdf_atomic_t ps_en_cmd_cnt;
qdf_atomic_t ps_dis_cmd_cnt;
struct wlan_objmgr_vdev *vdev;
#endif
struct wlan_green_ap_egap_params egap_params;
bool dbg_enable;
@@ -144,7 +155,7 @@ struct wlan_pdev_green_ap_ctx {
* wlan_psoc_get_green_ap_tx_ops() - Obtain green ap tx ops from green ap ctx
* @green_ap_ctx: green ap context
*
* @Return: green ap tx ops pointer
* Return: green ap tx ops pointer
*/
struct wlan_lmac_if_green_ap_tx_ops *
wlan_psoc_get_green_ap_tx_ops(struct wlan_pdev_green_ap_ctx *green_ap_ctx);
@@ -162,7 +173,7 @@ bool wlan_is_egap_enabled(struct wlan_pdev_green_ap_ctx *green_ap_ctx);
* @green_ap_ctx: green ap context
* @event: ps event
*
* @Return: Success or Failure
* Return: Success or Failure
*/
QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx,
enum wlan_green_ap_ps_event event);
@@ -171,7 +182,7 @@ QDF_STATUS wlan_green_ap_state_mc(struct wlan_pdev_green_ap_ctx *green_ap_ctx,
* wlan_green_ap_timer_fn() - Green ap timer callback
* @pdev: pdev pointer
*
* @Return: None
* Return: None
*/
void wlan_green_ap_timer_fn(void *pdev);
@@ -183,9 +194,19 @@ void wlan_green_ap_timer_fn(void *pdev);
*
* Callback to check if all modes on radio are configured as AP
*
* @Return: None
* Return: None
*/
void wlan_green_ap_check_mode(struct wlan_objmgr_pdev *pdev,
void *object,
void *arg);
/**
* wlan_green_ap_get_cookie_id() - Get Low latency Power save cookie id
* @green_ap_ctx: green ap context
* @state: Received command state (Enable/Disable)
*
* Return: New cookie id
*/
uint32_t wlan_green_ap_get_cookie_id(struct wlan_pdev_green_ap_ctx *green_ap_ctx,
enum wlan_green_ap_ll_ps_state state);
#endif /* _WLAN_GREEN_AP_MAIN_I_H_ */

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -27,6 +28,7 @@
#include <wlan_objmgr_pdev_obj.h>
#include <qdf_status.h>
#include "wlan_utility.h"
#include "../../core/src/wlan_green_ap_main_i.h"
/**
* ucfg_green_ap_enable_egap() - Enable enhanced green ap
@@ -36,6 +38,22 @@
*/
QDF_STATUS ucfg_green_ap_enable_egap(struct wlan_objmgr_pdev *pdev);
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
/**
* ucfg_green_ap_ll_ps() - Enable/ Disable green ap low latency power save mode
* @pdev: pdev pointer
* @vdev: vdev pointer
* @state: low power state. refer enum wlan_green_ap_ll_ps_state
* @bcn_interval: beacon interval(in ms)
*
* Return: QDF_STATUS_SUCCESS on success or appropriate error status
*/
QDF_STATUS ucfg_green_ap_ll_ps(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
enum wlan_green_ap_ll_ps_state state,
uint32_t bcn_interval);
#endif
/**
* ucfg_green_ap_set_ps_config() - Set ps value
* @pdev: pdev pointer

View File

@@ -234,23 +234,40 @@ static void wlan_green_ap_set_bcn_mult(struct wlan_objmgr_pdev *pdev)
if (!psoc) {
green_ap_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
return;
}
green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
pdev, WLAN_UMAC_COMP_GREEN_AP);
if (!green_ap_ctx) {
green_ap_err("green ap context obtained is NULL");
return QDF_STATUS_E_FAILURE;
return;
}
green_ap_ctx->bcn_mult = cfg_get(psoc,
CFG_GAP_LL_PS_LOW_BEACON_MULT);
}
/**
* wlan_green_ap_init_cmd_count() - Initialize command count.
* @green_ap_ctx: green ap ctx
*/
static void wlan_green_ap_init_cmd_count(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
{
/* Disable cookie id will from 0,2,6,..*/
qdf_atomic_init(&green_ap_ctx->ps_dis_cmd_cnt);
/* Enable cookie id will be from 1,3,5,..*/
qdf_atomic_set(&green_ap_ctx->ps_en_cmd_cnt, 1);
}
#else
static inline void wlan_green_ap_set_bcn_mult(struct wlan_objmgr_pdev *pdev)
{
}
static inline
void wlan_green_ap_init_cmd_count(struct wlan_pdev_green_ap_ctx *green_ap_ctx)
{
}
#endif
QDF_STATUS wlan_green_ap_pdev_open(struct wlan_objmgr_pdev *pdev)
@@ -291,6 +308,8 @@ QDF_STATUS wlan_green_ap_pdev_open(struct wlan_objmgr_pdev *pdev)
wlan_green_ap_set_bcn_mult(pdev);
wlan_green_ap_init_cmd_count(green_ap_ctx);
qdf_spin_unlock_bh(&green_ap_ctx->lock);
return QDF_STATUS_SUCCESS;

View File

@@ -90,6 +90,58 @@ QDF_STATUS ucfg_green_ap_set_ps_config(struct wlan_objmgr_pdev *pdev,
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
QDF_STATUS ucfg_green_ap_ll_ps(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
enum wlan_green_ap_ll_ps_state state,
uint32_t bcn_interval)
{
struct wlan_pdev_green_ap_ctx *green_ap_ctx;
struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
struct green_ap_ll_ps_cmd_param green_ap_ll_ps_params;
if (!pdev) {
green_ap_err("pdev context passed is NULL");
return QDF_STATUS_E_INVAL;
}
green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
pdev, WLAN_UMAC_COMP_GREEN_AP);
if (!green_ap_ctx) {
green_ap_err("green ap context obtained is NULL");
return QDF_STATUS_E_FAILURE;
}
green_ap_tx_ops = wlan_psoc_get_green_ap_tx_ops(green_ap_ctx);
if (!green_ap_tx_ops) {
green_ap_err("green ap tx ops obtained are NULL");
return QDF_STATUS_E_FAILURE;
}
if (!green_ap_tx_ops->ll_ps) {
green_ap_err("tx op for sending green ap ll pwr save is NULL");
return QDF_STATUS_E_FAILURE;
}
green_ap_ctx->vdev = vdev;
green_ap_ll_ps_params.state = state;
if (state)
green_ap_ll_ps_params.bcn_interval =
green_ap_ctx->bcn_mult * bcn_interval;
else
green_ap_ll_ps_params.bcn_interval = bcn_interval;
green_ap_ll_ps_params.cookie =
wlan_green_ap_get_cookie_id(
green_ap_ctx,
(enum wlan_green_ap_ll_ps_state)state);
return green_ap_tx_ops->ll_ps(vdev, &green_ap_ll_ps_params);
}
#endif
QDF_STATUS ucfg_green_ap_get_ps_config(struct wlan_objmgr_pdev *pdev,
uint8_t *ps_enable)
{

View File

@@ -358,6 +358,19 @@ static inline int wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
}
#endif
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
/**
* wmi_unified_green_ap_ll_ps_send() - Send unified WMI command to
* enable/disable green ap low latency power save mode
* @wmi_handle: handle to WMI.
* @green_ap_ll_ps_params: low latency power save mode parameter
*
* Return: None
*/
QDF_STATUS wmi_unified_green_ap_ll_ps_send(wmi_unified_t wmi_handle,
struct green_ap_ll_ps_cmd_param *green_ap_ll_ps_params);
#endif
/**
* wmi_unified_cmd_send_pm_chk() - send unified WMI command with PM check,
* if target is in suspended state, WMI command will be sent over QMI.

View File

@@ -549,6 +549,10 @@ QDF_STATUS (*send_green_ap_ps_cmd)(wmi_unified_t wmi_handle,
QDF_STATUS (*extract_green_ap_egap_status_info)(
uint8_t *evt_buf,
struct wlan_green_ap_egap_status_info *egap_status_info_params);
#if defined(WLAN_SUPPORT_GAP_LL_PS_MODE)
QDF_STATUS (*send_green_ap_ll_ps_cmd)(wmi_unified_t wmi_handle,
struct green_ap_ll_ps_cmd_param *ll_ps_params);
#endif
#endif
QDF_STATUS

View File

@@ -259,6 +259,7 @@ QDF_STATUS wmi_unified_green_ap_ps_send(wmi_unified_t wmi_handle,
return QDF_STATUS_E_FAILURE;
}
#else
QDF_STATUS wmi_unified_green_ap_ps_send(wmi_unified_t wmi_handle,
uint32_t value, uint8_t pdev_id)
@@ -267,6 +268,20 @@ QDF_STATUS wmi_unified_green_ap_ps_send(wmi_unified_t wmi_handle,
}
#endif /* WLAN_SUPPORT_GREEN_AP */
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
QDF_STATUS wmi_unified_green_ap_ll_ps_send(
wmi_unified_t wmi_handle,
struct green_ap_ll_ps_cmd_param *ll_ps_params)
{
if (wmi_handle->ops->send_green_ap_ll_ps_cmd)
return wmi_handle->ops->send_green_ap_ll_ps_cmd(
wmi_handle,
ll_ps_params);
return QDF_STATUS_E_FAILURE;
}
#endif
QDF_STATUS
wmi_unified_pdev_utf_cmd_send(wmi_unified_t wmi_handle,
struct pdev_utf_params *param,

View File

@@ -2061,6 +2061,47 @@ static QDF_STATUS send_green_ap_ps_cmd_tlv(wmi_unified_t wmi_handle,
}
#endif
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
static QDF_STATUS send_green_ap_ll_ps_cmd_tlv(wmi_unified_t wmi_handle,
struct green_ap_ll_ps_cmd_param *green_ap_ll_ps_params)
{
uint32_t len;
wmi_buf_t buf;
wmi_xgap_enable_cmd_fixed_param *cmd;
len = sizeof(*cmd);
wmi_debug("Green AP low latency PS: bcn interval: %u state: %u cookie: %u",
green_ap_ll_ps_params->bcn_interval,
green_ap_ll_ps_params->state,
green_ap_ll_ps_params->cookie);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_xgap_enable_cmd_fixed_param *)wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_xgap_enable_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_xgap_enable_cmd_fixed_param));
cmd->beacon_interval = green_ap_ll_ps_params->bcn_interval;
cmd->sap_lp_flag = green_ap_ll_ps_params->state;
cmd->dialog_token = green_ap_ll_ps_params->cookie;
wmi_mtrace(WMI_XGAP_ENABLE_CMDID, NO_SESSION, 0);
if (wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_XGAP_ENABLE_CMDID)) {
wmi_err("Green AP Low latency PS cmd Failed");
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
#endif
/**
* send_pdev_utf_cmd_tlv() - send utf command to fw
* @wmi_handle: wmi handle
@@ -19892,6 +19933,9 @@ struct wmi_ops tlv_ops = {
.send_green_ap_ps_cmd = send_green_ap_ps_cmd_tlv,
.extract_green_ap_egap_status_info =
extract_green_ap_egap_status_info_tlv,
#endif
#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
.send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv,
#endif
.send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
.send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,