1 /*
2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-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 * DOC: Declare API's for wow pattern addition and deletion in fwr
21 */
22
23 #ifndef _WLAN_PMO_WOW_H_
24 #define _WLAN_PMO_WOW_H_
25
26 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
27
28 #include "wlan_pmo_main.h"
29 #include "wlan_pmo_wow_public_struct.h"
30 #include "wlan_pmo_tgt_api.h"
31 #include "wlan_pmo_common_public_struct.h"
32 #include "wlan_pmo_obj_mgmt_public_struct.h"
33
34 /**
35 * DOC: wlan_pmo_wowl
36 *
37 * This module houses all the logic for WOW(wake on wireless) in
38 * PMO(Power Management and Offload).
39 *
40 * It provides the following APIs
41 *
42 * - Ability to enable/disable following WoWL modes
43 * 1) Magic packet (MP) mode
44 * 2) Pattern Byte Matching (PBM) mode
45 * - Ability to add/remove patterns for PBM
46 *
47 * A Magic Packet is a packet that contains 6 0xFFs followed by 16
48 * contiguous copies of the receiving NIC's Ethernet address. There is
49 * no API to configure Magic Packet Pattern.
50 *
51 * Wakeup pattern (used for PBM) is defined as following:
52 * struct
53 * {
54 * U8 PatternSize; // Non-Zero pattern size
55 * U8 PatternMaskSize; // Non-zero pattern mask size
56 * U8 PatternMask[PatternMaskSize]; // Pattern mask
57 * U8 Pattern[PatternSize]; // Pattern
58 * } hdd_wowl_ptrn_t;
59 *
60 * PatternSize and PatternMaskSize indicate size of the variable
61 * length Pattern and PatternMask. PatternMask indicates which bytes
62 * of an incoming packet should be compared with corresponding bytes
63 * in the pattern.
64 *
65 * Maximum allowed pattern size is 128 bytes. Maximum allowed
66 * PatternMaskSize is 16 bytes.
67 *
68 * Maximum number of patterns that can be configured is 8
69 *
70 * PMO will add following 2 commonly used patterns for PBM by default:
71 * 1) ARP Broadcast Pattern
72 * 2) Unicast Pattern
73 *
74 * However note that WoWL will not be enabled by default by PMO. WoWL
75 * needs to enabled explcitly by exercising the iwpriv command.
76 *
77 * PMO will expose an API that accepts patterns as Hex string in the
78 * following format:
79 * "PatternSize:PatternMaskSize:PatternMask:Pattern"
80 *
81 * Multiple patterns can be specified by deleimiting each pattern with
82 * the ';' token:
83 * "PatternSize1:PatternMaskSize1:PatternMask1:Pattern1;PatternSize2:..."
84 *
85 * Patterns can be configured dynamically via iwpriv cmd or statically
86 * via qcom_cfg.ini file
87 *
88 * PBM (when enabled) can perform filtering on unicast data or
89 * broadcast data or both. These configurations are part of factory
90 * default (cfg.dat) and the default behavior is to perform filtering
91 * on both unicast and data frames.
92 *
93 * MP filtering (when enabled) is performed ALWAYS on both unicast and
94 * broadcast data frames.
95 *
96 * Management frames are not subjected to WoWL filtering and are
97 * discarded when WoWL is enabled.
98 *
99 * Whenever a pattern match succeeds, RX path is restored and packets
100 * (both management and data) will be pushed to the host from that
101 * point onwards. Therefore, exit from WoWL is implicit and happens
102 * automatically when the first packet match succeeds.
103 *
104 * WoWL works on top of BMPS. So when WoWL is requested, SME will
105 * attempt to put the device in BMPS mode (if not already in BMPS). If
106 * attempt to BMPS fails, request for WoWL will be rejected.
107 */
108
109 #define PMO_WOW_MAX_EVENT_BM_LEN 4
110
111 #define PMO_WOW_FILTERS_ARP_NS 2
112 #define PMO_WOW_FILTERS_PKT_OR_APF 6
113
114 /**
115 * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn
116 * @vdev_ctx: pmo vdev priv ctx
117 *
118 * API to get and increment wow default ptrn
119 *
120 * Return: current wow default ptrn count
121 */
pmo_get_and_increment_wow_default_ptrn(struct pmo_vdev_priv_obj * vdev_ctx)122 static inline uint8_t pmo_get_and_increment_wow_default_ptrn(
123 struct pmo_vdev_priv_obj *vdev_ctx)
124 {
125 uint8_t count;
126
127 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
128 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
129 count = vdev_ctx->num_wow_default_patterns++;
130 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
131 } else {
132 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
133 count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def++;
134 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
135 }
136
137 return count;
138 }
139
140 /**
141 * pmo_increment_wow_default_ptrn() -increment wow default ptrn
142 * @vdev_ctx: pmo vdev priv ctx
143 *
144 * API to increment wow default ptrn
145 *
146 * Return: None
147 */
pmo_increment_wow_default_ptrn(struct pmo_vdev_priv_obj * vdev_ctx)148 static inline void pmo_increment_wow_default_ptrn(
149 struct pmo_vdev_priv_obj *vdev_ctx)
150 {
151 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
152 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
153 vdev_ctx->num_wow_default_patterns++;
154 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
155 } else {
156 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
157 vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def++;
158 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
159 }
160 }
161
162 /**
163 * pmo_decrement_wow_default_ptrn() -decrement wow default ptrn
164 * @vdev_ctx: pmo vdev priv ctx
165 *
166 * API to decrement wow default ptrn
167 *
168 * Return: None
169 */
pmo_decrement_wow_default_ptrn(struct pmo_vdev_priv_obj * vdev_ctx)170 static inline void pmo_decrement_wow_default_ptrn(
171 struct pmo_vdev_priv_obj *vdev_ctx)
172 {
173 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
174 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
175 vdev_ctx->num_wow_default_patterns--;
176 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
177 } else {
178 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
179 vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def--;
180 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
181 }
182 }
183
184 /**
185 * pmo_get_wow_default_ptrn() -Get wow default ptrn
186 * @vdev_ctx: pmo vdev priv ctx
187 *
188 * API to get wow default ptrn
189 *
190 * Return: current wow default ptrn count
191 */
pmo_get_wow_default_ptrn(struct pmo_vdev_priv_obj * vdev_ctx)192 static inline uint8_t pmo_get_wow_default_ptrn(
193 struct pmo_vdev_priv_obj *vdev_ctx)
194 {
195 uint8_t count;
196
197 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
198 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
199 count = vdev_ctx->num_wow_default_patterns;
200 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
201 } else {
202 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
203 count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def;
204 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
205 }
206
207 return count;
208 }
209
210 /**
211 * pmo_set_wow_default_ptrn() - Set wow default ptrn
212 * @vdev_ctx: pmo vdev priv ctx
213 * @value: WoW default pattern
214 *
215 * API to set wow default ptrn
216 *
217 * Return: Set wow default ptrn count
218 */
pmo_set_wow_default_ptrn(struct pmo_vdev_priv_obj * vdev_ctx,uint8_t value)219 static inline void pmo_set_wow_default_ptrn(
220 struct pmo_vdev_priv_obj *vdev_ctx, uint8_t value)
221 {
222 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
223 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
224 vdev_ctx->num_wow_default_patterns = value;
225 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
226 } else {
227 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
228 vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_def = value;
229 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
230 }
231 }
232
233 /**
234 * pmo_increment_wow_user_ptrn() -increment wow user ptrn
235 * @vdev_ctx: pmo vdev priv ctx
236 *
237 * API to increment wow user ptrn
238 *
239 * Return: None
240 */
pmo_increment_wow_user_ptrn(struct pmo_vdev_priv_obj * vdev_ctx)241 static inline void pmo_increment_wow_user_ptrn(
242 struct pmo_vdev_priv_obj *vdev_ctx)
243 {
244 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
245 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
246 vdev_ctx->num_wow_user_patterns++;
247 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
248 } else {
249 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
250 vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_usr++;
251 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
252 }
253 }
254
255 /**
256 * pmo_decrement_wow_user_ptrn() -decrement wow user ptrn
257 * @vdev_ctx: pmo vdev priv ctx
258 *
259 * API to decrement wow user ptrn
260 *
261 * Return: None
262 */
pmo_decrement_wow_user_ptrn(struct pmo_vdev_priv_obj * vdev_ctx)263 static inline void pmo_decrement_wow_user_ptrn(
264 struct pmo_vdev_priv_obj *vdev_ctx)
265 {
266 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
267 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
268 vdev_ctx->num_wow_user_patterns--;
269 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
270 } else {
271 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
272 vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_usr--;
273 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
274 }
275 }
276
277 /**
278 * pmo_get_wow_user_ptrn() -Get wow user ptrn
279 * @vdev_ctx: pmo vdev priv ctx
280 *
281 * API to Get wow user ptrn
282 *
283 * Return: None
284 */
pmo_get_wow_user_ptrn(struct pmo_vdev_priv_obj * vdev_ctx)285 static inline uint8_t pmo_get_wow_user_ptrn(
286 struct pmo_vdev_priv_obj *vdev_ctx)
287 {
288 uint8_t count;
289
290 if (vdev_ctx->pmo_psoc_ctx->caps.unified_wow) {
291 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
292 count = vdev_ctx->num_wow_user_patterns;
293 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
294 } else {
295 qdf_spin_lock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
296 count = vdev_ctx->pmo_psoc_ctx->wow.ptrn_id_usr;
297 qdf_spin_unlock_bh(&vdev_ctx->pmo_psoc_ctx->lock);
298 }
299
300 return count;
301 }
302
303 /**
304 * pmo_core_del_wow_pattern() - Function which will delete the WoWL pattern
305 * @vdev: pointer to the vdev
306 *
307 * This function deletes all the user WoWl patterns and default WoWl patterns
308 *
309 * Return: error if any errors encountered, QDF_STATUS_SUCCESS otherwise
310 */
311
312 QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev);
313
314 /**
315 * pmo_core_add_wow_user_pattern() - Function which will add the WoWL pattern
316 * to be used when PBM filtering is enabled
317 * @vdev: pointer to the vdev
318 * @ptrn: pointer to the pattern string to be added
319 *
320 * Return: false if any errors encountered, QDF_STATUS_SUCCESS otherwise
321 */
322 QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
323 struct pmo_wow_add_pattern *ptrn);
324
325 /**
326 * pmo_core_del_wow_user_pattern() - Function which will delete the WoWL pattern
327 * @vdev: pointer to the vdev
328 * @pattern_id: pointer to the pattern string to be delete
329 *
330 * Return: error if any errors encountered, QDF_STATUS_SUCCESS otherwise
331 */
332 QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
333 uint8_t pattern_id);
334
335 /**
336 * pmo_core_enable_wakeup_event() - enable wow wakeup events
337 * @psoc: objmgr psoc
338 * @vdev_id: vdev id
339 * @wow_event: wow event to enable
340 *
341 * Return: none
342 */
343 void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
344 uint32_t vdev_id,
345 WOW_WAKE_EVENT_TYPE wow_event);
346
347 /**
348 * pmo_core_disable_wakeup_event() - disable wow wakeup events
349 * @psoc: objmgr psoc
350 * @vdev_id: vdev id
351 * @wow_event: wow event to disable
352 *
353 * Return: none
354 */
355 void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
356 uint32_t vdev_id,
357 WOW_WAKE_EVENT_TYPE wow_event);
358
359 /**
360 * pmo_core_is_wow_applicable(): should enable wow
361 * @psoc: objmgr psoc object
362 *
363 * Enable WOW if any one of the condition meets,
364 * 1) Is any one of vdev in beaconning mode (in AP mode) ?
365 * 2) Is any one of vdev in connected state (in STA mode) ?
366 * 3) Is PNO in progress in any one of vdev ?
367 * 4) Is Extscan in progress in any one of vdev ?
368 * 5) Is P2P listen offload in any one of vdev?
369 * 6) Is any vdev in NAN data mode? BSS is already started at the
370 * the time of device creation. It is ready to accept data
371 * requests.
372 * 7) If LPASS feature is enabled
373 * 8) If NaN feature is enabled
374 * If none of above conditions is true then return false
375 *
376 * Return: true if wma needs to configure wow false otherwise.
377 */
378 bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc);
379
380 /**
381 * pmo_core_update_wow_enable() - update wow enable flag
382 * @psoc_ctx: Pointer to objmgr psoc handle
383 * @value: true if wow mode enable else false
384 *
385 * Return: None
386 */
387 static inline
pmo_core_update_wow_enable(struct pmo_psoc_priv_obj * psoc_ctx,bool value)388 void pmo_core_update_wow_enable(struct pmo_psoc_priv_obj *psoc_ctx,
389 bool value)
390 {
391 qdf_spin_lock_bh(&psoc_ctx->lock);
392 psoc_ctx->wow.wow_enable = value;
393 qdf_spin_unlock_bh(&psoc_ctx->lock);
394 }
395
396 /**
397 * pmo_core_is_wow_enabled() - check if wow needs to be enabled in fw
398 * @psoc_ctx: Pointer to objmgr psoc handle
399 *
400 * API to check if wow mode is enabled in fwr as part of apps suspend or not
401 *
402 * Return: true is wow mode is enabled else false
403 */
404 static inline
pmo_core_is_wow_enabled(struct pmo_psoc_priv_obj * psoc_ctx)405 bool pmo_core_is_wow_enabled(struct pmo_psoc_priv_obj *psoc_ctx)
406 {
407 bool value;
408
409 if (!psoc_ctx) {
410 pmo_err("psoc_ctx is null");
411 return false;
412 }
413
414 qdf_spin_lock_bh(&psoc_ctx->lock);
415 value = psoc_ctx->wow.wow_enable;
416 qdf_spin_unlock_bh(&psoc_ctx->lock);
417 pmo_debug("WoW enable %d", value);
418
419 return value;
420 }
421
422 /**
423 * pmo_core_set_wow_nack() - Set wow nack flag
424 * @psoc_ctx: Pointer to objmgr psoc handle
425 * @value: true if received wow nack from else false
426 * @reason_code: WoW status reason code
427 *
428 * Return: None
429 */
430 static inline
pmo_core_set_wow_nack(struct pmo_psoc_priv_obj * psoc_ctx,bool value,uint16_t reason_code)431 void pmo_core_set_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx, bool value,
432 uint16_t reason_code)
433 {
434 qdf_spin_lock_bh(&psoc_ctx->lock);
435 psoc_ctx->wow.wow_nack = value;
436 psoc_ctx->wow.reason_code = reason_code;
437 qdf_spin_unlock_bh(&psoc_ctx->lock);
438 }
439
440 /**
441 * pmo_core_get_wow_nack() - Get wow nack flag
442 * @psoc_ctx: Pointer to objmgr psoc handle
443 *
444 * Return: wow nack flag
445 */
446 static inline
pmo_core_get_wow_nack(struct pmo_psoc_priv_obj * psoc_ctx)447 bool pmo_core_get_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx)
448 {
449 bool value;
450
451 qdf_spin_lock_bh(&psoc_ctx->lock);
452 value = psoc_ctx->wow.wow_nack;
453 qdf_spin_unlock_bh(&psoc_ctx->lock);
454
455 return value;
456 }
457
458 /**
459 * pmo_core_get_wow_reason_code() - Get wow status reason code
460 * @psoc_ctx: Pointer to objmgr psoc handle
461 *
462 * Return: wow status reason code
463 */
464 static inline
pmo_core_get_wow_reason_code(struct pmo_psoc_priv_obj * psoc_ctx)465 uint16_t pmo_core_get_wow_reason_code(struct pmo_psoc_priv_obj *psoc_ctx)
466 {
467 uint16_t value;
468
469 qdf_spin_lock_bh(&psoc_ctx->lock);
470 value = psoc_ctx->wow.reason_code;
471 qdf_spin_unlock_bh(&psoc_ctx->lock);
472
473 return value;
474 }
475
476 /**
477 * pmo_core_update_wow_enable_cmd_sent() - update wow enable cmd sent flag
478 * @psoc_ctx: Pointer to objmgr psoc handle
479 * @value: true if wow enable cmd sent else false
480 *
481 * Return: None
482 */
483 static inline
pmo_core_update_wow_enable_cmd_sent(struct pmo_psoc_priv_obj * psoc_ctx,bool value)484 void pmo_core_update_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx,
485 bool value)
486 {
487 qdf_spin_lock_bh(&psoc_ctx->lock);
488 psoc_ctx->wow.wow_enable_cmd_sent = value;
489 qdf_spin_unlock_bh(&psoc_ctx->lock);
490 }
491
492 /**
493 * pmo_core_get_wow_enable_cmd_sent() - Get wow enable cmd sent flag
494 * @psoc_ctx: Pointer to objmgr psoc handle
495 *
496 * Return: return true if wow enable cmd sent else false
497 */
498 static inline
pmo_core_get_wow_enable_cmd_sent(struct pmo_psoc_priv_obj * psoc_ctx)499 bool pmo_core_get_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx)
500 {
501 bool value;
502
503 qdf_spin_lock_bh(&psoc_ctx->lock);
504 value = psoc_ctx->wow.wow_enable_cmd_sent;
505 qdf_spin_unlock_bh(&psoc_ctx->lock);
506
507 return value;
508 }
509
510 /**
511 * pmo_core_update_wow_initial_wake_up() - update wow initial wake up
512 * @psoc_ctx: Pointer to objmgr psoc handle
513 * @value: set to 1 if wow initial wake up is received;
514 * if clean state, reset it to 0;
515 *
516 * Return: None
517 */
518 static inline
pmo_core_update_wow_initial_wake_up(struct pmo_psoc_priv_obj * psoc_ctx,int value)519 void pmo_core_update_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx,
520 int value)
521 {
522 qdf_atomic_set(&psoc_ctx->wow.wow_initial_wake_up, value);
523 }
524
525 /**
526 * pmo_core_get_wow_initial_wake_up() - Get wow initial wake up
527 * @psoc_ctx: Pointer to objmgr psoc handle
528 *
529 * Return: 1 if wow initial wake up is received;
530 * 0 if wow iniital wake up is not received;
531 */
532 static inline
pmo_core_get_wow_initial_wake_up(struct pmo_psoc_priv_obj * psoc_ctx)533 int pmo_core_get_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx)
534 {
535 return qdf_atomic_read(&psoc_ctx->wow.wow_initial_wake_up);
536 }
537
538 #ifdef FEATURE_WLAN_EXTSCAN
539 /**
540 * pmo_core_is_extscan_in_progress(): check if a extscan is in progress
541 * @vdev: objmgr vdev handle
542 *
543 * Return: TRUE/FALSE
544 */
545 static inline
pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev * vdev)546 bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
547 {
548 bool extscan_in_progress;
549 struct pmo_vdev_priv_obj *vdev_ctx;
550
551 vdev_ctx = pmo_vdev_get_priv(vdev);
552 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
553 extscan_in_progress = vdev_ctx->extscan_in_progress;
554 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
555
556 return extscan_in_progress;
557 }
558
559 /**
560 * pmo_core_update_extscan_in_progress(): update extscan is in progress flags
561 * @vdev: objmgr vdev handle
562 * @value:true if extscan is in progress else false
563 *
564 * Return: TRUE/FALSE
565 */
566 static inline
pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev * vdev,bool value)567 void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
568 bool value)
569 {
570 struct pmo_vdev_priv_obj *vdev_ctx;
571
572 vdev_ctx = pmo_vdev_get_priv(vdev);
573 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
574 vdev_ctx->extscan_in_progress = value;
575 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
576 }
577 #else
578 static inline
pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev * vdev)579 bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
580 {
581 return false;
582 }
583
584 static inline
pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev * vdev,bool value)585 void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
586 bool value)
587 {
588 }
589 #endif
590
591 /**
592 * pmo_core_is_p2plo_in_progress(): check if p2plo is in progress
593 * @vdev: objmgr vdev handle
594 *
595 * Return: TRUE/FALSE
596 */
597 static inline
pmo_core_is_p2plo_in_progress(struct wlan_objmgr_vdev * vdev)598 bool pmo_core_is_p2plo_in_progress(struct wlan_objmgr_vdev *vdev)
599 {
600 bool p2plo_in_progress;
601 struct pmo_vdev_priv_obj *vdev_ctx;
602
603 vdev_ctx = pmo_vdev_get_priv(vdev);
604 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
605 p2plo_in_progress = vdev_ctx->p2plo_in_progress;
606 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
607
608 return p2plo_in_progress;
609 }
610
611 /**
612 * pmo_core_update_p2plo_in_progress(): update p2plo is in progress flags
613 * @vdev: objmgr vdev handle
614 * @value:true if p2plo is in progress else false
615 *
616 * Return: TRUE/FALSE
617 */
618 static inline
pmo_core_update_p2plo_in_progress(struct wlan_objmgr_vdev * vdev,bool value)619 void pmo_core_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
620 bool value)
621 {
622 struct pmo_vdev_priv_obj *vdev_ctx;
623
624 vdev_ctx = pmo_vdev_get_priv(vdev);
625 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
626 vdev_ctx->p2plo_in_progress = value;
627 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
628 }
629
630 #ifdef WLAN_FEATURE_LPSS
631 /**
632 * pmo_core_is_lpass_enabled() - check if lpass is enabled
633 * @psoc: objmgr psoc object
634 *
635 * WoW is needed if LPASS or NaN feature is enabled in INI because
636 * target can't wake up itself if its put in PDEV suspend when LPASS
637 * or NaN features are supported
638 *
639 * Return: true if lpass is enabled else false
640 */
641 static inline
pmo_core_is_lpass_enabled(struct wlan_objmgr_psoc * psoc)642 bool pmo_core_is_lpass_enabled(struct wlan_objmgr_psoc *psoc)
643 {
644 struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc);
645
646 return pmo_psoc_ctx->psoc_cfg.lpass_enable;
647 }
648 #else
649 static inline
pmo_core_is_lpass_enabled(struct wlan_objmgr_psoc * psoc)650 bool pmo_core_is_lpass_enabled(struct wlan_objmgr_psoc *psoc)
651 {
652 return false;
653 }
654 #endif
655
656 /**
657 * pmo_get_event_bitmap_idx() - get indices for extended wow bitmaps
658 * @event: wow event
659 * @wow_bitmap_size: WOW bitmap size
660 * @bit_idx: bit index
661 * @idx: byte index
662 *
663 * Return: none
664 */
pmo_get_event_bitmap_idx(WOW_WAKE_EVENT_TYPE event,uint32_t wow_bitmap_size,uint32_t * bit_idx,uint32_t * idx)665 static inline void pmo_get_event_bitmap_idx(WOW_WAKE_EVENT_TYPE event,
666 uint32_t wow_bitmap_size,
667 uint32_t *bit_idx,
668 uint32_t *idx)
669 {
670
671 if (!bit_idx || !idx || wow_bitmap_size == 0) {
672 pmo_err("bit_idx:%pK idx:%pK wow_bitmap_size:%u",
673 bit_idx, idx, wow_bitmap_size);
674 return;
675 }
676 if (event == 0) {
677 *idx = *bit_idx = 0;
678 } else {
679 *idx = event / (wow_bitmap_size * 8);
680 *bit_idx = event % (wow_bitmap_size * 8);
681 }
682 }
683
684 /**
685 * pmo_get_num_wow_filters() - get the supported number of WoW filters
686 * @psoc: the psoc to query
687 *
688 * Return: number of WoW filters supported
689 */
690 uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc);
691
692 /**
693 * pmo_core_get_wow_state() - Get wow state
694 * @pmo_ctx: Pointer to pmo priv object
695 *
696 * Return: current WoW status(none/D0/D3)
697 */
698 static inline
pmo_core_get_wow_state(struct pmo_psoc_priv_obj * pmo_ctx)699 enum pmo_wow_state pmo_core_get_wow_state(struct pmo_psoc_priv_obj *pmo_ctx)
700 {
701 return pmo_ctx->wow.wow_state;
702 }
703 #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
704
705 #endif /* end of _WLAN_PMO_WOW_H_ */
706