1 /*
2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**
21 * DOC: Implements public API for pmo to interact with target/WMI
22 */
23
24 #include "wlan_pmo_tgt_api.h"
25 #include "wlan_pmo_wow.h"
26 #include "wlan_pmo_obj_mgmt_public_struct.h"
27 #include "wlan_pmo_main.h"
28
pmo_tgt_vdev_update_param_req(struct wlan_objmgr_vdev * vdev,enum pmo_vdev_param_id param_id,uint32_t param_value)29 QDF_STATUS pmo_tgt_vdev_update_param_req(struct wlan_objmgr_vdev *vdev,
30 enum pmo_vdev_param_id param_id, uint32_t param_value)
31 {
32 QDF_STATUS status;
33 struct wlan_objmgr_psoc *psoc;
34 struct wlan_pmo_tx_ops pmo_tx_ops;
35
36 pmo_enter();
37
38 psoc = pmo_vdev_get_psoc(vdev);
39
40 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
41 if (!pmo_tx_ops.send_vdev_param_update_req) {
42 pmo_err("send_vdev_param_update_req is null");
43 status = QDF_STATUS_E_NULL_VALUE;
44 goto out;
45 }
46
47 status = pmo_tx_ops.send_vdev_param_update_req(vdev, param_id,
48 param_value);
49 out:
50 pmo_exit();
51
52 return status;
53 }
54
55 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
56 QDF_STATUS
pmo_tgt_send_igmp_offload_req(struct wlan_objmgr_vdev * vdev,struct pmo_igmp_offload_req * pmo_igmp_req)57 pmo_tgt_send_igmp_offload_req(struct wlan_objmgr_vdev *vdev,
58 struct pmo_igmp_offload_req *pmo_igmp_req)
59 {
60 QDF_STATUS status;
61 struct wlan_objmgr_psoc *psoc;
62 struct wlan_pmo_tx_ops pmo_tx_ops;
63
64 psoc = pmo_vdev_get_psoc(vdev);
65
66 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
67 if (!pmo_tx_ops.send_igmp_offload_req) {
68 pmo_err("send_vdev_param_set_req is null");
69 return QDF_STATUS_E_NULL_VALUE;
70 }
71
72 status = pmo_tx_ops.send_igmp_offload_req(vdev, pmo_igmp_req);
73
74 return status;
75 }
76 #endif
77
pmo_tgt_send_vdev_sta_ps_param(struct wlan_objmgr_vdev * vdev,enum pmo_sta_powersave_param ps_param,uint32_t param_value)78 QDF_STATUS pmo_tgt_send_vdev_sta_ps_param(struct wlan_objmgr_vdev *vdev,
79 enum pmo_sta_powersave_param ps_param, uint32_t param_value)
80 {
81 QDF_STATUS status;
82 struct wlan_objmgr_psoc *psoc;
83 struct wlan_pmo_tx_ops pmo_tx_ops;
84
85 psoc = pmo_vdev_get_psoc(vdev);
86
87 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
88 if (!pmo_tx_ops.send_vdev_sta_ps_param_req) {
89 pmo_err("send_vdev_param_set_req is null");
90 status = QDF_STATUS_E_NULL_VALUE;
91 goto out;
92 }
93
94 status = pmo_tx_ops.send_vdev_sta_ps_param_req(vdev, ps_param,
95 param_value);
96 out:
97 return status;
98 }
99
pmo_tgt_psoc_update_wow_bus_suspend_state(struct wlan_objmgr_psoc * psoc,uint8_t val)100 void pmo_tgt_psoc_update_wow_bus_suspend_state(struct wlan_objmgr_psoc *psoc,
101 uint8_t val)
102 {
103 struct wlan_pmo_tx_ops pmo_tx_ops;
104
105 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
106 if (!pmo_tx_ops.psoc_update_wow_bus_suspend) {
107 pmo_err("psoc_update_wow_bus_suspend is null");
108 return;
109 }
110 pmo_tx_ops.psoc_update_wow_bus_suspend(psoc, val);
111 }
112
pmo_tgt_psoc_get_host_credits(struct wlan_objmgr_psoc * psoc)113 int pmo_tgt_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc)
114 {
115
116 struct wlan_pmo_tx_ops pmo_tx_ops;
117
118 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
119 if (!pmo_tx_ops.psoc_get_host_credits) {
120 pmo_err("psoc_get_host_credits is null");
121 return 0;
122 }
123
124 return pmo_tx_ops.psoc_get_host_credits(psoc);
125 }
126
pmo_tgt_psoc_get_pending_cmnds(struct wlan_objmgr_psoc * psoc)127 int pmo_tgt_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc)
128 {
129
130 struct wlan_pmo_tx_ops pmo_tx_ops;
131
132 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
133 if (!pmo_tx_ops.psoc_get_pending_cmnds) {
134 pmo_err("psoc_get_pending_cmnds is null");
135 return -EAGAIN;
136 }
137
138 return pmo_tx_ops.psoc_get_pending_cmnds(psoc);
139 }
140
pmo_tgt_update_target_suspend_flag(struct wlan_objmgr_psoc * psoc,uint8_t val)141 void pmo_tgt_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
142 uint8_t val)
143 {
144 struct wlan_pmo_tx_ops pmo_tx_ops;
145
146 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
147 if (!pmo_tx_ops.update_target_suspend_flag) {
148 pmo_err("update_target_suspend_flag is null");
149 return;
150 }
151 pmo_tx_ops.update_target_suspend_flag(psoc, val);
152 }
153
pmo_tgt_update_target_suspend_acked_flag(struct wlan_objmgr_psoc * psoc,uint8_t val)154 void pmo_tgt_update_target_suspend_acked_flag(struct wlan_objmgr_psoc *psoc,
155 uint8_t val)
156 {
157 struct wlan_pmo_tx_ops pmo_tx_ops;
158
159 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
160 if (!pmo_tx_ops.update_target_suspend_acked_flag) {
161 pmo_err("update_target_suspend_acked_flag is null");
162 return;
163 }
164 pmo_tx_ops.update_target_suspend_acked_flag(psoc, val);
165 }
166
pmo_tgt_is_target_suspended(struct wlan_objmgr_psoc * psoc)167 bool pmo_tgt_is_target_suspended(struct wlan_objmgr_psoc *psoc)
168 {
169 struct wlan_pmo_tx_ops pmo_tx_ops;
170
171 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
172 if (!pmo_tx_ops.is_target_suspended) {
173 pmo_err("is_target_suspended is null");
174 return false;
175 }
176 return pmo_tx_ops.is_target_suspended(psoc);
177 }
178
pmo_tgt_psoc_send_wow_enable_req(struct wlan_objmgr_psoc * psoc,struct pmo_wow_cmd_params * param)179 QDF_STATUS pmo_tgt_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
180 struct pmo_wow_cmd_params *param)
181 {
182 struct pmo_psoc_priv_obj *psoc_ctx;
183 struct wlan_pmo_tx_ops pmo_tx_ops;
184
185 psoc_ctx = pmo_psoc_get_priv(psoc);
186 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
187
188 if (psoc_ctx->wow.wow_state == pmo_wow_state_legacy_d0) {
189 if (!pmo_tx_ops.psoc_send_d0wow_enable_req) {
190 pmo_err("psoc_send_d0wow_enable_req is null");
191 return QDF_STATUS_E_NULL_VALUE;
192 }
193 pmo_debug("Sending D0WOW enable command...");
194 return pmo_tx_ops.psoc_send_d0wow_enable_req(psoc);
195 }
196
197 if (!pmo_tx_ops.psoc_send_wow_enable_req) {
198 pmo_err("psoc_send_wow_enable_req is null");
199 return QDF_STATUS_E_NULL_VALUE;
200 }
201 return pmo_tx_ops.psoc_send_wow_enable_req(psoc, param);
202 }
203
pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc * psoc,struct pmo_suspend_params * param)204 QDF_STATUS pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc *psoc,
205 struct pmo_suspend_params *param)
206 {
207 struct wlan_pmo_tx_ops pmo_tx_ops;
208
209 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
210 if (!pmo_tx_ops.psoc_send_supend_req) {
211 pmo_err("psoc_send_supend_req is null");
212 return QDF_STATUS_E_NULL_VALUE;
213 }
214
215 return pmo_tx_ops.psoc_send_supend_req(psoc, param);
216 }
217
pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc * psoc,bool value)218 QDF_STATUS pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc *psoc,
219 bool value)
220 {
221 struct wlan_pmo_tx_ops pmo_tx_ops;
222
223 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
224 if (!pmo_tx_ops.psoc_set_runtime_pm_in_progress) {
225 pmo_err("pmo ops is null");
226 return QDF_STATUS_E_NULL_VALUE;
227 }
228
229 pmo_tx_ops.psoc_set_runtime_pm_in_progress(psoc, value);
230
231 return QDF_STATUS_SUCCESS;
232 }
233
pmo_tgt_psoc_get_runtime_pm_in_progress(struct wlan_objmgr_psoc * psoc)234 bool pmo_tgt_psoc_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc)
235 {
236 struct wlan_pmo_tx_ops pmo_tx_ops;
237
238 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
239 if (!pmo_tx_ops.psoc_get_runtime_pm_in_progress) {
240 pmo_err("psoc_get_runtime_pm_in_progress is null");
241 return QDF_STATUS_E_NULL_VALUE;
242 }
243
244 return pmo_tx_ops.psoc_get_runtime_pm_in_progress(psoc);
245 }
246
pmo_tgt_psoc_send_host_wakeup_ind(struct wlan_objmgr_psoc * psoc)247 QDF_STATUS pmo_tgt_psoc_send_host_wakeup_ind(struct wlan_objmgr_psoc *psoc)
248 {
249 struct pmo_psoc_priv_obj *psoc_ctx;
250 struct wlan_pmo_tx_ops pmo_tx_ops;
251
252 psoc_ctx = pmo_psoc_get_priv(psoc);
253 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
254
255 if (psoc_ctx->psoc_cfg.d0_wow_supported &&
256 psoc_ctx->wow.wow_state == pmo_wow_state_legacy_d0) {
257 if (!pmo_tx_ops.psoc_send_d0wow_disable_req) {
258 pmo_err("psoc_send_d0wow_disable_req is null");
259 return QDF_STATUS_E_NULL_VALUE;
260 }
261 pmo_debug("Sending D0WOW disable command...");
262 return pmo_tx_ops.psoc_send_d0wow_disable_req(psoc);
263 }
264
265 if (!pmo_tx_ops.psoc_send_host_wakeup_ind) {
266 pmo_err("psoc_send_host_wakeup_ind is null");
267 return QDF_STATUS_E_NULL_VALUE;
268 }
269 return pmo_tx_ops.psoc_send_host_wakeup_ind(psoc);
270 }
271
pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc * psoc)272 QDF_STATUS pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc *psoc)
273 {
274 struct wlan_pmo_tx_ops pmo_tx_ops;
275
276 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
277 if (!pmo_tx_ops.psoc_send_target_resume_req) {
278 pmo_err("send_target_resume_req is null");
279 return QDF_STATUS_E_NULL_VALUE;
280 }
281
282 return pmo_tx_ops.psoc_send_target_resume_req(psoc);
283 }
284
pmo_tgt_psoc_send_idle_roam_monitor(struct wlan_objmgr_psoc * psoc,uint8_t val)285 QDF_STATUS pmo_tgt_psoc_send_idle_roam_monitor(struct wlan_objmgr_psoc *psoc,
286 uint8_t val)
287 {
288 struct wlan_pmo_tx_ops pmo_tx_ops;
289
290 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
291 if (!pmo_tx_ops.psoc_send_idle_roam_suspend_mode) {
292 pmo_err("NULL fp");
293 return QDF_STATUS_E_NULL_VALUE;
294 }
295 return pmo_tx_ops.psoc_send_idle_roam_suspend_mode(psoc, val);
296 }
297
pmo_tgt_psoc_set_wow_enable_ack_failed(struct wlan_objmgr_psoc * psoc)298 QDF_STATUS pmo_tgt_psoc_set_wow_enable_ack_failed(struct wlan_objmgr_psoc *psoc)
299 {
300 struct wlan_pmo_tx_ops pmo_tx_ops;
301
302 pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
303 if (!pmo_tx_ops.psoc_set_wow_enable_ack_failed) {
304 pmo_err("pmo ops is null");
305 return QDF_STATUS_E_NULL_VALUE;
306 }
307
308 pmo_tx_ops.psoc_set_wow_enable_ack_failed(psoc);
309
310 return QDF_STATUS_SUCCESS;
311 }
312