xref: /wlan-driver/qcacld-3.0/core/wma/src/wma_power.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  *  DOC:    wma_power.c
22*5113495bSYour Name  *  This file contains powersave related functions.
23*5113495bSYour Name  */
24*5113495bSYour Name 
25*5113495bSYour Name /* Header files */
26*5113495bSYour Name 
27*5113495bSYour Name #include "wma.h"
28*5113495bSYour Name #include "wma_api.h"
29*5113495bSYour Name #include "cds_api.h"
30*5113495bSYour Name #include "wmi_unified_api.h"
31*5113495bSYour Name #include "wlan_qct_sys.h"
32*5113495bSYour Name #include "wni_api.h"
33*5113495bSYour Name #include "ani_global.h"
34*5113495bSYour Name #include "wmi_unified.h"
35*5113495bSYour Name #include "wni_cfg.h"
36*5113495bSYour Name 
37*5113495bSYour Name #include "qdf_nbuf.h"
38*5113495bSYour Name #include "qdf_types.h"
39*5113495bSYour Name #include "qdf_mem.h"
40*5113495bSYour Name #include "wma_types.h"
41*5113495bSYour Name #include "lim_api.h"
42*5113495bSYour Name #include "lim_session_utils.h"
43*5113495bSYour Name 
44*5113495bSYour Name #include "cds_utils.h"
45*5113495bSYour Name 
46*5113495bSYour Name #if !defined(REMOVE_PKT_LOG)
47*5113495bSYour Name #include "pktlog_ac.h"
48*5113495bSYour Name #endif /* REMOVE_PKT_LOG */
49*5113495bSYour Name 
50*5113495bSYour Name #include "dbglog_host.h"
51*5113495bSYour Name #include "csr_api.h"
52*5113495bSYour Name #include "ol_fw.h"
53*5113495bSYour Name 
54*5113495bSYour Name #include "wma_internal.h"
55*5113495bSYour Name #include "wlan_pmo_ucfg_api.h"
56*5113495bSYour Name 
57*5113495bSYour Name /**
58*5113495bSYour Name  * wma_unified_modem_power_state() - set modem power state to fw
59*5113495bSYour Name  * @wmi_handle: wmi handle
60*5113495bSYour Name  * @param_value: parameter value
61*5113495bSYour Name  *
62*5113495bSYour Name  * Return: QDF_STATUS
63*5113495bSYour Name  */
64*5113495bSYour Name static QDF_STATUS
wma_unified_modem_power_state(wmi_unified_t wmi_handle,uint32_t param_value)65*5113495bSYour Name wma_unified_modem_power_state(wmi_unified_t wmi_handle, uint32_t param_value)
66*5113495bSYour Name {
67*5113495bSYour Name 	QDF_STATUS status;
68*5113495bSYour Name 	wmi_modem_power_state_cmd_param *cmd;
69*5113495bSYour Name 	wmi_buf_t buf;
70*5113495bSYour Name 	uint16_t len = sizeof(*cmd);
71*5113495bSYour Name 
72*5113495bSYour Name 	buf = wmi_buf_alloc(wmi_handle, len);
73*5113495bSYour Name 	if (!buf)
74*5113495bSYour Name 		return -ENOMEM;
75*5113495bSYour Name 
76*5113495bSYour Name 	cmd = (wmi_modem_power_state_cmd_param *) wmi_buf_data(buf);
77*5113495bSYour Name 	WMITLV_SET_HDR(&cmd->tlv_header,
78*5113495bSYour Name 		       WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param,
79*5113495bSYour Name 		       WMITLV_GET_STRUCT_TLVLEN
80*5113495bSYour Name 			       (wmi_modem_power_state_cmd_param));
81*5113495bSYour Name 	cmd->modem_power_state = param_value;
82*5113495bSYour Name 	wma_debug("Setting cmd->modem_power_state = %u", param_value);
83*5113495bSYour Name 	status = wmi_unified_cmd_send(wmi_handle, buf, len,
84*5113495bSYour Name 				      WMI_MODEM_POWER_STATE_CMDID);
85*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
86*5113495bSYour Name 		wmi_buf_free(buf);
87*5113495bSYour Name 
88*5113495bSYour Name 	return status;
89*5113495bSYour Name }
90*5113495bSYour Name 
91*5113495bSYour Name /**
92*5113495bSYour Name  * wma_unified_set_sta_ps_param() - set sta power save parameter to fw
93*5113495bSYour Name  * @wmi_handle: wmi handle
94*5113495bSYour Name  * @vdev_id: vdev id
95*5113495bSYour Name  * @param: param
96*5113495bSYour Name  * @value: parameter value
97*5113495bSYour Name  *
98*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
99*5113495bSYour Name  */
wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle,uint32_t vdev_id,uint32_t param,uint32_t value)100*5113495bSYour Name QDF_STATUS wma_unified_set_sta_ps_param(wmi_unified_t wmi_handle,
101*5113495bSYour Name 					    uint32_t vdev_id, uint32_t param,
102*5113495bSYour Name 					    uint32_t value)
103*5113495bSYour Name {
104*5113495bSYour Name 	tp_wma_handle wma;
105*5113495bSYour Name 	struct wma_txrx_node *iface;
106*5113495bSYour Name 	struct sta_ps_params sta_ps_param = {0};
107*5113495bSYour Name 	QDF_STATUS status;
108*5113495bSYour Name 
109*5113495bSYour Name 	wma = cds_get_context(QDF_MODULE_ID_WMA);
110*5113495bSYour Name 	if (!wma)
111*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
112*5113495bSYour Name 	if (!wma_is_vdev_valid(vdev_id))
113*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
114*5113495bSYour Name 
115*5113495bSYour Name 	wma_debug("Set Sta Ps param vdevId %d Param %d val %d",
116*5113495bSYour Name 		 vdev_id, param, value);
117*5113495bSYour Name 	iface = &wma->interfaces[vdev_id];
118*5113495bSYour Name 
119*5113495bSYour Name 	sta_ps_param.vdev_id = vdev_id;
120*5113495bSYour Name 	sta_ps_param.param_id = param;
121*5113495bSYour Name 	sta_ps_param.value = value;
122*5113495bSYour Name 	status = wmi_unified_sta_ps_cmd_send(wmi_handle, &sta_ps_param);
123*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
124*5113495bSYour Name 		return status;
125*5113495bSYour Name 
126*5113495bSYour Name 	return status;
127*5113495bSYour Name }
128*5113495bSYour Name 
129*5113495bSYour Name /**
130*5113495bSYour Name  * wma_set_ap_peer_uapsd() - set powersave parameters in ap mode to fw
131*5113495bSYour Name  * @wma: wma handle
132*5113495bSYour Name  * @vdev_id: vdev id
133*5113495bSYour Name  * @peer_addr: peer mac address
134*5113495bSYour Name  * @uapsd_value: uapsd value
135*5113495bSYour Name  * @max_sp: maximum service period
136*5113495bSYour Name  *
137*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
138*5113495bSYour Name  */
wma_set_ap_peer_uapsd(tp_wma_handle wma,uint32_t vdev_id,uint8_t * peer_addr,uint8_t uapsd_value,uint8_t max_sp)139*5113495bSYour Name QDF_STATUS wma_set_ap_peer_uapsd(tp_wma_handle wma, uint32_t vdev_id,
140*5113495bSYour Name 			      uint8_t *peer_addr, uint8_t uapsd_value,
141*5113495bSYour Name 			      uint8_t max_sp)
142*5113495bSYour Name {
143*5113495bSYour Name 	uint32_t uapsd = 0;
144*5113495bSYour Name 	uint32_t max_sp_len = 0;
145*5113495bSYour Name 	QDF_STATUS ret;
146*5113495bSYour Name 	struct ap_ps_params param = {0};
147*5113495bSYour Name 
148*5113495bSYour Name 	if (uapsd_value & UAPSD_VO_ENABLED) {
149*5113495bSYour Name 		uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
150*5113495bSYour Name 			 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
151*5113495bSYour Name 	}
152*5113495bSYour Name 
153*5113495bSYour Name 	if (uapsd_value & UAPSD_VI_ENABLED) {
154*5113495bSYour Name 		uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
155*5113495bSYour Name 			 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
156*5113495bSYour Name 	}
157*5113495bSYour Name 
158*5113495bSYour Name 	if (uapsd_value & UAPSD_BK_ENABLED) {
159*5113495bSYour Name 		uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
160*5113495bSYour Name 			 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
161*5113495bSYour Name 	}
162*5113495bSYour Name 
163*5113495bSYour Name 	if (uapsd_value & UAPSD_BE_ENABLED) {
164*5113495bSYour Name 		uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
165*5113495bSYour Name 			 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
166*5113495bSYour Name 	}
167*5113495bSYour Name 
168*5113495bSYour Name 	switch (max_sp) {
169*5113495bSYour Name 	case UAPSD_MAX_SP_LEN_2:
170*5113495bSYour Name 		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_2;
171*5113495bSYour Name 		break;
172*5113495bSYour Name 	case UAPSD_MAX_SP_LEN_4:
173*5113495bSYour Name 		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_4;
174*5113495bSYour Name 		break;
175*5113495bSYour Name 	case UAPSD_MAX_SP_LEN_6:
176*5113495bSYour Name 		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_6;
177*5113495bSYour Name 		break;
178*5113495bSYour Name 	default:
179*5113495bSYour Name 		max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_UNLIMITED;
180*5113495bSYour Name 		break;
181*5113495bSYour Name 	}
182*5113495bSYour Name 
183*5113495bSYour Name 	wma_debug("Set WMI_AP_PS_PEER_PARAM_UAPSD 0x%x for "QDF_MAC_ADDR_FMT,
184*5113495bSYour Name 		 uapsd, QDF_MAC_ADDR_REF(peer_addr));
185*5113495bSYour Name 	param.vdev_id = vdev_id;
186*5113495bSYour Name 	param.param = WMI_AP_PS_PEER_PARAM_UAPSD;
187*5113495bSYour Name 	param.value = uapsd;
188*5113495bSYour Name 	ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr,
189*5113495bSYour Name 						&param);
190*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
191*5113495bSYour Name 		wma_err("Failed to set WMI_AP_PS_PEER_PARAM_UAPSD for "QDF_MAC_ADDR_FMT,
192*5113495bSYour Name 			QDF_MAC_ADDR_REF(peer_addr));
193*5113495bSYour Name 		return ret;
194*5113495bSYour Name 	}
195*5113495bSYour Name 
196*5113495bSYour Name 	wma_debug("Set WMI_AP_PS_PEER_PARAM_MAX_SP 0x%x for "QDF_MAC_ADDR_FMT,
197*5113495bSYour Name 		 max_sp_len, QDF_MAC_ADDR_REF(peer_addr));
198*5113495bSYour Name 
199*5113495bSYour Name 	param.vdev_id = vdev_id;
200*5113495bSYour Name 	param.param = WMI_AP_PS_PEER_PARAM_MAX_SP;
201*5113495bSYour Name 	param.value = max_sp_len;
202*5113495bSYour Name 	ret = wmi_unified_ap_ps_cmd_send(wma->wmi_handle, peer_addr,
203*5113495bSYour Name 					  &param);
204*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
205*5113495bSYour Name 		wma_err("Failed to set WMI_AP_PS_PEER_PARAM_MAX_SP for "QDF_MAC_ADDR_FMT,
206*5113495bSYour Name 			 QDF_MAC_ADDR_REF(peer_addr));
207*5113495bSYour Name 		return ret;
208*5113495bSYour Name 	}
209*5113495bSYour Name 
210*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
211*5113495bSYour Name }
212*5113495bSYour Name 
213*5113495bSYour Name /**
214*5113495bSYour Name  * wma_update_edca_params_for_ac() - to update per ac EDCA parameters
215*5113495bSYour Name  * @edca_param: EDCA parameters
216*5113495bSYour Name  * @wmm_param: wmm parameters
217*5113495bSYour Name  * @ac: access category
218*5113495bSYour Name  *
219*5113495bSYour Name  * Return: none
220*5113495bSYour Name  */
wma_update_edca_params_for_ac(tSirMacEdcaParamRecord * edca_param,struct wmi_host_wme_vparams * wmm_param,int ac,bool mu_edca_param,uint8_t * debug_str,uint32_t debug_str_size,uint32_t * len)221*5113495bSYour Name void wma_update_edca_params_for_ac(tSirMacEdcaParamRecord *edca_param,
222*5113495bSYour Name 				   struct wmi_host_wme_vparams *wmm_param,
223*5113495bSYour Name 				   int ac, bool mu_edca_param,
224*5113495bSYour Name 				   uint8_t *debug_str,
225*5113495bSYour Name 				   uint32_t debug_str_size, uint32_t *len)
226*5113495bSYour Name {
227*5113495bSYour Name 	wmm_param->cwmin = WMA_WMM_EXPO_TO_VAL(edca_param->cw.min);
228*5113495bSYour Name 	wmm_param->cwmax = WMA_WMM_EXPO_TO_VAL(edca_param->cw.max);
229*5113495bSYour Name 	wmm_param->aifs = edca_param->aci.aifsn;
230*5113495bSYour Name 	if (mu_edca_param)
231*5113495bSYour Name 		wmm_param->mu_edca_timer = edca_param->mu_edca_timer;
232*5113495bSYour Name 	else
233*5113495bSYour Name 		wmm_param->txoplimit = edca_param->txoplimit;
234*5113495bSYour Name 	wmm_param->acm = edca_param->aci.acm;
235*5113495bSYour Name 
236*5113495bSYour Name 	wmm_param->noackpolicy = edca_param->no_ack;
237*5113495bSYour Name 
238*5113495bSYour Name 	*len += qdf_scnprintf(debug_str + *len, debug_str_size - *len,
239*5113495bSYour Name 			      "AC[%d]: AIFS %d Min %d Max %d %s %d ACM %d NOACK %d, ",
240*5113495bSYour Name 			      ac, wmm_param->aifs, wmm_param->cwmin,
241*5113495bSYour Name 			      wmm_param->cwmax,
242*5113495bSYour Name 			      mu_edca_param ? "MU_EDCA TIMER" : "TXOP",
243*5113495bSYour Name 			      mu_edca_param ? wmm_param->mu_edca_timer : wmm_param->txoplimit,
244*5113495bSYour Name 			      wmm_param->acm, wmm_param->noackpolicy);
245*5113495bSYour Name }
246*5113495bSYour Name 
247*5113495bSYour Name /**
248*5113495bSYour Name  * wma_set_tx_power() - set tx power limit in fw
249*5113495bSYour Name  * @handle: wma handle
250*5113495bSYour Name  * @tx_pwr_params: tx power parameters
251*5113495bSYour Name  *
252*5113495bSYour Name  * Return: none
253*5113495bSYour Name  */
wma_set_tx_power(WMA_HANDLE handle,tMaxTxPowerParams * tx_pwr_params)254*5113495bSYour Name void wma_set_tx_power(WMA_HANDLE handle,
255*5113495bSYour Name 		      tMaxTxPowerParams *tx_pwr_params)
256*5113495bSYour Name {
257*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
258*5113495bSYour Name 	uint8_t vdev_id;
259*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
260*5113495bSYour Name 	int8_t max_reg_power;
261*5113495bSYour Name 	struct wma_txrx_node *iface;
262*5113495bSYour Name 
263*5113495bSYour Name 	if (tx_pwr_params->dev_mode == QDF_SAP_MODE ||
264*5113495bSYour Name 	    tx_pwr_params->dev_mode == QDF_P2P_GO_MODE) {
265*5113495bSYour Name 		ret = wma_find_vdev_id_by_addr(wma_handle,
266*5113495bSYour Name 					       tx_pwr_params->bssId.bytes,
267*5113495bSYour Name 					       &vdev_id);
268*5113495bSYour Name 	} else {
269*5113495bSYour Name 		ret = wma_find_vdev_id_by_bssid(wma_handle,
270*5113495bSYour Name 						tx_pwr_params->bssId.bytes,
271*5113495bSYour Name 						&vdev_id);
272*5113495bSYour Name 	}
273*5113495bSYour Name 	if (ret) {
274*5113495bSYour Name 		wma_err("vdev id is invalid for "QDF_MAC_ADDR_FMT,
275*5113495bSYour Name 			QDF_MAC_ADDR_REF(tx_pwr_params->bssId.bytes));
276*5113495bSYour Name 		qdf_mem_free(tx_pwr_params);
277*5113495bSYour Name 		return;
278*5113495bSYour Name 	}
279*5113495bSYour Name 
280*5113495bSYour Name 	if (!wma_is_vdev_up(vdev_id)) {
281*5113495bSYour Name 		wma_err("vdev id %d is not up for "QDF_MAC_ADDR_FMT, vdev_id,
282*5113495bSYour Name 			QDF_MAC_ADDR_REF(tx_pwr_params->bssId.bytes));
283*5113495bSYour Name 		qdf_mem_free(tx_pwr_params);
284*5113495bSYour Name 		return;
285*5113495bSYour Name 	}
286*5113495bSYour Name 
287*5113495bSYour Name 	iface = &wma_handle->interfaces[vdev_id];
288*5113495bSYour Name 	if (tx_pwr_params->power == 0) {
289*5113495bSYour Name 		/* set to default. Since the app does not care the tx power
290*5113495bSYour Name 		 * we keep the previous setting
291*5113495bSYour Name 		 */
292*5113495bSYour Name 		mlme_set_tx_power(iface->vdev, tx_pwr_params->power);
293*5113495bSYour Name 		ret = 0;
294*5113495bSYour Name 		goto end;
295*5113495bSYour Name 	}
296*5113495bSYour Name 
297*5113495bSYour Name 	max_reg_power = mlme_get_max_reg_power(iface->vdev);
298*5113495bSYour Name 
299*5113495bSYour Name 	if (max_reg_power != 0) {
300*5113495bSYour Name 		/* make sure tx_power less than max_tx_power */
301*5113495bSYour Name 		if (tx_pwr_params->power > max_reg_power) {
302*5113495bSYour Name 			tx_pwr_params->power = max_reg_power;
303*5113495bSYour Name 		}
304*5113495bSYour Name 	}
305*5113495bSYour Name 	if (mlme_get_tx_power(iface->vdev) != tx_pwr_params->power) {
306*5113495bSYour Name 
307*5113495bSYour Name 		/* tx_power changed, Push the tx_power to FW */
308*5113495bSYour Name 		wma_nofl_debug("TXP[W][set_tx_pwr]: %d", tx_pwr_params->power);
309*5113495bSYour Name 		ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
310*5113495bSYour Name 					 wmi_vdev_param_tx_pwrlimit,
311*5113495bSYour Name 					 tx_pwr_params->power);
312*5113495bSYour Name 		if (ret == QDF_STATUS_SUCCESS)
313*5113495bSYour Name 			mlme_set_tx_power(iface->vdev, tx_pwr_params->power);
314*5113495bSYour Name 	} else {
315*5113495bSYour Name 		/* no tx_power change */
316*5113495bSYour Name 		ret = QDF_STATUS_SUCCESS;
317*5113495bSYour Name 	}
318*5113495bSYour Name end:
319*5113495bSYour Name 	qdf_mem_free(tx_pwr_params);
320*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
321*5113495bSYour Name 		wma_err("Failed to set vdev param wmi_vdev_param_tx_pwrlimit");
322*5113495bSYour Name }
323*5113495bSYour Name 
324*5113495bSYour Name /**
325*5113495bSYour Name  * wma_set_max_tx_power() - set max tx power limit in fw
326*5113495bSYour Name  * @handle: wma handle
327*5113495bSYour Name  * @tx_pwr_params: tx power parameters
328*5113495bSYour Name  *
329*5113495bSYour Name  * Return: none
330*5113495bSYour Name  */
wma_set_max_tx_power(WMA_HANDLE handle,tMaxTxPowerParams * tx_pwr_params)331*5113495bSYour Name void wma_set_max_tx_power(WMA_HANDLE handle,
332*5113495bSYour Name 			  tMaxTxPowerParams *tx_pwr_params)
333*5113495bSYour Name {
334*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
335*5113495bSYour Name 	uint8_t vdev_id;
336*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
337*5113495bSYour Name 	int8_t max_reg_power;
338*5113495bSYour Name 	struct wma_txrx_node *iface;
339*5113495bSYour Name 	int8_t max_tx_power;
340*5113495bSYour Name 	struct wlan_channel *channel;
341*5113495bSYour Name 	uint16_t ch_freq;
342*5113495bSYour Name 
343*5113495bSYour Name 	if (tx_pwr_params->dev_mode == QDF_SAP_MODE ||
344*5113495bSYour Name 	    tx_pwr_params->dev_mode == QDF_P2P_GO_MODE) {
345*5113495bSYour Name 		ret = wma_find_vdev_id_by_addr(wma_handle,
346*5113495bSYour Name 					       tx_pwr_params->bssId.bytes,
347*5113495bSYour Name 					       &vdev_id);
348*5113495bSYour Name 	} else {
349*5113495bSYour Name 		ret = wma_find_vdev_id_by_bssid(wma_handle,
350*5113495bSYour Name 						tx_pwr_params->bssId.bytes,
351*5113495bSYour Name 						&vdev_id);
352*5113495bSYour Name 	}
353*5113495bSYour Name 	if (ret) {
354*5113495bSYour Name 		wma_err("vdev id is invalid for "QDF_MAC_ADDR_FMT,
355*5113495bSYour Name 			 QDF_MAC_ADDR_REF(tx_pwr_params->bssId.bytes));
356*5113495bSYour Name 		qdf_mem_free(tx_pwr_params);
357*5113495bSYour Name 		return;
358*5113495bSYour Name 	}
359*5113495bSYour Name 
360*5113495bSYour Name 	if (!wma_is_vdev_up(vdev_id)) {
361*5113495bSYour Name 		wma_err("vdev id %d is not up", vdev_id);
362*5113495bSYour Name 		qdf_mem_free(tx_pwr_params);
363*5113495bSYour Name 		return;
364*5113495bSYour Name 	}
365*5113495bSYour Name 
366*5113495bSYour Name 	iface = &wma_handle->interfaces[vdev_id];
367*5113495bSYour Name 	channel = wlan_vdev_get_active_channel(iface->vdev);
368*5113495bSYour Name 	if (channel) {
369*5113495bSYour Name 		ch_freq = channel->ch_freq;
370*5113495bSYour Name 	} else {
371*5113495bSYour Name 		wma_err("Failed to get active channel");
372*5113495bSYour Name 		qdf_mem_free(tx_pwr_params);
373*5113495bSYour Name 		return;
374*5113495bSYour Name 	}
375*5113495bSYour Name 	max_reg_power = wlan_reg_get_channel_reg_power_for_freq(
376*5113495bSYour Name 			wma_handle->mac_context->pdev, ch_freq);
377*5113495bSYour Name 	/*
378*5113495bSYour Name 	 * When user tx power as auto, host will configure
379*5113495bSYour Name 	 * the tx power as max regulatory power allowed for
380*5113495bSYour Name 	 * that channel which signifies that it will be the
381*5113495bSYour Name 	 * upper limit for tx power used while transmission
382*5113495bSYour Name 	 */
383*5113495bSYour Name 	if (tx_pwr_params->power == 0)
384*5113495bSYour Name 		max_tx_power = max_reg_power;
385*5113495bSYour Name 	else
386*5113495bSYour Name 		max_tx_power = QDF_MIN(tx_pwr_params->power, max_reg_power);
387*5113495bSYour Name 
388*5113495bSYour Name 	wma_nofl_debug("TXP[W][set_max_pwr_req]: %d", max_tx_power);
389*5113495bSYour Name 	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
390*5113495bSYour Name 				wmi_vdev_param_tx_pwrlimit,
391*5113495bSYour Name 				max_tx_power);
392*5113495bSYour Name 	if (ret == QDF_STATUS_SUCCESS)
393*5113495bSYour Name 		mlme_set_tx_power(iface->vdev, max_tx_power);
394*5113495bSYour Name 	qdf_mem_free(tx_pwr_params);
395*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
396*5113495bSYour Name 		wma_err("Failed to set vdev param wmi_vdev_param_tx_pwrlimit");
397*5113495bSYour Name }
398*5113495bSYour Name 
399*5113495bSYour Name /**
400*5113495bSYour Name  * wmi_unified_set_sta_ps() - set sta powersave params in fw
401*5113495bSYour Name  * @handle: wma handle
402*5113495bSYour Name  * @vdev_id: vdev id
403*5113495bSYour Name  * @val: value
404*5113495bSYour Name  *
405*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
406*5113495bSYour Name  */
wmi_unified_set_sta_ps(wmi_unified_t wmi_handle,uint32_t vdev_id,uint8_t val)407*5113495bSYour Name static QDF_STATUS wmi_unified_set_sta_ps(wmi_unified_t wmi_handle,
408*5113495bSYour Name 					 uint32_t vdev_id, uint8_t val)
409*5113495bSYour Name {
410*5113495bSYour Name 	QDF_STATUS ret;
411*5113495bSYour Name 
412*5113495bSYour Name 	ret = wmi_unified_set_sta_ps_mode(wmi_handle, vdev_id,
413*5113495bSYour Name 				   val);
414*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
415*5113495bSYour Name 		wma_err("Failed to send set Mimo PS ret = %d", ret);
416*5113495bSYour Name 
417*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
418*5113495bSYour Name }
419*5113495bSYour Name 
420*5113495bSYour Name /**
421*5113495bSYour Name  * wma_get_uapsd_mask() - get uapsd mask based on uapsd parameters
422*5113495bSYour Name  * @uapsd_params: uapsed parameters
423*5113495bSYour Name  *
424*5113495bSYour Name  * Return: uapsd mask
425*5113495bSYour Name  */
wma_get_uapsd_mask(tpUapsd_Params uapsd_params)426*5113495bSYour Name static inline uint32_t wma_get_uapsd_mask(tpUapsd_Params uapsd_params)
427*5113495bSYour Name {
428*5113495bSYour Name 	uint32_t uapsd_val = 0;
429*5113495bSYour Name 
430*5113495bSYour Name 	if (uapsd_params->beDeliveryEnabled)
431*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC0_DELIVERY_EN;
432*5113495bSYour Name 
433*5113495bSYour Name 	if (uapsd_params->beTriggerEnabled)
434*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
435*5113495bSYour Name 
436*5113495bSYour Name 	if (uapsd_params->bkDeliveryEnabled)
437*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC1_DELIVERY_EN;
438*5113495bSYour Name 
439*5113495bSYour Name 	if (uapsd_params->bkTriggerEnabled)
440*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
441*5113495bSYour Name 
442*5113495bSYour Name 	if (uapsd_params->viDeliveryEnabled)
443*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC2_DELIVERY_EN;
444*5113495bSYour Name 
445*5113495bSYour Name 	if (uapsd_params->viTriggerEnabled)
446*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
447*5113495bSYour Name 
448*5113495bSYour Name 	if (uapsd_params->voDeliveryEnabled)
449*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC3_DELIVERY_EN;
450*5113495bSYour Name 
451*5113495bSYour Name 	if (uapsd_params->voTriggerEnabled)
452*5113495bSYour Name 		uapsd_val |= WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
453*5113495bSYour Name 
454*5113495bSYour Name 	return uapsd_val;
455*5113495bSYour Name }
456*5113495bSYour Name 
457*5113495bSYour Name /**
458*5113495bSYour Name  * wma_set_force_sleep() - set power save parameters to fw
459*5113495bSYour Name  * @wma: wma handle
460*5113495bSYour Name  * @vdev_id: vdev id
461*5113495bSYour Name  * @enable: enable/disable
462*5113495bSYour Name  * @ps_param: OPM params
463*5113495bSYour Name  * @enable_ps: enable power save
464*5113495bSYour Name  *
465*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
466*5113495bSYour Name  */
wma_set_force_sleep(tp_wma_handle wma,uint32_t vdev_id,uint8_t enable,struct wma_ps_params * ps_params,bool enable_ps)467*5113495bSYour Name static QDF_STATUS wma_set_force_sleep(tp_wma_handle wma,
468*5113495bSYour Name 				uint32_t vdev_id,
469*5113495bSYour Name 				uint8_t enable,
470*5113495bSYour Name 				struct wma_ps_params *ps_params,
471*5113495bSYour Name 				bool enable_ps)
472*5113495bSYour Name {
473*5113495bSYour Name 	QDF_STATUS ret;
474*5113495bSYour Name 	/* get mac to access CFG data base */
475*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
476*5113495bSYour Name 	uint32_t rx_wake_policy;
477*5113495bSYour Name 	uint32_t tx_wake_threshold;
478*5113495bSYour Name 	uint32_t pspoll_count;
479*5113495bSYour Name 	uint32_t psmode;
480*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
481*5113495bSYour Name 	u32 listen_interval = 0;
482*5113495bSYour Name 
483*5113495bSYour Name 	wma_debug("Set Force Sleep vdevId %d val %d", vdev_id, enable);
484*5113495bSYour Name 
485*5113495bSYour Name 	if (!mac) {
486*5113495bSYour Name 		wma_err("Unable to get PE context");
487*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
488*5113495bSYour Name 	}
489*5113495bSYour Name 
490*5113495bSYour Name 	if (enable) {
491*5113495bSYour Name 		/* override normal configuration and force station asleep */
492*5113495bSYour Name 		rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
493*5113495bSYour Name 		tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
494*5113495bSYour Name 
495*5113495bSYour Name 		if (ucfg_pmo_get_max_ps_poll(mac->psoc))
496*5113495bSYour Name 			pspoll_count =
497*5113495bSYour Name 				(uint32_t)ucfg_pmo_get_max_ps_poll(mac->psoc);
498*5113495bSYour Name 		else
499*5113495bSYour Name 			pspoll_count = WMA_DEFAULT_MAX_PSPOLL_BEFORE_WAKE;
500*5113495bSYour Name 
501*5113495bSYour Name 		psmode = WMI_STA_PS_MODE_ENABLED;
502*5113495bSYour Name 	} else {
503*5113495bSYour Name 		/* Ps Poll Wake Policy */
504*5113495bSYour Name 		if (ucfg_pmo_get_max_ps_poll(mac->psoc)) {
505*5113495bSYour Name 			/* Ps Poll is enabled */
506*5113495bSYour Name 			rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
507*5113495bSYour Name 			pspoll_count =
508*5113495bSYour Name 				(uint32_t)ucfg_pmo_get_max_ps_poll(mac->psoc);
509*5113495bSYour Name 			tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
510*5113495bSYour Name 		} else {
511*5113495bSYour Name 			rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
512*5113495bSYour Name 			pspoll_count = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
513*5113495bSYour Name 			tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
514*5113495bSYour Name 		}
515*5113495bSYour Name 		psmode = WMI_STA_PS_MODE_ENABLED;
516*5113495bSYour Name 	}
517*5113495bSYour Name 
518*5113495bSYour Name 	/*
519*5113495bSYour Name 	 * Advanced power save is enabled by default in Firmware
520*5113495bSYour Name 	 * So Disable advanced power save explicitly
521*5113495bSYour Name 	 */
522*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
523*5113495bSYour Name 					   WMI_STA_PS_ENABLE_OPM,
524*5113495bSYour Name 					   ps_params->opm_mode);
525*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
526*5113495bSYour Name 		wma_err("%s(%d) Power Failed vdevId %d",
527*5113495bSYour Name 			ps_params->opm_mode ? "Enable" : "Disable",
528*5113495bSYour Name 			ps_params->opm_mode, vdev_id);
529*5113495bSYour Name 		return ret;
530*5113495bSYour Name 	}
531*5113495bSYour Name 	wma_debug("Power %s(%d) vdevId %d",
532*5113495bSYour Name 		 ps_params->opm_mode ? "Enabled" : "Disabled",
533*5113495bSYour Name 		 ps_params->opm_mode, vdev_id);
534*5113495bSYour Name 
535*5113495bSYour Name 	/* Set the Tx/Rx InActivity */
536*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
537*5113495bSYour Name 					   WMI_STA_PS_PARAM_INACTIVITY_TIME,
538*5113495bSYour Name 					   ps_params->ps_ito);
539*5113495bSYour Name 
540*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
541*5113495bSYour Name 		wma_err("Setting Tx/Rx InActivity Failed vdevId %d InAct %d",
542*5113495bSYour Name 			vdev_id, ps_params->ps_ito);
543*5113495bSYour Name 		return ret;
544*5113495bSYour Name 	}
545*5113495bSYour Name 	wma_debug("Set Tx/Rx InActivity vdevId %d InAct %d",
546*5113495bSYour Name 		  vdev_id, ps_params->ps_ito);
547*5113495bSYour Name 
548*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
549*5113495bSYour Name 					   WMI_STA_PS_PARAM_SPEC_WAKE_INTERVAL,
550*5113495bSYour Name 					   ps_params->spec_wake);
551*5113495bSYour Name 
552*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
553*5113495bSYour Name 		wma_err("Setting Spec wake Failed vdevId %d InAct %d",
554*5113495bSYour Name 			vdev_id, ps_params->spec_wake);
555*5113495bSYour Name 		return ret;
556*5113495bSYour Name 	}
557*5113495bSYour Name 	wma_debug("Set Spec wake vdevId %d InAct %d",
558*5113495bSYour Name 		  vdev_id, ps_params->spec_wake);
559*5113495bSYour Name 
560*5113495bSYour Name 	/* Set the Wake Policy to WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD */
561*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
562*5113495bSYour Name 					   WMI_STA_PS_PARAM_RX_WAKE_POLICY,
563*5113495bSYour Name 					   rx_wake_policy);
564*5113495bSYour Name 
565*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
566*5113495bSYour Name 		wma_err("Setting wake policy Failed vdevId %d", vdev_id);
567*5113495bSYour Name 		return ret;
568*5113495bSYour Name 	}
569*5113495bSYour Name 	wma_debug("Setting wake policy to %d vdevId %d",
570*5113495bSYour Name 		 rx_wake_policy, vdev_id);
571*5113495bSYour Name 
572*5113495bSYour Name 	/* Set the Tx Wake Threshold */
573*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
574*5113495bSYour Name 					   WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD,
575*5113495bSYour Name 					   tx_wake_threshold);
576*5113495bSYour Name 
577*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
578*5113495bSYour Name 		wma_err("Setting TxWake Threshold vdevId %d", vdev_id);
579*5113495bSYour Name 		return ret;
580*5113495bSYour Name 	}
581*5113495bSYour Name 	wma_debug("Setting TxWake Threshold to %d vdevId %d",
582*5113495bSYour Name 		 tx_wake_threshold, vdev_id);
583*5113495bSYour Name 
584*5113495bSYour Name 	/* Set the Ps Poll Count */
585*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
586*5113495bSYour Name 					   WMI_STA_PS_PARAM_PSPOLL_COUNT,
587*5113495bSYour Name 					   pspoll_count);
588*5113495bSYour Name 
589*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
590*5113495bSYour Name 		wma_err("Set Ps Poll Count Failed vdevId %d ps poll cnt %d",
591*5113495bSYour Name 			 vdev_id, pspoll_count);
592*5113495bSYour Name 		return ret;
593*5113495bSYour Name 	}
594*5113495bSYour Name 	wma_debug("Set Ps Poll Count vdevId %d ps poll cnt %d",
595*5113495bSYour Name 		 vdev_id, pspoll_count);
596*5113495bSYour Name 
597*5113495bSYour Name 	/* Enable Sta Mode Power save */
598*5113495bSYour Name 	if (enable_ps) {
599*5113495bSYour Name 		ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, true);
600*5113495bSYour Name 
601*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret)) {
602*5113495bSYour Name 			wma_err("Enable Sta Mode Ps Failed vdevId %d",
603*5113495bSYour Name 				vdev_id);
604*5113495bSYour Name 			return ret;
605*5113495bSYour Name 		}
606*5113495bSYour Name 	}
607*5113495bSYour Name 
608*5113495bSYour Name 	/* Set Listen Interval */
609*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
610*5113495bSYour Name 						    WLAN_LEGACY_WMA_ID);
611*5113495bSYour Name 	/* If user has configured listen interval already
612*5113495bSYour Name 	 * No need to send vdev set param cmd
613*5113495bSYour Name 	 */
614*5113495bSYour Name 	if (vdev) {
615*5113495bSYour Name 		ret = wlan_pmo_get_listen_interval(vdev, &listen_interval);
616*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
617*5113495bSYour Name 	}
618*5113495bSYour Name 
619*5113495bSYour Name 	if (!listen_interval || QDF_IS_STATUS_ERROR(ret)) {
620*5113495bSYour Name 		listen_interval = mac->mlme_cfg->sap_cfg.listen_interval;
621*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
622*5113495bSYour Name 					 wmi_vdev_param_listen_interval,
623*5113495bSYour Name 					 listen_interval);
624*5113495bSYour Name 	}
625*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
626*5113495bSYour Name 		/* Even it fails continue Fw will take default LI */
627*5113495bSYour Name 		wma_err("Failed to Set Listen Interval vdevId %d", vdev_id);
628*5113495bSYour Name 	}
629*5113495bSYour Name 	wma_debug("Set Listen Interval vdevId %d Listen Intv %d",
630*5113495bSYour Name 		 vdev_id, listen_interval);
631*5113495bSYour Name 
632*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
633*5113495bSYour Name }
634*5113495bSYour Name 
wma_wlan_pmo_get_ps_params(struct wlan_objmgr_vdev * vdev,struct wma_ps_params * ps_params)635*5113495bSYour Name static QDF_STATUS wma_wlan_pmo_get_ps_params(struct wlan_objmgr_vdev *vdev,
636*5113495bSYour Name 					     struct wma_ps_params *ps_params)
637*5113495bSYour Name {
638*5113495bSYour Name 	struct pmo_ps_params pmo_ps_param = {0};
639*5113495bSYour Name 	QDF_STATUS status;
640*5113495bSYour Name 
641*5113495bSYour Name 	status = wlan_pmo_get_ps_params(vdev, &pmo_ps_param);
642*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
643*5113495bSYour Name 		return status;
644*5113495bSYour Name 
645*5113495bSYour Name 	switch (pmo_ps_param.opm_mode) {
646*5113495bSYour Name 	case PMO_PS_ADVANCED_POWER_SAVE_DISABLE:
647*5113495bSYour Name 		ps_params->opm_mode = WMI_STA_PS_OPM_CONSERVATIVE;
648*5113495bSYour Name 		break;
649*5113495bSYour Name 	case PMO_PS_ADVANCED_POWER_SAVE_ENABLE:
650*5113495bSYour Name 		ps_params->opm_mode = WMI_STA_PS_OPM_AGGRESSIVE;
651*5113495bSYour Name 		break;
652*5113495bSYour Name 	case PMO_PS_ADVANCED_POWER_SAVE_USER_DEFINED:
653*5113495bSYour Name 		ps_params->opm_mode = WMI_STA_PS_USER_DEF;
654*5113495bSYour Name 		break;
655*5113495bSYour Name 	default:
656*5113495bSYour Name 		wma_err("Invalid opm_mode:%d", pmo_ps_param.opm_mode);
657*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
658*5113495bSYour Name 	}
659*5113495bSYour Name 	ps_params->ps_ito = pmo_ps_param.ps_ito;
660*5113495bSYour Name 	ps_params->spec_wake = pmo_ps_param.spec_wake;
661*5113495bSYour Name 
662*5113495bSYour Name 	return status;
663*5113495bSYour Name }
664*5113495bSYour Name 
wma_enable_sta_ps_mode(tpEnablePsParams ps_req)665*5113495bSYour Name void wma_enable_sta_ps_mode(tpEnablePsParams ps_req)
666*5113495bSYour Name {
667*5113495bSYour Name 	uint32_t vdev_id = ps_req->sessionid;
668*5113495bSYour Name 	QDF_STATUS ret;
669*5113495bSYour Name 	struct wma_txrx_node *iface;
670*5113495bSYour Name 	t_wma_handle *wma_handle;
671*5113495bSYour Name 	struct wma_ps_params ps_params = {0};
672*5113495bSYour Name 
673*5113495bSYour Name 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
674*5113495bSYour Name 	if (!wma_handle)
675*5113495bSYour Name 		return;
676*5113495bSYour Name 
677*5113495bSYour Name 	iface = &wma_handle->interfaces[vdev_id];
678*5113495bSYour Name 
679*5113495bSYour Name 	if (!iface || !iface->vdev) {
680*5113495bSYour Name 		wma_err("vdev is NULL for vdev_%d", vdev_id);
681*5113495bSYour Name 		return;
682*5113495bSYour Name 	}
683*5113495bSYour Name 
684*5113495bSYour Name 	ret = wma_wlan_pmo_get_ps_params(iface->vdev, &ps_params);
685*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
686*5113495bSYour Name 		return;
687*5113495bSYour Name 
688*5113495bSYour Name 	if (eSIR_ADDON_NOTHING == ps_req->psSetting) {
689*5113495bSYour Name 		if (ps_params.opm_mode && iface->uapsd_cached_val) {
690*5113495bSYour Name 			ps_params.opm_mode = WMI_STA_PS_OPM_CONSERVATIVE;
691*5113495bSYour Name 			wma_debug("Advanced power save is disabled");
692*5113495bSYour Name 		}
693*5113495bSYour Name 		wma_debug("Enable Sta Mode Ps vdevId %d", vdev_id);
694*5113495bSYour Name 		ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
695*5113495bSYour Name 						   vdev_id,
696*5113495bSYour Name 				WMI_STA_PS_PARAM_UAPSD, 0);
697*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret)) {
698*5113495bSYour Name 			wma_err("Set Uapsd param 0 Failed vdevId %d", vdev_id);
699*5113495bSYour Name 			return;
700*5113495bSYour Name 		}
701*5113495bSYour Name 
702*5113495bSYour Name 		ret = wma_set_force_sleep(wma_handle, vdev_id, false,
703*5113495bSYour Name 					  &ps_params, true);
704*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret)) {
705*5113495bSYour Name 			wma_err("Enable Sta Ps Failed vdevId %d", vdev_id);
706*5113495bSYour Name 			return;
707*5113495bSYour Name 		}
708*5113495bSYour Name 	} else if (eSIR_ADDON_ENABLE_UAPSD == ps_req->psSetting) {
709*5113495bSYour Name 		uint32_t uapsd_val = 0;
710*5113495bSYour Name 
711*5113495bSYour Name 		uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams);
712*5113495bSYour Name 		if (uapsd_val != iface->uapsd_cached_val) {
713*5113495bSYour Name 			wma_debug("Enable Uapsd vdevId %d Mask %d",
714*5113495bSYour Name 					vdev_id, uapsd_val);
715*5113495bSYour Name 			ret =
716*5113495bSYour Name 			 wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
717*5113495bSYour Name 						      vdev_id,
718*5113495bSYour Name 						      WMI_STA_PS_PARAM_UAPSD,
719*5113495bSYour Name 						      uapsd_val);
720*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(ret)) {
721*5113495bSYour Name 				wma_err("Enable Uapsd Failed vdevId %d",
722*5113495bSYour Name 					vdev_id);
723*5113495bSYour Name 				return;
724*5113495bSYour Name 			}
725*5113495bSYour Name 			/* Cache the Uapsd Mask */
726*5113495bSYour Name 			iface->uapsd_cached_val = uapsd_val;
727*5113495bSYour Name 		} else {
728*5113495bSYour Name 			wma_debug("Already Uapsd Enabled vdevId %d Mask %d",
729*5113495bSYour Name 					vdev_id, uapsd_val);
730*5113495bSYour Name 		}
731*5113495bSYour Name 
732*5113495bSYour Name 		if (!!ps_params.opm_mode && !!iface->uapsd_cached_val) {
733*5113495bSYour Name 			ps_params.opm_mode = WMI_STA_PS_OPM_CONSERVATIVE;
734*5113495bSYour Name 			wma_debug("Qpower is disabled");
735*5113495bSYour Name 		}
736*5113495bSYour Name 		wma_debug("Enable Forced Sleep vdevId %d", vdev_id);
737*5113495bSYour Name 		ret = wma_set_force_sleep(wma_handle, vdev_id, true,
738*5113495bSYour Name 					  &ps_params, true);
739*5113495bSYour Name 
740*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret)) {
741*5113495bSYour Name 			wma_err("Enable Forced Sleep Failed vdevId %d",
742*5113495bSYour Name 				 vdev_id);
743*5113495bSYour Name 			return;
744*5113495bSYour Name 		}
745*5113495bSYour Name 	}
746*5113495bSYour Name 
747*5113495bSYour Name 	if (wma_handle->ito_repeat_count) {
748*5113495bSYour Name 		wma_debug("Set ITO count to %d for vdevId %d",
749*5113495bSYour Name 			 wma_handle->ito_repeat_count, vdev_id);
750*5113495bSYour Name 
751*5113495bSYour Name 		ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
752*5113495bSYour Name 			vdev_id,
753*5113495bSYour Name 			WMI_STA_PS_PARAM_MAX_RESET_ITO_COUNT_ON_TIM_NO_TXRX,
754*5113495bSYour Name 			wma_handle->ito_repeat_count);
755*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret)) {
756*5113495bSYour Name 			wma_err("Set ITO count failed vdevId %d Error %d",
757*5113495bSYour Name 				 vdev_id, ret);
758*5113495bSYour Name 			return;
759*5113495bSYour Name 		}
760*5113495bSYour Name 	}
761*5113495bSYour Name 
762*5113495bSYour Name 	/* power save request succeeded */
763*5113495bSYour Name 	iface->in_bmps = true;
764*5113495bSYour Name }
765*5113495bSYour Name 
766*5113495bSYour Name 
767*5113495bSYour Name /**
768*5113495bSYour Name  * wma_disable_sta_ps_mode() - disable sta powersave params in fw
769*5113495bSYour Name  * @wma: wma handle
770*5113495bSYour Name  * @ps_req: power save request
771*5113495bSYour Name  *
772*5113495bSYour Name  * Return: none
773*5113495bSYour Name  */
wma_disable_sta_ps_mode(tpDisablePsParams ps_req)774*5113495bSYour Name void wma_disable_sta_ps_mode(tpDisablePsParams ps_req)
775*5113495bSYour Name {
776*5113495bSYour Name 	QDF_STATUS ret;
777*5113495bSYour Name 	uint32_t vdev_id = ps_req->sessionid;
778*5113495bSYour Name 	struct wma_txrx_node *iface;
779*5113495bSYour Name 	t_wma_handle *wma_handle;
780*5113495bSYour Name 
781*5113495bSYour Name 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
782*5113495bSYour Name 	if (!wma_handle)
783*5113495bSYour Name 		return;
784*5113495bSYour Name 
785*5113495bSYour Name 	iface = &wma_handle->interfaces[vdev_id];
786*5113495bSYour Name 
787*5113495bSYour Name 	wma_debug("Disable Sta Mode Ps vdevId %d", vdev_id);
788*5113495bSYour Name 
789*5113495bSYour Name 	/* Disable Sta Mode Power save */
790*5113495bSYour Name 	ret = wmi_unified_set_sta_ps(wma_handle->wmi_handle, vdev_id, false);
791*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
792*5113495bSYour Name 		wma_err("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
793*5113495bSYour Name 		return;
794*5113495bSYour Name 	}
795*5113495bSYour Name 	iface->in_bmps = false;
796*5113495bSYour Name 
797*5113495bSYour Name 	/* Disable UAPSD incase if additional Req came */
798*5113495bSYour Name 	if (eSIR_ADDON_DISABLE_UAPSD == ps_req->psSetting) {
799*5113495bSYour Name 		wma_debug("Disable Uapsd vdevId %d", vdev_id);
800*5113495bSYour Name 		ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle,
801*5113495bSYour Name 						   vdev_id,
802*5113495bSYour Name 				WMI_STA_PS_PARAM_UAPSD, 0);
803*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret)) {
804*5113495bSYour Name 			wma_err("Disable Uapsd Failed vdevId %d", vdev_id);
805*5113495bSYour Name 			/*
806*5113495bSYour Name 			 * Even this fails we can proceed as success
807*5113495bSYour Name 			 * since we disabled powersave
808*5113495bSYour Name 			 */
809*5113495bSYour Name 		}
810*5113495bSYour Name 	}
811*5113495bSYour Name }
812*5113495bSYour Name 
813*5113495bSYour Name /**
814*5113495bSYour Name  * wma_convert_opm_mode() - convert opm with equivalent wmi opm
815*5113495bSYour Name  * @opm_mode: Optimized power management mode
816*5113495bSYour Name  *
817*5113495bSYour Name  * Return: enum wmi_sta_ps_scheme_cfg
818*5113495bSYour Name  */
819*5113495bSYour Name static enum wmi_sta_ps_scheme_cfg
wma_convert_opm_mode(enum wma_sta_ps_scheme_cfg opm_mode)820*5113495bSYour Name wma_convert_opm_mode(enum wma_sta_ps_scheme_cfg opm_mode)
821*5113495bSYour Name {
822*5113495bSYour Name 	switch (opm_mode) {
823*5113495bSYour Name 	case WMA_STA_PS_OPM_CONSERVATIVE:
824*5113495bSYour Name 		return WMI_STA_PS_OPM_CONSERVATIVE;
825*5113495bSYour Name 	case WMA_STA_PS_OPM_AGGRESSIVE:
826*5113495bSYour Name 		return WMI_STA_PS_OPM_AGGRESSIVE;
827*5113495bSYour Name 	case WMA_STA_PS_USER_DEF:
828*5113495bSYour Name 		return WMI_STA_PS_USER_DEF;
829*5113495bSYour Name 	default:
830*5113495bSYour Name 		wma_err("Invalid opm_mode: %d", opm_mode);
831*5113495bSYour Name 		return WMI_STA_PS_OPM_CONSERVATIVE;
832*5113495bSYour Name 	}
833*5113495bSYour Name }
834*5113495bSYour Name 
wma_set_power_config(uint8_t vdev_id,enum wma_sta_ps_scheme_cfg power)835*5113495bSYour Name QDF_STATUS wma_set_power_config(uint8_t vdev_id,
836*5113495bSYour Name 				enum wma_sta_ps_scheme_cfg power)
837*5113495bSYour Name {
838*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
839*5113495bSYour Name 
840*5113495bSYour Name 	if (!wma)
841*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
842*5113495bSYour Name 
843*5113495bSYour Name 	wma_info("configuring power: %d", power);
844*5113495bSYour Name 	return wma_unified_set_sta_ps_param(wma->wmi_handle,
845*5113495bSYour Name 					    vdev_id,
846*5113495bSYour Name 					    WMI_STA_PS_ENABLE_OPM,
847*5113495bSYour Name 					    wma_convert_opm_mode(power));
848*5113495bSYour Name }
849*5113495bSYour Name 
wma_set_power_config_ito(uint8_t vdev_id,uint16_t ps_ito)850*5113495bSYour Name QDF_STATUS wma_set_power_config_ito(uint8_t vdev_id, uint16_t ps_ito)
851*5113495bSYour Name {
852*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
853*5113495bSYour Name 
854*5113495bSYour Name 	if (!wma) {
855*5113495bSYour Name 		wma_err("wma_handle is NULL");
856*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
857*5113495bSYour Name 	}
858*5113495bSYour Name 
859*5113495bSYour Name 	return wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
860*5113495bSYour Name 					   WMI_STA_PS_PARAM_INACTIVITY_TIME,
861*5113495bSYour Name 					   ps_ito);
862*5113495bSYour Name }
863*5113495bSYour Name 
wma_set_power_config_spec_wake(uint8_t vdev_id,uint16_t spec_wake)864*5113495bSYour Name QDF_STATUS wma_set_power_config_spec_wake(uint8_t vdev_id, uint16_t spec_wake)
865*5113495bSYour Name {
866*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
867*5113495bSYour Name 
868*5113495bSYour Name 	if (!wma) {
869*5113495bSYour Name 		wma_err("wma_handle is NULL");
870*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
871*5113495bSYour Name 	}
872*5113495bSYour Name 
873*5113495bSYour Name 	return wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
874*5113495bSYour Name 			WMI_STA_PS_PARAM_SPEC_WAKE_INTERVAL,
875*5113495bSYour Name 			spec_wake);
876*5113495bSYour Name }
877*5113495bSYour Name 
wma_enable_uapsd_mode(tp_wma_handle wma,tpEnableUapsdParams ps_req)878*5113495bSYour Name void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req)
879*5113495bSYour Name {
880*5113495bSYour Name 	QDF_STATUS ret;
881*5113495bSYour Name 	uint32_t vdev_id = ps_req->sessionid;
882*5113495bSYour Name 	uint32_t uapsd_val = 0;
883*5113495bSYour Name 	struct wma_ps_params ps_params = {0};
884*5113495bSYour Name 	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
885*5113495bSYour Name 
886*5113495bSYour Name 	if (!iface->vdev) {
887*5113495bSYour Name 		wma_err("vdev is NULL for vdev_%d", vdev_id);
888*5113495bSYour Name 		return;
889*5113495bSYour Name 	}
890*5113495bSYour Name 
891*5113495bSYour Name 	ret = wma_wlan_pmo_get_ps_params(iface->vdev, &ps_params);
892*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
893*5113495bSYour Name 		wma_err("ps_param is invalid for vdev_%d", vdev_id);
894*5113495bSYour Name 		return;
895*5113495bSYour Name 	}
896*5113495bSYour Name 
897*5113495bSYour Name 	/* Disable Sta Mode Power save */
898*5113495bSYour Name 	ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
899*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
900*5113495bSYour Name 		wma_err("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
901*5113495bSYour Name 		return;
902*5113495bSYour Name 	}
903*5113495bSYour Name 
904*5113495bSYour Name 	uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams);
905*5113495bSYour Name 
906*5113495bSYour Name 	wma_debug("Enable Uapsd vdevId %d Mask %d", vdev_id, uapsd_val);
907*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
908*5113495bSYour Name 			WMI_STA_PS_PARAM_UAPSD, uapsd_val);
909*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
910*5113495bSYour Name 		wma_err("Enable Uapsd Failed vdevId %d", vdev_id);
911*5113495bSYour Name 		return;
912*5113495bSYour Name 	}
913*5113495bSYour Name 
914*5113495bSYour Name 	if (!!ps_params.opm_mode && !!uapsd_val) {
915*5113495bSYour Name 		ps_params.opm_mode = 0;
916*5113495bSYour Name 		wma_debug("Disable power %d", vdev_id);
917*5113495bSYour Name 	}
918*5113495bSYour Name 	iface->uapsd_cached_val = uapsd_val;
919*5113495bSYour Name 	wma_debug("Enable Forced Sleep vdevId %d", vdev_id);
920*5113495bSYour Name 	ret = wma_set_force_sleep(wma, vdev_id, true,
921*5113495bSYour Name 				  &ps_params, ps_req->uapsdParams.enable_ps);
922*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
923*5113495bSYour Name 		wma_err("Enable Forced Sleep Failed vdevId %d", vdev_id);
924*5113495bSYour Name 		return;
925*5113495bSYour Name 	}
926*5113495bSYour Name 
927*5113495bSYour Name }
928*5113495bSYour Name 
929*5113495bSYour Name /**
930*5113495bSYour Name  * wma_disable_uapsd_mode() - disable uapsd mode in fw
931*5113495bSYour Name  * @wma: wma handle
932*5113495bSYour Name  * @ps_req: power save request
933*5113495bSYour Name  *
934*5113495bSYour Name  * Return: none
935*5113495bSYour Name  */
wma_disable_uapsd_mode(tp_wma_handle wma,tpDisableUapsdParams ps_req)936*5113495bSYour Name void wma_disable_uapsd_mode(tp_wma_handle wma,
937*5113495bSYour Name 			    tpDisableUapsdParams ps_req)
938*5113495bSYour Name {
939*5113495bSYour Name 	QDF_STATUS ret;
940*5113495bSYour Name 	uint32_t vdev_id = ps_req->sessionid;
941*5113495bSYour Name 	struct wma_ps_params ps_params = {0};
942*5113495bSYour Name 	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
943*5113495bSYour Name 
944*5113495bSYour Name 	if (!iface->vdev) {
945*5113495bSYour Name 		wma_err("vdev is null for vdev_%d", vdev_id);
946*5113495bSYour Name 		return;
947*5113495bSYour Name 	}
948*5113495bSYour Name 
949*5113495bSYour Name 	wma_debug("Disable Uapsd vdevId %d", vdev_id);
950*5113495bSYour Name 
951*5113495bSYour Name 	ret = wma_wlan_pmo_get_ps_params(iface->vdev, &ps_params);
952*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
953*5113495bSYour Name 		wma_err("ps_param is invalid for vdev_%d", vdev_id);
954*5113495bSYour Name 		return;
955*5113495bSYour Name 	}
956*5113495bSYour Name 
957*5113495bSYour Name 	/* Disable Sta Mode Power save */
958*5113495bSYour Name 	ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false);
959*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
960*5113495bSYour Name 		wma_err("Disable Sta Mode Ps Failed vdevId %d", vdev_id);
961*5113495bSYour Name 		return;
962*5113495bSYour Name 	}
963*5113495bSYour Name 
964*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
965*5113495bSYour Name 			WMI_STA_PS_PARAM_UAPSD, 0);
966*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
967*5113495bSYour Name 		wma_err("Disable Uapsd Failed vdevId %d", vdev_id);
968*5113495bSYour Name 		return;
969*5113495bSYour Name 	}
970*5113495bSYour Name 
971*5113495bSYour Name 	/* Re enable Sta Mode Powersave with proper configuration */
972*5113495bSYour Name 	ret = wma_set_force_sleep(wma, vdev_id, false,
973*5113495bSYour Name 			&ps_params, true);
974*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
975*5113495bSYour Name 		wma_err("Disable Forced Sleep Failed vdevId %d", vdev_id);
976*5113495bSYour Name 		return;
977*5113495bSYour Name 	}
978*5113495bSYour Name }
979*5113495bSYour Name 
980*5113495bSYour Name /**
981*5113495bSYour Name  * wma_set_sta_uapsd_auto_trig_cmd() - set uapsd auto trigger command
982*5113495bSYour Name  * @wmi_handle: wma handle
983*5113495bSYour Name  * @vdevid: vdev id
984*5113495bSYour Name  * @peer_addr: peer mac address
985*5113495bSYour Name  * @trig_param: auto trigger parameters
986*5113495bSYour Name  * @num_ac: number of access category
987*5113495bSYour Name  *
988*5113495bSYour Name  * This function sets the trigger
989*5113495bSYour Name  * uapsd params such as service interval, delay interval
990*5113495bSYour Name  * and suspend interval which will be used by the firmware
991*5113495bSYour Name  * to send trigger frames periodically when there is no
992*5113495bSYour Name  * traffic on the transmit side.
993*5113495bSYour Name  *
994*5113495bSYour Name  * Return: 0 for success or error code.
995*5113495bSYour Name  */
wma_set_sta_uapsd_auto_trig_cmd(wmi_unified_t wmi_handle,uint32_t vdevid,uint8_t peer_addr[QDF_MAC_ADDR_SIZE],struct sta_uapsd_params * trig_param,uint32_t num_ac)996*5113495bSYour Name static QDF_STATUS wma_set_sta_uapsd_auto_trig_cmd(wmi_unified_t wmi_handle,
997*5113495bSYour Name 					uint32_t vdevid,
998*5113495bSYour Name 					uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
999*5113495bSYour Name 					struct sta_uapsd_params *trig_param,
1000*5113495bSYour Name 					uint32_t num_ac)
1001*5113495bSYour Name {
1002*5113495bSYour Name 	QDF_STATUS ret;
1003*5113495bSYour Name 	struct sta_uapsd_trig_params cmd = {0};
1004*5113495bSYour Name 
1005*5113495bSYour Name 	cmd.vdevid = vdevid;
1006*5113495bSYour Name 	cmd.auto_triggerparam = trig_param;
1007*5113495bSYour Name 	cmd.num_ac = num_ac;
1008*5113495bSYour Name 
1009*5113495bSYour Name 	qdf_mem_copy((uint8_t *) cmd.peer_addr, (uint8_t *) peer_addr,
1010*5113495bSYour Name 		     sizeof(uint8_t) * QDF_MAC_ADDR_SIZE);
1011*5113495bSYour Name 	ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(wmi_handle,
1012*5113495bSYour Name 				   &cmd);
1013*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1014*5113495bSYour Name 		wma_err("Failed to send set uapsd param ret = %d", ret);
1015*5113495bSYour Name 
1016*5113495bSYour Name 	return ret;
1017*5113495bSYour Name }
1018*5113495bSYour Name 
wma_trigger_uapsd_params(tp_wma_handle wma_handle,uint32_t vdev_id,tp_wma_trigger_uapsd_params trigger_uapsd_params)1019*5113495bSYour Name QDF_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, uint32_t vdev_id,
1020*5113495bSYour Name 				    tp_wma_trigger_uapsd_params
1021*5113495bSYour Name 				    trigger_uapsd_params)
1022*5113495bSYour Name {
1023*5113495bSYour Name 	QDF_STATUS ret;
1024*5113495bSYour Name 	uint8_t *bssid;
1025*5113495bSYour Name 	struct sta_uapsd_params uapsd_trigger_param;
1026*5113495bSYour Name 
1027*5113495bSYour Name 	wma_debug("Trigger uapsd params vdev id %d", vdev_id);
1028*5113495bSYour Name 
1029*5113495bSYour Name 	wma_debug("WMM AC %d User Priority %d SvcIntv %d DelIntv %d SusIntv %d",
1030*5113495bSYour Name 		 trigger_uapsd_params->wmm_ac,
1031*5113495bSYour Name 		 trigger_uapsd_params->user_priority,
1032*5113495bSYour Name 		 trigger_uapsd_params->service_interval,
1033*5113495bSYour Name 		 trigger_uapsd_params->delay_interval,
1034*5113495bSYour Name 		 trigger_uapsd_params->suspend_interval);
1035*5113495bSYour Name 
1036*5113495bSYour Name 	if (!wmi_service_enabled(wma_handle->wmi_handle,
1037*5113495bSYour Name 				    wmi_sta_uapsd_basic_auto_trig) ||
1038*5113495bSYour Name 	    !wmi_service_enabled(wma_handle->wmi_handle,
1039*5113495bSYour Name 				    wmi_sta_uapsd_var_auto_trig)) {
1040*5113495bSYour Name 		wma_debug("Trigger uapsd is not supported vdev id %d", vdev_id);
1041*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1042*5113495bSYour Name 	}
1043*5113495bSYour Name 
1044*5113495bSYour Name 	uapsd_trigger_param.wmm_ac = trigger_uapsd_params->wmm_ac;
1045*5113495bSYour Name 	uapsd_trigger_param.user_priority = trigger_uapsd_params->user_priority;
1046*5113495bSYour Name 	uapsd_trigger_param.service_interval =
1047*5113495bSYour Name 		trigger_uapsd_params->service_interval;
1048*5113495bSYour Name 	uapsd_trigger_param.suspend_interval =
1049*5113495bSYour Name 		trigger_uapsd_params->suspend_interval;
1050*5113495bSYour Name 	uapsd_trigger_param.delay_interval =
1051*5113495bSYour Name 		trigger_uapsd_params->delay_interval;
1052*5113495bSYour Name 
1053*5113495bSYour Name 	bssid = wma_get_vdev_bssid(wma_handle->interfaces[vdev_id].vdev);
1054*5113495bSYour Name 	if (!bssid) {
1055*5113495bSYour Name 		wma_err("Failed to get bssid for vdev_%d", vdev_id);
1056*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1057*5113495bSYour Name 	}
1058*5113495bSYour Name 	ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle,
1059*5113495bSYour Name 			vdev_id, bssid,
1060*5113495bSYour Name 			&uapsd_trigger_param, 1);
1061*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1062*5113495bSYour Name 		wma_err("Fail to send uapsd param cmd for vdevid %d ret = %d",
1063*5113495bSYour Name 			ret, vdev_id);
1064*5113495bSYour Name 		return ret;
1065*5113495bSYour Name 	}
1066*5113495bSYour Name 
1067*5113495bSYour Name 	return ret;
1068*5113495bSYour Name }
1069*5113495bSYour Name 
wma_disable_uapsd_per_ac(tp_wma_handle wma_handle,uint32_t vdev_id,enum uapsd_ac ac)1070*5113495bSYour Name QDF_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle,
1071*5113495bSYour Name 				    uint32_t vdev_id, enum uapsd_ac ac)
1072*5113495bSYour Name {
1073*5113495bSYour Name 	QDF_STATUS ret;
1074*5113495bSYour Name 	uint8_t *bssid;
1075*5113495bSYour Name 	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
1076*5113495bSYour Name 	struct sta_uapsd_params uapsd_trigger_param;
1077*5113495bSYour Name 	enum uapsd_up user_priority;
1078*5113495bSYour Name 
1079*5113495bSYour Name 	wma_debug("Disable Uapsd per ac vdevId %d ac %d", vdev_id, ac);
1080*5113495bSYour Name 
1081*5113495bSYour Name 	switch (ac) {
1082*5113495bSYour Name 	case UAPSD_VO:
1083*5113495bSYour Name 		iface->uapsd_cached_val &=
1084*5113495bSYour Name 			~(WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
1085*5113495bSYour Name 			  WMI_STA_PS_UAPSD_AC3_TRIGGER_EN);
1086*5113495bSYour Name 		user_priority = UAPSD_UP_VO;
1087*5113495bSYour Name 		break;
1088*5113495bSYour Name 	case UAPSD_VI:
1089*5113495bSYour Name 		iface->uapsd_cached_val &=
1090*5113495bSYour Name 			~(WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
1091*5113495bSYour Name 			  WMI_STA_PS_UAPSD_AC2_TRIGGER_EN);
1092*5113495bSYour Name 		user_priority = UAPSD_UP_VI;
1093*5113495bSYour Name 		break;
1094*5113495bSYour Name 	case UAPSD_BK:
1095*5113495bSYour Name 		iface->uapsd_cached_val &=
1096*5113495bSYour Name 			~(WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
1097*5113495bSYour Name 			  WMI_STA_PS_UAPSD_AC1_TRIGGER_EN);
1098*5113495bSYour Name 		user_priority = UAPSD_UP_BK;
1099*5113495bSYour Name 		break;
1100*5113495bSYour Name 	case UAPSD_BE:
1101*5113495bSYour Name 		iface->uapsd_cached_val &=
1102*5113495bSYour Name 			~(WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
1103*5113495bSYour Name 			  WMI_STA_PS_UAPSD_AC0_TRIGGER_EN);
1104*5113495bSYour Name 		user_priority = UAPSD_UP_BE;
1105*5113495bSYour Name 		break;
1106*5113495bSYour Name 	default:
1107*5113495bSYour Name 		wma_err("Invalid AC vdevId %d ac %d", vdev_id, ac);
1108*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1109*5113495bSYour Name 	}
1110*5113495bSYour Name 
1111*5113495bSYour Name 	/*
1112*5113495bSYour Name 	 * Disable Auto Trigger Functionality before
1113*5113495bSYour Name 	 * disabling uapsd for a particular AC
1114*5113495bSYour Name 	 */
1115*5113495bSYour Name 	uapsd_trigger_param.wmm_ac = ac;
1116*5113495bSYour Name 	uapsd_trigger_param.user_priority = user_priority;
1117*5113495bSYour Name 	uapsd_trigger_param.service_interval = 0;
1118*5113495bSYour Name 	uapsd_trigger_param.suspend_interval = 0;
1119*5113495bSYour Name 	uapsd_trigger_param.delay_interval = 0;
1120*5113495bSYour Name 
1121*5113495bSYour Name 	bssid = wma_get_vdev_bssid(wma_handle->interfaces[vdev_id].vdev);
1122*5113495bSYour Name 	if (!bssid) {
1123*5113495bSYour Name 		wma_err("Failed to get bssid for vdev_%d", vdev_id);
1124*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1125*5113495bSYour Name 	}
1126*5113495bSYour Name 	ret = wma_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle,
1127*5113495bSYour Name 		vdev_id, bssid,
1128*5113495bSYour Name 		&uapsd_trigger_param, 1);
1129*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1130*5113495bSYour Name 		wma_err("Fail to send auto trig cmd for vdevid %d ret = %d",
1131*5113495bSYour Name 			ret, vdev_id);
1132*5113495bSYour Name 		return ret;
1133*5113495bSYour Name 	}
1134*5113495bSYour Name 
1135*5113495bSYour Name 	ret = wma_unified_set_sta_ps_param(wma_handle->wmi_handle, vdev_id,
1136*5113495bSYour Name 					   WMI_STA_PS_PARAM_UAPSD,
1137*5113495bSYour Name 					   iface->uapsd_cached_val);
1138*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1139*5113495bSYour Name 		wma_err("Disable Uapsd per ac Failed vdevId %d ac %d", vdev_id,
1140*5113495bSYour Name 			ac);
1141*5113495bSYour Name 		return ret;
1142*5113495bSYour Name 	}
1143*5113495bSYour Name 	wma_debug("Disable Uapsd per ac vdevId %d val %d", vdev_id,
1144*5113495bSYour Name 		 iface->uapsd_cached_val);
1145*5113495bSYour Name 
1146*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1147*5113495bSYour Name }
1148*5113495bSYour Name 
1149*5113495bSYour Name /**
1150*5113495bSYour Name  * wma_get_temperature() - get pdev temperature req
1151*5113495bSYour Name  * @wmi_handle: wma handle
1152*5113495bSYour Name  *
1153*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1154*5113495bSYour Name  */
wma_get_temperature(tp_wma_handle wma_handle)1155*5113495bSYour Name QDF_STATUS wma_get_temperature(tp_wma_handle wma_handle)
1156*5113495bSYour Name {
1157*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1158*5113495bSYour Name 
1159*5113495bSYour Name 	ret = wmi_unified_get_temperature(wma_handle->wmi_handle);
1160*5113495bSYour Name 	if (ret)
1161*5113495bSYour Name 		wma_err("Failed to send set Mimo PS ret = %d", ret);
1162*5113495bSYour Name 
1163*5113495bSYour Name 	return ret;
1164*5113495bSYour Name }
1165*5113495bSYour Name 
1166*5113495bSYour Name /**
1167*5113495bSYour Name  * wma_pdev_temperature_evt_handler() - pdev temperature event handler
1168*5113495bSYour Name  * @handle: wma handle
1169*5113495bSYour Name  * @event: event buffer
1170*5113495bSYour Name  * @len : length
1171*5113495bSYour Name  *
1172*5113495bSYour Name  * Return: 0 for success or error code.
1173*5113495bSYour Name  */
wma_pdev_temperature_evt_handler(void * handle,uint8_t * event,uint32_t len)1174*5113495bSYour Name int wma_pdev_temperature_evt_handler(void *handle, uint8_t *event,
1175*5113495bSYour Name 				     uint32_t len)
1176*5113495bSYour Name {
1177*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1178*5113495bSYour Name 	struct scheduler_msg sme_msg = { 0 };
1179*5113495bSYour Name 	WMI_PDEV_TEMPERATURE_EVENTID_param_tlvs *param_buf;
1180*5113495bSYour Name 	wmi_pdev_temperature_event_fixed_param *wmi_event;
1181*5113495bSYour Name 
1182*5113495bSYour Name 	param_buf = (WMI_PDEV_TEMPERATURE_EVENTID_param_tlvs *) event;
1183*5113495bSYour Name 	if (!param_buf) {
1184*5113495bSYour Name 		wma_err("Invalid pdev_temperature event buffer");
1185*5113495bSYour Name 		return -EINVAL;
1186*5113495bSYour Name 	}
1187*5113495bSYour Name 
1188*5113495bSYour Name 	wmi_event = param_buf->fixed_param;
1189*5113495bSYour Name 	wma_info("temperature: %d", wmi_event->value);
1190*5113495bSYour Name 
1191*5113495bSYour Name 	sme_msg.type = eWNI_SME_MSG_GET_TEMPERATURE_IND;
1192*5113495bSYour Name 	sme_msg.bodyptr = NULL;
1193*5113495bSYour Name 	sme_msg.bodyval = wmi_event->value;
1194*5113495bSYour Name 
1195*5113495bSYour Name 	qdf_status = scheduler_post_message(QDF_MODULE_ID_WMA,
1196*5113495bSYour Name 					    QDF_MODULE_ID_SME,
1197*5113495bSYour Name 					    QDF_MODULE_ID_SME, &sme_msg);
1198*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1199*5113495bSYour Name 		wma_err("Fail to post get temperature ind msg");
1200*5113495bSYour Name 	return 0;
1201*5113495bSYour Name }
1202*5113495bSYour Name 
1203*5113495bSYour Name #define MAX_PDEV_TXPOWER_PARAMS 2
1204*5113495bSYour Name /* params being sent:
1205*5113495bSYour Name  * wmi_pdev_param_txpower_limit2g
1206*5113495bSYour Name  * wmi_pdev_param_txpower_limit5g
1207*5113495bSYour Name  */
1208*5113495bSYour Name 
1209*5113495bSYour Name /**
1210*5113495bSYour Name  * wma_process_tx_power_limits() - sends the power limits for 2g/5g to firmware
1211*5113495bSYour Name  * @handle: wma handle
1212*5113495bSYour Name  * @ptxlim: power limit value
1213*5113495bSYour Name  *
1214*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1215*5113495bSYour Name  */
wma_process_tx_power_limits(WMA_HANDLE handle,struct tx_power_limit * ptxlim)1216*5113495bSYour Name QDF_STATUS wma_process_tx_power_limits(WMA_HANDLE handle,
1217*5113495bSYour Name 				       struct tx_power_limit *ptxlim)
1218*5113495bSYour Name {
1219*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
1220*5113495bSYour Name 	int32_t ret = 0;
1221*5113495bSYour Name 	uint32_t txpower_params2g = 0;
1222*5113495bSYour Name 	uint32_t txpower_params5g = 0;
1223*5113495bSYour Name 	struct wmi_unified *wmi_handle;
1224*5113495bSYour Name 	struct dev_set_param setparam[MAX_PDEV_TXPOWER_PARAMS] = {};
1225*5113495bSYour Name 	uint8_t index = 0;
1226*5113495bSYour Name 
1227*5113495bSYour Name 	if (wma_validate_handle(wma))
1228*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1229*5113495bSYour Name 
1230*5113495bSYour Name 	wmi_handle = wma->wmi_handle;
1231*5113495bSYour Name 	if (wmi_validate_handle(wmi_handle))
1232*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1233*5113495bSYour Name 
1234*5113495bSYour Name 	/* Set value and reason code for 2g and 5g power limit */
1235*5113495bSYour Name 
1236*5113495bSYour Name 	SET_PDEV_PARAM_TXPOWER_REASON(txpower_params2g,
1237*5113495bSYour Name 				      wmi_pdev_param_txpower_reason_sar);
1238*5113495bSYour Name 	SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params2g, ptxlim->txPower2g);
1239*5113495bSYour Name 
1240*5113495bSYour Name 	SET_PDEV_PARAM_TXPOWER_REASON(txpower_params5g,
1241*5113495bSYour Name 				      wmi_pdev_param_txpower_reason_sar);
1242*5113495bSYour Name 	SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params5g, ptxlim->txPower5g);
1243*5113495bSYour Name 
1244*5113495bSYour Name 	wma_debug("txpower2g: %x txpower5g: %x",
1245*5113495bSYour Name 		 txpower_params2g, txpower_params5g);
1246*5113495bSYour Name 	ret = mlme_check_index_setparam(setparam,
1247*5113495bSYour Name 					wmi_pdev_param_txpower_limit2g,
1248*5113495bSYour Name 					txpower_params2g, index++,
1249*5113495bSYour Name 					MAX_PDEV_TXPOWER_PARAMS);
1250*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1251*5113495bSYour Name 		wma_err("failed at wmi_pdev_param_txpower_limit2g");
1252*5113495bSYour Name 		goto error;
1253*5113495bSYour Name 	}
1254*5113495bSYour Name 	ret = mlme_check_index_setparam(setparam,
1255*5113495bSYour Name 					wmi_pdev_param_txpower_limit5g,
1256*5113495bSYour Name 					txpower_params5g, index++,
1257*5113495bSYour Name 					MAX_PDEV_TXPOWER_PARAMS);
1258*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1259*5113495bSYour Name 		wma_err("failed at wmi_pdev_param_txpower_limit5g");
1260*5113495bSYour Name 		goto error;
1261*5113495bSYour Name 	}
1262*5113495bSYour Name 	ret = wma_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
1263*5113495bSYour Name 						  WMI_PDEV_ID_SOC, setparam,
1264*5113495bSYour Name 						  index);
1265*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1266*5113495bSYour Name 		wma_err("failed to send tx power pdev set params");
1267*5113495bSYour Name error:
1268*5113495bSYour Name 	return ret;
1269*5113495bSYour Name }
1270*5113495bSYour Name 
1271*5113495bSYour Name #ifdef WLAN_WMI_BCN
1272*5113495bSYour Name /**
1273*5113495bSYour Name  * wma_add_p2p_ie() - add p2p IE
1274*5113495bSYour Name  * @frm: ptr where p2p ie needs to add
1275*5113495bSYour Name  *
1276*5113495bSYour Name  * Return: ptr after p2p ie
1277*5113495bSYour Name  */
wma_add_p2p_ie(uint8_t * frm)1278*5113495bSYour Name static uint8_t *wma_add_p2p_ie(uint8_t *frm)
1279*5113495bSYour Name {
1280*5113495bSYour Name 	uint8_t wfa_oui[3] = WMA_P2P_WFA_OUI;
1281*5113495bSYour Name 	struct p2p_ie *p2p_ie = (struct p2p_ie *)frm;
1282*5113495bSYour Name 
1283*5113495bSYour Name 	p2p_ie->p2p_id = WMA_P2P_IE_ID;
1284*5113495bSYour Name 	p2p_ie->p2p_oui[0] = wfa_oui[0];
1285*5113495bSYour Name 	p2p_ie->p2p_oui[1] = wfa_oui[1];
1286*5113495bSYour Name 	p2p_ie->p2p_oui[2] = wfa_oui[2];
1287*5113495bSYour Name 	p2p_ie->p2p_oui_type = WMA_P2P_WFA_VER;
1288*5113495bSYour Name 	p2p_ie->p2p_len = 4;
1289*5113495bSYour Name 	return frm + sizeof(struct p2p_ie);
1290*5113495bSYour Name }
1291*5113495bSYour Name 
1292*5113495bSYour Name /**
1293*5113495bSYour Name  * wma_update_beacon_noa_ie() - update beacon ie
1294*5113495bSYour Name  * @bcn: beacon info
1295*5113495bSYour Name  * @new_noa_sub_ie_len: ie length
1296*5113495bSYour Name  *
1297*5113495bSYour Name  * Return: none
1298*5113495bSYour Name  */
wma_update_beacon_noa_ie(struct beacon_info * bcn,uint16_t new_noa_sub_ie_len)1299*5113495bSYour Name static void wma_update_beacon_noa_ie(struct beacon_info *bcn,
1300*5113495bSYour Name 				     uint16_t new_noa_sub_ie_len)
1301*5113495bSYour Name {
1302*5113495bSYour Name 	struct p2p_ie *p2p_ie;
1303*5113495bSYour Name 	uint8_t *buf;
1304*5113495bSYour Name 
1305*5113495bSYour Name 	/* if there is nothing to add, just return */
1306*5113495bSYour Name 	if (new_noa_sub_ie_len == 0) {
1307*5113495bSYour Name 		if (bcn->noa_sub_ie_len && bcn->noa_ie) {
1308*5113495bSYour Name 			wma_debug("NoA is present in previous beacon, but not present in swba event, So Reset the NoA");
1309*5113495bSYour Name 			/* TODO: Assuming p2p noa ie is last ie in the beacon */
1310*5113495bSYour Name 			qdf_mem_zero(bcn->noa_ie, (bcn->noa_sub_ie_len +
1311*5113495bSYour Name 						   sizeof(struct p2p_ie)));
1312*5113495bSYour Name 			bcn->len -= (bcn->noa_sub_ie_len +
1313*5113495bSYour Name 				     sizeof(struct p2p_ie));
1314*5113495bSYour Name 			bcn->noa_ie = NULL;
1315*5113495bSYour Name 			bcn->noa_sub_ie_len = 0;
1316*5113495bSYour Name 		}
1317*5113495bSYour Name 		wma_debug("No need to update NoA");
1318*5113495bSYour Name 		return;
1319*5113495bSYour Name 	}
1320*5113495bSYour Name 
1321*5113495bSYour Name 	if (bcn->noa_sub_ie_len && bcn->noa_ie) {
1322*5113495bSYour Name 		/* NoA present in previous beacon, update it */
1323*5113495bSYour Name 		wma_debug("NoA present in previous beacon, update the NoA IE, bcn->len %u bcn->noa_sub_ie_len %u",
1324*5113495bSYour Name 			 bcn->len, bcn->noa_sub_ie_len);
1325*5113495bSYour Name 		bcn->len -= (bcn->noa_sub_ie_len + sizeof(struct p2p_ie));
1326*5113495bSYour Name 		qdf_mem_zero(bcn->noa_ie,
1327*5113495bSYour Name 			     (bcn->noa_sub_ie_len + sizeof(struct p2p_ie)));
1328*5113495bSYour Name 	} else {                /* NoA is not present in previous beacon */
1329*5113495bSYour Name 		wma_debug("NoA not present in previous beacon, add it bcn->len %u",
1330*5113495bSYour Name 			 bcn->len);
1331*5113495bSYour Name 		buf = qdf_nbuf_data(bcn->buf);
1332*5113495bSYour Name 		bcn->noa_ie = buf + bcn->len;
1333*5113495bSYour Name 	}
1334*5113495bSYour Name 
1335*5113495bSYour Name 	if (bcn->len + sizeof(struct p2p_ie) + new_noa_sub_ie_len >
1336*5113495bSYour Name 	    SIR_MAX_BEACON_SIZE) {
1337*5113495bSYour Name 		wma_err("exceed max beacon length, bcn->len %d, new_noa_sub_ie_len %d, p2p len %u",
1338*5113495bSYour Name 			bcn->len, new_noa_sub_ie_len,
1339*5113495bSYour Name 			(uint32_t)sizeof(struct p2p_ie));
1340*5113495bSYour Name 		return;
1341*5113495bSYour Name 	}
1342*5113495bSYour Name 
1343*5113495bSYour Name 	bcn->noa_sub_ie_len = new_noa_sub_ie_len;
1344*5113495bSYour Name 	wma_add_p2p_ie(bcn->noa_ie);
1345*5113495bSYour Name 	p2p_ie = (struct p2p_ie *)bcn->noa_ie;
1346*5113495bSYour Name 	p2p_ie->p2p_len += new_noa_sub_ie_len;
1347*5113495bSYour Name 	qdf_mem_copy((bcn->noa_ie + sizeof(struct p2p_ie)), bcn->noa_sub_ie,
1348*5113495bSYour Name 		     new_noa_sub_ie_len);
1349*5113495bSYour Name 
1350*5113495bSYour Name 	bcn->len += (new_noa_sub_ie_len + sizeof(struct p2p_ie));
1351*5113495bSYour Name 	wma_debug("Updated beacon length with NoA Ie is %u", bcn->len);
1352*5113495bSYour Name }
1353*5113495bSYour Name 
1354*5113495bSYour Name /**
1355*5113495bSYour Name  * wma_p2p_create_sub_ie_noa() - put p2p noa ie
1356*5113495bSYour Name  * @buf: buffer
1357*5113495bSYour Name  * @noa: noa element ie
1358*5113495bSYour Name  * @new_noa_sub_ie_len: ie length
1359*5113495bSYour Name  *
1360*5113495bSYour Name  * Return: none
1361*5113495bSYour Name  */
wma_p2p_create_sub_ie_noa(uint8_t * buf,struct p2p_sub_element_noa * noa,uint16_t * new_noa_sub_ie_len)1362*5113495bSYour Name static void wma_p2p_create_sub_ie_noa(uint8_t *buf,
1363*5113495bSYour Name 				      struct p2p_sub_element_noa *noa,
1364*5113495bSYour Name 				      uint16_t *new_noa_sub_ie_len)
1365*5113495bSYour Name {
1366*5113495bSYour Name 	uint8_t tmp_octet = 0;
1367*5113495bSYour Name 	int i;
1368*5113495bSYour Name 	uint8_t *buf_start = buf;
1369*5113495bSYour Name 
1370*5113495bSYour Name 	*buf++ = WMA_P2P_SUB_ELEMENT_NOA;       /* sub-element id */
1371*5113495bSYour Name 	ASSERT(noa->num_descriptors <= WMA_MAX_NOA_DESCRIPTORS);
1372*5113495bSYour Name 
1373*5113495bSYour Name 	/*
1374*5113495bSYour Name 	 * Length = (2 octets for Index and CTWin/Opp PS) and
1375*5113495bSYour Name 	 * (13 octets for each NOA Descriptors)
1376*5113495bSYour Name 	 */
1377*5113495bSYour Name 	P2PIE_PUT_LE16(buf, WMA_NOA_IE_SIZE(noa->num_descriptors));
1378*5113495bSYour Name 	buf += 2;
1379*5113495bSYour Name 
1380*5113495bSYour Name 	*buf++ = noa->index;    /* Instance Index */
1381*5113495bSYour Name 
1382*5113495bSYour Name 	tmp_octet = noa->ctwindow & WMA_P2P_NOA_IE_CTWIN_MASK;
1383*5113495bSYour Name 	if (noa->oppPS)
1384*5113495bSYour Name 		tmp_octet |= WMA_P2P_NOA_IE_OPP_PS_SET;
1385*5113495bSYour Name 	*buf++ = tmp_octet;     /* Opp Ps and CTWin capabilities */
1386*5113495bSYour Name 
1387*5113495bSYour Name 	for (i = 0; i < noa->num_descriptors; i++) {
1388*5113495bSYour Name 		ASSERT(noa->noa_descriptors[i].type_count != 0);
1389*5113495bSYour Name 
1390*5113495bSYour Name 		*buf++ = noa->noa_descriptors[i].type_count;
1391*5113495bSYour Name 
1392*5113495bSYour Name 		P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].duration);
1393*5113495bSYour Name 		buf += 4;
1394*5113495bSYour Name 		P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].interval);
1395*5113495bSYour Name 		buf += 4;
1396*5113495bSYour Name 		P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].start_time);
1397*5113495bSYour Name 		buf += 4;
1398*5113495bSYour Name 	}
1399*5113495bSYour Name 	*new_noa_sub_ie_len = (buf - buf_start);
1400*5113495bSYour Name }
1401*5113495bSYour Name 
1402*5113495bSYour Name /**
1403*5113495bSYour Name  * wma_update_noa() - update noa params
1404*5113495bSYour Name  * @beacon: beacon info
1405*5113495bSYour Name  * @noa_ie: noa ie
1406*5113495bSYour Name  *
1407*5113495bSYour Name  * Return: none
1408*5113495bSYour Name  */
wma_update_noa(struct beacon_info * beacon,struct p2p_sub_element_noa * noa_ie)1409*5113495bSYour Name void wma_update_noa(struct beacon_info *beacon,
1410*5113495bSYour Name 		    struct p2p_sub_element_noa *noa_ie)
1411*5113495bSYour Name {
1412*5113495bSYour Name 	uint16_t new_noa_sub_ie_len;
1413*5113495bSYour Name 
1414*5113495bSYour Name 	/* Call this function by holding the spinlock on beacon->lock */
1415*5113495bSYour Name 
1416*5113495bSYour Name 	if (noa_ie) {
1417*5113495bSYour Name 		if ((noa_ie->ctwindow == 0) && (noa_ie->oppPS == 0) &&
1418*5113495bSYour Name 		    (noa_ie->num_descriptors == 0)) {
1419*5113495bSYour Name 			/* NoA is not present */
1420*5113495bSYour Name 			wma_debug("NoA is not present");
1421*5113495bSYour Name 			new_noa_sub_ie_len = 0;
1422*5113495bSYour Name 		} else {
1423*5113495bSYour Name 			/* Create the binary blob containing NOA sub-IE */
1424*5113495bSYour Name 			wma_debug("Create NOA sub ie");
1425*5113495bSYour Name 			wma_p2p_create_sub_ie_noa(&beacon->noa_sub_ie[0],
1426*5113495bSYour Name 						  noa_ie, &new_noa_sub_ie_len);
1427*5113495bSYour Name 		}
1428*5113495bSYour Name 	} else {
1429*5113495bSYour Name 		wma_debug("No need to add NOA");
1430*5113495bSYour Name 		new_noa_sub_ie_len = 0; /* no NOA IE sub-attributes */
1431*5113495bSYour Name 	}
1432*5113495bSYour Name 
1433*5113495bSYour Name 	wma_update_beacon_noa_ie(beacon, new_noa_sub_ie_len);
1434*5113495bSYour Name }
1435*5113495bSYour Name 
1436*5113495bSYour Name /**
1437*5113495bSYour Name  * wma_update_probe_resp_noa() - update noa IE in probe response
1438*5113495bSYour Name  * @wma_handle: wma handle
1439*5113495bSYour Name  * @noa_ie: noa ie
1440*5113495bSYour Name  *
1441*5113495bSYour Name  * Return: none
1442*5113495bSYour Name  */
wma_update_probe_resp_noa(tp_wma_handle wma_handle,struct p2p_sub_element_noa * noa_ie)1443*5113495bSYour Name void wma_update_probe_resp_noa(tp_wma_handle wma_handle,
1444*5113495bSYour Name 			       struct p2p_sub_element_noa *noa_ie)
1445*5113495bSYour Name {
1446*5113495bSYour Name 	tSirP2PNoaAttr *noa_attr = qdf_mem_malloc(sizeof(tSirP2PNoaAttr));
1447*5113495bSYour Name 	wma_debug("Received update NoA event");
1448*5113495bSYour Name 	if (!noa_attr)
1449*5113495bSYour Name 		return;
1450*5113495bSYour Name 
1451*5113495bSYour Name 	qdf_mem_zero(noa_attr, sizeof(tSirP2PNoaAttr));
1452*5113495bSYour Name 
1453*5113495bSYour Name 	noa_attr->index = noa_ie->index;
1454*5113495bSYour Name 	noa_attr->oppPsFlag = noa_ie->oppPS;
1455*5113495bSYour Name 	noa_attr->ctWin = noa_ie->ctwindow;
1456*5113495bSYour Name 	if (!noa_ie->num_descriptors) {
1457*5113495bSYour Name 		wma_debug("Zero NoA descriptors");
1458*5113495bSYour Name 	} else {
1459*5113495bSYour Name 		wma_debug("%d NoA descriptors", noa_ie->num_descriptors);
1460*5113495bSYour Name 		noa_attr->uNoa1IntervalCnt =
1461*5113495bSYour Name 			noa_ie->noa_descriptors[0].type_count;
1462*5113495bSYour Name 		noa_attr->uNoa1Duration = noa_ie->noa_descriptors[0].duration;
1463*5113495bSYour Name 		noa_attr->uNoa1Interval = noa_ie->noa_descriptors[0].interval;
1464*5113495bSYour Name 		noa_attr->uNoa1StartTime =
1465*5113495bSYour Name 			noa_ie->noa_descriptors[0].start_time;
1466*5113495bSYour Name 		if (noa_ie->num_descriptors > 1) {
1467*5113495bSYour Name 			noa_attr->uNoa2IntervalCnt =
1468*5113495bSYour Name 				noa_ie->noa_descriptors[1].type_count;
1469*5113495bSYour Name 			noa_attr->uNoa2Duration =
1470*5113495bSYour Name 				noa_ie->noa_descriptors[1].duration;
1471*5113495bSYour Name 			noa_attr->uNoa2Interval =
1472*5113495bSYour Name 				noa_ie->noa_descriptors[1].interval;
1473*5113495bSYour Name 			noa_attr->uNoa2StartTime =
1474*5113495bSYour Name 				noa_ie->noa_descriptors[1].start_time;
1475*5113495bSYour Name 		}
1476*5113495bSYour Name 	}
1477*5113495bSYour Name 	wma_debug("Sending SIR_HAL_P2P_NOA_ATTR_IND to LIM");
1478*5113495bSYour Name 	wma_send_msg(wma_handle, SIR_HAL_P2P_NOA_ATTR_IND, (void *)noa_attr, 0);
1479*5113495bSYour Name }
1480*5113495bSYour Name 
1481*5113495bSYour Name #else
wma_add_p2p_ie(uint8_t * frm)1482*5113495bSYour Name static inline uint8_t *wma_add_p2p_ie(uint8_t *frm)
1483*5113495bSYour Name {
1484*5113495bSYour Name 	return 0;
1485*5113495bSYour Name }
1486*5113495bSYour Name 
1487*5113495bSYour Name static inline void
wma_update_beacon_noa_ie(struct beacon_info * bcn,uint16_t new_noa_sub_ie_len)1488*5113495bSYour Name wma_update_beacon_noa_ie(struct beacon_info *bcn,
1489*5113495bSYour Name 			 uint16_t new_noa_sub_ie_len)
1490*5113495bSYour Name {
1491*5113495bSYour Name }
1492*5113495bSYour Name 
1493*5113495bSYour Name static inline void
wma_p2p_create_sub_ie_noa(uint8_t * buf,struct p2p_sub_element_noa * noa,uint16_t * new_noa_sub_ie_len)1494*5113495bSYour Name wma_p2p_create_sub_ie_noa(uint8_t *buf,
1495*5113495bSYour Name 			  struct p2p_sub_element_noa *noa,
1496*5113495bSYour Name 			  uint16_t *new_noa_sub_ie_len)
1497*5113495bSYour Name {
1498*5113495bSYour Name }
1499*5113495bSYour Name 
wma_update_noa(struct beacon_info * beacon,struct p2p_sub_element_noa * noa_ie)1500*5113495bSYour Name void wma_update_noa(struct beacon_info *beacon,
1501*5113495bSYour Name 		    struct p2p_sub_element_noa *noa_ie)
1502*5113495bSYour Name {
1503*5113495bSYour Name }
1504*5113495bSYour Name 
wma_update_probe_resp_noa(tp_wma_handle wma_handle,struct p2p_sub_element_noa * noa_ie)1505*5113495bSYour Name void wma_update_probe_resp_noa(tp_wma_handle wma_handle,
1506*5113495bSYour Name 			       struct p2p_sub_element_noa *noa_ie)
1507*5113495bSYour Name {
1508*5113495bSYour Name }
1509*5113495bSYour Name 
1510*5113495bSYour Name #endif
1511*5113495bSYour Name 
1512*5113495bSYour Name /**
1513*5113495bSYour Name  * wma_process_set_mimops_req() - Set the received MiMo PS state to firmware
1514*5113495bSYour Name  * @handle: wma handle
1515*5113495bSYour Name  * @mimops: MIMO powersave params
1516*5113495bSYour Name  *
1517*5113495bSYour Name  * Return: none
1518*5113495bSYour Name  */
wma_process_set_mimops_req(tp_wma_handle wma_handle,tSetMIMOPS * mimops)1519*5113495bSYour Name void wma_process_set_mimops_req(tp_wma_handle wma_handle,
1520*5113495bSYour Name 				tSetMIMOPS *mimops)
1521*5113495bSYour Name {
1522*5113495bSYour Name 	/* Translate to what firmware understands */
1523*5113495bSYour Name 	if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_DYNAMIC)
1524*5113495bSYour Name 		mimops->htMIMOPSState = WMI_PEER_MIMO_PS_DYNAMIC;
1525*5113495bSYour Name 	else if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_STATIC)
1526*5113495bSYour Name 		mimops->htMIMOPSState = WMI_PEER_MIMO_PS_STATIC;
1527*5113495bSYour Name 	else if (mimops->htMIMOPSState == eSIR_HT_MIMO_PS_NO_LIMIT)
1528*5113495bSYour Name 		mimops->htMIMOPSState = WMI_PEER_MIMO_PS_NONE;
1529*5113495bSYour Name 
1530*5113495bSYour Name 	wma_debug("htMIMOPSState = %d, sessionId = %d peerMac <"QDF_MAC_ADDR_FMT">",
1531*5113495bSYour Name 		 mimops->htMIMOPSState, mimops->sessionId,
1532*5113495bSYour Name 		 QDF_MAC_ADDR_REF(mimops->peerMac));
1533*5113495bSYour Name 
1534*5113495bSYour Name 	wma_set_peer_param(wma_handle, mimops->peerMac,
1535*5113495bSYour Name 			   WMI_HOST_PEER_MIMO_PS_STATE, mimops->htMIMOPSState,
1536*5113495bSYour Name 			   mimops->sessionId);
1537*5113495bSYour Name }
1538*5113495bSYour Name 
1539*5113495bSYour Name /**
1540*5113495bSYour Name  * wma_set_mimops() - set MIMO powersave
1541*5113495bSYour Name  * @handle: wma handle
1542*5113495bSYour Name  * @vdev_id: vdev id
1543*5113495bSYour Name  * @value: value
1544*5113495bSYour Name  *
1545*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1546*5113495bSYour Name  */
wma_set_mimops(tp_wma_handle wma,uint8_t vdev_id,int value)1547*5113495bSYour Name QDF_STATUS wma_set_mimops(tp_wma_handle wma, uint8_t vdev_id, int value)
1548*5113495bSYour Name {
1549*5113495bSYour Name 	QDF_STATUS ret;
1550*5113495bSYour Name 
1551*5113495bSYour Name 	ret = wmi_unified_set_mimops(wma->wmi_handle, vdev_id,
1552*5113495bSYour Name 				   value);
1553*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1554*5113495bSYour Name 		wma_err("Failed to send set Mimo PS ret = %d", ret);
1555*5113495bSYour Name 
1556*5113495bSYour Name 	return ret;
1557*5113495bSYour Name }
1558*5113495bSYour Name 
1559*5113495bSYour Name /**
1560*5113495bSYour Name  * wma_notify_modem_power_state() - notify modem power state
1561*5113495bSYour Name  * @wma_ptr: wma handle
1562*5113495bSYour Name  * @pReq: modem power state
1563*5113495bSYour Name  *
1564*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1565*5113495bSYour Name  */
wma_notify_modem_power_state(void * wma_ptr,tSirModemPowerStateInd * pReq)1566*5113495bSYour Name QDF_STATUS wma_notify_modem_power_state(void *wma_ptr,
1567*5113495bSYour Name 					tSirModemPowerStateInd *pReq)
1568*5113495bSYour Name {
1569*5113495bSYour Name 	QDF_STATUS status;
1570*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) wma_ptr;
1571*5113495bSYour Name 
1572*5113495bSYour Name 	wma_debug("WMA notify Modem Power State %d", pReq->param);
1573*5113495bSYour Name 
1574*5113495bSYour Name 	status = wma_unified_modem_power_state(wma->wmi_handle, pReq->param);
1575*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
1576*5113495bSYour Name 		wma_err("Failed to notify Modem Power State %d", pReq->param);
1577*5113495bSYour Name 		return status;
1578*5113495bSYour Name 	}
1579*5113495bSYour Name 
1580*5113495bSYour Name 	wma_debug("Successfully notify Modem Power State %d", pReq->param);
1581*5113495bSYour Name 
1582*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1583*5113495bSYour Name }
1584*5113495bSYour Name 
1585*5113495bSYour Name /**
1586*5113495bSYour Name  * wma_set_idle_ps_config() - enable/disable Low Power Support(Pdev Specific)
1587*5113495bSYour Name  * @wma_ptr: wma handle
1588*5113495bSYour Name  * @idle_ps: idle powersave
1589*5113495bSYour Name  *
1590*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1591*5113495bSYour Name  */
wma_set_idle_ps_config(void * wma_ptr,uint32_t idle_ps)1592*5113495bSYour Name QDF_STATUS wma_set_idle_ps_config(void *wma_ptr, uint32_t idle_ps)
1593*5113495bSYour Name {
1594*5113495bSYour Name 	int32_t ret;
1595*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) wma_ptr;
1596*5113495bSYour Name 	struct pdev_params pdevparam = {};
1597*5113495bSYour Name 
1598*5113495bSYour Name 	wma_debug("WMA Set Idle Ps Config [1:set 0:clear] val %d", idle_ps);
1599*5113495bSYour Name 
1600*5113495bSYour Name 	/* Set Idle Mode Power Save Config */
1601*5113495bSYour Name 	pdevparam.param_id = wmi_pdev_param_idle_ps_config;
1602*5113495bSYour Name 	pdevparam.param_value = idle_ps;
1603*5113495bSYour Name 	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
1604*5113495bSYour Name 					 &pdevparam,
1605*5113495bSYour Name 					 WMA_WILDCARD_PDEV_ID);
1606*5113495bSYour Name 
1607*5113495bSYour Name 	if (ret) {
1608*5113495bSYour Name 		wma_err("Fail to Set Idle Ps Config %d", idle_ps);
1609*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1610*5113495bSYour Name 	}
1611*5113495bSYour Name 	wma->in_imps = !!idle_ps;
1612*5113495bSYour Name 
1613*5113495bSYour Name 	wma_debug("Successfully Set Idle Ps Config %d", idle_ps);
1614*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1615*5113495bSYour Name }
1616*5113495bSYour Name 
1617*5113495bSYour Name /**
1618*5113495bSYour Name  * wma_set_smps_params() - set smps params
1619*5113495bSYour Name  * @wma: wma handle
1620*5113495bSYour Name  * @vdev_id: vdev id
1621*5113495bSYour Name  * @value: value
1622*5113495bSYour Name  *
1623*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1624*5113495bSYour Name  */
wma_set_smps_params(tp_wma_handle wma,uint8_t vdev_id,int value)1625*5113495bSYour Name QDF_STATUS wma_set_smps_params(tp_wma_handle wma, uint8_t vdev_id,
1626*5113495bSYour Name 			       int value)
1627*5113495bSYour Name {
1628*5113495bSYour Name 	QDF_STATUS ret;
1629*5113495bSYour Name 
1630*5113495bSYour Name 	if (!wma_is_vdev_valid(vdev_id)) {
1631*5113495bSYour Name 		wma_err("Invalid VDEV ID: %d", vdev_id);
1632*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1633*5113495bSYour Name 	}
1634*5113495bSYour Name 
1635*5113495bSYour Name 	ret = wmi_unified_set_smps_params(wma->wmi_handle, vdev_id,
1636*5113495bSYour Name 				   value);
1637*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1638*5113495bSYour Name 		wma_err("Failed to send set Mimo PS ret = %d", ret);
1639*5113495bSYour Name 
1640*5113495bSYour Name 	return ret;
1641*5113495bSYour Name }
1642*5113495bSYour Name 
1643*5113495bSYour Name #ifdef FEATURE_TX_POWER
1644*5113495bSYour Name /**
1645*5113495bSYour Name  * wma_set_tx_power_scale() - set tx power scale
1646*5113495bSYour Name  * @vdev_id: vdev id
1647*5113495bSYour Name  * @value: value
1648*5113495bSYour Name  *
1649*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1650*5113495bSYour Name  */
wma_set_tx_power_scale(uint8_t vdev_id,int value)1651*5113495bSYour Name QDF_STATUS wma_set_tx_power_scale(uint8_t vdev_id, int value)
1652*5113495bSYour Name {
1653*5113495bSYour Name 	QDF_STATUS ret;
1654*5113495bSYour Name 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1655*5113495bSYour Name 
1656*5113495bSYour Name 	if (!wma_handle)
1657*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1658*5113495bSYour Name 
1659*5113495bSYour Name 	if (!wma_is_vdev_up(vdev_id)) {
1660*5113495bSYour Name 		wma_err("vdev id %d is not up", vdev_id);
1661*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1662*5113495bSYour Name 	}
1663*5113495bSYour Name 
1664*5113495bSYour Name 	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
1665*5113495bSYour Name 				 wmi_vdev_param_txpower_scale, value);
1666*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1667*5113495bSYour Name 		wma_err("Set tx power scale failed");
1668*5113495bSYour Name 
1669*5113495bSYour Name 	return ret;
1670*5113495bSYour Name }
1671*5113495bSYour Name 
1672*5113495bSYour Name /**
1673*5113495bSYour Name  * wma_set_tx_power_scale_decr_db() - decrease power by DB value
1674*5113495bSYour Name  * @vdev_id: vdev id
1675*5113495bSYour Name  * @value: value
1676*5113495bSYour Name  *
1677*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1678*5113495bSYour Name  */
wma_set_tx_power_scale_decr_db(uint8_t vdev_id,int value)1679*5113495bSYour Name QDF_STATUS wma_set_tx_power_scale_decr_db(uint8_t vdev_id, int value)
1680*5113495bSYour Name {
1681*5113495bSYour Name 	QDF_STATUS ret;
1682*5113495bSYour Name 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1683*5113495bSYour Name 
1684*5113495bSYour Name 	if (!wma_handle)
1685*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1686*5113495bSYour Name 
1687*5113495bSYour Name 	if (!wma_is_vdev_up(vdev_id)) {
1688*5113495bSYour Name 		wma_err("vdev id %d is not up", vdev_id);
1689*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1690*5113495bSYour Name 	}
1691*5113495bSYour Name 
1692*5113495bSYour Name 	ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
1693*5113495bSYour Name 				 wmi_vdev_param_txpower_scale_decr_db, value);
1694*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1695*5113495bSYour Name 		wma_err("Decrease tx power value failed");
1696*5113495bSYour Name 
1697*5113495bSYour Name 	return ret;
1698*5113495bSYour Name }
1699*5113495bSYour Name 
1700*5113495bSYour Name /**
1701*5113495bSYour Name  * wma_enable_disable_imps() - enable/disable FW IMPS feature
1702*5113495bSYour Name  * @pdev_id: pdev id
1703*5113495bSYour Name  * @param_val: value
1704*5113495bSYour Name  *
1705*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code.
1706*5113495bSYour Name  */
wma_enable_disable_imps(uint32_t pdev_id,uint32_t param_val)1707*5113495bSYour Name QDF_STATUS wma_enable_disable_imps(uint32_t pdev_id, uint32_t param_val)
1708*5113495bSYour Name {
1709*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
1710*5113495bSYour Name 	struct pdev_params pparam = {0};
1711*5113495bSYour Name 	QDF_STATUS status;
1712*5113495bSYour Name 
1713*5113495bSYour Name 	if (!wma)
1714*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1715*5113495bSYour Name 
1716*5113495bSYour Name 	pparam.is_host_pdev_id = false;
1717*5113495bSYour Name 
1718*5113495bSYour Name 	/* Enable-disable IMPS */
1719*5113495bSYour Name 	pparam.param_id = WMI_PDEV_PARAM_IDLE_PS_CONFIG;
1720*5113495bSYour Name 	pparam.param_value = param_val;
1721*5113495bSYour Name 	status = wmi_unified_pdev_param_send(wma->wmi_handle,
1722*5113495bSYour Name 					     &pparam, pdev_id);
1723*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
1724*5113495bSYour Name 		wma_err("Unable to enable/disable:(%d) IMPS",
1725*5113495bSYour Name 			param_val);
1726*5113495bSYour Name 
1727*5113495bSYour Name 	wma->in_imps = !!param_val;
1728*5113495bSYour Name 
1729*5113495bSYour Name 	return status;
1730*5113495bSYour Name }
1731*5113495bSYour Name #endif /* FEATURE_TX_POWER */
1732*5113495bSYour Name 
1733