blob: 4b82ba87c5243cd5290df5ec9b7ff82b3c7cfe8e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/*============================================================================
29 * @file wlan_hdd_wowl.c
30 *
31 * Copyright (c) 2009 QUALCOMM Incorporated.
32 * All Rights Reserved.
33 * Qualcomm Confidential and Proprietary
34 *
35 * ==========================================================================*/
36
37/*----------------------------------------------------------------------------
38 * Include Files
39 * -------------------------------------------------------------------------*/
40
41#include <wlan_hdd_includes.h>
42#include <wlan_hdd_wowl.h>
43
44/*----------------------------------------------------------------------------
45 * Preprocessor Definitions and Constants
46 * -------------------------------------------------------------------------*/
47
48#define WOWL_PTRN_MAX_SIZE 128
49#define WOWL_PTRN_MASK_MAX_SIZE 16
Yue Ma0d4891e2013-08-06 17:01:45 -070050#define WOWL_MAX_PTRNS_ALLOWED 16
Jeff Johnson295189b2012-06-20 16:38:30 -070051#define WOWL_INTER_PTRN_TOKENIZER ';'
52#define WOWL_INTRA_PTRN_TOKENIZER ':'
53
54/*----------------------------------------------------------------------------
55 * Type Declarations
56 * -------------------------------------------------------------------------*/
57
Yue Ma0d4891e2013-08-06 17:01:45 -070058static char *g_hdd_wowl_ptrns[WOWL_MAX_PTRNS_ALLOWED]; //Patterns 0-15
59static v_BOOL_t g_hdd_wowl_ptrns_debugfs[WOWL_MAX_PTRNS_ALLOWED] = {0};
60static v_U8_t g_hdd_wowl_ptrns_count = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070061
Srinivas Girigowda100eb322013-03-15 16:48:20 -070062int hdd_parse_hex(unsigned char c)
Jeff Johnson295189b2012-06-20 16:38:30 -070063{
64 if (c >= '0' && c <= '9')
65 return c-'0';
66 if (c >= 'a' && c <= 'f')
67 return c-'a'+10;
68 if (c >= 'A' && c <= 'F')
69 return c-'A'+10;
70
71 return 0;
72}
73
74static inline int find_ptrn_len(const char* ptrn)
75{
76 int len = 0;
77 while (*ptrn != '\0' && *ptrn != WOWL_INTER_PTRN_TOKENIZER)
78 {
79 len++; ptrn++;
80 }
81 return len;
82}
83
84static void hdd_wowl_callback( void *pContext, eHalStatus halStatus )
85{
Kumar Anandaca924e2013-07-22 14:35:34 -070086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080087 "%s: Return code = (%d)", __func__, halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -070088}
89
Kumar Anandaca924e2013-07-22 14:35:34 -070090#ifdef WLAN_WAKEUP_EVENTS
91static void hdd_wowl_wakeIndication_callback( void *pContext,
92 tpSirWakeReasonInd pWakeReasonInd )
93{
94 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Wake Reason %d",
95 __func__, pWakeReasonInd->ulReason );
c_hpothu01484c02014-05-16 14:05:15 +053096 hdd_exit_wowl( (hdd_adapter_t *)pContext, eWOWL_EXIT_WAKEIND );
Kumar Anandaca924e2013-07-22 14:35:34 -070097}
98#endif
99
Jeff Johnson295189b2012-06-20 16:38:30 -0700100static void dump_hdd_wowl_ptrn(tSirWowlAddBcastPtrn *ptrn)
101{
102 int i;
103
104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatetrnId = 0x%x", __func__,
105 ptrn->ucPatternId);
106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternByteOffset = 0x%x", __func__,
107 ptrn->ucPatternByteOffset);
108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternSize = 0x%x", __func__,
109 ptrn->ucPatternSize);
110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternMaskSize = 0x%x", __func__,
111 ptrn->ucPatternMaskSize);
112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Pattern: ", __func__);
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800113 for(i = 0; i < ptrn->ucPatternSize; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", ptrn->ucPattern[i]);
115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: PatternMask: ", __func__);
116 for(i = 0; i<ptrn->ucPatternMaskSize; i++)
117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%02X", ptrn->ucPatternMask[i]);
118}
119
120
121/**============================================================================
122 @brief hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be
123 used when PBM filtering is enabled
124
125 @param ptrn : [in] pointer to the pattern string to be added
126
127 @return : FALSE if any errors encountered
128 : TRUE otherwise
129 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700130v_BOOL_t hdd_add_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn)
Jeff Johnson295189b2012-06-20 16:38:30 -0700131{
132 tSirWowlAddBcastPtrn localPattern;
133 int i, first_empty_slot, len, offset;
134 eHalStatus halStatus;
135 const char *temp;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700136 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
137 v_U8_t sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700138
139 len = find_ptrn_len(ptrn);
140
141 /* There has to have atleast 1 byte for each field (pattern size, mask size,
142 * pattern, mask) e.g. PP:QQ:RR:SS ==> 11 chars */
143 while ( len >= 11 )
144 {
145 first_empty_slot = -1;
146
147 // Find an empty slot to store the pattern
148 for (i=0; i<WOWL_MAX_PTRNS_ALLOWED; i++)
149 {
150 if(g_hdd_wowl_ptrns[i] == NULL) {
151 first_empty_slot = i;
152 break;
153 }
154 }
155
156 // Maximum number of patterns have been configured already
157 if(first_empty_slot == -1)
158 {
159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700160 "%s: Cannot add anymore patterns. No free slot!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700161 return VOS_FALSE;
162 }
163
164 // Detect duplicate pattern
165 for (i=0; i<WOWL_MAX_PTRNS_ALLOWED; i++)
166 {
167 if(g_hdd_wowl_ptrns[i] == NULL) continue;
168
169 if(!memcmp(ptrn, g_hdd_wowl_ptrns[i], len))
170 {
171 // Pattern Already configured, skip to next pattern
172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
173 "Trying to add duplicate WoWL pattern. Skip it!");
174 ptrn += len;
175 goto next_ptrn;
176 }
177 }
178
179 //Validate the pattern
180 if(ptrn[2] != WOWL_INTRA_PTRN_TOKENIZER ||
181 ptrn[5] != WOWL_INTRA_PTRN_TOKENIZER)
182 {
183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800184 "%s: Malformed pattern string. Skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700185 ptrn += len;
186 goto next_ptrn;
187 }
188
189 // Extract the pattern size
190 localPattern.ucPatternSize =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700191 ( hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700192
193 // Extract the pattern mask size
194 localPattern.ucPatternMaskSize =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700195 ( hdd_parse_hex( ptrn[3] ) * 0x10 ) + hdd_parse_hex( ptrn[4] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700196
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800197 if(localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700198 localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE)
199 {
200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800201 "%s: Invalid length specified. Skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700202 ptrn += len;
203 goto next_ptrn;
204 }
205
206 //compute the offset of tokenizer after the pattern
207 offset = 5 + 2*localPattern.ucPatternSize + 1;
208 if(offset >= len || ptrn[offset] != WOWL_INTRA_PTRN_TOKENIZER)
209 {
210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800211 "%s: Malformed pattern string..skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700212 ptrn += len;
213 goto next_ptrn;
214 }
215
216 //compute the end of pattern sring
217 offset = offset + 2*localPattern.ucPatternMaskSize;
218 if(offset+1 != len) //offset begins with 0
219 {
220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800221 "%s: Malformed pattern string...skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 ptrn += len;
223 goto next_ptrn;
224 }
225
226 temp = ptrn;
227
228 // Now advance to where pattern begins
229 ptrn += 6;
230
231 // Extract the pattern
232 for(i=0; i < localPattern.ucPatternSize; i++)
233 {
234 localPattern.ucPattern[i] =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700235 (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 ptrn += 2; //skip to next byte
237 }
238
239 ptrn++; // Skip over the ':' seperator after the pattern
240
241 // Extract the pattern Mask
242 for(i=0; i < localPattern.ucPatternMaskSize; i++)
243 {
244 localPattern.ucPatternMask[i] =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700245 (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700246 ptrn += 2; //skip to next byte
247 }
248
249 //All is good. Store the pattern locally
250 g_hdd_wowl_ptrns[first_empty_slot] = (char*) kmalloc(len+1, GFP_KERNEL);
251 if(g_hdd_wowl_ptrns[first_empty_slot] == NULL)
252 {
253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700254 "%s: kmalloc failure", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 return VOS_FALSE;
256 }
257
258 memcpy(g_hdd_wowl_ptrns[first_empty_slot], temp, len);
259 g_hdd_wowl_ptrns[first_empty_slot][len] = '\0';
260 localPattern.ucPatternId = first_empty_slot;
261 localPattern.ucPatternByteOffset = 0;
262
263 // Register the pattern downstream
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700264 halStatus = sme_WowlAddBcastPattern( hHal, &localPattern, sessionId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 if ( !HAL_STATUS_SUCCESS( halStatus ) )
266 {
267 // Add failed, so invalidate the local storage
268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700269 "sme_WowlAddBcastPattern failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 kfree(g_hdd_wowl_ptrns[first_empty_slot]);
271 g_hdd_wowl_ptrns[first_empty_slot] = NULL;
272 }
273
274 dump_hdd_wowl_ptrn(&localPattern);
275
276 next_ptrn:
277 if (*ptrn == WOWL_INTER_PTRN_TOKENIZER)
278 {
279 ptrn += 1; // move past the tokenizer
280 len = find_ptrn_len(ptrn);
281 continue;
282 }
283 else
284 break;
285 }
286
287 return VOS_TRUE;
288}
289
290/**============================================================================
291 @brief hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern
292
293 @param ptrn : [in] pointer to the pattern string to be removed
294
295 @return : FALSE if any errors encountered
296 : TRUE otherwise
297 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700298v_BOOL_t hdd_del_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn)
Jeff Johnson295189b2012-06-20 16:38:30 -0700299{
300 tSirWowlDelBcastPtrn delPattern;
301 unsigned char id;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700302 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700303 v_BOOL_t patternFound = VOS_FALSE;
304 eHalStatus halStatus;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700305 v_U8_t sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700306
307 // Detect pattern
308 for (id=0; id<WOWL_MAX_PTRNS_ALLOWED && g_hdd_wowl_ptrns[id] != NULL; id++)
309 {
310 if(!strcmp(ptrn, g_hdd_wowl_ptrns[id]))
311 {
312 patternFound = VOS_TRUE;
313 break;
314 }
315 }
316
317 // If pattern present, remove it from downstream
318 if(patternFound)
319 {
320 delPattern.ucPatternId = id;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700321 halStatus = sme_WowlDelBcastPattern( hHal, &delPattern, sessionId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 if ( HAL_STATUS_SUCCESS( halStatus ) )
323 {
324 // Remove from local storage as well
325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
326 "Deleted pattern with id %d [%s]", id, g_hdd_wowl_ptrns[id]);
327
328 kfree(g_hdd_wowl_ptrns[id]);
329 g_hdd_wowl_ptrns[id] = NULL;
330 return VOS_TRUE;
331 }
332 }
333 return VOS_FALSE;
334}
335
336/**============================================================================
Yue Ma0d4891e2013-08-06 17:01:45 -0700337 @brief hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern
Yue Maddad6a72013-11-19 12:40:59 -0800338 sent from debugfs interface
Yue Ma0d4891e2013-08-06 17:01:45 -0700339
340 @param pAdapter : [in] pointer to the adapter
341 pattern_idx : [in] index of the pattern to be added
342 pattern_offset : [in] offset of the pattern in the frame payload
343 pattern_buf : [in] pointer to the pattern hex string to be added
Yue Maddad6a72013-11-19 12:40:59 -0800344 pattern_mask : [in] pointer to the pattern mask hex string
Yue Ma0d4891e2013-08-06 17:01:45 -0700345
346 @return : FALSE if any errors encountered
347 : TRUE otherwise
348 ===========================================================================*/
349v_BOOL_t hdd_add_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx,
Yue Maddad6a72013-11-19 12:40:59 -0800350 v_U8_t pattern_offset, char *pattern_buf,
351 char *pattern_mask)
Yue Ma0d4891e2013-08-06 17:01:45 -0700352{
353 tSirWowlAddBcastPtrn localPattern;
354 eHalStatus halStatus;
355 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
356 v_U8_t sessionId = pAdapter->sessionId;
Yue Maddad6a72013-11-19 12:40:59 -0800357 v_U16_t pattern_len, mask_len, i;
Yue Ma0d4891e2013-08-06 17:01:45 -0700358
359 if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1))
360 {
361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
362 "%s: WoW pattern index %d is out of range (0 ~ %d).",
363 __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
364
365 return VOS_FALSE;
366 }
367
368 pattern_len = strlen(pattern_buf);
369
370 /* Since the pattern is a hex string, 2 characters represent 1 byte. */
371 if (pattern_len % 2)
372 {
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
374 "%s: Malformed WoW pattern!", __func__);
375
376 return VOS_FALSE;
377 }
378 else
379 pattern_len >>= 1;
380
381 if (!pattern_len || pattern_len > WOWL_PTRN_MAX_SIZE)
382 {
383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
384 "%s: WoW pattern length %d is out of range (1 ~ %d).",
385 __func__, pattern_len, WOWL_PTRN_MAX_SIZE);
386
387 return VOS_FALSE;
388 }
389
390 localPattern.ucPatternId = pattern_idx;
391 localPattern.ucPatternByteOffset = pattern_offset;
392 localPattern.ucPatternSize = pattern_len;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800393 if (localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE) {
394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
395 "%s: WoW pattern size (%d) greater than max (%d)",
396 __func__, localPattern.ucPatternSize,
397 SIR_WOWL_BCAST_PATTERN_MAX_SIZE);
398 return VOS_FALSE;
399 }
Yue Ma0d4891e2013-08-06 17:01:45 -0700400 /* Extract the pattern */
401 for (i = 0; i < localPattern.ucPatternSize; i++)
402 {
403 localPattern.ucPattern[i] =
404 (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]);
405
406 /* Skip to next byte */
407 pattern_buf += 2;
408 }
409
Yue Maddad6a72013-11-19 12:40:59 -0800410 /* Get pattern mask size by pattern length */
411 localPattern.ucPatternMaskSize = pattern_len >> 3;
Yue Ma0d4891e2013-08-06 17:01:45 -0700412 if (pattern_len % 8)
Yue Ma0d4891e2013-08-06 17:01:45 -0700413 localPattern.ucPatternMaskSize += 1;
Yue Maddad6a72013-11-19 12:40:59 -0800414
415 mask_len = strlen(pattern_mask);
416 if ((mask_len % 2) || (localPattern.ucPatternMaskSize != (mask_len >> 1)))
417 {
418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
419 "%s: Malformed WoW pattern mask!", __func__);
420
421 return VOS_FALSE;
422 }
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800423 if (localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE) {
424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
425 "%s: WoW pattern mask size (%d) greater than max (%d)",
426 __func__, localPattern.ucPatternMaskSize, WOWL_PTRN_MASK_MAX_SIZE);
427 return VOS_FALSE;
428 }
Yue Maddad6a72013-11-19 12:40:59 -0800429 /* Extract the pattern mask */
430 for (i = 0; i < localPattern.ucPatternMaskSize; i++)
431 {
432 localPattern.ucPatternMask[i] =
433 (hdd_parse_hex(pattern_mask[0]) << 4) + hdd_parse_hex(pattern_mask[1]);
434
435 /* Skip to next byte */
436 pattern_mask += 2;
Yue Ma0d4891e2013-08-06 17:01:45 -0700437 }
438
439 /* Register the pattern downstream */
440 halStatus = sme_WowlAddBcastPattern(hHal, &localPattern, sessionId);
441
442 if (!HAL_STATUS_SUCCESS(halStatus))
443 {
444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700445 "%s: sme_WowlAddBcastPattern failed with error code (%d).",
Yue Ma0d4891e2013-08-06 17:01:45 -0700446 __func__, halStatus);
447
448 return VOS_FALSE;
449 }
450
Yue Ma0d4891e2013-08-06 17:01:45 -0700451 /* All is good. */
452 if (!g_hdd_wowl_ptrns_debugfs[pattern_idx])
453 {
454 g_hdd_wowl_ptrns_debugfs[pattern_idx] = 1;
455 g_hdd_wowl_ptrns_count++;
456 }
457
458 dump_hdd_wowl_ptrn(&localPattern);
459
460 return VOS_TRUE;
461}
462
463/**============================================================================
464 @brief hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern
Yue Maddad6a72013-11-19 12:40:59 -0800465 sent from debugfs interface
Yue Ma0d4891e2013-08-06 17:01:45 -0700466
467 @param pAdapter : [in] pointer to the adapter
468 pattern_idx : [in] index of the pattern to be removed
469
470 @return : FALSE if any errors encountered
471 : TRUE otherwise
472 ===========================================================================*/
473v_BOOL_t hdd_del_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx)
474{
475 tSirWowlDelBcastPtrn delPattern;
476 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
477 eHalStatus halStatus;
478 v_U8_t sessionId = pAdapter->sessionId;
479
480 if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1))
481 {
482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
483 "%s: WoW pattern index %d is not in the range (0 ~ %d).",
484 __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
485
486 return VOS_FALSE;
487 }
488
489 if (!g_hdd_wowl_ptrns_debugfs[pattern_idx])
490 {
491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
492 "%s: WoW pattern %d is not in the table.",
493 __func__, pattern_idx);
494
495 return VOS_FALSE;
496 }
497
498 delPattern.ucPatternId = pattern_idx;
499 halStatus = sme_WowlDelBcastPattern(hHal, &delPattern, sessionId);
500
501 if (!HAL_STATUS_SUCCESS(halStatus))
502 {
503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700504 "%s: sme_WowlDelBcastPattern failed with error code (%d).",
Yue Ma0d4891e2013-08-06 17:01:45 -0700505 __func__, halStatus);
506
507 return VOS_FALSE;
508 }
509
510 g_hdd_wowl_ptrns_debugfs[pattern_idx] = 0;
511 g_hdd_wowl_ptrns_count--;
512
Yue Ma0d4891e2013-08-06 17:01:45 -0700513 return VOS_TRUE;
514}
515
516/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -0700517 @brief hdd_enter_wowl() - Function which will enable WoWL. Atleast one
518 of MP and PBM must be enabled
519
520 @param enable_mp : [in] Whether to enable magic packet WoWL mode
521 @param enable_pbm : [in] Whether to enable pattern byte matching WoWL mode
522
523 @return : FALSE if any errors encountered
524 : TRUE otherwise
525 ===========================================================================*/
Kumar Anand42277932014-03-29 21:09:21 -0700526v_BOOL_t hdd_enter_wowl (hdd_adapter_t *pAdapter, v_BOOL_t enable_mp, v_BOOL_t enable_pbm)
Jeff Johnson295189b2012-06-20 16:38:30 -0700527{
528 tSirSmeWowlEnterParams wowParams;
529 eHalStatus halStatus;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700530 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700531
Kumar Anand42277932014-03-29 21:09:21 -0700532 vos_mem_zero( &wowParams, sizeof( tSirSmeWowlEnterParams ) );
533
Jeff Johnson295189b2012-06-20 16:38:30 -0700534 wowParams.ucPatternFilteringEnable = enable_pbm;
535 wowParams.ucMagicPktEnable = enable_mp;
536 if(enable_mp)
537 {
538 vos_copy_macaddr( (v_MACADDR_t *)&(wowParams.magicPtrn),
539 &(pAdapter->macAddressCurrent) );
540 }
541
Kumar Anand42277932014-03-29 21:09:21 -0700542#ifdef WLAN_WAKEUP_EVENTS
543 wowParams.ucWoWEAPIDRequestEnable = VOS_TRUE;
544 wowParams.ucWoWEAPOL4WayEnable = VOS_TRUE;
545 wowParams.ucWowNetScanOffloadMatch = VOS_TRUE;
546 wowParams.ucWowGTKRekeyError = VOS_TRUE;
547 wowParams.ucWoWBSSConnLoss = VOS_TRUE;
548#endif // WLAN_WAKEUP_EVENTS
549
Jeff Johnson295189b2012-06-20 16:38:30 -0700550 // Request to put Libra into WoWL
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700551 halStatus = sme_EnterWowl( hHal, hdd_wowl_callback,
Kumar Anandaca924e2013-07-22 14:35:34 -0700552 pAdapter,
553#ifdef WLAN_WAKEUP_EVENTS
554 hdd_wowl_wakeIndication_callback,
555 pAdapter,
556#endif // WLAN_WAKEUP_EVENTS
557 &wowParams, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
559 if ( !HAL_STATUS_SUCCESS( halStatus ) )
560 {
561 if ( eHAL_STATUS_PMC_PENDING != halStatus )
562 {
563 // We failed to enter WoWL
564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700565 "sme_EnterWowl failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700566 return VOS_FALSE;
567 }
568 }
569 return VOS_TRUE;
570}
571
572/**============================================================================
573 @brief hdd_exit_wowl() - Function which will disable WoWL
574
c_hpothu01484c02014-05-16 14:05:15 +0530575 @param wowlExitSrc: To know is wowl exiting because of wakeup pkt or user
576 explicitly disabling WoWL
Jeff Johnson295189b2012-06-20 16:38:30 -0700577 @return : FALSE if any errors encountered
578 : TRUE otherwise
579 ===========================================================================*/
c_hpothu01484c02014-05-16 14:05:15 +0530580v_BOOL_t hdd_exit_wowl (hdd_adapter_t*pAdapter, tWowlExitSource wowlExitSrc)
Jeff Johnson295189b2012-06-20 16:38:30 -0700581{
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700582 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700583 eHalStatus halStatus;
584
c_hpothu01484c02014-05-16 14:05:15 +0530585 halStatus = sme_ExitWowl( hHal, wowlExitSrc );
Jeff Johnson295189b2012-06-20 16:38:30 -0700586 if ( !HAL_STATUS_SUCCESS( halStatus ) )
587 {
588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700589 "sme_ExitWowl failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700590 return VOS_FALSE;
591 }
592
593 return VOS_TRUE;
594}
595
596/**============================================================================
597 @brief hdd_init_wowl() - Init function which will initialize the WoWL module
598 and perform any required intial configuration
599
600 @return : FALSE if any errors encountered
601 : TRUE otherwise
602 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700603v_BOOL_t hdd_init_wowl (hdd_adapter_t*pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700604{
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700605 hdd_context_t *pHddCtx = NULL;
606 pHddCtx = pAdapter->pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700607
608 memset(g_hdd_wowl_ptrns, 0, sizeof(g_hdd_wowl_ptrns));
609
610 //Add any statically configured patterns
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700611 hdd_add_wowl_ptrn(pAdapter, pHddCtx->cfg_ini->wowlPattern);
Jeff Johnson295189b2012-06-20 16:38:30 -0700612
613 return VOS_TRUE;
614}