blob: 96e04a87f846fa58ecb646e6e7fe7701cb014e31 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05302 * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/**
20 * DOC: wma_power.c
21 * This file contains powersave related functions.
22 */
23
24/* Header files */
25
26#include "wma.h"
27#include "wma_api.h"
28#include "cds_api.h"
29#include "wmi_unified_api.h"
30#include "wlan_qct_sys.h"
31#include "wni_api.h"
32#include "ani_global.h"
33#include "wmi_unified.h"
34#include "wni_cfg.h"
35#include "cfg_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080036
Nirav Shahcbc6d722016-03-01 16:24:53 +053037#include "qdf_nbuf.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053038#include "qdf_types.h"
Anurag Chouhan600c3a02016-03-01 10:33:54 +053039#include "qdf_mem.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040#include "wma_types.h"
41#include "lim_api.h"
42#include "lim_session_utils.h"
43
44#include "cds_utils.h"
45
46#if !defined(REMOVE_PKT_LOG)
47#include "pktlog_ac.h"
48#endif /* REMOVE_PKT_LOG */
49
50#include "dbglog_host.h"
51#include "csr_api.h"
52#include "ol_fw.h"
53
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054#include "wma_internal.h"
55
56/**
Govind Singhd76a5b02016-03-08 15:12:14 +053057 * wma_unified_modem_power_state() - set modem power state to fw
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058 * @wmi_handle: wmi handle
59 * @param_value: parameter value
60 *
61 * Return: 0 for success or error code
62 */
63static int
Govind Singhd76a5b02016-03-08 15:12:14 +053064wma_unified_modem_power_state(wmi_unified_t wmi_handle, uint32_t param_value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065{
66 int ret;
67 wmi_modem_power_state_cmd_param *cmd;
68 wmi_buf_t buf;
69 uint16_t len = sizeof(*cmd);
70
71 buf = wmi_buf_alloc(wmi_handle, len);
72 if (!buf) {
73 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
74 return -ENOMEM;
75 }
76 cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
77 WMITLV_SET_HDR(&cmd->tlv_header,
78 WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
79 WMITLV_GET_STRUCT_TLVLEN
80 (wmi_modem_power_state_cmd_param));
81 cmd->modem_power_state = param_value;
82 WMA_LOGD("%s: Setting cmd->modem_power_state = %u", __func__,
83 param_value);
84 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
85 WMI_MODEM_POWER_STATE_CMDID);
86 if (ret != EOK) {
87 WMA_LOGE("Failed to send notify cmd ret = %d", ret);
88 wmi_buf_free(buf);
89 }
90 return ret;
91}
92
93/**
Govind Singhd76a5b02016-03-08 15:12:14 +053094 * wma_unified_set_sta_ps_param() - set sta power save parameter to fw
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080095 * @wmi_handle: wmi handle
96 * @vdev_id: vdev id
97 * @param: param
98 * @value: parameter value
99 *
Govind Singhd76a5b02016-03-08 15:12:14 +0530100 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800101 */
Govind Singhd76a5b02016-03-08 15:12:14 +0530102QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800103 uint32_t vdev_id, uint32_t param,
104 uint32_t value)
105{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106 tp_wma_handle wma;
107 struct wma_txrx_node *iface;
Govind Singhd76a5b02016-03-08 15:12:14 +0530108 struct sta_ps_params sta_ps_param = {0};
109 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800110
Anurag Chouhan6d760662016-02-20 16:05:43 +0530111 wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800112 if (NULL == wma) {
113 WMA_LOGE("%s: wma is NULL", __func__);
Govind Singhd76a5b02016-03-08 15:12:14 +0530114 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800116 WMA_LOGD("Set Sta Ps param vdevId %d Param %d val %d",
117 vdev_id, param, value);
Govind Singhd76a5b02016-03-08 15:12:14 +0530118 iface = &wma->interfaces[vdev_id];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800119
Govind Singhd76a5b02016-03-08 15:12:14 +0530120 sta_ps_param.vdev_id = vdev_id;
121 sta_ps_param.param = param;
122 sta_ps_param.value = value;
123 status = wmi_unified_sta_ps_cmd_send(wmi_handle, &sta_ps_param);
124 if (QDF_IS_STATUS_ERROR(status))
125 return status;
Govind Singhd76a5b02016-03-08 15:12:14 +0530126
127 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800128}
129
130#ifdef QCA_IBSS_SUPPORT
131/**
132 * wma_set_ibss_pwrsave_params() - set ibss power save parameter to fw
133 * @wma: wma handle
134 * @vdev_id: vdev id
135 *
136 * Return: 0 for success or error code.
137 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530138QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800139wma_set_ibss_pwrsave_params(tp_wma_handle wma, uint8_t vdev_id)
140{
Govind Singhd76a5b02016-03-08 15:12:14 +0530141 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800142
Govind Singhd76a5b02016-03-08 15:12:14 +0530143 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800144 WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH,
145 wma->wma_ibss_power_save_params.atimWindowLength);
Govind Singhd76a5b02016-03-08 15:12:14 +0530146 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800147 WMA_LOGE("Failed to set WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH ret = %d",
148 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530149 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800150 }
151
Govind Singhd76a5b02016-03-08 15:12:14 +0530152 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800153 WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED,
154 wma->wma_ibss_power_save_params.isPowerSaveAllowed);
Govind Singhd76a5b02016-03-08 15:12:14 +0530155 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800156 WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED ret=%d",
157 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530158 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800159 }
160
Govind Singhd76a5b02016-03-08 15:12:14 +0530161 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162 WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED,
163 wma->wma_ibss_power_save_params.isPowerCollapseAllowed);
Govind Singhd76a5b02016-03-08 15:12:14 +0530164 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800165 WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED ret=%d",
166 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530167 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800168 }
169
Govind Singhd76a5b02016-03-08 15:12:14 +0530170 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171 WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED,
172 wma->wma_ibss_power_save_params.isAwakeonTxRxEnabled);
Govind Singhd76a5b02016-03-08 15:12:14 +0530173 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174 WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED ret=%d",
175 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530176 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177 }
178
Govind Singhd76a5b02016-03-08 15:12:14 +0530179 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800180 WMI_VDEV_PARAM_INACTIVITY_CNT,
181 wma->wma_ibss_power_save_params.inactivityCount);
Govind Singhd76a5b02016-03-08 15:12:14 +0530182 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800183 WMA_LOGE("Failed, set WMI_VDEV_PARAM_INACTIVITY_CNT ret=%d",
184 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530185 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800186 }
187
Govind Singhd76a5b02016-03-08 15:12:14 +0530188 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189 WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS,
190 wma->wma_ibss_power_save_params.txSPEndInactivityTime);
Govind Singhd76a5b02016-03-08 15:12:14 +0530191 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800192 WMA_LOGE("Failed, set WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS ret=%d",
193 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530194 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800195 }
196
Govind Singhd76a5b02016-03-08 15:12:14 +0530197 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198 WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS,
199 wma->wma_ibss_power_save_params.ibssPsWarmupTime);
Govind Singhd76a5b02016-03-08 15:12:14 +0530200 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800201 WMA_LOGE("Failed, set WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS ret=%d",
202 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530203 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800204 }
205
Govind Singhd76a5b02016-03-08 15:12:14 +0530206 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800207 WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE,
208 wma->wma_ibss_power_save_params.ibssPs1RxChainInAtimEnable);
Govind Singhd76a5b02016-03-08 15:12:14 +0530209 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800210 WMA_LOGE("Failed to set IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE ret=%d",
211 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530212 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 }
214
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530215 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800216}
217#endif /* QCA_IBSS_SUPPORT */
218
219/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220 * wma_set_ap_peer_uapsd() - set powersave parameters in ap mode to fw
221 * @wma: wma handle
222 * @vdev_id: vdev id
223 * @peer_addr: peer mac address
224 * @uapsd_value: uapsd value
225 * @max_sp: maximum service period
226 *
Govind Singhd76a5b02016-03-08 15:12:14 +0530227 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 */
Govind Singhd76a5b02016-03-08 15:12:14 +0530229QDF_STATUS wma_set_ap_peer_uapsd(tp_wma_handle wma, uint32_t vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230 uint8_t *peer_addr, uint8_t uapsd_value,
231 uint8_t max_sp)
232{
233 uint32_t uapsd = 0;
234 uint32_t max_sp_len = 0;
Govind Singhd76a5b02016-03-08 15:12:14 +0530235 QDF_STATUS ret;
236 struct ap_ps_params param = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800237
238 if (uapsd_value & UAPSD_VO_ENABLED) {
239 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
240 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
241 }
242
243 if (uapsd_value & UAPSD_VI_ENABLED) {
244 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
245 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
246 }
247
248 if (uapsd_value & UAPSD_BK_ENABLED) {
249 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
250 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
251 }
252
253 if (uapsd_value & UAPSD_BE_ENABLED) {
254 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
255 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
256 }
257
258 switch (max_sp) {
259 case UAPSD_MAX_SP_LEN_2:
260 max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_2;
261 break;
262 case UAPSD_MAX_SP_LEN_4:
263 max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_4;
264 break;
265 case UAPSD_MAX_SP_LEN_6:
266 max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_6;
267 break;
268 default:
269 max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_UNLIMITED;
270 break;
271 }
272
273 WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_UAPSD 0x%x for %pM",
274 uapsd, peer_addr);
Govind Singhd76a5b02016-03-08 15:12:14 +0530275 param.vdev_id = vdev_id;
276 param.param = WMI_AP_PS_PEER_PARAM_UAPSD;
277 param.value = uapsd;
278 ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr,
279 &param);
280 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800281 WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_UAPSD for %pM",
282 peer_addr);
283 return ret;
284 }
285
286 WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_MAX_SP 0x%x for %pM",
287 max_sp_len, peer_addr);
288
Govind Singhd76a5b02016-03-08 15:12:14 +0530289 param.vdev_id = vdev_id;
290 param.param = WMI_AP_PS_PEER_PARAM_MAX_SP;
291 param.value = max_sp_len;
292 ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr,
293 &param);
294 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295 WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_MAX_SP for %pM",
296 peer_addr);
297 return ret;
298 }
Govind Singhd76a5b02016-03-08 15:12:14 +0530299
300 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800301}
302
303/**
304 * wma_update_edca_params_for_ac() - to update per ac EDCA parameters
305 * @edca_param: EDCA parameters
306 * @wmm_param: wmm parameters
307 * @ac: access category
308 *
309 * Return: none
310 */
311void wma_update_edca_params_for_ac(tSirMacEdcaParamRecord *edca_param,
Jeff Johnsonaadd7892017-10-11 13:40:11 -0700312 struct wmi_host_wme_vparams *wmm_param,
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -0800313 int ac, bool mu_edca_param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800314{
315#define WMA_WMM_EXPO_TO_VAL(val) ((1 << (val)) - 1)
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -0800316 if (mu_edca_param) {
317 wmm_param->cwmin = edca_param->cw.min;
318 wmm_param->cwmax = edca_param->cw.max;
319 } else {
320 wmm_param->cwmin = WMA_WMM_EXPO_TO_VAL(edca_param->cw.min);
321 wmm_param->cwmax = WMA_WMM_EXPO_TO_VAL(edca_param->cw.max);
322 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323 wmm_param->aifs = edca_param->aci.aifsn;
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -0800324 if (mu_edca_param)
325 wmm_param->mu_edca_timer = edca_param->mu_edca_timer;
326 else
327 wmm_param->txoplimit = edca_param->txoplimit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800328 wmm_param->acm = edca_param->aci.acm;
329
Kiran Kumar Lokere3324f632018-03-01 21:43:21 -0800330 wmm_param->noackpolicy = edca_param->no_ack;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -0800332 WMA_LOGD("WMM PARAMS AC[%d]: AIFS %d Min %d Max %d %s %d ACM %d NOACK %d",
333 ac, wmm_param->aifs, wmm_param->cwmin,
334 wmm_param->cwmax,
335 mu_edca_param ? "MU_EDCA TIMER" : "TXOP",
336 mu_edca_param ? wmm_param->mu_edca_timer :
337 wmm_param->txoplimit,
338 wmm_param->acm, wmm_param->noackpolicy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800339}
340
341/**
342 * wma_set_tx_power() - set tx power limit in fw
343 * @handle: wma handle
344 * @tx_pwr_params: tx power parameters
345 *
346 * Return: none
347 */
348void wma_set_tx_power(WMA_HANDLE handle,
349 tMaxTxPowerParams *tx_pwr_params)
350{
351 tp_wma_handle wma_handle = (tp_wma_handle) handle;
352 uint8_t vdev_id;
Govind Singhd76a5b02016-03-08 15:12:14 +0530353 QDF_STATUS ret = QDF_STATUS_E_FAILURE;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800354 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800355
Anurag Chouhan6d760662016-02-20 16:05:43 +0530356 if (tx_pwr_params->dev_mode == QDF_SAP_MODE ||
357 tx_pwr_params->dev_mode == QDF_P2P_GO_MODE) {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800358 vdev = wma_find_vdev_by_addr(wma_handle,
Srinivas Girigowda97215232015-09-24 12:26:28 -0700359 tx_pwr_params->bssId.bytes,
360 &vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800361 } else {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800362 vdev = wma_find_vdev_by_bssid(wma_handle,
Srinivas Girigowda97215232015-09-24 12:26:28 -0700363 tx_pwr_params->bssId.bytes,
364 &vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800365 }
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800366 if (!vdev) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800367 WMA_LOGE("vdev handle is invalid for %pM",
Srinivas Girigowda97215232015-09-24 12:26:28 -0700368 tx_pwr_params->bssId.bytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530369 qdf_mem_free(tx_pwr_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800370 return;
371 }
372
Mukul Sharmaf9047232017-03-02 16:58:56 +0530373 if (!wma_is_vdev_up(vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800374 WMA_LOGE("%s: vdev id %d is not up for %pM", __func__, vdev_id,
Srinivas Girigowda97215232015-09-24 12:26:28 -0700375 tx_pwr_params->bssId.bytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530376 qdf_mem_free(tx_pwr_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377 return;
378 }
379
380 if (tx_pwr_params->power == 0) {
381 /* set to default. Since the app does not care the tx power
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700382 * we keep the previous setting
383 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 wma_handle->interfaces[vdev_id].tx_power = 0;
385 ret = 0;
386 goto end;
387 }
388 if (wma_handle->interfaces[vdev_id].max_tx_power != 0) {
389 /* make sure tx_power less than max_tx_power */
390 if (tx_pwr_params->power >
391 wma_handle->interfaces[vdev_id].max_tx_power) {
392 tx_pwr_params->power =
393 wma_handle->interfaces[vdev_id].max_tx_power;
394 }
395 }
396 if (wma_handle->interfaces[vdev_id].tx_power != tx_pwr_params->power) {
397
398 /* tx_power changed, Push the tx_power to FW */
Padma, Santhosh Kumar29df3622016-08-16 19:15:16 +0530399 WMA_LOGI("%s: Set TX pwr limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400 __func__, tx_pwr_params->power);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700401 ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
402 WMI_VDEV_PARAM_TX_PWRLIMIT,
403 tx_pwr_params->power);
Govind Singhd76a5b02016-03-08 15:12:14 +0530404 if (ret == QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800405 wma_handle->interfaces[vdev_id].tx_power =
406 tx_pwr_params->power;
407 } else {
408 /* no tx_power change */
Govind Singhd76a5b02016-03-08 15:12:14 +0530409 ret = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410 }
411end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530412 qdf_mem_free(tx_pwr_params);
Govind Singhd76a5b02016-03-08 15:12:14 +0530413 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 WMA_LOGE("Failed to set vdev param WMI_VDEV_PARAM_TX_PWRLIMIT");
415}
416
417/**
418 * wma_set_max_tx_power() - set max tx power limit in fw
419 * @handle: wma handle
420 * @tx_pwr_params: tx power parameters
421 *
422 * Return: none
423 */
424void wma_set_max_tx_power(WMA_HANDLE handle,
425 tMaxTxPowerParams *tx_pwr_params)
426{
427 tp_wma_handle wma_handle = (tp_wma_handle) handle;
428 uint8_t vdev_id;
Govind Singhd76a5b02016-03-08 15:12:14 +0530429 QDF_STATUS ret = QDF_STATUS_E_FAILURE;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800430 struct cdp_vdev *vdev;
Amar Singhala297bfa2015-10-15 15:07:29 -0700431 int8_t prev_max_power;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800432
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800433 vdev = wma_find_vdev_by_addr(wma_handle, tx_pwr_params->bssId.bytes,
Srinivas Girigowda97215232015-09-24 12:26:28 -0700434 &vdev_id);
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800435 if (vdev == NULL) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 /* not in SAP array. Try the station/p2p array */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800437 vdev = wma_find_vdev_by_bssid(wma_handle,
Srinivas Girigowda97215232015-09-24 12:26:28 -0700438 tx_pwr_params->bssId.bytes,
439 &vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440 }
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800441 if (!vdev) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442 WMA_LOGE("vdev handle is invalid for %pM",
Srinivas Girigowda97215232015-09-24 12:26:28 -0700443 tx_pwr_params->bssId.bytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530444 qdf_mem_free(tx_pwr_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800445 return;
446 }
447
Mukul Sharmaf9047232017-03-02 16:58:56 +0530448 if (!wma_is_vdev_up(vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 WMA_LOGE("%s: vdev id %d is not up", __func__, vdev_id);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530450 qdf_mem_free(tx_pwr_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 return;
452 }
453
454 if (wma_handle->interfaces[vdev_id].max_tx_power ==
455 tx_pwr_params->power) {
Govind Singhd76a5b02016-03-08 15:12:14 +0530456 ret = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457 goto end;
458 }
459 prev_max_power = wma_handle->interfaces[vdev_id].max_tx_power;
460 wma_handle->interfaces[vdev_id].max_tx_power = tx_pwr_params->power;
461 if (wma_handle->interfaces[vdev_id].max_tx_power == 0) {
Govind Singhd76a5b02016-03-08 15:12:14 +0530462 ret = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 goto end;
464 }
Padma, Santhosh Kumar29df3622016-08-16 19:15:16 +0530465 WMA_LOGI("Set MAX TX pwr limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466 wma_handle->interfaces[vdev_id].max_tx_power);
Govind Singhd76a5b02016-03-08 15:12:14 +0530467 ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800468 WMI_VDEV_PARAM_TX_PWRLIMIT,
469 wma_handle->interfaces[vdev_id].max_tx_power);
Govind Singhd76a5b02016-03-08 15:12:14 +0530470 if (ret == QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800471 wma_handle->interfaces[vdev_id].tx_power =
472 wma_handle->interfaces[vdev_id].max_tx_power;
473 else
474 wma_handle->interfaces[vdev_id].max_tx_power = prev_max_power;
475end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530476 qdf_mem_free(tx_pwr_params);
Govind Singhd76a5b02016-03-08 15:12:14 +0530477 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800478 WMA_LOGE("%s: Failed to set vdev param WMI_VDEV_PARAM_TX_PWRLIMIT",
479 __func__);
480}
481
482/**
483 * wmi_unified_set_sta_ps() - set sta powersave params in fw
484 * @handle: wma handle
485 * @vdev_id: vdev id
486 * @val: value
487 *
Govind Singh09c3b492016-03-08 16:05:14 +0530488 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700490static QDF_STATUS wmi_unified_set_sta_ps(wmi_unified_t wmi_handle,
491 uint32_t vdev_id, uint8_t val)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800492{
Govind Singh09c3b492016-03-08 16:05:14 +0530493 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800494
Govind Singh09c3b492016-03-08 16:05:14 +0530495 ret = wmi_unified_set_sta_ps_mode(wmi_handle, vdev_id,
496 val);
497 if (QDF_IS_STATUS_ERROR(ret))
498 WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800499
Govind Singh09c3b492016-03-08 16:05:14 +0530500 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800501}
502
503/**
504 * wma_get_uapsd_mask() - get uapsd mask based on uapsd parameters
505 * @uapsd_params: uapsed parameters
506 *
507 * Return: uapsd mask
508 */
509static inline uint32_t wma_get_uapsd_mask(tpUapsd_Params uapsd_params)
510{
511 uint32_t uapsd_val = 0;
512
513 if (uapsd_params->beDeliveryEnabled)
514 uapsd_val |= WMI_STA_PS_UAPSD_AC0_DELIVERY_EN;
515
516 if (uapsd_params->beTriggerEnabled)
517 uapsd_val |= WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
518
519 if (uapsd_params->bkDeliveryEnabled)
520 uapsd_val |= WMI_STA_PS_UAPSD_AC1_DELIVERY_EN;
521
522 if (uapsd_params->bkTriggerEnabled)
523 uapsd_val |= WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
524
525 if (uapsd_params->viDeliveryEnabled)
526 uapsd_val |= WMI_STA_PS_UAPSD_AC2_DELIVERY_EN;
527
528 if (uapsd_params->viTriggerEnabled)
529 uapsd_val |= WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
530
531 if (uapsd_params->voDeliveryEnabled)
532 uapsd_val |= WMI_STA_PS_UAPSD_AC3_DELIVERY_EN;
533
534 if (uapsd_params->voTriggerEnabled)
535 uapsd_val |= WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
536
537 return uapsd_val;
538}
539
540/**
541 * wma_set_force_sleep() - set power save parameters to fw
542 * @wma: wma handle
543 * @vdev_id: vdev id
544 * @enable: enable/disable
545 * @qpower_config: qpower configuration
546 *
Govind Singhd76a5b02016-03-08 15:12:14 +0530547 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548 */
Govind Singhd76a5b02016-03-08 15:12:14 +0530549static QDF_STATUS wma_set_force_sleep(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800550 uint32_t vdev_id,
551 uint8_t enable,
Kiran Kumar Lokere830ba162016-03-11 17:28:28 -0800552 enum powersave_qpower_mode qpower_config,
553 bool enable_ps)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800554{
Govind Singhd76a5b02016-03-08 15:12:14 +0530555 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800556 uint32_t cfg_data_val = 0;
Jeff Johnsonc97816c2018-05-12 17:13:23 -0700557 /* get mac to access CFG data base */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530558 struct sAniSirGlobal *mac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559 uint32_t rx_wake_policy;
560 uint32_t tx_wake_threshold;
561 uint32_t pspoll_count;
562 uint32_t inactivity_time;
563 uint32_t psmode;
564
565 WMA_LOGD("Set Force Sleep vdevId %d val %d", vdev_id, enable);
566
567 if (NULL == mac) {
568 WMA_LOGE("%s: Unable to get PE context", __func__);
Govind Singhd76a5b02016-03-08 15:12:14 +0530569 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 }
571
572 /* Set Tx/Rx Data InActivity Timeout */
573 if (wlan_cfg_get_int(mac, WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
Jeff Johnsone88dd752018-06-07 22:57:54 -0700574 &cfg_data_val) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530575 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576 "Failed to get WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT");
577 cfg_data_val = POWERSAVE_DEFAULT_INACTIVITY_TIME;
578 }
579 inactivity_time = (uint32_t) cfg_data_val;
580
581 if (enable) {
582 /* override normal configuration and force station asleep */
583 rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
584 tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
585
586 if (wlan_cfg_get_int(mac, WNI_CFG_MAX_PS_POLL,
Jeff Johnsone88dd752018-06-07 22:57:54 -0700587 &cfg_data_val) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530588 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 "Failed to get value for WNI_CFG_MAX_PS_POLL");
590 }
591 if (cfg_data_val)
592 pspoll_count = (uint32_t) cfg_data_val;
593 else
594 pspoll_count = WMA_DEFAULT_MAX_PSPOLL_BEFORE_WAKE;
595
596 psmode = WMI_STA_PS_MODE_ENABLED;
597 } else {
598 /* Ps Poll Wake Policy */
599 if (wlan_cfg_get_int(mac, WNI_CFG_MAX_PS_POLL,
Jeff Johnsone88dd752018-06-07 22:57:54 -0700600 &cfg_data_val) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530601 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602 "Failed to get value for WNI_CFG_MAX_PS_POLL");
603 }
604 if (cfg_data_val) {
605 /* Ps Poll is enabled */
606 rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
607 pspoll_count = (uint32_t) cfg_data_val;
608 tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
609 } else {
610 rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
611 pspoll_count = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
612 tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
613 }
614 psmode = WMI_STA_PS_MODE_ENABLED;
615 }
616
617 /*
618 * QPower is enabled by default in Firmware
619 * So Disable QPower explicitly
620 */
Govind Singhd76a5b02016-03-08 15:12:14 +0530621 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800622 WMI_STA_PS_ENABLE_QPOWER,
623 qpower_config);
Govind Singhd76a5b02016-03-08 15:12:14 +0530624 if (QDF_IS_STATUS_ERROR(ret)) {
Abhishek Singh779a55c2016-08-08 17:55:47 +0530625 WMA_LOGE("%s(%d) QPower Failed vdevId %d",
626 qpower_config ? "Enable" : "Disable",
627 qpower_config, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628 return ret;
629 }
Abhishek Singh779a55c2016-08-08 17:55:47 +0530630 WMA_LOGD("QPower %s(%d) vdevId %d",
631 qpower_config ? "Enabled" : "Disabled",
632 qpower_config, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800633
634 /* Set the Wake Policy to WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD */
Govind Singhd76a5b02016-03-08 15:12:14 +0530635 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
637 rx_wake_policy);
638
Govind Singhd76a5b02016-03-08 15:12:14 +0530639 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800640 WMA_LOGE("Setting wake policy Failed vdevId %d", vdev_id);
641 return ret;
642 }
643 WMA_LOGD("Setting wake policy to %d vdevId %d",
644 rx_wake_policy, vdev_id);
645
646 /* Set the Tx Wake Threshold */
Govind Singhd76a5b02016-03-08 15:12:14 +0530647 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800648 WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD,
649 tx_wake_threshold);
650
Govind Singhd76a5b02016-03-08 15:12:14 +0530651 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652 WMA_LOGE("Setting TxWake Threshold vdevId %d", vdev_id);
653 return ret;
654 }
655 WMA_LOGD("Setting TxWake Threshold to %d vdevId %d",
656 tx_wake_threshold, vdev_id);
657
658 /* Set the Ps Poll Count */
Govind Singhd76a5b02016-03-08 15:12:14 +0530659 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800660 WMI_STA_PS_PARAM_PSPOLL_COUNT,
661 pspoll_count);
662
Govind Singhd76a5b02016-03-08 15:12:14 +0530663 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800664 WMA_LOGE("Set Ps Poll Count Failed vdevId %d ps poll cnt %d",
665 vdev_id, pspoll_count);
666 return ret;
667 }
668 WMA_LOGD("Set Ps Poll Count vdevId %d ps poll cnt %d",
669 vdev_id, pspoll_count);
670
671 /* Set the Tx/Rx InActivity */
Govind Singhd76a5b02016-03-08 15:12:14 +0530672 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800673 WMI_STA_PS_PARAM_INACTIVITY_TIME,
674 inactivity_time);
675
Govind Singhd76a5b02016-03-08 15:12:14 +0530676 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677 WMA_LOGE("Setting Tx/Rx InActivity Failed vdevId %d InAct %d",
678 vdev_id, inactivity_time);
679 return ret;
680 }
681 WMA_LOGD("Set Tx/Rx InActivity vdevId %d InAct %d",
682 vdev_id, inactivity_time);
683
684 /* Enable Sta Mode Power save */
Kiran Kumar Lokere830ba162016-03-11 17:28:28 -0800685 if (enable_ps) {
686 ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800687
Kiran Kumar Lokere830ba162016-03-11 17:28:28 -0800688 if (QDF_IS_STATUS_ERROR(ret)) {
689 WMA_LOGE("Enable Sta Mode Ps Failed vdevId %d",
690 vdev_id);
691 return ret;
692 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 }
694
695 /* Set Listen Interval */
696 if (wlan_cfg_get_int(mac, WNI_CFG_LISTEN_INTERVAL,
Jeff Johnsone88dd752018-06-07 22:57:54 -0700697 &cfg_data_val) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530698 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699 "Failed to get value for WNI_CFG_LISTEN_INTERVAL");
700 cfg_data_val = POWERSAVE_DEFAULT_LISTEN_INTERVAL;
701 }
702
Govind Singhd76a5b02016-03-08 15:12:14 +0530703 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704 WMI_VDEV_PARAM_LISTEN_INTERVAL,
705 cfg_data_val);
Govind Singhd76a5b02016-03-08 15:12:14 +0530706 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800707 /* Even it fails continue Fw will take default LI */
708 WMA_LOGE("Failed to Set Listen Interval vdevId %d", vdev_id);
709 }
710 WMA_LOGD("Set Listen Interval vdevId %d Listen Intv %d",
711 vdev_id, cfg_data_val);
Govind Singhd76a5b02016-03-08 15:12:14 +0530712
713 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800714}
715
716/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 * wma_get_qpower_config() - get qpower configuration
718 * @wma: WMA handle
719 *
720 * Power Save Offload configuration:
721 * 0 -> Power save offload is disabled
722 * 1 -> Legacy Power save enabled + Deep sleep Disabled
723 * 2 -> QPower enabled + Deep sleep Disabled
724 * 3 -> Legacy Power save enabled + Deep sleep Enabled
725 * 4 -> QPower enabled + Deep sleep Enabled
726 * 5 -> Duty cycling QPower enabled
727 *
728 * Return: enum powersave_qpower_mode with below values
729 * QPOWER_DISABLED if QPOWER is disabled
730 * QPOWER_ENABLED if QPOWER is enabled
731 * QPOWER_DUTY_CYCLING if DUTY CYCLING QPOWER is enabled
732 */
733static enum powersave_qpower_mode wma_get_qpower_config(tp_wma_handle wma)
734{
735 switch (wma->powersave_mode) {
736 case PS_QPOWER_NODEEPSLEEP:
737 case PS_QPOWER_DEEPSLEEP:
738 WMA_LOGI("QPOWER is enabled in power save mode %d",
739 wma->powersave_mode);
740 return QPOWER_ENABLED;
741 case PS_DUTY_CYCLING_QPOWER:
742 WMA_LOGI("DUTY cycling QPOWER is enabled in power save mode %d",
743 wma->powersave_mode);
744 return QPOWER_DUTY_CYCLING;
745
746 default:
747 WMA_LOGI("QPOWER is disabled in power save mode %d",
748 wma->powersave_mode);
749 return QPOWER_DISABLED;
750 }
751}
752
753/**
754 * wma_enable_sta_ps_mode() - enable sta powersave params in fw
755 * @wma: wma handle
756 * @ps_req: power save request
757 *
758 * Return: none
759 */
760void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
761{
762 uint32_t vdev_id = ps_req->sessionid;
Govind Singhd76a5b02016-03-08 15:12:14 +0530763 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800764 enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma);
765 struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
Govind Singhd76a5b02016-03-08 15:12:14 +0530766
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767 if (!iface->handle) {
768 WMA_LOGE("vdev id %d is not active", vdev_id);
769 return;
770 }
771 if (eSIR_ADDON_NOTHING == ps_req->psSetting) {
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -0800772 if (qpower_config && iface->uapsd_cached_val) {
773 qpower_config = 0;
774 WMA_LOGD("Qpower is disabled");
775 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800776 WMA_LOGD("Enable Sta Mode Ps vdevId %d", vdev_id);
Govind Singhd76a5b02016-03-08 15:12:14 +0530777 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 WMI_STA_PS_PARAM_UAPSD, 0);
Govind Singhd76a5b02016-03-08 15:12:14 +0530779 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800780 WMA_LOGE("Set Uapsd param 0 Failed vdevId %d", vdev_id);
781 return;
782 }
783
784 ret = wma_set_force_sleep(wma, vdev_id, false,
Kiran Kumar Lokere830ba162016-03-11 17:28:28 -0800785 qpower_config, true);
Govind Singhd76a5b02016-03-08 15:12:14 +0530786 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 WMA_LOGE("Enable Sta Ps Failed vdevId %d", vdev_id);
788 return;
789 }
790 } else if (eSIR_ADDON_ENABLE_UAPSD == ps_req->psSetting) {
791 uint32_t uapsd_val = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700793 uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800794 if (uapsd_val != iface->uapsd_cached_val) {
795 WMA_LOGD("Enable Uapsd vdevId %d Mask %d",
796 vdev_id, uapsd_val);
Govind Singhd76a5b02016-03-08 15:12:14 +0530797 ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800798 vdev_id,
799 WMI_STA_PS_PARAM_UAPSD,
800 uapsd_val);
Govind Singhd76a5b02016-03-08 15:12:14 +0530801 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800802 WMA_LOGE("Enable Uapsd Failed vdevId %d",
803 vdev_id);
804 return;
805 }
806 /* Cache the Uapsd Mask */
807 iface->uapsd_cached_val = uapsd_val;
808 } else {
809 WMA_LOGD("Already Uapsd Enabled vdevId %d Mask %d",
810 vdev_id, uapsd_val);
811 }
812
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -0800813 if (qpower_config && iface->uapsd_cached_val) {
814 qpower_config = 0;
815 WMA_LOGD("Qpower is disabled");
816 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id);
818 ret = wma_set_force_sleep(wma, vdev_id, true,
Kiran Kumar Lokere830ba162016-03-11 17:28:28 -0800819 qpower_config, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820
Govind Singhd76a5b02016-03-08 15:12:14 +0530821 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 WMA_LOGE("Enable Forced Sleep Failed vdevId %d",
823 vdev_id);
824 return;
825 }
826 }
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +0530827
828 if (wma->ito_repeat_count) {
829 WMA_LOGI("Set ITO count to %d for vdevId %d",
830 wma->ito_repeat_count, vdev_id);
831
832 ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
833 vdev_id,
834 WMI_STA_PS_PARAM_MAX_RESET_ITO_COUNT_ON_TIM_NO_TXRX,
835 wma->ito_repeat_count);
836 if (QDF_IS_STATUS_ERROR(ret)) {
837 WMA_LOGE("Set ITO count failed vdevId %d Error %d",
838 vdev_id, ret);
839 return;
840 }
841 }
842
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +0530843 /* power save request succeeded */
844 iface->in_bmps = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845}
846
847/**
848 * wma_disable_sta_ps_mode() - disable sta powersave params in fw
849 * @wma: wma handle
850 * @ps_req: power save request
851 *
852 * Return: none
853 */
854void wma_disable_sta_ps_mode(tp_wma_handle wma, tpDisablePsParams ps_req)
855{
Govind Singhd76a5b02016-03-08 15:12:14 +0530856 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800857 uint32_t vdev_id = ps_req->sessionid;
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +0530858 struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859
860 WMA_LOGD("Disable Sta Mode Ps vdevId %d", vdev_id);
861
862 /* Disable Sta Mode Power save */
863 ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
Govind Singhd76a5b02016-03-08 15:12:14 +0530864 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865 WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
866 return;
867 }
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +0530868 iface->in_bmps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869
870 /* Disable UAPSD incase if additional Req came */
871 if (eSIR_ADDON_DISABLE_UAPSD == ps_req->psSetting) {
872 WMA_LOGD("Disable Uapsd vdevId %d", vdev_id);
Govind Singhd76a5b02016-03-08 15:12:14 +0530873 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800874 WMI_STA_PS_PARAM_UAPSD, 0);
Govind Singhd76a5b02016-03-08 15:12:14 +0530875 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800876 WMA_LOGE("Disable Uapsd Failed vdevId %d", vdev_id);
877 /*
878 * Even this fails we can proceed as success
879 * since we disabled powersave
880 */
881 }
882 }
883}
884
Dustin Brown10a7b712016-10-07 10:31:16 -0700885QDF_STATUS wma_set_qpower_config(uint8_t vdev_id, uint8_t qpower)
Kapil Gupta6213c012016-09-02 19:39:09 +0530886{
Dustin Brown10a7b712016-10-07 10:31:16 -0700887 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Kapil Gupta6213c012016-09-02 19:39:09 +0530888
Dustin Brown10a7b712016-10-07 10:31:16 -0700889 if (!wma) {
Kapil Gupta6213c012016-09-02 19:39:09 +0530890 WMA_LOGE("%s: WMA context is invald!", __func__);
891 return QDF_STATUS_E_INVAL;
892 }
Kapil Gupta6213c012016-09-02 19:39:09 +0530893
Dustin Brown10a7b712016-10-07 10:31:16 -0700894 WMA_LOGI("configuring qpower: %d", qpower);
895 wma->powersave_mode = qpower;
896 return wma_unified_set_sta_ps_param(wma->wmi_handle,
897 vdev_id,
898 WMI_STA_PS_ENABLE_QPOWER,
899 wma_get_qpower_config(wma));
Kapil Gupta6213c012016-09-02 19:39:09 +0530900}
901
902/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800903 * wma_enable_uapsd_mode() - enable uapsd mode in fw
904 * @wma: wma handle
905 * @ps_req: power save request
906 *
907 * Return: none
908 */
909void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req)
910{
Govind Singhd76a5b02016-03-08 15:12:14 +0530911 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912 uint32_t vdev_id = ps_req->sessionid;
913 uint32_t uapsd_val = 0;
914 enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma);
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -0800915 struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
916
917 if (!iface->handle) {
918 WMA_LOGE("vdev id %d is not active", vdev_id);
919 return;
920 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800921
922 /* Disable Sta Mode Power save */
923 ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
Govind Singhd76a5b02016-03-08 15:12:14 +0530924 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
926 return;
927 }
928
929 uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams);
930
931 WMA_LOGD("Enable Uapsd vdevId %d Mask %d", vdev_id, uapsd_val);
Govind Singhd76a5b02016-03-08 15:12:14 +0530932 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800933 WMI_STA_PS_PARAM_UAPSD, uapsd_val);
Govind Singhd76a5b02016-03-08 15:12:14 +0530934 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 WMA_LOGE("Enable Uapsd Failed vdevId %d", vdev_id);
936 return;
937 }
938
Kiran Kumar Lokere7006e0a2017-03-07 19:28:36 -0800939 if (qpower_config && uapsd_val) {
940 qpower_config = 0;
941 WMA_LOGD("Disable Qpower %d", vdev_id);
942 }
943 iface->uapsd_cached_val = uapsd_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id);
945 ret = wma_set_force_sleep(wma, vdev_id, true,
Kiran Kumar Lokere830ba162016-03-11 17:28:28 -0800946 qpower_config, ps_req->uapsdParams.enable_ps);
Govind Singhd76a5b02016-03-08 15:12:14 +0530947 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800948 WMA_LOGE("Enable Forced Sleep Failed vdevId %d", vdev_id);
949 return;
950 }
951
952}
953
954/**
955 * wma_disable_uapsd_mode() - disable uapsd mode in fw
956 * @wma: wma handle
957 * @ps_req: power save request
958 *
959 * Return: none
960 */
961void wma_disable_uapsd_mode(tp_wma_handle wma,
962 tpDisableUapsdParams ps_req)
963{
Govind Singhd76a5b02016-03-08 15:12:14 +0530964 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800965 uint32_t vdev_id = ps_req->sessionid;
966 enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma);
967
968 WMA_LOGD("Disable Uapsd vdevId %d", vdev_id);
969
970 /* Disable Sta Mode Power save */
971 ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
Govind Singhd76a5b02016-03-08 15:12:14 +0530972 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800973 WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
974 return;
975 }
976
Govind Singhd76a5b02016-03-08 15:12:14 +0530977 ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800978 WMI_STA_PS_PARAM_UAPSD, 0);
Govind Singhd76a5b02016-03-08 15:12:14 +0530979 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800980 WMA_LOGE("Disable Uapsd Failed vdevId %d", vdev_id);
981 return;
982 }
983
984 /* Re enable Sta Mode Powersave with proper configuration */
985 ret = wma_set_force_sleep(wma, vdev_id, false,
Kiran Kumar Lokere830ba162016-03-11 17:28:28 -0800986 qpower_config, true);
Govind Singhd76a5b02016-03-08 15:12:14 +0530987 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800988 WMA_LOGE("Disable Forced Sleep Failed vdevId %d", vdev_id);
989 return;
990 }
991}
992
993/**
Govind Singh09c3b492016-03-08 16:05:14 +0530994 * wma_set_sta_uapsd_auto_trig_cmd() - set uapsd auto trigger command
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 * @wmi_handle: wma handle
996 * @vdevid: vdev id
997 * @peer_addr: peer mac address
Frank Liud4b2fa02017-03-29 11:46:48 +0800998 * @trig_param: auto trigger parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800999 * @num_ac: number of access category
1000 *
1001 * This function sets the trigger
1002 * uapsd params such as service interval, delay interval
1003 * and suspend interval which will be used by the firmware
1004 * to send trigger frames periodically when there is no
1005 * traffic on the transmit side.
1006 *
1007 * Return: 0 for success or error code.
1008 */
Govind Singh09c3b492016-03-08 16:05:14 +05301009static QDF_STATUS wma_set_sta_uapsd_auto_trig_cmd(wmi_unified_t wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010 uint32_t vdevid,
1011 uint8_t peer_addr[IEEE80211_ADDR_LEN],
Frank Liud4b2fa02017-03-29 11:46:48 +08001012 struct sta_uapsd_params *trig_param,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 uint32_t num_ac)
1014{
Govind Singh09c3b492016-03-08 16:05:14 +05301015 QDF_STATUS ret;
1016 struct sta_uapsd_trig_params cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001017
Govind Singh09c3b492016-03-08 16:05:14 +05301018 cmd.vdevid = vdevid;
Frank Liud4b2fa02017-03-29 11:46:48 +08001019 cmd.auto_triggerparam = trig_param;
Govind Singh09c3b492016-03-08 16:05:14 +05301020 cmd.num_ac = num_ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021
Govind Singh09c3b492016-03-08 16:05:14 +05301022 qdf_mem_copy((uint8_t *) cmd.peer_addr, (uint8_t *) peer_addr,
Leo Chang96464902016-10-28 11:10:54 -07001023 sizeof(uint8_t) * IEEE80211_ADDR_LEN);
Govind Singh09c3b492016-03-08 16:05:14 +05301024 ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(wmi_handle,
1025 &cmd);
1026 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001027 WMA_LOGE("Failed to send set uapsd param ret = %d", ret);
Govind Singh09c3b492016-03-08 16:05:14 +05301028
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029 return ret;
1030}
1031
1032/**
1033 * wma_trigger_uapsd_params() - set trigger uapsd parameter
1034 * @wmi_handle: wma handle
1035 * @vdev_id: vdev id
1036 * @trigger_uapsd_params: trigger uapsd parameters
1037 *
1038 * This function sets the trigger uapsd
1039 * params such as service interval, delay
1040 * interval and suspend interval which
1041 * will be used by the firmware to send
1042 * trigger frames periodically when there
1043 * is no traffic on the transmit side.
1044 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301045 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001046 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301047QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048 tp_wma_trigger_uapsd_params
1049 trigger_uapsd_params)
1050{
Govind Singh09c3b492016-03-08 16:05:14 +05301051 QDF_STATUS ret;
Frank Liud4b2fa02017-03-29 11:46:48 +08001052 struct sta_uapsd_params uapsd_trigger_param;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001053
1054 WMA_LOGD("Trigger uapsd params vdev id %d", vdev_id);
1055
1056 WMA_LOGD("WMM AC %d User Priority %d SvcIntv %d DelIntv %d SusIntv %d",
1057 trigger_uapsd_params->wmm_ac,
1058 trigger_uapsd_params->user_priority,
1059 trigger_uapsd_params->service_interval,
1060 trigger_uapsd_params->delay_interval,
1061 trigger_uapsd_params->suspend_interval);
1062
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05301063 if (!wmi_service_enabled(wma_handle->wmi_handle,
1064 wmi_sta_uapsd_basic_auto_trig) ||
1065 !wmi_service_enabled(wma_handle->wmi_handle,
1066 wmi_sta_uapsd_var_auto_trig)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001067 WMA_LOGD("Trigger uapsd is not supported vdev id %d", vdev_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301068 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001069 }
1070
1071 uapsd_trigger_param.wmm_ac = trigger_uapsd_params->wmm_ac;
1072 uapsd_trigger_param.user_priority = trigger_uapsd_params->user_priority;
1073 uapsd_trigger_param.service_interval =
1074 trigger_uapsd_params->service_interval;
1075 uapsd_trigger_param.suspend_interval =
1076 trigger_uapsd_params->suspend_interval;
1077 uapsd_trigger_param.delay_interval =
1078 trigger_uapsd_params->delay_interval;
1079
Govind Singh09c3b492016-03-08 16:05:14 +05301080 ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001081 vdev_id, wma_handle->interfaces[vdev_id].bssid,
Frank Liud4b2fa02017-03-29 11:46:48 +08001082 &uapsd_trigger_param, 1);
Govind Singh09c3b492016-03-08 16:05:14 +05301083 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001084 WMA_LOGE("Fail to send uapsd param cmd for vdevid %d ret = %d",
1085 ret, vdev_id);
Govind Singh09c3b492016-03-08 16:05:14 +05301086 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001087 }
Govind Singh09c3b492016-03-08 16:05:14 +05301088
1089 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001090}
1091
1092/**
1093 * wma_disable_uapsd_per_ac() - disable uapsd per ac
1094 * @wmi_handle: wma handle
1095 * @vdev_id: vdev id
1096 * @ac: access category
1097 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301098 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001099 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301100QDF_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001101 uint32_t vdev_id, enum uapsd_ac ac)
1102{
Govind Singh09c3b492016-03-08 16:05:14 +05301103 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001104 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
Frank Liud4b2fa02017-03-29 11:46:48 +08001105 struct sta_uapsd_params uapsd_trigger_param;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001106 enum uapsd_up user_priority;
1107
1108 WMA_LOGD("Disable Uapsd per ac vdevId %d ac %d", vdev_id, ac);
1109
1110 switch (ac) {
1111 case UAPSD_VO:
1112 iface->uapsd_cached_val &=
1113 ~(WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
1114 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN);
1115 user_priority = UAPSD_UP_VO;
1116 break;
1117 case UAPSD_VI:
1118 iface->uapsd_cached_val &=
1119 ~(WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
1120 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN);
1121 user_priority = UAPSD_UP_VI;
1122 break;
1123 case UAPSD_BK:
1124 iface->uapsd_cached_val &=
1125 ~(WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
1126 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN);
1127 user_priority = UAPSD_UP_BK;
1128 break;
1129 case UAPSD_BE:
1130 iface->uapsd_cached_val &=
1131 ~(WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
1132 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN);
1133 user_priority = UAPSD_UP_BE;
1134 break;
1135 default:
1136 WMA_LOGE("Invalid AC vdevId %d ac %d", vdev_id, ac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301137 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001138 }
1139
1140 /*
1141 * Disable Auto Trigger Functionality before
1142 * disabling uapsd for a particular AC
1143 */
1144 uapsd_trigger_param.wmm_ac = ac;
1145 uapsd_trigger_param.user_priority = user_priority;
1146 uapsd_trigger_param.service_interval = 0;
1147 uapsd_trigger_param.suspend_interval = 0;
1148 uapsd_trigger_param.delay_interval = 0;
1149
Govind Singh09c3b492016-03-08 16:05:14 +05301150 ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001151 vdev_id, wma_handle->interfaces[vdev_id].bssid,
Frank Liud4b2fa02017-03-29 11:46:48 +08001152 &uapsd_trigger_param, 1);
Govind Singh09c3b492016-03-08 16:05:14 +05301153 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001154 WMA_LOGE("Fail to send auto trig cmd for vdevid %d ret = %d",
1155 ret, vdev_id);
Govind Singh09c3b492016-03-08 16:05:14 +05301156 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 }
1158
Govind Singhd76a5b02016-03-08 15:12:14 +05301159 ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001160 WMI_STA_PS_PARAM_UAPSD,
1161 iface->uapsd_cached_val);
Govind Singh09c3b492016-03-08 16:05:14 +05301162 if (QDF_IS_STATUS_ERROR(ret)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163 WMA_LOGE("Disable Uapsd per ac Failed vdevId %d ac %d", vdev_id,
1164 ac);
Govind Singh09c3b492016-03-08 16:05:14 +05301165 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166 }
1167 WMA_LOGD("Disable Uapsd per ac vdevId %d val %d", vdev_id,
1168 iface->uapsd_cached_val);
Govind Singh09c3b492016-03-08 16:05:14 +05301169
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301170 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001171}
1172
1173/**
1174 * wma_get_temperature() - get pdev temperature req
1175 * @wmi_handle: wma handle
1176 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301177 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001178 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301179QDF_STATUS wma_get_temperature(tp_wma_handle wma_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001180{
Govind Singh09c3b492016-03-08 16:05:14 +05301181 QDF_STATUS ret = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001182
Govind Singh09c3b492016-03-08 16:05:14 +05301183 ret = wmi_unified_get_temperature(wma_handle->wmi_handle);
1184 if (ret)
1185 WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001186
Govind Singh09c3b492016-03-08 16:05:14 +05301187 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188}
1189
1190/**
1191 * wma_pdev_temperature_evt_handler() - pdev temperature event handler
1192 * @handle: wma handle
1193 * @event: event buffer
1194 * @len : length
1195 *
1196 * Return: 0 for success or error code.
1197 */
1198int wma_pdev_temperature_evt_handler(void *handle, uint8_t *event,
1199 uint32_t len)
1200{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301201 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001202 struct scheduler_msg sme_msg = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 WMI_PDEV_TEMPERATURE_EVENTID_param_tlvs *param_buf;
1204 wmi_pdev_temperature_event_fixed_param *wmi_event;
1205
1206 param_buf = (WMI_PDEV_TEMPERATURE_EVENTID_param_tlvs *) event;
1207 if (!param_buf) {
1208 WMA_LOGE("Invalid pdev_temperature event buffer");
1209 return -EINVAL;
1210 }
1211
1212 wmi_event = param_buf->fixed_param;
1213 WMA_LOGI(FL("temperature: %d"), wmi_event->value);
1214
1215 sme_msg.type = eWNI_SME_MSG_GET_TEMPERATURE_IND;
1216 sme_msg.bodyptr = NULL;
1217 sme_msg.bodyval = wmi_event->value;
1218
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001219 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001220 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 WMA_LOGE(FL("Fail to post get temperature ind msg"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001222 return 0;
1223}
1224
1225/**
1226 * wma_process_tx_power_limits() - sends the power limits for 2g/5g to firmware
1227 * @handle: wma handle
1228 * @ptxlim: power limit value
1229 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301230 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001231 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301232QDF_STATUS wma_process_tx_power_limits(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233 tSirTxPowerLimit *ptxlim)
1234{
1235 tp_wma_handle wma = (tp_wma_handle) handle;
1236 int32_t ret = 0;
1237 uint32_t txpower_params2g = 0;
1238 uint32_t txpower_params5g = 0;
Govind Singhd76a5b02016-03-08 15:12:14 +05301239 struct pdev_params pdevparam;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240
1241 if (!wma || !wma->wmi_handle) {
1242 WMA_LOGE("%s: WMA is closed, can not issue tx power limit",
1243 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301244 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001245 }
1246 /* Set value and reason code for 2g and 5g power limit */
1247
1248 SET_PDEV_PARAM_TXPOWER_REASON(txpower_params2g,
1249 WMI_PDEV_PARAM_TXPOWER_REASON_SAR);
1250 SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params2g, ptxlim->txPower2g);
1251
1252 SET_PDEV_PARAM_TXPOWER_REASON(txpower_params5g,
1253 WMI_PDEV_PARAM_TXPOWER_REASON_SAR);
1254 SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params5g, ptxlim->txPower5g);
1255
1256 WMA_LOGD("%s: txpower2g: %x txpower5g: %x",
1257 __func__, txpower_params2g, txpower_params5g);
1258
Govind Singhd76a5b02016-03-08 15:12:14 +05301259 pdevparam.param_id = WMI_PDEV_PARAM_TXPOWER_LIMIT2G;
1260 pdevparam.param_value = txpower_params2g;
1261 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
1262 &pdevparam,
1263 WMA_WILDCARD_PDEV_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001264 if (ret) {
1265 WMA_LOGE("%s: Failed to set txpower 2g (%d)", __func__, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301266 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267 }
Govind Singhd76a5b02016-03-08 15:12:14 +05301268 pdevparam.param_id = WMI_PDEV_PARAM_TXPOWER_LIMIT5G;
1269 pdevparam.param_value = txpower_params5g;
1270 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
1271 &pdevparam,
1272 WMA_WILDCARD_PDEV_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 if (ret) {
1274 WMA_LOGE("%s: Failed to set txpower 5g (%d)", __func__, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301275 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301277 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001278}
1279
1280/**
1281 * wma_add_p2p_ie() - add p2p IE
1282 * @frm: ptr where p2p ie needs to add
1283 *
1284 * Return: ptr after p2p ie
1285 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07001286static uint8_t *wma_add_p2p_ie(uint8_t *frm)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001287{
1288 uint8_t wfa_oui[3] = WMA_P2P_WFA_OUI;
1289 struct p2p_ie *p2p_ie = (struct p2p_ie *)frm;
1290
1291 p2p_ie->p2p_id = WMA_P2P_IE_ID;
1292 p2p_ie->p2p_oui[0] = wfa_oui[0];
1293 p2p_ie->p2p_oui[1] = wfa_oui[1];
1294 p2p_ie->p2p_oui[2] = wfa_oui[2];
1295 p2p_ie->p2p_oui_type = WMA_P2P_WFA_VER;
1296 p2p_ie->p2p_len = 4;
1297 return frm + sizeof(struct p2p_ie);
1298}
1299
1300/**
1301 * wma_update_beacon_noa_ie() - update beacon ie
1302 * @bcn: beacon info
1303 * @new_noa_sub_ie_len: ie length
1304 *
1305 * Return: none
1306 */
1307static void wma_update_beacon_noa_ie(struct beacon_info *bcn,
1308 uint16_t new_noa_sub_ie_len)
1309{
1310 struct p2p_ie *p2p_ie;
1311 uint8_t *buf;
1312
1313 /* if there is nothing to add, just return */
1314 if (new_noa_sub_ie_len == 0) {
1315 if (bcn->noa_sub_ie_len && bcn->noa_ie) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001316 WMA_LOGD("%s: NoA is present in previous beacon, but not present in swba event, So Reset the NoA",
1317 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001318 /* TODO: Assuming p2p noa ie is last ie in the beacon */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301319 qdf_mem_zero(bcn->noa_ie, (bcn->noa_sub_ie_len +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001320 sizeof(struct p2p_ie)));
1321 bcn->len -= (bcn->noa_sub_ie_len +
1322 sizeof(struct p2p_ie));
1323 bcn->noa_ie = NULL;
1324 bcn->noa_sub_ie_len = 0;
1325 }
1326 WMA_LOGD("%s: No need to update NoA", __func__);
1327 return;
1328 }
1329
1330 if (bcn->noa_sub_ie_len && bcn->noa_ie) {
1331 /* NoA present in previous beacon, update it */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001332 WMA_LOGD("%s: NoA present in previous beacon, update the NoA IE, bcn->len %u bcn->noa_sub_ie_len %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333 __func__, bcn->len, bcn->noa_sub_ie_len);
1334 bcn->len -= (bcn->noa_sub_ie_len + sizeof(struct p2p_ie));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301335 qdf_mem_zero(bcn->noa_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336 (bcn->noa_sub_ie_len + sizeof(struct p2p_ie)));
1337 } else { /* NoA is not present in previous beacon */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001338 WMA_LOGD("%s: NoA not present in previous beacon, add it bcn->len %u",
1339 __func__, bcn->len);
Nirav Shahcbc6d722016-03-01 16:24:53 +05301340 buf = qdf_nbuf_data(bcn->buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001341 bcn->noa_ie = buf + bcn->len;
1342 }
1343
1344 bcn->noa_sub_ie_len = new_noa_sub_ie_len;
1345 wma_add_p2p_ie(bcn->noa_ie);
1346 p2p_ie = (struct p2p_ie *)bcn->noa_ie;
1347 p2p_ie->p2p_len += new_noa_sub_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301348 qdf_mem_copy((bcn->noa_ie + sizeof(struct p2p_ie)), bcn->noa_sub_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001349 new_noa_sub_ie_len);
1350
1351 bcn->len += (new_noa_sub_ie_len + sizeof(struct p2p_ie));
1352 WMA_LOGI("%s: Updated beacon length with NoA Ie is %u",
1353 __func__, bcn->len);
1354}
1355
1356/**
1357 * wma_p2p_create_sub_ie_noa() - put p2p noa ie
1358 * @buf: buffer
1359 * @noa: noa element ie
1360 * @new_noa_sub_ie_len: ie length
1361 *
1362 * Return: none
1363 */
1364static void wma_p2p_create_sub_ie_noa(uint8_t *buf,
1365 struct p2p_sub_element_noa *noa,
1366 uint16_t *new_noa_sub_ie_len)
1367{
1368 uint8_t tmp_octet = 0;
1369 int i;
1370 uint8_t *buf_start = buf;
1371
1372 *buf++ = WMA_P2P_SUB_ELEMENT_NOA; /* sub-element id */
1373 ASSERT(noa->num_descriptors <= WMA_MAX_NOA_DESCRIPTORS);
1374
1375 /*
1376 * Length = (2 octets for Index and CTWin/Opp PS) and
1377 * (13 octets for each NOA Descriptors)
1378 */
1379 P2PIE_PUT_LE16(buf, WMA_NOA_IE_SIZE(noa->num_descriptors));
1380 buf += 2;
1381
1382 *buf++ = noa->index; /* Instance Index */
1383
1384 tmp_octet = noa->ctwindow & WMA_P2P_NOA_IE_CTWIN_MASK;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001385 if (noa->oppPS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 tmp_octet |= WMA_P2P_NOA_IE_OPP_PS_SET;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 *buf++ = tmp_octet; /* Opp Ps and CTWin capabilities */
1388
1389 for (i = 0; i < noa->num_descriptors; i++) {
1390 ASSERT(noa->noa_descriptors[i].type_count != 0);
1391
1392 *buf++ = noa->noa_descriptors[i].type_count;
1393
1394 P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].duration);
1395 buf += 4;
1396 P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].interval);
1397 buf += 4;
1398 P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].start_time);
1399 buf += 4;
1400 }
1401 *new_noa_sub_ie_len = (buf - buf_start);
1402}
1403
1404/**
1405 * wma_update_noa() - update noa params
1406 * @beacon: beacon info
1407 * @noa_ie: noa ie
1408 *
1409 * Return: none
1410 */
1411void wma_update_noa(struct beacon_info *beacon,
1412 struct p2p_sub_element_noa *noa_ie)
1413{
1414 uint16_t new_noa_sub_ie_len;
1415
1416 /* Call this function by holding the spinlock on beacon->lock */
1417
1418 if (noa_ie) {
1419 if ((noa_ie->ctwindow == 0) && (noa_ie->oppPS == 0) &&
1420 (noa_ie->num_descriptors == 0)) {
1421 /* NoA is not present */
1422 WMA_LOGD("%s: NoA is not present", __func__);
1423 new_noa_sub_ie_len = 0;
1424 } else {
1425 /* Create the binary blob containing NOA sub-IE */
1426 WMA_LOGD("%s: Create NOA sub ie", __func__);
1427 wma_p2p_create_sub_ie_noa(&beacon->noa_sub_ie[0],
1428 noa_ie, &new_noa_sub_ie_len);
1429 }
1430 } else {
1431 WMA_LOGD("%s: No need to add NOA", __func__);
1432 new_noa_sub_ie_len = 0; /* no NOA IE sub-attributes */
1433 }
1434
1435 wma_update_beacon_noa_ie(beacon, new_noa_sub_ie_len);
1436}
1437
1438/**
1439 * wma_update_probe_resp_noa() - update noa IE in probe response
1440 * @wma_handle: wma handle
1441 * @noa_ie: noa ie
1442 *
1443 * Return: none
1444 */
1445void wma_update_probe_resp_noa(tp_wma_handle wma_handle,
1446 struct p2p_sub_element_noa *noa_ie)
1447{
1448 tSirP2PNoaAttr *noa_attr =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301449 (tSirP2PNoaAttr *) qdf_mem_malloc(sizeof(tSirP2PNoaAttr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001450 WMA_LOGD("Received update NoA event");
1451 if (!noa_attr) {
1452 WMA_LOGE("Failed to allocate memory for tSirP2PNoaAttr");
1453 return;
1454 }
1455
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301456 qdf_mem_zero(noa_attr, sizeof(tSirP2PNoaAttr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001457
1458 noa_attr->index = noa_ie->index;
1459 noa_attr->oppPsFlag = noa_ie->oppPS;
1460 noa_attr->ctWin = noa_ie->ctwindow;
1461 if (!noa_ie->num_descriptors) {
1462 WMA_LOGD("Zero NoA descriptors");
1463 } else {
1464 WMA_LOGD("%d NoA descriptors", noa_ie->num_descriptors);
1465 noa_attr->uNoa1IntervalCnt =
1466 noa_ie->noa_descriptors[0].type_count;
1467 noa_attr->uNoa1Duration = noa_ie->noa_descriptors[0].duration;
1468 noa_attr->uNoa1Interval = noa_ie->noa_descriptors[0].interval;
1469 noa_attr->uNoa1StartTime =
1470 noa_ie->noa_descriptors[0].start_time;
1471 if (noa_ie->num_descriptors > 1) {
1472 noa_attr->uNoa2IntervalCnt =
1473 noa_ie->noa_descriptors[1].type_count;
1474 noa_attr->uNoa2Duration =
1475 noa_ie->noa_descriptors[1].duration;
1476 noa_attr->uNoa2Interval =
1477 noa_ie->noa_descriptors[1].interval;
1478 noa_attr->uNoa2StartTime =
1479 noa_ie->noa_descriptors[1].start_time;
1480 }
1481 }
1482 WMA_LOGI("Sending SIR_HAL_P2P_NOA_ATTR_IND to LIM");
1483 wma_send_msg(wma_handle, SIR_HAL_P2P_NOA_ATTR_IND, (void *)noa_attr, 0);
1484}
1485
1486/**
1487 * wma_p2p_noa_event_handler() - p2p noa event handler
1488 * @handle: wma handle
1489 * @event: event data
1490 * @len: length
1491 *
1492 * Return: 0 for success or error code.
1493 */
1494int wma_p2p_noa_event_handler(void *handle, uint8_t *event,
1495 uint32_t len)
1496{
1497 tp_wma_handle wma = (tp_wma_handle) handle;
1498 WMI_P2P_NOA_EVENTID_param_tlvs *param_buf;
1499 wmi_p2p_noa_event_fixed_param *p2p_noa_event;
1500 uint8_t vdev_id, i;
1501 wmi_p2p_noa_info *p2p_noa_info;
1502 struct p2p_sub_element_noa noa_ie;
1503 uint8_t *buf_ptr;
1504 uint32_t descriptors;
1505
1506 param_buf = (WMI_P2P_NOA_EVENTID_param_tlvs *) event;
1507 if (!param_buf) {
1508 WMA_LOGE("Invalid P2P NoA event buffer");
1509 return -EINVAL;
1510 }
1511
1512 p2p_noa_event = param_buf->fixed_param;
1513 buf_ptr = (uint8_t *) p2p_noa_event;
1514 buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
1515 p2p_noa_info = (wmi_p2p_noa_info *) (buf_ptr);
1516 vdev_id = p2p_noa_event->vdev_id;
1517
1518 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
1519
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301520 qdf_mem_zero(&noa_ie, sizeof(noa_ie));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 noa_ie.index =
1522 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
1523 noa_ie.oppPS =
1524 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
1525 noa_ie.ctwindow =
1526 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
1527 descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
1528 noa_ie.num_descriptors = (uint8_t) descriptors;
1529
Varun Reddy Yeturu74c87c92017-09-26 15:08:49 -07001530 if (noa_ie.num_descriptors > WMA_MAX_NOA_DESCRIPTORS) {
1531 WMA_LOGD("Sizing down the no of desc %d to max",
1532 noa_ie.num_descriptors);
1533 noa_ie.num_descriptors = WMA_MAX_NOA_DESCRIPTORS;
1534 }
1535 WMA_LOGD("%s: index %u, oppPs %u, ctwindow %u, num_desc = %u",
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001536 __func__, noa_ie.index,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
1538 for (i = 0; i < noa_ie.num_descriptors; i++) {
1539 noa_ie.noa_descriptors[i].type_count =
1540 (uint8_t) p2p_noa_info->noa_descriptors[i].
1541 type_count;
1542 noa_ie.noa_descriptors[i].duration =
1543 p2p_noa_info->noa_descriptors[i].duration;
1544 noa_ie.noa_descriptors[i].interval =
1545 p2p_noa_info->noa_descriptors[i].interval;
1546 noa_ie.noa_descriptors[i].start_time =
1547 p2p_noa_info->noa_descriptors[i].start_time;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001548 WMA_LOGI("%s: NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001549 __func__, i,
1550 noa_ie.noa_descriptors[i].type_count,
1551 noa_ie.noa_descriptors[i].duration,
1552 noa_ie.noa_descriptors[i].interval,
1553 noa_ie.noa_descriptors[i].start_time);
1554 }
1555
1556 /* Send a msg to LIM to update the NoA IE in probe response
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001557 * frames transmitted by the host
1558 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 wma_update_probe_resp_noa(wma, &noa_ie);
1560 }
1561
1562 return 0;
1563}
1564
1565/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001566 * wma_process_set_mimops_req() - Set the received MiMo PS state to firmware
1567 * @handle: wma handle
1568 * @mimops: MIMO powersave params
1569 *
1570 * Return: none
1571 */
1572void wma_process_set_mimops_req(tp_wma_handle wma_handle,
1573 tSetMIMOPS *mimops)
1574{
1575 /* Translate to what firmware understands */
1576 if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_DYNAMIC)
1577 mimops->htMIMOPSState = WMI_PEER_MIMO_PS_DYNAMIC;
1578 else if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_STATIC)
1579 mimops->htMIMOPSState = WMI_PEER_MIMO_PS_STATIC;
1580 else if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_NO_LIMIT)
1581 mimops->htMIMOPSState = WMI_PEER_MIMO_PS_NONE;
1582
Jeff Johnson3fd21822016-11-08 11:30:37 -08001583 WMA_LOGD("%s: htMIMOPSState = %d, sessionId = %d peerMac <%02x:%02x:%02x:%02x:%02x:%02x>",
1584 __func__,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585 mimops->htMIMOPSState, mimops->sessionId, mimops->peerMac[0],
1586 mimops->peerMac[1], mimops->peerMac[2], mimops->peerMac[3],
1587 mimops->peerMac[4], mimops->peerMac[5]);
1588
1589 wma_set_peer_param(wma_handle, mimops->peerMac,
1590 WMI_PEER_MIMO_PS_STATE, mimops->htMIMOPSState,
1591 mimops->sessionId);
1592}
1593
1594/**
1595 * wma_set_mimops() - set MIMO powersave
1596 * @handle: wma handle
1597 * @vdev_id: vdev id
1598 * @value: value
1599 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301600 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301602QDF_STATUS wma_set_mimops(tp_wma_handle wma, uint8_t vdev_id, int value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001603{
Govind Singh09c3b492016-03-08 16:05:14 +05301604 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001605
Govind Singh09c3b492016-03-08 16:05:14 +05301606 ret = wmi_unified_set_mimops(wma->wmi_handle, vdev_id,
1607 value);
1608 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609 WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610
1611 return ret;
1612}
1613
1614/**
1615 * wma_notify_modem_power_state() - notify modem power state
1616 * @wma_ptr: wma handle
1617 * @pReq: modem power state
1618 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301619 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301621QDF_STATUS wma_notify_modem_power_state(void *wma_ptr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001622 tSirModemPowerStateInd *pReq)
1623{
1624 int32_t ret;
1625 tp_wma_handle wma = (tp_wma_handle) wma_ptr;
1626
1627 WMA_LOGD("%s: WMA notify Modem Power State %d", __func__, pReq->param);
1628
Govind Singhd76a5b02016-03-08 15:12:14 +05301629 ret = wma_unified_modem_power_state(wma->wmi_handle, pReq->param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630 if (ret) {
1631 WMA_LOGE("%s: Fail to notify Modem Power State %d",
1632 __func__, pReq->param);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301633 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001634 }
1635
1636 WMA_LOGD("Successfully notify Modem Power State %d", pReq->param);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301637 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638}
1639
1640/**
1641 * wma_set_idle_ps_config() - enable/disble Low Power Support(Pdev Specific)
1642 * @wma_ptr: wma handle
1643 * @idle_ps: idle powersave
1644 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301645 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001646 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301647QDF_STATUS wma_set_idle_ps_config(void *wma_ptr, uint32_t idle_ps)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648{
1649 int32_t ret;
1650 tp_wma_handle wma = (tp_wma_handle) wma_ptr;
Govind Singhd76a5b02016-03-08 15:12:14 +05301651 struct pdev_params pdevparam;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652
1653 WMA_LOGD("WMA Set Idle Ps Config [1:set 0:clear] val %d", idle_ps);
1654
1655 /* Set Idle Mode Power Save Config */
Govind Singhd76a5b02016-03-08 15:12:14 +05301656 pdevparam.param_id = WMI_PDEV_PARAM_IDLE_PS_CONFIG;
1657 pdevparam.param_value = idle_ps;
1658 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
1659 &pdevparam,
1660 WMA_WILDCARD_PDEV_ID);
1661
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 if (ret) {
1663 WMA_LOGE("Fail to Set Idle Ps Config %d", idle_ps);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301664 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 }
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05301666 wma->in_imps = !!idle_ps;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667
1668 WMA_LOGD("Successfully Set Idle Ps Config %d", idle_ps);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301669 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670}
1671
1672/**
1673 * wma_set_smps_params() - set smps params
1674 * @wma: wma handle
1675 * @vdev_id: vdev id
1676 * @value: value
1677 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301678 * Return: QDF_STATUS_SUCCESS for success or error code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301680QDF_STATUS wma_set_smps_params(tp_wma_handle wma, uint8_t vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001681 int value)
1682{
Govind Singh09c3b492016-03-08 16:05:14 +05301683 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001684
Govind Singh09c3b492016-03-08 16:05:14 +05301685 ret = wmi_unified_set_smps_params(wma->wmi_handle, vdev_id,
1686 value);
1687 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689
1690 return ret;
1691}
1692
Qiwei Caie689a262018-07-26 15:50:22 +08001693#ifdef FEATURE_TX_POWER
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001694/**
Peng Xu4d67c8f2015-10-16 16:02:26 -07001695 * wma_set_tx_power_scale() - set tx power scale
1696 * @vdev_id: vdev id
1697 * @value: value
1698 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301699 * Return: QDF_STATUS_SUCCESS for success or error code.
Peng Xu4d67c8f2015-10-16 16:02:26 -07001700 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301701QDF_STATUS wma_set_tx_power_scale(uint8_t vdev_id, int value)
Peng Xu4d67c8f2015-10-16 16:02:26 -07001702{
Peng Xu62c8c432016-05-09 15:23:02 -07001703 QDF_STATUS ret;
Peng Xu4d67c8f2015-10-16 16:02:26 -07001704 tp_wma_handle wma_handle =
Anurag Chouhan6d760662016-02-20 16:05:43 +05301705 (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
Govind Singhd76a5b02016-03-08 15:12:14 +05301706
Peng Xu4d67c8f2015-10-16 16:02:26 -07001707 if (NULL == wma_handle) {
1708 WMA_LOGE("%s: wma_handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301709 return QDF_STATUS_E_FAILURE;
Peng Xu4d67c8f2015-10-16 16:02:26 -07001710 }
1711
Mukul Sharmaf9047232017-03-02 16:58:56 +05301712 if (!wma_is_vdev_up(vdev_id)) {
Peng Xu4d67c8f2015-10-16 16:02:26 -07001713 WMA_LOGE("%s: vdev id %d is not up", __func__, vdev_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301714 return QDF_STATUS_E_FAILURE;
Peng Xu4d67c8f2015-10-16 16:02:26 -07001715 }
1716
Govind Singhd76a5b02016-03-08 15:12:14 +05301717 ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
Peng Xu4d67c8f2015-10-16 16:02:26 -07001718 WMI_VDEV_PARAM_TXPOWER_SCALE, value);
Govind Singhd76a5b02016-03-08 15:12:14 +05301719 if (QDF_IS_STATUS_ERROR(ret))
Peng Xu4d67c8f2015-10-16 16:02:26 -07001720 WMA_LOGE("Set tx power scale failed");
1721
1722 return ret;
1723}
1724
1725/**
1726 * wma_set_tx_power_scale_decr_db() - decrease power by DB value
1727 * @vdev_id: vdev id
1728 * @value: value
1729 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301730 * Return: QDF_STATUS_SUCCESS for success or error code.
Peng Xu4d67c8f2015-10-16 16:02:26 -07001731 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301732QDF_STATUS wma_set_tx_power_scale_decr_db(uint8_t vdev_id, int value)
Peng Xu4d67c8f2015-10-16 16:02:26 -07001733{
Peng Xu62c8c432016-05-09 15:23:02 -07001734 QDF_STATUS ret;
Peng Xu4d67c8f2015-10-16 16:02:26 -07001735 tp_wma_handle wma_handle =
Anurag Chouhan6d760662016-02-20 16:05:43 +05301736 (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
Govind Singhd76a5b02016-03-08 15:12:14 +05301737
Peng Xu4d67c8f2015-10-16 16:02:26 -07001738 if (NULL == wma_handle) {
1739 WMA_LOGE("%s: wma_handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301740 return QDF_STATUS_E_FAILURE;
Peng Xu4d67c8f2015-10-16 16:02:26 -07001741 }
1742
Mukul Sharmaf9047232017-03-02 16:58:56 +05301743 if (!wma_is_vdev_up(vdev_id)) {
Peng Xu4d67c8f2015-10-16 16:02:26 -07001744 WMA_LOGE("%s: vdev id %d is not up", __func__, vdev_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301745 return QDF_STATUS_E_FAILURE;
Peng Xu4d67c8f2015-10-16 16:02:26 -07001746 }
1747
Govind Singhd76a5b02016-03-08 15:12:14 +05301748 ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
Peng Xu4d67c8f2015-10-16 16:02:26 -07001749 WMI_VDEV_PARAM_TXPOWER_SCALE_DECR_DB, value);
Govind Singhd76a5b02016-03-08 15:12:14 +05301750 if (QDF_IS_STATUS_ERROR(ret))
Peng Xu4d67c8f2015-10-16 16:02:26 -07001751 WMA_LOGE("Decrease tx power value failed");
1752
1753 return ret;
1754}
Qiwei Caie689a262018-07-26 15:50:22 +08001755#endif /* FEATURE_TX_POWER */
1756