blob: 47d2eb53a603ff79b222384a9e35b44647aaf09e [file] [log] [blame]
Mukul Sharmad75a6672017-06-22 15:40:53 +05301/*
2 * Copyright (c) 2017 The Linux Foundation. All rights reserved.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18/**
19 * DOC: Declare API's for wow pattern addition and deletion in fwr
20 */
21
22#ifndef _WLAN_PMO_WOW_H_
23#define _WLAN_PMO_WOW_H_
24
25#include "wlan_pmo_main.h"
26#include "wlan_pmo_wow_public_struct.h"
27#include "wlan_pmo_tgt_api.h"
28#include "wlan_pmo_common_public_struct.h"
29#include "wlan_pmo_obj_mgmt_public_struct.h"
30
31/**
32 * DOC: wlan_pmo_wowl
33 *
34 * This module houses all the logic for WOW(wake on wireless) in
35 * PMO(Power Management and Offload).
36 *
37 * It provides the following APIs
38 *
39 * - Ability to enable/disable following WoWL modes
40 * 1) Magic packet (MP) mode
41 * 2) Pattern Byte Matching (PBM) mode
42 * - Ability to add/remove patterns for PBM
43 *
44 * A Magic Packet is a packet that contains 6 0xFFs followed by 16
45 * contiguous copies of the receiving NIC's Ethernet address. There is
46 * no API to configure Magic Packet Pattern.
47 *
48 * Wakeup pattern (used for PBM) is defined as following:
49 * struct
50 * {
51 * U8 PatternSize; // Non-Zero pattern size
52 * U8 PatternMaskSize; // Non-zero pattern mask size
53 * U8 PatternMask[PatternMaskSize]; // Pattern mask
54 * U8 Pattern[PatternSize]; // Pattern
55 * } hdd_wowl_ptrn_t;
56 *
57 * PatternSize and PatternMaskSize indicate size of the variable
58 * length Pattern and PatternMask. PatternMask indicates which bytes
59 * of an incoming packet should be compared with corresponding bytes
60 * in the pattern.
61 *
62 * Maximum allowed pattern size is 128 bytes. Maximum allowed
63 * PatternMaskSize is 16 bytes.
64 *
65 * Maximum number of patterns that can be configured is 8
66 *
67 * PMO will add following 2 commonly used patterns for PBM by default:
68 * 1) ARP Broadcast Pattern
69 * 2) Unicast Pattern
70 *
71 * However note that WoWL will not be enabled by default by PMO. WoWL
72 * needs to enabled explcitly by exercising the iwpriv command.
73 *
74 * PMO will expose an API that accepts patterns as Hex string in the
75 * following format:
76 * "PatternSize:PatternMaskSize:PatternMask:Pattern"
77 *
78 * Multiple patterns can be specified by deleimiting each pattern with
79 * the ';' token:
80 * "PatternSize1:PatternMaskSize1:PatternMask1:Pattern1;PatternSize2:..."
81 *
82 * Patterns can be configured dynamically via iwpriv cmd or statically
83 * via qcom_cfg.ini file
84 *
85 * PBM (when enabled) can perform filtering on unicast data or
86 * broadcast data or both. These configurations are part of factory
87 * default (cfg.dat) and the default behavior is to perform filtering
88 * on both unicast and data frames.
89 *
90 * MP filtering (when enabled) is performed ALWAYS on both unicast and
91 * broadcast data frames.
92 *
93 * Management frames are not subjected to WoWL filtering and are
94 * discarded when WoWL is enabled.
95 *
96 * Whenever a patern match succeeds, RX path is restored and packets
97 * (both management and data) will be pushed to the host from that
98 * point onwards. Therefore, exit from WoWL is implicit and happens
99 * automatically when the first packet match succeeds.
100 *
101 * WoWL works on top of BMPS. So when WoWL is requested, SME will
102 * attempt to put the device in BMPS mode (if not already in BMPS). If
103 * attempt to BMPS fails, request for WoWL will be rejected.
104 */
105
106#define PMO_WOW_MAX_EVENT_BM_LEN 4
107
108/**
109 * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn
110 * @vdev_ctx: pmo vdev priv ctx
111 *
112 * API to get and increment wow default ptrn
113 *
114 * Return: current wow default ptrn count
115 */
116static inline uint8_t pmo_get_and_increment_wow_default_ptrn(
117 struct pmo_vdev_priv_obj *vdev_ctx)
118{
119 uint8_t count;
120
121 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
122 count = vdev_ctx->num_wow_default_patterns++;
123 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
124
125 return count;
126}
127
128/**
129 * pmo_increment_wow_default_ptrn() -increment wow default ptrn
130 * @vdev_ctx: pmo vdev priv ctx
131 *
132 * API to increment wow default ptrn
133 *
134 * Return: None
135 */
136static inline void pmo_increment_wow_default_ptrn(
137 struct pmo_vdev_priv_obj *vdev_ctx)
138{
139 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
140 vdev_ctx->num_wow_default_patterns++;
141 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
142}
143
144/**
145 * pmo_decrement_wow_default_ptrn() -decrement wow default ptrn
146 * @vdev_ctx: pmo vdev priv ctx
147 *
148 * API to decrement wow default ptrn
149 *
150 * Return: None
151 */
152static inline void pmo_decrement_wow_default_ptrn(
153 struct pmo_vdev_priv_obj *vdev_ctx)
154{
155 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
156 vdev_ctx->num_wow_default_patterns--;
157 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
158}
159
160/**
161 * pmo_increment_wow_user_ptrn() -increment wow user ptrn
162 * @vdev_ctx: pmo vdev priv ctx
163 *
164 * API to increment wow user ptrn
165 *
166 * Return: None
167 */
168static inline void pmo_increment_wow_user_ptrn(
169 struct pmo_vdev_priv_obj *vdev_ctx)
170{
171 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
172 vdev_ctx->num_wow_user_patterns++;
173 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
174}
175
176/**
177 * pmo_decrement_wow_user_ptrn() -decrement wow user ptrn
178 * @vdev_ctx: pmo vdev priv ctx
179 *
180 * API to decrement wow user ptrn
181 *
182 * Return: None
183 */
184static inline void pmo_decrement_wow_user_ptrn(
185 struct pmo_vdev_priv_obj *vdev_ctx)
186{
187 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
188 vdev_ctx->num_wow_user_patterns--;
189 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
190}
191
192void pmo_dump_wow_ptrn(struct pmo_wow_add_pattern *ptrn);
193
194/**
195 * pmo_core_add_wow_pattern() - Function which will add the WoWL pattern to be
196 * used when PBM filtering is enabled
197 * @vdev: pointer to the vdev
198 * @ptrn: pointer to the pattern string to be added
199 *
200 * Return: false if any errors encountered, QDF_STATUS_SUCCESS otherwise
201 */
202QDF_STATUS pmo_core_add_wow_pattern(struct wlan_objmgr_vdev *vdev,
203 const char *ptrn);
204
205/**
206 * pmo_core_del_wow_pattern() - Function which will delete the WoWL pattern
207 * @vdev: pointer to the vdev
208 * @ptrn: pointer to the pattern string to be added
209 *
210 * Return: error if any errors encountered, QDF_STATUS_SUCCESS otherwise
211 */
212QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev,
213 const char *ptrn);
214
215/**
216 * pmo_core_wow_enter() - store enable/disable status for pattern
217 * @wma: wma handle
218 * @info: wow parameters
219 *
220 * Records pattern enable/disable status locally. This choice will
221 * take effect when the driver enter into suspend state.
222 *
223 * Return: QDF status
224 */
225QDF_STATUS pmo_core_wow_enter(struct wlan_objmgr_vdev *vdev,
226 struct pmo_wow_enter_params *wow_enter_param);
227
228/**
229 * pmo_core_wow_exit() - clear all wma states
230 * @wma: wma handle
231 * @info: wow params
232 *
233 * Return: QDF status
234 */
235QDF_STATUS pmo_core_wow_exit(struct wlan_objmgr_vdev *vdev);
236
237/**
238 * pmo_core_enable_wakeup_event() - enable wow wakeup events
239 * @psoc: objmgr psoc
240 * @vdev_id: vdev id
241 * @bitmap: Event bitmap
242 *
243 * Return: none
244 */
245void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
246 uint32_t vdev_id, uint32_t *bitmap);
247
248/**
249 * pmo_core_disable_wakeup_event() - disable wow wakeup events
250 * @psoc: objmgr psoc
251 * @vdev_id: vdev id
252 * @bitmap: Event bitmap
253 *
254 * Return: none
255 */
256void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
257 uint32_t vdev_id, uint32_t *bitmap);
258
259/**
260 * pmo_is_wow_applicable(): should enable wow
261 * @psoc: objmgr psoc object
262 *
263 * Enable WOW if any one of the condition meets,
264 * 1) Is any one of vdev in beaconning mode (in AP mode) ?
265 * 2) Is any one of vdev in connected state (in STA mode) ?
266 * 3) Is PNO in progress in any one of vdev ?
267 * 4) Is Extscan in progress in any one of vdev ?
268 * 5) Is P2P listen offload in any one of vdev?
269 * 6) Is any vdev in NAN data mode? BSS is already started at the
270 * the time of device creation. It is ready to accept data
271 * requests.
272 * 7) If LPASS feature is enabled
273 * 8) If NaN feature is enabled
274 * If none of above conditions is true then return false
275 *
276 * Return: true if wma needs to configure wow false otherwise.
277 */
278bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc);
279
280/**
281 * pmo_core_update_wow_enable() - update wow enable flag
282 * @psoc_ctx: Pointer to objmgr psoc handle
283 * @value: true if wow mode enable else false
284 *
285 * Return: None
286 */
287static inline
288void pmo_core_update_wow_enable(struct pmo_psoc_priv_obj *psoc_ctx,
289 bool value)
290{
291 qdf_spin_lock_bh(&psoc_ctx->lock);
292 psoc_ctx->wow.wow_enable = value;
293 qdf_spin_unlock_bh(&psoc_ctx->lock);
294}
295
296/**
297 * pmo_core_is_wow_mode_enabled() - check if wow needs to be enabled in fw
298 * @psoc_ctx: Pointer to objmgr psoc handle
299 *
300 * API to check if wow mode is enabled in fwr as part of apps suspend or not
301 *
302 * Return: true is wow mode is enabled else false
303 */
304static inline
305bool pmo_core_is_wow_enabled(struct pmo_psoc_priv_obj *psoc_ctx)
306{
307 bool value;
308
309 if (!psoc_ctx) {
310 pmo_err("psoc_ctx is null");
311 return false;
312 }
313
314 qdf_spin_lock_bh(&psoc_ctx->lock);
315 value = psoc_ctx->wow.wow_enable;
316 qdf_spin_unlock_bh(&psoc_ctx->lock);
317 pmo_debug("WoW enable %d", value);
318
319 return value;
320}
321
322/**
323 * pmo_core_set_wow_nack() - Set wow nack flag
324 * @psoc_ctx: Pointer to objmgr psoc handle
325 * @value: true if received wow nack from else false
326 *
327 * Return: None
328 */
329static inline
330void pmo_core_set_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx, bool value)
331{
332 qdf_spin_lock_bh(&psoc_ctx->lock);
333 psoc_ctx->wow.wow_nack = value;
334 qdf_spin_unlock_bh(&psoc_ctx->lock);
335}
336
337/**
338 * pmo_core_get_wow_nack() - Get wow nack flag
339 * @psoc_ctx: Pointer to objmgr psoc handle
340 *
341 * Return: wow nack flag
342 */
343static inline
344bool pmo_core_get_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx)
345{
346 bool value;
347
348 qdf_spin_lock_bh(&psoc_ctx->lock);
349 value = psoc_ctx->wow.wow_nack;
350 qdf_spin_unlock_bh(&psoc_ctx->lock);
351
352 return value;
353}
354/**
355 * pmo_core_update_wow_enable_cmd_sent() - update wow enable cmd sent flag
356 * @psoc_ctx: Pointer to objmgr psoc handle
357 * @value: true if wow enable cmd sent else false
358 *
359 * Return: None
360 */
361static inline
362void pmo_core_update_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx,
363 bool value)
364{
365 qdf_spin_lock_bh(&psoc_ctx->lock);
366 psoc_ctx->wow.wow_enable_cmd_sent = value;
367 qdf_spin_unlock_bh(&psoc_ctx->lock);
368}
369
370/**
371 * pmo_core_get_wow_enable_cmd_sent() - Get wow enable cmd sent flag
372 * @psoc_ctx: Pointer to objmgr psoc handle
373 *
374 * Return: return true if wow enable cmd sent else false
375 */
376static inline
377bool pmo_core_get_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx)
378{
379 bool value;
380
381 qdf_spin_lock_bh(&psoc_ctx->lock);
382 value = psoc_ctx->wow.wow_enable_cmd_sent;
383 qdf_spin_unlock_bh(&psoc_ctx->lock);
384
385 return value;
386}
387
388/**
389 * pmo_core_update_wow_initial_wake_up() - update wow initial wake up
390 * @psoc_ctx: Pointer to objmgr psoc handle
391 * @value: true if wow initial wake up is received else false
392 *
393 * Return: None
394 */
395static inline
396void pmo_core_update_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx,
397 bool value)
398{
399 qdf_spin_lock_bh(&psoc_ctx->lock);
400 psoc_ctx->wow.wow_initial_wake_up = value;
401 qdf_spin_unlock_bh(&psoc_ctx->lock);
402}
403
404/**
405 * pmo_core_get_wow_initial_wake_up() - Get wow initial wake up
406 * @psoc_ctx: Pointer to objmgr psoc handle
407 *
408 * Return: true if wow initial wake up is received else false
409 */
410static inline
411bool pmo_core_get_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx)
412{
413 bool value;
414
415 qdf_spin_lock_bh(&psoc_ctx->lock);
416 value = psoc_ctx->wow.wow_initial_wake_up;
417 qdf_spin_unlock_bh(&psoc_ctx->lock);
418
419 return value;
420}
421
422#ifdef FEATURE_WLAN_EXTSCAN
423/**
424 * pmo_core_is_extscan_in_progress(): check if a extscan is in progress
425 * @vdev: objmgr vdev handle
426 *
427 * Return: TRUE/FALSE
428 */
429static inline
430bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
431{
432 bool extscan_in_progress;
433 struct pmo_vdev_priv_obj *vdev_ctx;
434
435 vdev_ctx = pmo_vdev_get_priv(vdev);
436 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
437 extscan_in_progress = vdev_ctx->extscan_in_progress;
438 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
439
440 return extscan_in_progress;
441}
442
443/**
444 * pmo_core_update_extscan_in_progress(): update extscan is in progress flags
445 * @vdev: objmgr vdev handle
446 * @value:true if extscan is in progress else false
447 *
448 * Return: TRUE/FALSE
449 */
450static inline
451void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
452 bool value)
453{
454 struct pmo_vdev_priv_obj *vdev_ctx;
455
456 vdev_ctx = pmo_vdev_get_priv(vdev);
457 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
458 vdev_ctx->extscan_in_progress = value;
459 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
460}
461#else
462static inline
463bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
464{
465 return false;
466}
467
468static inline
469void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
470 bool value)
471{
472}
473#endif
474
475/**
476 * pmo_core_is_p2plo_in_progress(): check if p2plo is in progress
477 * @vdev: objmgr vdev handle
478 *
479 * Return: TRUE/FALSE
480 */
481static inline
482bool pmo_core_is_p2plo_in_progress(struct wlan_objmgr_vdev *vdev)
483{
484 bool p2plo_in_progress;
485 struct pmo_vdev_priv_obj *vdev_ctx;
486
487 vdev_ctx = pmo_vdev_get_priv(vdev);
488 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
489 p2plo_in_progress = vdev_ctx->p2plo_in_progress;
490 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
491
492 return p2plo_in_progress;
493}
494
495/**
496 * pmo_core_update_p2plo_in_progress(): update p2plo is in progress flags
497 * @vdev: objmgr vdev handle
498 * @value:true if p2plo is in progress else false
499 *
500 * Return: TRUE/FALSE
501 */
502static inline
503void pmo_core_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
504 bool value)
505{
506 struct pmo_vdev_priv_obj *vdev_ctx;
507
508 vdev_ctx = pmo_vdev_get_priv(vdev);
509 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
510 vdev_ctx->p2plo_in_progress = value;
511 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
512}
513
514#ifdef WLAN_FEATURE_LPSS
515/**
516 * pmo_is_lpass_enabled() - check if lpass is enabled
517 * @vdev: objmgr vdev handle
518 *
519 * WoW is needed if LPASS or NaN feature is enabled in INI because
520 * target can't wake up itself if its put in PDEV suspend when LPASS
521 * or NaN features are supported
522 *
523 * Return: true if lpass is enabled else false
524 */
525static inline
526bool pmo_core_is_lpass_enabled(struct wlan_objmgr_vdev *vdev)
527{
528 bool lpass_enable;
529 struct pmo_vdev_priv_obj *vdev_ctx;
530
531 vdev_ctx = pmo_vdev_get_priv(vdev);
532 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
533 lpass_enable = vdev_ctx->pmo_psoc_ctx->psoc_cfg.lpass_enable;
534 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
535
536 return lpass_enable;
537}
538#else
539static inline
540bool pmo_core_is_lpass_enabled(struct wlan_objmgr_vdev *vdev)
541{
542 return false;
543}
544#endif
545
546#ifdef WLAN_FEATURE_NAN
547/**
548 * pmo_is_nan_enabled() - check if NaN is enabled
549 * @vdev: objmgr vdev handle
550 *
551 * WoW is needed if LPASS or NaN feature is enabled in INI because
552 * target can't wake up itself if its put in PDEV suspend when LPASS
553 * or NaN features are supported
554 *
555 * Return: true if NaN is enabled else false
556 */
557static inline
558bool pmo_core_is_nan_enabled(struct wlan_objmgr_vdev *vdev)
559{
560 bool nan_enable;
561 struct pmo_vdev_priv_obj *vdev_ctx;
562
563 vdev_ctx = pmo_vdev_get_priv(vdev);
564 qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
565 nan_enable = vdev_ctx->pmo_psoc_ctx->psoc_cfg.nan_enable;
566 qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
567
568 return nan_enable;
569}
570#else
571static inline
572bool pmo_core_is_nan_enabled(struct wlan_objmgr_vdev *vdev)
573{
574 return false;
575}
576#endif
577
578/**
579 * pmo_get_event_bitmap_idx() - get indices for extended wow bitmaps
580 * @event: wow event
581 * @wow_bitmap_size: WOW bitmap size
582 * @bit_idx: bit index
583 * @idx: byte index
584 *
585 * Return: none
586 */
587static inline void pmo_get_event_bitmap_idx(WOW_WAKE_EVENT_TYPE event,
588 uint32_t wow_bitmap_size,
589 uint32_t *bit_idx,
590 uint32_t *idx)
591{
592
593 if (!bit_idx || !idx || wow_bitmap_size == 0) {
594 pmo_err("bit_idx:%p idx:%p wow_bitmap_size:%u",
595 bit_idx, idx, wow_bitmap_size);
596 return;
597 }
598 if (event == 0) {
599 *idx = *bit_idx = 0;
600 } else {
601 *idx = event / (wow_bitmap_size * 8);
602 *bit_idx = event % (wow_bitmap_size * 8);
603 }
604}
605#endif /* end of _WLAN_PMO_WOW_H_ */