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