blob: ad3f5fa1a9bf170560756e635e0eb0da3ba530e8 [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 *
Jeff Johnson295189b2012-06-20 16:38:30 -070031 *
32 * ==========================================================================*/
33
34/*----------------------------------------------------------------------------
35 * Include Files
36 * -------------------------------------------------------------------------*/
37
38#include <wlan_hdd_includes.h>
39#include <wlan_hdd_wowl.h>
40
41/*----------------------------------------------------------------------------
42 * Preprocessor Definitions and Constants
43 * -------------------------------------------------------------------------*/
44
45#define WOWL_PTRN_MAX_SIZE 128
46#define WOWL_PTRN_MASK_MAX_SIZE 16
Yue Ma0d4891e2013-08-06 17:01:45 -070047#define WOWL_MAX_PTRNS_ALLOWED 16
Jeff Johnson295189b2012-06-20 16:38:30 -070048#define WOWL_INTER_PTRN_TOKENIZER ';'
49#define WOWL_INTRA_PTRN_TOKENIZER ':'
50
51/*----------------------------------------------------------------------------
52 * Type Declarations
53 * -------------------------------------------------------------------------*/
54
Yue Ma0d4891e2013-08-06 17:01:45 -070055static char *g_hdd_wowl_ptrns[WOWL_MAX_PTRNS_ALLOWED]; //Patterns 0-15
56static v_BOOL_t g_hdd_wowl_ptrns_debugfs[WOWL_MAX_PTRNS_ALLOWED] = {0};
57static v_U8_t g_hdd_wowl_ptrns_count = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070058
Srinivas Girigowda100eb322013-03-15 16:48:20 -070059int hdd_parse_hex(unsigned char c)
Jeff Johnson295189b2012-06-20 16:38:30 -070060{
61 if (c >= '0' && c <= '9')
62 return c-'0';
63 if (c >= 'a' && c <= 'f')
64 return c-'a'+10;
65 if (c >= 'A' && c <= 'F')
66 return c-'A'+10;
67
68 return 0;
69}
70
71static inline int find_ptrn_len(const char* ptrn)
72{
73 int len = 0;
74 while (*ptrn != '\0' && *ptrn != WOWL_INTER_PTRN_TOKENIZER)
75 {
76 len++; ptrn++;
77 }
78 return len;
79}
80
81static void hdd_wowl_callback( void *pContext, eHalStatus halStatus )
82{
Kumar Anandaca924e2013-07-22 14:35:34 -070083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080084 "%s: Return code = (%d)", __func__, halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -070085}
86
Kumar Anandaca924e2013-07-22 14:35:34 -070087#ifdef WLAN_WAKEUP_EVENTS
88static void hdd_wowl_wakeIndication_callback( void *pContext,
89 tpSirWakeReasonInd pWakeReasonInd )
90{
91 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Wake Reason %d",
92 __func__, pWakeReasonInd->ulReason );
c_hpothu01484c02014-05-16 14:05:15 +053093 hdd_exit_wowl( (hdd_adapter_t *)pContext, eWOWL_EXIT_WAKEIND );
Kumar Anandaca924e2013-07-22 14:35:34 -070094}
95#endif
96
Jeff Johnson295189b2012-06-20 16:38:30 -070097static void dump_hdd_wowl_ptrn(tSirWowlAddBcastPtrn *ptrn)
98{
99 int i;
100
101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatetrnId = 0x%x", __func__,
102 ptrn->ucPatternId);
103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternByteOffset = 0x%x", __func__,
104 ptrn->ucPatternByteOffset);
105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternSize = 0x%x", __func__,
106 ptrn->ucPatternSize);
107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternMaskSize = 0x%x", __func__,
108 ptrn->ucPatternMaskSize);
109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Pattern: ", __func__);
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800110 for(i = 0; i < ptrn->ucPatternSize; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", ptrn->ucPattern[i]);
112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: PatternMask: ", __func__);
113 for(i = 0; i<ptrn->ucPatternMaskSize; i++)
114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%02X", ptrn->ucPatternMask[i]);
115}
116
117
118/**============================================================================
119 @brief hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be
120 used when PBM filtering is enabled
121
122 @param ptrn : [in] pointer to the pattern string to be added
123
124 @return : FALSE if any errors encountered
125 : TRUE otherwise
126 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700127v_BOOL_t hdd_add_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn)
Jeff Johnson295189b2012-06-20 16:38:30 -0700128{
129 tSirWowlAddBcastPtrn localPattern;
130 int i, first_empty_slot, len, offset;
131 eHalStatus halStatus;
132 const char *temp;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700133 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
134 v_U8_t sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700135
136 len = find_ptrn_len(ptrn);
137
138 /* There has to have atleast 1 byte for each field (pattern size, mask size,
139 * pattern, mask) e.g. PP:QQ:RR:SS ==> 11 chars */
140 while ( len >= 11 )
141 {
142 first_empty_slot = -1;
143
144 // Find an empty slot to store the pattern
145 for (i=0; i<WOWL_MAX_PTRNS_ALLOWED; i++)
146 {
147 if(g_hdd_wowl_ptrns[i] == NULL) {
148 first_empty_slot = i;
149 break;
150 }
151 }
152
153 // Maximum number of patterns have been configured already
154 if(first_empty_slot == -1)
155 {
156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700157 "%s: Cannot add anymore patterns. No free slot!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700158 return VOS_FALSE;
159 }
160
161 // Detect duplicate pattern
162 for (i=0; i<WOWL_MAX_PTRNS_ALLOWED; i++)
163 {
164 if(g_hdd_wowl_ptrns[i] == NULL) continue;
165
166 if(!memcmp(ptrn, g_hdd_wowl_ptrns[i], len))
167 {
168 // Pattern Already configured, skip to next pattern
169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
170 "Trying to add duplicate WoWL pattern. Skip it!");
171 ptrn += len;
172 goto next_ptrn;
173 }
174 }
175
176 //Validate the pattern
177 if(ptrn[2] != WOWL_INTRA_PTRN_TOKENIZER ||
178 ptrn[5] != WOWL_INTRA_PTRN_TOKENIZER)
179 {
180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800181 "%s: Malformed pattern string. Skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700182 ptrn += len;
183 goto next_ptrn;
184 }
185
186 // Extract the pattern size
187 localPattern.ucPatternSize =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700188 ( hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700189
190 // Extract the pattern mask size
191 localPattern.ucPatternMaskSize =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700192 ( hdd_parse_hex( ptrn[3] ) * 0x10 ) + hdd_parse_hex( ptrn[4] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700193
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800194 if(localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE)
196 {
197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800198 "%s: Invalid length specified. Skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700199 ptrn += len;
200 goto next_ptrn;
201 }
202
203 //compute the offset of tokenizer after the pattern
204 offset = 5 + 2*localPattern.ucPatternSize + 1;
205 if(offset >= len || ptrn[offset] != WOWL_INTRA_PTRN_TOKENIZER)
206 {
207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800208 "%s: Malformed pattern string..skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 ptrn += len;
210 goto next_ptrn;
211 }
212
213 //compute the end of pattern sring
214 offset = offset + 2*localPattern.ucPatternMaskSize;
215 if(offset+1 != len) //offset begins with 0
216 {
217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800218 "%s: Malformed pattern string...skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 ptrn += len;
220 goto next_ptrn;
221 }
222
223 temp = ptrn;
224
225 // Now advance to where pattern begins
226 ptrn += 6;
227
228 // Extract the pattern
229 for(i=0; i < localPattern.ucPatternSize; i++)
230 {
231 localPattern.ucPattern[i] =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700232 (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 ptrn += 2; //skip to next byte
234 }
235
236 ptrn++; // Skip over the ':' seperator after the pattern
237
238 // Extract the pattern Mask
239 for(i=0; i < localPattern.ucPatternMaskSize; i++)
240 {
241 localPattern.ucPatternMask[i] =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700242 (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700243 ptrn += 2; //skip to next byte
244 }
245
246 //All is good. Store the pattern locally
247 g_hdd_wowl_ptrns[first_empty_slot] = (char*) kmalloc(len+1, GFP_KERNEL);
248 if(g_hdd_wowl_ptrns[first_empty_slot] == NULL)
249 {
250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700251 "%s: kmalloc failure", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700252 return VOS_FALSE;
253 }
254
255 memcpy(g_hdd_wowl_ptrns[first_empty_slot], temp, len);
256 g_hdd_wowl_ptrns[first_empty_slot][len] = '\0';
257 localPattern.ucPatternId = first_empty_slot;
258 localPattern.ucPatternByteOffset = 0;
259
260 // Register the pattern downstream
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700261 halStatus = sme_WowlAddBcastPattern( hHal, &localPattern, sessionId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 if ( !HAL_STATUS_SUCCESS( halStatus ) )
263 {
264 // Add failed, so invalidate the local storage
265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700266 "sme_WowlAddBcastPattern failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 kfree(g_hdd_wowl_ptrns[first_empty_slot]);
268 g_hdd_wowl_ptrns[first_empty_slot] = NULL;
269 }
270
271 dump_hdd_wowl_ptrn(&localPattern);
272
273 next_ptrn:
274 if (*ptrn == WOWL_INTER_PTRN_TOKENIZER)
275 {
276 ptrn += 1; // move past the tokenizer
277 len = find_ptrn_len(ptrn);
278 continue;
279 }
280 else
281 break;
282 }
283
284 return VOS_TRUE;
285}
286
287/**============================================================================
288 @brief hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern
289
290 @param ptrn : [in] pointer to the pattern string to be removed
291
292 @return : FALSE if any errors encountered
293 : TRUE otherwise
294 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700295v_BOOL_t hdd_del_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn)
Jeff Johnson295189b2012-06-20 16:38:30 -0700296{
297 tSirWowlDelBcastPtrn delPattern;
298 unsigned char id;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700299 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700300 v_BOOL_t patternFound = VOS_FALSE;
301 eHalStatus halStatus;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700302 v_U8_t sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700303
304 // Detect pattern
305 for (id=0; id<WOWL_MAX_PTRNS_ALLOWED && g_hdd_wowl_ptrns[id] != NULL; id++)
306 {
307 if(!strcmp(ptrn, g_hdd_wowl_ptrns[id]))
308 {
309 patternFound = VOS_TRUE;
310 break;
311 }
312 }
313
314 // If pattern present, remove it from downstream
315 if(patternFound)
316 {
317 delPattern.ucPatternId = id;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700318 halStatus = sme_WowlDelBcastPattern( hHal, &delPattern, sessionId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 if ( HAL_STATUS_SUCCESS( halStatus ) )
320 {
321 // Remove from local storage as well
322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
323 "Deleted pattern with id %d [%s]", id, g_hdd_wowl_ptrns[id]);
324
325 kfree(g_hdd_wowl_ptrns[id]);
326 g_hdd_wowl_ptrns[id] = NULL;
327 return VOS_TRUE;
328 }
329 }
330 return VOS_FALSE;
331}
332
333/**============================================================================
Yue Ma0d4891e2013-08-06 17:01:45 -0700334 @brief hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern
Yue Maddad6a72013-11-19 12:40:59 -0800335 sent from debugfs interface
Yue Ma0d4891e2013-08-06 17:01:45 -0700336
337 @param pAdapter : [in] pointer to the adapter
338 pattern_idx : [in] index of the pattern to be added
339 pattern_offset : [in] offset of the pattern in the frame payload
340 pattern_buf : [in] pointer to the pattern hex string to be added
Yue Maddad6a72013-11-19 12:40:59 -0800341 pattern_mask : [in] pointer to the pattern mask hex string
Yue Ma0d4891e2013-08-06 17:01:45 -0700342
343 @return : FALSE if any errors encountered
344 : TRUE otherwise
345 ===========================================================================*/
346v_BOOL_t hdd_add_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx,
Yue Maddad6a72013-11-19 12:40:59 -0800347 v_U8_t pattern_offset, char *pattern_buf,
348 char *pattern_mask)
Yue Ma0d4891e2013-08-06 17:01:45 -0700349{
350 tSirWowlAddBcastPtrn localPattern;
351 eHalStatus halStatus;
352 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
353 v_U8_t sessionId = pAdapter->sessionId;
Yue Maddad6a72013-11-19 12:40:59 -0800354 v_U16_t pattern_len, mask_len, i;
Yue Ma0d4891e2013-08-06 17:01:45 -0700355
356 if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1))
357 {
358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
359 "%s: WoW pattern index %d is out of range (0 ~ %d).",
360 __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
361
362 return VOS_FALSE;
363 }
364
365 pattern_len = strlen(pattern_buf);
366
367 /* Since the pattern is a hex string, 2 characters represent 1 byte. */
368 if (pattern_len % 2)
369 {
370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
371 "%s: Malformed WoW pattern!", __func__);
372
373 return VOS_FALSE;
374 }
375 else
376 pattern_len >>= 1;
377
378 if (!pattern_len || pattern_len > WOWL_PTRN_MAX_SIZE)
379 {
380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
381 "%s: WoW pattern length %d is out of range (1 ~ %d).",
382 __func__, pattern_len, WOWL_PTRN_MAX_SIZE);
383
384 return VOS_FALSE;
385 }
386
387 localPattern.ucPatternId = pattern_idx;
388 localPattern.ucPatternByteOffset = pattern_offset;
389 localPattern.ucPatternSize = pattern_len;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800390 if (localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE) {
391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
392 "%s: WoW pattern size (%d) greater than max (%d)",
393 __func__, localPattern.ucPatternSize,
394 SIR_WOWL_BCAST_PATTERN_MAX_SIZE);
395 return VOS_FALSE;
396 }
Yue Ma0d4891e2013-08-06 17:01:45 -0700397 /* Extract the pattern */
398 for (i = 0; i < localPattern.ucPatternSize; i++)
399 {
400 localPattern.ucPattern[i] =
401 (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]);
402
403 /* Skip to next byte */
404 pattern_buf += 2;
405 }
406
Yue Maddad6a72013-11-19 12:40:59 -0800407 /* Get pattern mask size by pattern length */
408 localPattern.ucPatternMaskSize = pattern_len >> 3;
Yue Ma0d4891e2013-08-06 17:01:45 -0700409 if (pattern_len % 8)
Yue Ma0d4891e2013-08-06 17:01:45 -0700410 localPattern.ucPatternMaskSize += 1;
Yue Maddad6a72013-11-19 12:40:59 -0800411
412 mask_len = strlen(pattern_mask);
413 if ((mask_len % 2) || (localPattern.ucPatternMaskSize != (mask_len >> 1)))
414 {
415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
416 "%s: Malformed WoW pattern mask!", __func__);
417
418 return VOS_FALSE;
419 }
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800420 if (localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE) {
421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
422 "%s: WoW pattern mask size (%d) greater than max (%d)",
423 __func__, localPattern.ucPatternMaskSize, WOWL_PTRN_MASK_MAX_SIZE);
424 return VOS_FALSE;
425 }
Yue Maddad6a72013-11-19 12:40:59 -0800426 /* Extract the pattern mask */
427 for (i = 0; i < localPattern.ucPatternMaskSize; i++)
428 {
429 localPattern.ucPatternMask[i] =
430 (hdd_parse_hex(pattern_mask[0]) << 4) + hdd_parse_hex(pattern_mask[1]);
431
432 /* Skip to next byte */
433 pattern_mask += 2;
Yue Ma0d4891e2013-08-06 17:01:45 -0700434 }
435
436 /* Register the pattern downstream */
437 halStatus = sme_WowlAddBcastPattern(hHal, &localPattern, sessionId);
438
439 if (!HAL_STATUS_SUCCESS(halStatus))
440 {
441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700442 "%s: sme_WowlAddBcastPattern failed with error code (%d).",
Yue Ma0d4891e2013-08-06 17:01:45 -0700443 __func__, halStatus);
444
445 return VOS_FALSE;
446 }
447
Yue Ma0d4891e2013-08-06 17:01:45 -0700448 /* All is good. */
449 if (!g_hdd_wowl_ptrns_debugfs[pattern_idx])
450 {
451 g_hdd_wowl_ptrns_debugfs[pattern_idx] = 1;
452 g_hdd_wowl_ptrns_count++;
453 }
454
455 dump_hdd_wowl_ptrn(&localPattern);
456
457 return VOS_TRUE;
458}
459
460/**============================================================================
461 @brief hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern
Yue Maddad6a72013-11-19 12:40:59 -0800462 sent from debugfs interface
Yue Ma0d4891e2013-08-06 17:01:45 -0700463
464 @param pAdapter : [in] pointer to the adapter
465 pattern_idx : [in] index of the pattern to be removed
466
467 @return : FALSE if any errors encountered
468 : TRUE otherwise
469 ===========================================================================*/
470v_BOOL_t hdd_del_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx)
471{
472 tSirWowlDelBcastPtrn delPattern;
473 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
474 eHalStatus halStatus;
475 v_U8_t sessionId = pAdapter->sessionId;
476
477 if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1))
478 {
479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
480 "%s: WoW pattern index %d is not in the range (0 ~ %d).",
481 __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
482
483 return VOS_FALSE;
484 }
485
486 if (!g_hdd_wowl_ptrns_debugfs[pattern_idx])
487 {
488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
489 "%s: WoW pattern %d is not in the table.",
490 __func__, pattern_idx);
491
492 return VOS_FALSE;
493 }
494
495 delPattern.ucPatternId = pattern_idx;
496 halStatus = sme_WowlDelBcastPattern(hHal, &delPattern, sessionId);
497
498 if (!HAL_STATUS_SUCCESS(halStatus))
499 {
500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700501 "%s: sme_WowlDelBcastPattern failed with error code (%d).",
Yue Ma0d4891e2013-08-06 17:01:45 -0700502 __func__, halStatus);
503
504 return VOS_FALSE;
505 }
506
507 g_hdd_wowl_ptrns_debugfs[pattern_idx] = 0;
508 g_hdd_wowl_ptrns_count--;
509
Yue Ma0d4891e2013-08-06 17:01:45 -0700510 return VOS_TRUE;
511}
512
513/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -0700514 @brief hdd_enter_wowl() - Function which will enable WoWL. Atleast one
515 of MP and PBM must be enabled
516
517 @param enable_mp : [in] Whether to enable magic packet WoWL mode
518 @param enable_pbm : [in] Whether to enable pattern byte matching WoWL mode
519
520 @return : FALSE if any errors encountered
521 : TRUE otherwise
522 ===========================================================================*/
Kumar Anand42277932014-03-29 21:09:21 -0700523v_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 -0700524{
525 tSirSmeWowlEnterParams wowParams;
526 eHalStatus halStatus;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700527 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700528
Kumar Anand42277932014-03-29 21:09:21 -0700529 vos_mem_zero( &wowParams, sizeof( tSirSmeWowlEnterParams ) );
530
Jeff Johnson295189b2012-06-20 16:38:30 -0700531 wowParams.ucPatternFilteringEnable = enable_pbm;
532 wowParams.ucMagicPktEnable = enable_mp;
533 if(enable_mp)
534 {
535 vos_copy_macaddr( (v_MACADDR_t *)&(wowParams.magicPtrn),
536 &(pAdapter->macAddressCurrent) );
537 }
538
Kumar Anand42277932014-03-29 21:09:21 -0700539#ifdef WLAN_WAKEUP_EVENTS
540 wowParams.ucWoWEAPIDRequestEnable = VOS_TRUE;
541 wowParams.ucWoWEAPOL4WayEnable = VOS_TRUE;
542 wowParams.ucWowNetScanOffloadMatch = VOS_TRUE;
543 wowParams.ucWowGTKRekeyError = VOS_TRUE;
544 wowParams.ucWoWBSSConnLoss = VOS_TRUE;
545#endif // WLAN_WAKEUP_EVENTS
546
Jeff Johnson295189b2012-06-20 16:38:30 -0700547 // Request to put Libra into WoWL
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700548 halStatus = sme_EnterWowl( hHal, hdd_wowl_callback,
Kumar Anandaca924e2013-07-22 14:35:34 -0700549 pAdapter,
550#ifdef WLAN_WAKEUP_EVENTS
551 hdd_wowl_wakeIndication_callback,
552 pAdapter,
553#endif // WLAN_WAKEUP_EVENTS
554 &wowParams, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700555
556 if ( !HAL_STATUS_SUCCESS( halStatus ) )
557 {
558 if ( eHAL_STATUS_PMC_PENDING != halStatus )
559 {
560 // We failed to enter WoWL
561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700562 "sme_EnterWowl failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700563 return VOS_FALSE;
564 }
565 }
566 return VOS_TRUE;
567}
568
569/**============================================================================
570 @brief hdd_exit_wowl() - Function which will disable WoWL
571
c_hpothu01484c02014-05-16 14:05:15 +0530572 @param wowlExitSrc: To know is wowl exiting because of wakeup pkt or user
573 explicitly disabling WoWL
Jeff Johnson295189b2012-06-20 16:38:30 -0700574 @return : FALSE if any errors encountered
575 : TRUE otherwise
576 ===========================================================================*/
c_hpothu01484c02014-05-16 14:05:15 +0530577v_BOOL_t hdd_exit_wowl (hdd_adapter_t*pAdapter, tWowlExitSource wowlExitSrc)
Jeff Johnson295189b2012-06-20 16:38:30 -0700578{
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700579 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700580 eHalStatus halStatus;
581
c_hpothu01484c02014-05-16 14:05:15 +0530582 halStatus = sme_ExitWowl( hHal, wowlExitSrc );
Jeff Johnson295189b2012-06-20 16:38:30 -0700583 if ( !HAL_STATUS_SUCCESS( halStatus ) )
584 {
585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700586 "sme_ExitWowl failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700587 return VOS_FALSE;
588 }
589
590 return VOS_TRUE;
591}
592
593/**============================================================================
594 @brief hdd_init_wowl() - Init function which will initialize the WoWL module
595 and perform any required intial configuration
596
597 @return : FALSE if any errors encountered
598 : TRUE otherwise
599 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700600v_BOOL_t hdd_init_wowl (hdd_adapter_t*pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700601{
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700602 hdd_context_t *pHddCtx = NULL;
603 pHddCtx = pAdapter->pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700604
605 memset(g_hdd_wowl_ptrns, 0, sizeof(g_hdd_wowl_ptrns));
606
607 //Add any statically configured patterns
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700608 hdd_add_wowl_ptrn(pAdapter, pHddCtx->cfg_ini->wowlPattern);
Jeff Johnson295189b2012-06-20 16:38:30 -0700609
610 return VOS_TRUE;
611}