xref: /wlan-driver/qca-wifi-host-cmn/target_if/green_ap/src/target_if_green_ap.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-2023 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: offload lmac interface APIs definitions for Green ap
22*5113495bSYour Name  */
23*5113495bSYour Name 
24*5113495bSYour Name #include <target_if_green_ap.h>
25*5113495bSYour Name #include <wlan_green_ap_api.h>
26*5113495bSYour Name #include <../../core/src/wlan_green_ap_main_i.h>
27*5113495bSYour Name #include <target_if.h>
28*5113495bSYour Name #include <wmi_unified_api.h>
29*5113495bSYour Name 
30*5113495bSYour Name #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
31*5113495bSYour Name /**
32*5113495bSYour Name  * target_if_green_ap_ll_ps_cmd() - Green AP low latency power save mode
33*5113495bSYour Name  * cmd api
34*5113495bSYour Name  * @vdev: vdev object
35*5113495bSYour Name  * @ll_ps_params: low latency power save command parameter
36*5113495bSYour Name  *
37*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success, otherwise appropriate failure reason
38*5113495bSYour Name  */
39*5113495bSYour Name static QDF_STATUS
target_if_green_ap_ll_ps_cmd(struct wlan_objmgr_vdev * vdev,struct green_ap_ll_ps_cmd_param * ll_ps_params)40*5113495bSYour Name target_if_green_ap_ll_ps_cmd(struct wlan_objmgr_vdev *vdev,
41*5113495bSYour Name 			     struct green_ap_ll_ps_cmd_param *ll_ps_params)
42*5113495bSYour Name {
43*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
44*5113495bSYour Name 	wmi_unified_t wmi_hdl;
45*5113495bSYour Name 
46*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
47*5113495bSYour Name 	if (!pdev) {
48*5113495bSYour Name 		green_ap_err("pdev context passed is NULL");
49*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
50*5113495bSYour Name 	}
51*5113495bSYour Name 
52*5113495bSYour Name 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
53*5113495bSYour Name 	if (!wmi_hdl) {
54*5113495bSYour Name 		green_ap_err("null wmi_hdl");
55*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
56*5113495bSYour Name 	}
57*5113495bSYour Name 
58*5113495bSYour Name 	return wmi_unified_green_ap_ll_ps_send(wmi_hdl, ll_ps_params);
59*5113495bSYour Name }
60*5113495bSYour Name 
target_if_register_ll_ps_tx_ops(struct wlan_lmac_if_green_ap_tx_ops * tx_ops)61*5113495bSYour Name static inline void target_if_register_ll_ps_tx_ops(
62*5113495bSYour Name 		struct wlan_lmac_if_green_ap_tx_ops *tx_ops)
63*5113495bSYour Name {
64*5113495bSYour Name 	tx_ops->ll_ps = target_if_green_ap_ll_ps_cmd;
65*5113495bSYour Name }
66*5113495bSYour Name #else
target_if_register_ll_ps_tx_ops(struct wlan_lmac_if_green_ap_tx_ops * tx_ops)67*5113495bSYour Name static inline void target_if_register_ll_ps_tx_ops(
68*5113495bSYour Name 		struct wlan_lmac_if_green_ap_tx_ops *tx_ops)
69*5113495bSYour Name {
70*5113495bSYour Name }
71*5113495bSYour Name #endif
72*5113495bSYour Name 
target_if_register_green_ap_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)73*5113495bSYour Name QDF_STATUS target_if_register_green_ap_tx_ops(
74*5113495bSYour Name 		struct wlan_lmac_if_tx_ops *tx_ops)
75*5113495bSYour Name {
76*5113495bSYour Name 	struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops;
77*5113495bSYour Name 
78*5113495bSYour Name 	if (!tx_ops) {
79*5113495bSYour Name 		target_if_err("invalid tx_ops");
80*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
81*5113495bSYour Name 	}
82*5113495bSYour Name 
83*5113495bSYour Name 	green_ap_tx_ops = &tx_ops->green_ap_tx_ops;
84*5113495bSYour Name 
85*5113495bSYour Name 	green_ap_tx_ops->enable_egap = target_if_green_ap_enable_egap;
86*5113495bSYour Name 	green_ap_tx_ops->ps_on_off_send = target_if_green_ap_set_ps_on_off;
87*5113495bSYour Name 	green_ap_tx_ops->reset_dev = NULL;
88*5113495bSYour Name 	green_ap_tx_ops->get_current_channel = NULL;
89*5113495bSYour Name 	green_ap_tx_ops->get_current_channel_flags = NULL;
90*5113495bSYour Name 	green_ap_tx_ops->get_capab = NULL;
91*5113495bSYour Name 
92*5113495bSYour Name 	target_if_register_ll_ps_tx_ops(green_ap_tx_ops);
93*5113495bSYour Name 
94*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
95*5113495bSYour Name }
96*5113495bSYour Name 
97*5113495bSYour Name #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
98*5113495bSYour Name /**
99*5113495bSYour Name  * target_if_green_ap_ll_ps_event() - Green AP low latency
100*5113495bSYour Name  * Power save event handler
101*5113495bSYour Name  * @scn: pointer to scn handle
102*5113495bSYour Name  * @evt_buf: pointer to event buffer
103*5113495bSYour Name  * @data_len: data len of the event buffer
104*5113495bSYour Name  *
105*5113495bSYour Name  * Return: 0 for success, otherwise appropriate error code
106*5113495bSYour Name  */
target_if_green_ap_ll_ps_event(ol_scn_t scn,uint8_t * evt_buf,uint32_t data_len)107*5113495bSYour Name static int target_if_green_ap_ll_ps_event(ol_scn_t scn, uint8_t *evt_buf,
108*5113495bSYour Name 					  uint32_t data_len)
109*5113495bSYour Name {
110*5113495bSYour Name 	QDF_STATUS status;
111*5113495bSYour Name 	int err = 0;
112*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
113*5113495bSYour Name 	struct wlan_green_ap_ll_ps_event_param *ll_ps_param;
114*5113495bSYour Name 	void *wmi_hdl;
115*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
116*5113495bSYour Name 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
117*5113495bSYour Name 
118*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
119*5113495bSYour Name 	if (!psoc) {
120*5113495bSYour Name 		green_ap_err("psoc is null");
121*5113495bSYour Name 		return -ENOMEM;
122*5113495bSYour Name 	}
123*5113495bSYour Name 
124*5113495bSYour Name 	pdev = target_if_get_pdev_from_scn_hdl(scn);
125*5113495bSYour Name 	if (!pdev) {
126*5113495bSYour Name 		green_ap_err("pdev is null");
127*5113495bSYour Name 		return -ENOMEM;
128*5113495bSYour Name 	}
129*5113495bSYour Name 
130*5113495bSYour Name 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
131*5113495bSYour Name 			pdev, WLAN_UMAC_COMP_GREEN_AP);
132*5113495bSYour Name 	if (!green_ap_ctx) {
133*5113495bSYour Name 		green_ap_err("green_ap_ctx not found");
134*5113495bSYour Name 		return -ENOMEM;
135*5113495bSYour Name 	}
136*5113495bSYour Name 
137*5113495bSYour Name 	ll_ps_param = qdf_mem_malloc(sizeof(*ll_ps_param));
138*5113495bSYour Name 	if (!ll_ps_param) {
139*5113495bSYour Name 		green_ap_err("Unable to allocate memory");
140*5113495bSYour Name 		return -ENOMEM;
141*5113495bSYour Name 	}
142*5113495bSYour Name 
143*5113495bSYour Name 	qdf_mem_zero(ll_ps_param, sizeof(*ll_ps_param));
144*5113495bSYour Name 
145*5113495bSYour Name 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
146*5113495bSYour Name 	if (!wmi_hdl) {
147*5113495bSYour Name 		green_ap_err("null wmi_hdl");
148*5113495bSYour Name 		err = -EINVAL;
149*5113495bSYour Name 		goto free_event_param;
150*5113495bSYour Name 	}
151*5113495bSYour Name 
152*5113495bSYour Name 	if (wmi_unified_extract_green_ap_ll_ps_param(wmi_hdl,
153*5113495bSYour Name 						     evt_buf,
154*5113495bSYour Name 						     ll_ps_param)) {
155*5113495bSYour Name 		green_ap_err("unable to extract green ap ll ps event params");
156*5113495bSYour Name 		err = -EINVAL;
157*5113495bSYour Name 		goto free_event_param;
158*5113495bSYour Name 	}
159*5113495bSYour Name 
160*5113495bSYour Name 	if ((ll_ps_param->dialog_token % 2))
161*5113495bSYour Name 		ll_ps_param->bcn_mult = green_ap_ctx->bcn_mult;
162*5113495bSYour Name 	else
163*5113495bSYour Name 		ll_ps_param->bcn_mult = 1;
164*5113495bSYour Name 
165*5113495bSYour Name 	green_ap_debug("Next TSF: %llu Dialog Token: %u bcn_mult: %u",
166*5113495bSYour Name 		       ll_ps_param->next_tsf,
167*5113495bSYour Name 		       ll_ps_param->dialog_token,
168*5113495bSYour Name 		       ll_ps_param->bcn_mult);
169*5113495bSYour Name 
170*5113495bSYour Name 	status = wlan_green_ap_send_ll_ps_event_params(pdev,
171*5113495bSYour Name 						       ll_ps_param);
172*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
173*5113495bSYour Name 		wmi_err("wlan_green_ap_send_ll_ps_event failed");
174*5113495bSYour Name 		err = -EINVAL;
175*5113495bSYour Name 		goto free_event_param;
176*5113495bSYour Name 	}
177*5113495bSYour Name 
178*5113495bSYour Name free_event_param:
179*5113495bSYour Name 	qdf_mem_free(ll_ps_param);
180*5113495bSYour Name 	return err;
181*5113495bSYour Name }
182*5113495bSYour Name 
target_if_green_ap_register_ll_ps_event_handler(struct wlan_objmgr_pdev * pdev)183*5113495bSYour Name QDF_STATUS target_if_green_ap_register_ll_ps_event_handler(
184*5113495bSYour Name 				struct wlan_objmgr_pdev *pdev)
185*5113495bSYour Name {
186*5113495bSYour Name 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
187*5113495bSYour Name 	QDF_STATUS ret;
188*5113495bSYour Name 	wmi_unified_t wmi_hdl;
189*5113495bSYour Name 
190*5113495bSYour Name 	if (!pdev) {
191*5113495bSYour Name 		green_ap_err("pdev is null");
192*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
193*5113495bSYour Name 		}
194*5113495bSYour Name 
195*5113495bSYour Name 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
196*5113495bSYour Name 	if (!wmi_hdl) {
197*5113495bSYour Name 		green_ap_err("null wmi_hdl");
198*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
199*5113495bSYour Name 	}
200*5113495bSYour Name 
201*5113495bSYour Name 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
202*5113495bSYour Name 			pdev, WLAN_UMAC_COMP_GREEN_AP);
203*5113495bSYour Name 	if (!green_ap_ctx) {
204*5113495bSYour Name 		green_ap_err("green ap context obtained is NULL");
205*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
206*5113495bSYour Name 	}
207*5113495bSYour Name 
208*5113495bSYour Name 	ret = wmi_unified_register_event_handler(
209*5113495bSYour Name 			wmi_hdl,
210*5113495bSYour Name 			wmi_xgap_enable_complete_eventid,
211*5113495bSYour Name 			target_if_green_ap_ll_ps_event,
212*5113495bSYour Name 			WMI_RX_UMAC_CTX);
213*5113495bSYour Name 
214*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
215*5113495bSYour Name 		green_ap_err("Failed to register Enhance Green AP event");
216*5113495bSYour Name 	else
217*5113495bSYour Name 		green_ap_debug("Set the Enhance Green AP event handler");
218*5113495bSYour Name 
219*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
220*5113495bSYour Name }
221*5113495bSYour Name #endif
222*5113495bSYour Name 
223*5113495bSYour Name /**
224*5113495bSYour Name  * target_if_green_ap_egap_status_info_event() - egap status info event
225*5113495bSYour Name  * @scn: pointer to scn handle
226*5113495bSYour Name  * @evt_buf: pointer to event buffer
227*5113495bSYour Name  * @data_len: data len of the event buffer
228*5113495bSYour Name  *
229*5113495bSYour Name  * Return: 0 for success, otherwise appropriate error code
230*5113495bSYour Name  */
target_if_green_ap_egap_status_info_event(ol_scn_t scn,uint8_t * evt_buf,uint32_t data_len)231*5113495bSYour Name static int target_if_green_ap_egap_status_info_event(
232*5113495bSYour Name 		ol_scn_t scn, uint8_t *evt_buf, uint32_t data_len)
233*5113495bSYour Name {
234*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
235*5113495bSYour Name 	struct wlan_green_ap_egap_status_info egap_status_info_params;
236*5113495bSYour Name 	void *wmi_hdl;
237*5113495bSYour Name 
238*5113495bSYour Name 	pdev = target_if_get_pdev_from_scn_hdl(scn);
239*5113495bSYour Name 	if (!pdev) {
240*5113495bSYour Name 		green_ap_err("pdev is null");
241*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
242*5113495bSYour Name 	}
243*5113495bSYour Name 
244*5113495bSYour Name 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
245*5113495bSYour Name 	if (!wmi_hdl) {
246*5113495bSYour Name 		green_ap_err("null wmi_hdl");
247*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
248*5113495bSYour Name 	}
249*5113495bSYour Name 
250*5113495bSYour Name 	if (wmi_extract_green_ap_egap_status_info(wmi_hdl,
251*5113495bSYour Name 						  evt_buf,
252*5113495bSYour Name 						  &egap_status_info_params) !=
253*5113495bSYour Name 						  QDF_STATUS_SUCCESS) {
254*5113495bSYour Name 		green_ap_err("unable to extract green ap egap status info");
255*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
256*5113495bSYour Name 	}
257*5113495bSYour Name 
258*5113495bSYour Name 	green_ap_debug("mac_id: %d, status: %d, tx_mask: %x, rx_mask: %d",
259*5113495bSYour Name 		       egap_status_info_params.mac_id,
260*5113495bSYour Name 		       egap_status_info_params.status,
261*5113495bSYour Name 		       egap_status_info_params.tx_chainmask,
262*5113495bSYour Name 		       egap_status_info_params.rx_chainmask);
263*5113495bSYour Name 
264*5113495bSYour Name 	return 0;
265*5113495bSYour Name }
266*5113495bSYour Name 
target_if_green_ap_register_egap_event_handler(struct wlan_objmgr_pdev * pdev)267*5113495bSYour Name QDF_STATUS target_if_green_ap_register_egap_event_handler(
268*5113495bSYour Name 			struct wlan_objmgr_pdev *pdev)
269*5113495bSYour Name {
270*5113495bSYour Name 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
271*5113495bSYour Name 	struct wlan_green_ap_egap_params *egap_params;
272*5113495bSYour Name 	QDF_STATUS ret;
273*5113495bSYour Name 	wmi_unified_t wmi_hdl;
274*5113495bSYour Name 
275*5113495bSYour Name 	if (!pdev) {
276*5113495bSYour Name 		green_ap_err("pdev is null");
277*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
278*5113495bSYour Name 	}
279*5113495bSYour Name 
280*5113495bSYour Name 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
281*5113495bSYour Name 	if (!wmi_hdl) {
282*5113495bSYour Name 		green_ap_err("null wmi_hdl");
283*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
284*5113495bSYour Name 	}
285*5113495bSYour Name 
286*5113495bSYour Name 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
287*5113495bSYour Name 			pdev, WLAN_UMAC_COMP_GREEN_AP);
288*5113495bSYour Name 	if (!green_ap_ctx) {
289*5113495bSYour Name 		green_ap_err("green ap context obtained is NULL");
290*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
291*5113495bSYour Name 	}
292*5113495bSYour Name 	egap_params = &green_ap_ctx->egap_params;
293*5113495bSYour Name 
294*5113495bSYour Name 	ret = wmi_unified_register_event_handler(
295*5113495bSYour Name 			wmi_hdl,
296*5113495bSYour Name 			wmi_ap_ps_egap_info_event_id,
297*5113495bSYour Name 			target_if_green_ap_egap_status_info_event,
298*5113495bSYour Name 			WMI_RX_UMAC_CTX);
299*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
300*5113495bSYour Name 		green_ap_err("Failed to register Enhance Green AP event");
301*5113495bSYour Name 		egap_params->fw_egap_support = false;
302*5113495bSYour Name 	} else {
303*5113495bSYour Name 		green_ap_info("Set the Enhance Green AP event handler");
304*5113495bSYour Name 		egap_params->fw_egap_support = true;
305*5113495bSYour Name 	}
306*5113495bSYour Name 
307*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
308*5113495bSYour Name }
309*5113495bSYour Name 
target_if_green_ap_enable_egap(struct wlan_objmgr_pdev * pdev,struct wlan_green_ap_egap_params * egap_params)310*5113495bSYour Name QDF_STATUS target_if_green_ap_enable_egap(
311*5113495bSYour Name 		struct wlan_objmgr_pdev *pdev,
312*5113495bSYour Name 		struct wlan_green_ap_egap_params *egap_params)
313*5113495bSYour Name {
314*5113495bSYour Name 	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
315*5113495bSYour Name 	wmi_unified_t wmi_hdl;
316*5113495bSYour Name 
317*5113495bSYour Name 	if (!pdev) {
318*5113495bSYour Name 		green_ap_err("pdev context passed is NULL");
319*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
320*5113495bSYour Name 	}
321*5113495bSYour Name 
322*5113495bSYour Name 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
323*5113495bSYour Name 	if (!wmi_hdl) {
324*5113495bSYour Name 		green_ap_err("null wmi_hdl");
325*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
326*5113495bSYour Name 	}
327*5113495bSYour Name 
328*5113495bSYour Name 	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
329*5113495bSYour Name 			pdev, WLAN_UMAC_COMP_GREEN_AP);
330*5113495bSYour Name 	if (!green_ap_ctx) {
331*5113495bSYour Name 		green_ap_err("green ap context obtained is NULL");
332*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
333*5113495bSYour Name 	}
334*5113495bSYour Name 
335*5113495bSYour Name 	qdf_spin_lock_bh(&green_ap_ctx->lock);
336*5113495bSYour Name 	if (!wlan_is_egap_enabled(green_ap_ctx)) {
337*5113495bSYour Name 		green_ap_info("enhanced green ap support is not present");
338*5113495bSYour Name 		qdf_spin_unlock_bh(&green_ap_ctx->lock);
339*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
340*5113495bSYour Name 	}
341*5113495bSYour Name 	qdf_spin_unlock_bh(&green_ap_ctx->lock);
342*5113495bSYour Name 
343*5113495bSYour Name 	return wmi_unified_egap_conf_params_cmd(wmi_hdl,
344*5113495bSYour Name 							egap_params);
345*5113495bSYour Name }
346*5113495bSYour Name 
target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev * pdev,bool value,uint8_t pdev_id)347*5113495bSYour Name QDF_STATUS target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev *pdev,
348*5113495bSYour Name 					    bool value, uint8_t pdev_id)
349*5113495bSYour Name {
350*5113495bSYour Name 	wmi_unified_t wmi_hdl;
351*5113495bSYour Name 
352*5113495bSYour Name 	if (!pdev) {
353*5113495bSYour Name 		green_ap_err("pdev context passed is NULL");
354*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
355*5113495bSYour Name 	}
356*5113495bSYour Name 
357*5113495bSYour Name 	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
358*5113495bSYour Name 	if (!wmi_hdl) {
359*5113495bSYour Name 		green_ap_err("null wmi_hdl");
360*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
361*5113495bSYour Name 	}
362*5113495bSYour Name 
363*5113495bSYour Name 	return wmi_unified_green_ap_ps_send(wmi_hdl,
364*5113495bSYour Name 					    value, pdev_id);
365*5113495bSYour Name }
366