1 /*
2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021,2023-2024 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 * DOC: Implement various api / helper function which shall be used
21 * PMO user and target interface.
22 */
23
24 #include "wlan_pmo_main.h"
25 #include "wlan_pmo_obj_mgmt_public_struct.h"
26 #include "wlan_pmo_cfg.h"
27 #include "cfg_ucfg_api.h"
28 #include "wlan_fwol_ucfg_api.h"
29 #include "wlan_ipa_obj_mgmt_api.h"
30 #include "wlan_pmo_icmp.h"
31
32 static struct wlan_pmo_ctx *gp_pmo_ctx;
33
pmo_allocate_ctx(void)34 QDF_STATUS pmo_allocate_ctx(void)
35 {
36 /* If it is already created, ignore */
37 if (gp_pmo_ctx) {
38 pmo_debug("already allocated pmo_ctx");
39 return QDF_STATUS_SUCCESS;
40 }
41
42 /* allocate offload mgr ctx */
43 gp_pmo_ctx = (struct wlan_pmo_ctx *)qdf_mem_malloc(
44 sizeof(*gp_pmo_ctx));
45 if (!gp_pmo_ctx)
46 return QDF_STATUS_E_NOMEM;
47
48 qdf_spinlock_create(&gp_pmo_ctx->lock);
49
50 return QDF_STATUS_SUCCESS;
51 }
52
pmo_free_ctx(void)53 void pmo_free_ctx(void)
54 {
55 if (!gp_pmo_ctx) {
56 pmo_err("pmo ctx is already freed");
57 QDF_ASSERT(0);
58 return;
59 }
60 qdf_spinlock_destroy(&gp_pmo_ctx->lock);
61 qdf_mem_free(gp_pmo_ctx);
62 gp_pmo_ctx = NULL;
63 }
64
pmo_get_context(void)65 struct wlan_pmo_ctx *pmo_get_context(void)
66 {
67 return gp_pmo_ctx;
68 }
69
70 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
wlan_extwow_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)71 static void wlan_extwow_init_cfg(struct wlan_objmgr_psoc *psoc,
72 struct pmo_psoc_cfg *psoc_cfg)
73 {
74 psoc_cfg->extwow_goto_suspend =
75 cfg_get(psoc, CFG_EXTWOW_GOTO_SUSPEND);
76 psoc_cfg->extwow_app1_wakeup_pin_num =
77 cfg_get(psoc, CFG_EXTWOW_APP1_WAKE_PIN_NUMBER);
78 psoc_cfg->extwow_app2_wakeup_pin_num =
79 cfg_get(psoc, CFG_EXTWOW_APP2_WAKE_PIN_NUMBER);
80 psoc_cfg->extwow_app2_init_ping_interval =
81 cfg_get(psoc, CFG_EXTWOW_KA_INIT_PING_INTERVAL);
82 psoc_cfg->extwow_app2_min_ping_interval =
83 cfg_get(psoc, CFG_EXTWOW_KA_MIN_PING_INTERVAL);
84 psoc_cfg->extwow_app2_max_ping_interval =
85 cfg_get(psoc, CFG_EXTWOW_KA_MAX_PING_INTERVAL);
86 psoc_cfg->extwow_app2_inc_ping_interval =
87 cfg_get(psoc, CFG_EXTWOW_KA_INC_PING_INTERVAL);
88 psoc_cfg->extwow_app2_tcp_src_port =
89 cfg_get(psoc, CFG_EXTWOW_TCP_SRC_PORT);
90 psoc_cfg->extwow_app2_tcp_dst_port =
91 cfg_get(psoc, CFG_EXTWOW_TCP_DST_PORT);
92 psoc_cfg->extwow_app2_tcp_tx_timeout =
93 cfg_get(psoc, CFG_EXTWOW_TCP_TX_TIMEOUT);
94 psoc_cfg->extwow_app2_tcp_rx_timeout =
95 cfg_get(psoc, CFG_EXTWOW_TCP_RX_TIMEOUT);
96 }
97 #else
wlan_extwow_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)98 static void wlan_extwow_init_cfg(struct wlan_objmgr_psoc *psoc,
99 struct pmo_psoc_cfg *psoc_cfg)
100 {
101 }
102 #endif
103
104 #ifdef WLAN_FEATURE_WOW_PULSE
wlan_pmo_wow_pulse_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)105 static void wlan_pmo_wow_pulse_init_cfg(struct wlan_objmgr_psoc *psoc,
106 struct pmo_psoc_cfg *psoc_cfg)
107 {
108 psoc_cfg->is_wow_pulse_supported =
109 cfg_get(psoc, CFG_PMO_WOW_PULSE_ENABLE);
110 psoc_cfg->wow_pulse_pin = cfg_get(psoc, CFG_PMO_WOW_PULSE_PIN);
111 psoc_cfg->wow_pulse_interval_high =
112 cfg_get(psoc, CFG_PMO_WOW_PULSE_HIGH);
113 psoc_cfg->wow_pulse_interval_low =
114 cfg_get(psoc, CFG_PMO_WOW_PULSE_LOW);
115 psoc_cfg->wow_pulse_repeat_count =
116 cfg_get(psoc, CFG_PMO_WOW_PULSE_REPEAT);
117 psoc_cfg->wow_pulse_init_state =
118 cfg_get(psoc, CFG_PMO_WOW_PULSE_INIT);
119 }
120 #else
wlan_pmo_wow_pulse_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)121 static void wlan_pmo_wow_pulse_init_cfg(struct wlan_objmgr_psoc *psoc,
122 struct pmo_psoc_cfg *psoc_cfg)
123 {
124 }
125 #endif
126
127 #ifdef WLAN_FEATURE_PACKET_FILTERING
wlan_pmo_pkt_filter_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)128 static void wlan_pmo_pkt_filter_init_cfg(struct wlan_objmgr_psoc *psoc,
129 struct pmo_psoc_cfg *psoc_cfg)
130 {
131 psoc_cfg->packet_filters_bitmap = cfg_get(psoc, CFG_PMO_PKT_FILTER);
132 psoc_cfg->packet_filter_enabled =
133 !cfg_get(psoc, CFG_PMO_DISABLE_PKT_FILTER);
134 }
135 #else
wlan_pmo_pkt_filter_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)136 static void wlan_pmo_pkt_filter_init_cfg(struct wlan_objmgr_psoc *psoc,
137 struct pmo_psoc_cfg *psoc_cfg)
138 {
139 psoc_cfg->packet_filter_enabled =
140 !cfg_get(psoc, CFG_PMO_DISABLE_PKT_FILTER);
141 }
142 #endif
143
144 #ifdef FEATURE_RUNTIME_PM
wlan_pmo_runtime_pm_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)145 static void wlan_pmo_runtime_pm_init_cfg(struct wlan_objmgr_psoc *psoc,
146 struct pmo_psoc_cfg *psoc_cfg)
147 {
148 psoc_cfg->runtime_pm_delay = cfg_get(psoc, CFG_PMO_RUNTIME_PM_DELAY);
149 }
150 #else
wlan_pmo_runtime_pm_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)151 static void wlan_pmo_runtime_pm_init_cfg(struct wlan_objmgr_psoc *psoc,
152 struct pmo_psoc_cfg *psoc_cfg)
153 {
154 }
155 #endif
156
157 #ifdef FEATURE_WLAN_RA_FILTERING
wlan_pmo_ra_filtering_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)158 static void wlan_pmo_ra_filtering_init_cfg(struct wlan_objmgr_psoc *psoc,
159 struct pmo_psoc_cfg *psoc_cfg)
160 {
161 bool ra_enable;
162
163 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_is_rate_limit_enabled(psoc,
164 &ra_enable)))
165 psoc_cfg->ra_ratelimit_enable = ra_enable;
166
167 psoc_cfg->ra_ratelimit_interval =
168 cfg_get(psoc, CFG_RA_RATE_LIMIT_INTERVAL);
169 }
170 #else
wlan_pmo_ra_filtering_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)171 static void wlan_pmo_ra_filtering_init_cfg(struct wlan_objmgr_psoc *psoc,
172 struct pmo_psoc_cfg *psoc_cfg)
173 {
174 }
175 #endif
176
177 #ifdef WLAN_ENABLE_GPIO_WAKEUP
wlan_pmo_gpio_wakeup_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)178 static void wlan_pmo_gpio_wakeup_init_cfg(struct wlan_objmgr_psoc *psoc,
179 struct pmo_psoc_cfg *psoc_cfg)
180 {
181 psoc_cfg->enable_gpio_wakeup =
182 cfg_get(psoc, CFG_PMO_ENABLE_GPIO_WAKEUP);
183 psoc_cfg->gpio_wakeup_pin =
184 cfg_get(psoc, CFG_PMO_GPIO_WAKEUP_PIN);
185 psoc_cfg->gpio_wakeup_mode =
186 cfg_get(psoc, CFG_PMO_GPIO_WAKEUP_MODE);
187 }
188 #else
wlan_pmo_gpio_wakeup_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)189 static void wlan_pmo_gpio_wakeup_init_cfg(struct wlan_objmgr_psoc *psoc,
190 struct pmo_psoc_cfg *psoc_cfg)
191 {
192 }
193 #endif
194
195 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
196 static void
wlan_pmo_get_igmp_version_support_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)197 wlan_pmo_get_igmp_version_support_cfg(struct wlan_objmgr_psoc *psoc,
198 struct pmo_psoc_cfg *psoc_cfg)
199 {
200 psoc_cfg->igmp_version_support =
201 cfg_get(psoc, CFG_IGMP_VERSION_SUPPORT);
202 }
203
204 static void
wlan_pmo_get_igmp_offload_enable_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)205 wlan_pmo_get_igmp_offload_enable_cfg(struct wlan_objmgr_psoc *psoc,
206 struct pmo_psoc_cfg *psoc_cfg)
207 {
208 psoc_cfg->igmp_offload_enable = cfg_get(psoc,
209 CFG_PMO_ENABLE_IGMP_OFFLOAD);
210 }
211 #else
212 static void
wlan_pmo_get_igmp_version_support_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)213 wlan_pmo_get_igmp_version_support_cfg(struct wlan_objmgr_psoc *psoc,
214 struct pmo_psoc_cfg *psoc_cfg)
215 {}
216
217 static void
wlan_pmo_get_igmp_offload_enable_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)218 wlan_pmo_get_igmp_offload_enable_cfg(struct wlan_objmgr_psoc *psoc,
219 struct pmo_psoc_cfg *psoc_cfg)
220 {}
221 #endif
222
223 #ifdef WLAN_FEATURE_ICMP_OFFLOAD
224 static void
wlan_pmo_get_icmp_offload_enable_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)225 wlan_pmo_get_icmp_offload_enable_cfg(struct wlan_objmgr_psoc *psoc,
226 struct pmo_psoc_cfg *psoc_cfg)
227 {
228 psoc_cfg->is_icmp_offload_enable =
229 cfg_get(psoc, CFG_ENABLE_ICMP_OFFLOAD);
230 }
231 #else
232 static inline void
wlan_pmo_get_icmp_offload_enable_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)233 wlan_pmo_get_icmp_offload_enable_cfg(struct wlan_objmgr_psoc *psoc,
234 struct pmo_psoc_cfg *psoc_cfg)
235 {}
236 #endif
237
wlan_pmo_init_cfg(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)238 static void wlan_pmo_init_cfg(struct wlan_objmgr_psoc *psoc,
239 struct pmo_psoc_cfg *psoc_cfg)
240 {
241 psoc_cfg->arp_offload_enable =
242 cfg_get(psoc, CFG_PMO_ENABLE_HOST_ARPOFFLOAD);
243 psoc_cfg->hw_filter_mode_bitmap = cfg_get(psoc, CFG_PMO_HW_FILTER_MODE);
244 psoc_cfg->ssdp = cfg_get(psoc, CFG_PMO_ENABLE_HOST_SSDP);
245 psoc_cfg->ns_offload_enable_static =
246 cfg_get(psoc, CFG_PMO_ENABLE_HOST_NSOFFLOAD);
247 psoc_cfg->ns_offload_enable_dynamic =
248 cfg_get(psoc, CFG_PMO_ENABLE_HOST_NSOFFLOAD);
249 psoc_cfg->sta_dynamic_dtim = cfg_get(psoc, CFG_PMO_ENABLE_DYNAMIC_DTIM);
250 wlan_pmo_get_igmp_version_support_cfg(psoc, psoc_cfg);
251 psoc_cfg->sta_mod_dtim = cfg_get(psoc, CFG_PMO_ENABLE_MODULATED_DTIM);
252 psoc_cfg->enable_mc_list = cfg_get(psoc, CFG_PMO_MC_ADDR_LIST_ENABLE);
253 psoc_cfg->power_save_mode = cfg_get(psoc, CFG_PMO_POWERSAVE_MODE);
254 psoc_cfg->sta_forced_dtim = cfg_get(psoc, CFG_PMO_ENABLE_FORCED_DTIM);
255 psoc_cfg->is_mod_dtim_on_sys_suspend_enabled =
256 cfg_get(psoc, CFG_PMO_MOD_DTIM_ON_SYS_SUSPEND);
257 psoc_cfg->is_bus_suspend_enabled_in_sap_mode =
258 cfg_get(psoc, CFG_ENABLE_BUS_SUSPEND_IN_SAP_MODE);
259 psoc_cfg->is_bus_suspend_enabled_in_go_mode =
260 cfg_get(psoc, CFG_ENABLE_BUS_SUSPEND_IN_GO_MODE);
261 if (wlan_ipa_config_is_enabled() &&
262 !ipa_config_is_opt_wifi_dp_enabled()) {
263 pmo_info("ipa is enabled and hence disable sap/go d3 wow");
264 psoc_cfg->is_bus_suspend_enabled_in_sap_mode = 0;
265 psoc_cfg->is_bus_suspend_enabled_in_go_mode = 0;
266 }
267 psoc_cfg->default_power_save_mode = psoc_cfg->power_save_mode;
268 psoc_cfg->max_ps_poll = cfg_get(psoc, CFG_PMO_MAX_PS_POLL);
269
270 psoc_cfg->wow_enable = cfg_get(psoc, CFG_PMO_WOW_ENABLE);
271 psoc_cfg->suspend_mode = cfg_get(psoc, CFG_PMO_SUSPEND_MODE);
272
273 wlan_extwow_init_cfg(psoc, psoc_cfg);
274 psoc_cfg->apf_enable = cfg_get(psoc, CFG_PMO_APF_ENABLE);
275 psoc_cfg->active_mode_offload = cfg_get(psoc, CFG_PMO_ACTIVE_MODE);
276 wlan_pmo_wow_pulse_init_cfg(psoc, psoc_cfg);
277 wlan_pmo_pkt_filter_init_cfg(psoc, psoc_cfg);
278 wlan_pmo_runtime_pm_init_cfg(psoc, psoc_cfg);
279 psoc_cfg->auto_power_save_fail_mode =
280 cfg_get(psoc, CFG_PMO_PWR_FAILURE);
281 psoc_cfg->enable_sap_suspend = cfg_get(psoc, CFG_ENABLE_SAP_SUSPEND);
282 psoc_cfg->wow_data_inactivity_timeout =
283 cfg_get(psoc, CFG_PMO_WOW_DATA_INACTIVITY_TIMEOUT);
284 psoc_cfg->wow_spec_wake_interval =
285 cfg_get(psoc, CFG_PMO_WOW_SPEC_WAKE_INTERVAL);
286 psoc_cfg->active_uc_apf_mode =
287 cfg_get(psoc, CFG_ACTIVE_UC_APF_MODE);
288 psoc_cfg->active_mc_bc_apf_mode =
289 cfg_get(psoc, CFG_ACTIVE_MC_BC_APF_MODE);
290 psoc_cfg->ito_repeat_count = cfg_get(psoc, CFG_ITO_REPEAT_COUNT);
291 wlan_pmo_ra_filtering_init_cfg(psoc, psoc_cfg);
292 wlan_pmo_gpio_wakeup_init_cfg(psoc, psoc_cfg);
293 wlan_pmo_get_igmp_offload_enable_cfg(psoc, psoc_cfg);
294 psoc_cfg->disconnect_sap_tdls_in_wow =
295 cfg_get(psoc, CFG_DISCONNECT_SAP_TDLS_IN_WOW);
296 wlan_pmo_get_icmp_offload_enable_cfg(psoc, psoc_cfg);
297
298 psoc_cfg->host_pf_action = cfg_get(psoc, CFG_HOST_ACTION_ON_PAGEFAULT);
299 psoc_cfg->min_pagefault_wakeups_for_action =
300 cfg_get(psoc,
301 CFG_MIN_PAGEFAULT_WAKEUPS_FOR_ACTION);
302 psoc_cfg->interval_for_pagefault_wakeup_counts =
303 cfg_get(psoc,
304 CFG_INTERVAL_FOR_PAGEFAULT_WAKEUP_COUNT);
305 psoc_cfg->ssr_frequency_on_pagefault =
306 cfg_get(psoc, CFG_SSR_FREQUENCY_ON_PAGEFAULT);
307 }
308
pmo_psoc_open(struct wlan_objmgr_psoc * psoc)309 QDF_STATUS pmo_psoc_open(struct wlan_objmgr_psoc *psoc)
310 {
311 struct pmo_psoc_priv_obj *pmo_psoc_ctx;
312
313 if (!psoc) {
314 pmo_err("null psoc");
315 return QDF_STATUS_E_INVAL;
316 }
317
318 pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
319 wlan_pmo_init_cfg(psoc, &pmo_psoc_ctx->psoc_cfg);
320
321 return QDF_STATUS_SUCCESS;
322 }
323
pmo_psoc_close(struct wlan_objmgr_psoc * psoc)324 QDF_STATUS pmo_psoc_close(struct wlan_objmgr_psoc *psoc)
325 {
326 return QDF_STATUS_SUCCESS;
327 }
328
pmo_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode)329 bool pmo_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode)
330 {
331 switch (vdev_opmode) {
332 case QDF_SAP_MODE:
333 case QDF_P2P_GO_MODE:
334 case QDF_IBSS_MODE:
335 return true;
336 default:
337 return false;
338 }
339 }
340
pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bss_peer_mac_address)341 QDF_STATUS pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev *vdev,
342 struct qdf_mac_addr *bss_peer_mac_address)
343 {
344 struct wlan_objmgr_peer *peer;
345
346 if (!vdev) {
347 pmo_err("vdev is null");
348 return QDF_STATUS_E_INVAL;
349 }
350
351 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_PMO_ID);
352 if (!peer) {
353 pmo_err("peer is null");
354 return QDF_STATUS_E_INVAL;
355 }
356 wlan_peer_obj_lock(peer);
357 qdf_mem_copy(bss_peer_mac_address->bytes, wlan_peer_get_macaddr(peer),
358 QDF_MAC_ADDR_SIZE);
359 wlan_peer_obj_unlock(peer);
360
361 wlan_objmgr_peer_release_ref(peer, WLAN_PMO_ID);
362
363 return QDF_STATUS_SUCCESS;
364 }
365
pmo_core_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE vdev_opmode)366 bool pmo_core_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
367 enum QDF_OPMODE vdev_opmode)
368 {
369 struct pmo_psoc_priv_obj *psoc_ctx;
370
371 psoc_ctx = pmo_psoc_get_priv(psoc);
372
373 if ((vdev_opmode == QDF_SAP_MODE ||
374 vdev_opmode == QDF_P2P_GO_MODE) &&
375 !psoc_ctx->psoc_cfg.ap_arpns_support) {
376 pmo_debug("ARP/NS Offload is not supported in SAP/P2PGO mode");
377 return false;
378 }
379
380 return true;
381 }
382
pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev * vdev)383 bool pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
384 {
385 enum QDF_OPMODE opmode;
386 bool val;
387
388 opmode = pmo_get_vdev_opmode(vdev);
389 pmo_debug("vdev opmode: %d", opmode);
390 switch (opmode) {
391 case QDF_STA_MODE:
392 case QDF_P2P_CLIENT_MODE:
393 case QDF_NDI_MODE:
394 val = true;
395 break;
396 default:
397 val = false;
398 break;
399 }
400
401 return val;
402 }
403
pmo_core_get_psoc_config(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)404 QDF_STATUS pmo_core_get_psoc_config(struct wlan_objmgr_psoc *psoc,
405 struct pmo_psoc_cfg *psoc_cfg)
406 {
407 struct pmo_psoc_priv_obj *psoc_ctx;
408 QDF_STATUS status = QDF_STATUS_SUCCESS;
409
410 pmo_enter();
411 if (!psoc || !psoc_cfg) {
412 pmo_err("%s is null", !psoc ? "psoc":"psoc_cfg");
413 status = QDF_STATUS_E_NULL_VALUE;
414 goto out;
415 }
416
417 pmo_psoc_with_ctx(psoc, psoc_ctx) {
418 qdf_mem_copy(psoc_cfg, &psoc_ctx->psoc_cfg, sizeof(*psoc_cfg));
419 }
420
421 out:
422 pmo_exit();
423
424 return status;
425 }
426
pmo_core_update_psoc_config(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_cfg * psoc_cfg)427 QDF_STATUS pmo_core_update_psoc_config(struct wlan_objmgr_psoc *psoc,
428 struct pmo_psoc_cfg *psoc_cfg)
429 {
430 struct pmo_psoc_priv_obj *psoc_ctx;
431 QDF_STATUS status = QDF_STATUS_SUCCESS;
432
433 pmo_enter();
434 if (!psoc || !psoc_cfg) {
435 pmo_err("%s is null", !psoc ? "psoc":"psoc_cfg");
436 status = QDF_STATUS_E_NULL_VALUE;
437 goto out;
438 }
439
440 pmo_psoc_with_ctx(psoc, psoc_ctx) {
441 qdf_mem_copy(&psoc_ctx->psoc_cfg, psoc_cfg, sizeof(*psoc_cfg));
442 }
443
444 out:
445 pmo_exit();
446
447 return status;
448 }
449
pmo_psoc_set_caps(struct wlan_objmgr_psoc * psoc,struct pmo_device_caps * caps)450 void pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc,
451 struct pmo_device_caps *caps)
452 {
453 struct pmo_psoc_priv_obj *psoc_ctx;
454
455 pmo_psoc_with_ctx(psoc, psoc_ctx) {
456 qdf_mem_copy(&psoc_ctx->caps, caps, sizeof(psoc_ctx->caps));
457 }
458 }
459
pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc * psoc,void * hif_hdl)460 void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
461 void *hif_hdl)
462 {
463 struct pmo_psoc_priv_obj *psoc_ctx;
464
465 pmo_psoc_with_ctx(psoc, psoc_ctx) {
466 psoc_ctx->hif_hdl = hif_hdl;
467 }
468 }
469
pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc * psoc)470 void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc)
471 {
472 void *hif_hdl = NULL;
473 struct pmo_psoc_priv_obj *psoc_ctx;
474
475 pmo_psoc_with_ctx(psoc, psoc_ctx) {
476 hif_hdl = psoc_ctx->hif_hdl;
477 }
478
479 return hif_hdl;
480 }
481
pmo_core_psoc_set_txrx_pdev_id(struct wlan_objmgr_psoc * psoc,uint8_t txrx_pdev_id)482 void pmo_core_psoc_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc,
483 uint8_t txrx_pdev_id)
484 {
485 struct pmo_psoc_priv_obj *psoc_ctx;
486
487 pmo_psoc_with_ctx(psoc, psoc_ctx) {
488 psoc_ctx->txrx_pdev_id = txrx_pdev_id;
489 }
490 }
491
pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc * psoc)492 uint8_t pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc)
493 {
494 uint8_t txrx_pdev_id = OL_TXRX_INVALID_PDEV_ID;
495 struct pmo_psoc_priv_obj *psoc_ctx;
496
497 pmo_psoc_with_ctx(psoc, psoc_ctx) {
498 txrx_pdev_id = psoc_ctx->txrx_pdev_id;
499 }
500
501 return txrx_pdev_id;
502 }
503
504 enum pmo_page_fault_action
pmo_host_action_on_page_fault(struct wlan_objmgr_psoc * psoc)505 pmo_host_action_on_page_fault(struct wlan_objmgr_psoc *psoc)
506 {
507 struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
508
509 if (!pmo_psoc_ctx)
510 return PMO_PF_HOST_ACTION_NO_OP;
511
512 return pmo_psoc_ctx->psoc_cfg.host_pf_action;
513 }
514
pmo_get_min_pagefault_wakeups_for_action(struct wlan_objmgr_psoc * psoc)515 uint8_t pmo_get_min_pagefault_wakeups_for_action(struct wlan_objmgr_psoc *psoc)
516 {
517 struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
518
519 if (!pmo_psoc_ctx)
520 return 0;
521
522 return pmo_psoc_ctx->psoc_cfg.min_pagefault_wakeups_for_action;
523 }
524
525 uint32_t
pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc * psoc)526 pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc)
527 {
528 struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
529
530 if (!pmo_psoc_ctx)
531 return 0;
532
533 return pmo_psoc_ctx->psoc_cfg.interval_for_pagefault_wakeup_counts;
534 }
535
pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc * psoc)536 uint32_t pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc)
537 {
538 struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
539
540 if (!pmo_psoc_ctx)
541 return 0;
542
543 return pmo_psoc_ctx->psoc_cfg.ssr_frequency_on_pagefault;
544 }
545
pmo_get_vdev_bridge_addr(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bridgeaddr)546 QDF_STATUS pmo_get_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
547 struct qdf_mac_addr *bridgeaddr)
548 {
549 struct pmo_vdev_priv_obj *vdev_ctx;
550
551 if (!vdev) {
552 pmo_err("vdev is null");
553 return QDF_STATUS_E_INVAL;
554 }
555
556 vdev_ctx = pmo_vdev_get_priv(vdev);
557 qdf_mem_copy(bridgeaddr->bytes, vdev_ctx->bridgeaddr,
558 QDF_MAC_ADDR_SIZE);
559
560 return QDF_STATUS_SUCCESS;
561 }
562
pmo_set_vdev_bridge_addr(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bridgeaddr)563 QDF_STATUS pmo_set_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
564 struct qdf_mac_addr *bridgeaddr)
565 {
566 struct pmo_vdev_priv_obj *vdev_ctx;
567
568 if (!vdev) {
569 pmo_err("vdev is null");
570 return QDF_STATUS_E_INVAL;
571 }
572
573 vdev_ctx = pmo_vdev_get_priv(vdev);
574 qdf_mem_copy(vdev_ctx->bridgeaddr, bridgeaddr->bytes, QDF_MAC_ADDR_SIZE);
575
576 return QDF_STATUS_SUCCESS;
577 }
578
pmo_core_get_listen_interval(struct wlan_objmgr_vdev * vdev,uint32_t * listen_interval)579 QDF_STATUS pmo_core_get_listen_interval(struct wlan_objmgr_vdev *vdev,
580 uint32_t *listen_interval)
581 {
582 struct pmo_vdev_priv_obj *vdev_ctx;
583
584 if (!vdev || !listen_interval) {
585 pmo_err("vdev NULL or NULL ptr");
586 return QDF_STATUS_E_NULL_VALUE;
587 }
588
589 vdev_ctx = pmo_vdev_get_priv(vdev);
590 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
591 *listen_interval = vdev_ctx->dyn_listen_interval;
592 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
593
594 return QDF_STATUS_SUCCESS;
595 }
596