blob: 73268c5a26e07ef302e126eca90d217439ff6063 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula8f8d54d2017-11-14 14:38:45 +05302 * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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
Hanumanth Reddy Pothula8f8d54d2017-11-14 14:38:45 +053038#include <net/cfg80211.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070039#include <wlan_hdd_includes.h>
40#include <wlan_hdd_wowl.h>
41
42/*----------------------------------------------------------------------------
43 * Preprocessor Definitions and Constants
44 * -------------------------------------------------------------------------*/
45
Jeff Johnson295189b2012-06-20 16:38:30 -070046#define WOWL_INTER_PTRN_TOKENIZER ';'
47#define WOWL_INTRA_PTRN_TOKENIZER ':'
48
49/*----------------------------------------------------------------------------
50 * Type Declarations
51 * -------------------------------------------------------------------------*/
52
Yue Ma0d4891e2013-08-06 17:01:45 -070053static char *g_hdd_wowl_ptrns[WOWL_MAX_PTRNS_ALLOWED]; //Patterns 0-15
54static v_BOOL_t g_hdd_wowl_ptrns_debugfs[WOWL_MAX_PTRNS_ALLOWED] = {0};
55static v_U8_t g_hdd_wowl_ptrns_count = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070056
Srinivas Girigowda100eb322013-03-15 16:48:20 -070057int hdd_parse_hex(unsigned char c)
Jeff Johnson295189b2012-06-20 16:38:30 -070058{
59 if (c >= '0' && c <= '9')
60 return c-'0';
61 if (c >= 'a' && c <= 'f')
62 return c-'a'+10;
63 if (c >= 'A' && c <= 'F')
64 return c-'A'+10;
65
66 return 0;
67}
68
69static inline int find_ptrn_len(const char* ptrn)
70{
71 int len = 0;
72 while (*ptrn != '\0' && *ptrn != WOWL_INTER_PTRN_TOKENIZER)
73 {
74 len++; ptrn++;
75 }
76 return len;
77}
78
79static void hdd_wowl_callback( void *pContext, eHalStatus halStatus )
80{
Kumar Anandaca924e2013-07-22 14:35:34 -070081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080082 "%s: Return code = (%d)", __func__, halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -070083}
84
Kumar Anandaca924e2013-07-22 14:35:34 -070085#ifdef WLAN_WAKEUP_EVENTS
Hanumanth Reddy Pothula8f8d54d2017-11-14 14:38:45 +053086#ifdef CONFIG_PM
87static void hdd_wowl_report_wakeup(hdd_adapter_t *adapter,
88 tpSirWakeReasonInd wake_reason_ind)
89{
90 struct cfg80211_wowlan_wakeup wakeup_report = { 0 };
91 struct net_device *dev = adapter->dev;
92 struct wireless_dev *wdev = dev->ieee80211_ptr;
93 enum hdd_wakeup_reason_type reason_type =
94 (enum hdd_wakeup_reason_type)wake_reason_ind->ulReason;
95
96 ENTER();
97
98 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "reason_type:%u reason_arg:%u",
99 reason_type, wake_reason_ind->ulReasonArg);
100
101 wakeup_report.pattern_idx = -1;
102
103 switch(reason_type) {
104 case WLAN_HDD_WAKE_REASON_MAGIC_PACKET:
105 wakeup_report.magic_pkt = TRUE;
106 break;
107 case WLAN_HDD_WAKE_REASON_PATTERN_MATCH:
108 wakeup_report.pattern_idx =
109 wake_reason_ind->ulReasonArg;
110 break;
111 case WLAN_HDD_WAKE_REASON_EAPID_PACKET:
112 wakeup_report.eap_identity_req = TRUE;
113 break;
114 case WLAN_HDD_WAKE_REASON_EAPOL4WAY_PACKET:
115 wakeup_report.four_way_handshake = TRUE;
116 break;
117 case WLAN_HDD_WAKE_REASON_GTK_REKEY_STATUS:
118 wakeup_report.gtk_rekey_failure = TRUE;
119 break;
120 case WLAN_HDD_WAKE_REASON_BSS_CONN_LOST:
121 wakeup_report.disconnect = TRUE;
122 break;
123 case WLAN_HDD_WAKE_REASON_NETSCAN_OFFL_MATCH:
124 case WLAN_HDD_WAKE_REASON_NONE:
125 default:
126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "unsupported reason code");
127 break;
128 }
129
130 cfg80211_report_wowlan_wakeup(wdev, &wakeup_report, GFP_KERNEL);
131
132 EXIT();
133}
134#endif
135
Kumar Anandaca924e2013-07-22 14:35:34 -0700136static void hdd_wowl_wakeIndication_callback( void *pContext,
137 tpSirWakeReasonInd pWakeReasonInd )
138{
139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Wake Reason %d",
140 __func__, pWakeReasonInd->ulReason );
Hanumanth Reddy Pothula8f8d54d2017-11-14 14:38:45 +0530141#ifdef CONFIG_PM
142 hdd_wowl_report_wakeup((hdd_adapter_t *)pContext, pWakeReasonInd);
143#endif
c_hpothu01484c02014-05-16 14:05:15 +0530144 hdd_exit_wowl( (hdd_adapter_t *)pContext, eWOWL_EXIT_WAKEIND );
Kumar Anandaca924e2013-07-22 14:35:34 -0700145}
146#endif
147
Jeff Johnson295189b2012-06-20 16:38:30 -0700148static void dump_hdd_wowl_ptrn(tSirWowlAddBcastPtrn *ptrn)
149{
150 int i;
151
152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatetrnId = 0x%x", __func__,
153 ptrn->ucPatternId);
154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternByteOffset = 0x%x", __func__,
155 ptrn->ucPatternByteOffset);
156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternSize = 0x%x", __func__,
157 ptrn->ucPatternSize);
158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternMaskSize = 0x%x", __func__,
159 ptrn->ucPatternMaskSize);
160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Pattern: ", __func__);
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800161 for(i = 0; i < ptrn->ucPatternSize; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", ptrn->ucPattern[i]);
163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: PatternMask: ", __func__);
164 for(i = 0; i<ptrn->ucPatternMaskSize; i++)
165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%02X", ptrn->ucPatternMask[i]);
166}
167
168
169/**============================================================================
170 @brief hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be
171 used when PBM filtering is enabled
172
173 @param ptrn : [in] pointer to the pattern string to be added
174
175 @return : FALSE if any errors encountered
176 : TRUE otherwise
177 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700178v_BOOL_t hdd_add_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn)
Jeff Johnson295189b2012-06-20 16:38:30 -0700179{
180 tSirWowlAddBcastPtrn localPattern;
181 int i, first_empty_slot, len, offset;
182 eHalStatus halStatus;
183 const char *temp;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700184 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
185 v_U8_t sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700186
187 len = find_ptrn_len(ptrn);
188
189 /* There has to have atleast 1 byte for each field (pattern size, mask size,
190 * pattern, mask) e.g. PP:QQ:RR:SS ==> 11 chars */
191 while ( len >= 11 )
192 {
193 first_empty_slot = -1;
194
195 // Find an empty slot to store the pattern
196 for (i=0; i<WOWL_MAX_PTRNS_ALLOWED; i++)
197 {
198 if(g_hdd_wowl_ptrns[i] == NULL) {
199 first_empty_slot = i;
200 break;
201 }
202 }
203
204 // Maximum number of patterns have been configured already
205 if(first_empty_slot == -1)
206 {
207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700208 "%s: Cannot add anymore patterns. No free slot!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 return VOS_FALSE;
210 }
211
212 // Detect duplicate pattern
213 for (i=0; i<WOWL_MAX_PTRNS_ALLOWED; i++)
214 {
215 if(g_hdd_wowl_ptrns[i] == NULL) continue;
216
217 if(!memcmp(ptrn, g_hdd_wowl_ptrns[i], len))
218 {
219 // Pattern Already configured, skip to next pattern
220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
221 "Trying to add duplicate WoWL pattern. Skip it!");
222 ptrn += len;
223 goto next_ptrn;
224 }
225 }
226
227 //Validate the pattern
228 if(ptrn[2] != WOWL_INTRA_PTRN_TOKENIZER ||
229 ptrn[5] != WOWL_INTRA_PTRN_TOKENIZER)
230 {
231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800232 "%s: Malformed pattern string. Skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 ptrn += len;
234 goto next_ptrn;
235 }
236
237 // Extract the pattern size
238 localPattern.ucPatternSize =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700239 ( hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700240
241 // Extract the pattern mask size
242 localPattern.ucPatternMaskSize =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700243 ( hdd_parse_hex( ptrn[3] ) * 0x10 ) + hdd_parse_hex( ptrn[4] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700244
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800245 if(localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700246 localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE)
247 {
248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800249 "%s: Invalid length specified. Skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 ptrn += len;
251 goto next_ptrn;
252 }
253
254 //compute the offset of tokenizer after the pattern
255 offset = 5 + 2*localPattern.ucPatternSize + 1;
256 if(offset >= len || ptrn[offset] != WOWL_INTRA_PTRN_TOKENIZER)
257 {
258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800259 "%s: Malformed pattern string..skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 ptrn += len;
261 goto next_ptrn;
262 }
263
264 //compute the end of pattern sring
265 offset = offset + 2*localPattern.ucPatternMaskSize;
266 if(offset+1 != len) //offset begins with 0
267 {
268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800269 "%s: Malformed pattern string...skip!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 ptrn += len;
271 goto next_ptrn;
272 }
273
274 temp = ptrn;
275
276 // Now advance to where pattern begins
277 ptrn += 6;
278
279 // Extract the pattern
280 for(i=0; i < localPattern.ucPatternSize; i++)
281 {
282 localPattern.ucPattern[i] =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700283 (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700284 ptrn += 2; //skip to next byte
285 }
286
287 ptrn++; // Skip over the ':' seperator after the pattern
288
289 // Extract the pattern Mask
290 for(i=0; i < localPattern.ucPatternMaskSize; i++)
291 {
292 localPattern.ucPatternMask[i] =
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700293 (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 ptrn += 2; //skip to next byte
295 }
296
297 //All is good. Store the pattern locally
298 g_hdd_wowl_ptrns[first_empty_slot] = (char*) kmalloc(len+1, GFP_KERNEL);
299 if(g_hdd_wowl_ptrns[first_empty_slot] == NULL)
300 {
301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700302 "%s: kmalloc failure", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700303 return VOS_FALSE;
304 }
305
306 memcpy(g_hdd_wowl_ptrns[first_empty_slot], temp, len);
307 g_hdd_wowl_ptrns[first_empty_slot][len] = '\0';
308 localPattern.ucPatternId = first_empty_slot;
309 localPattern.ucPatternByteOffset = 0;
310
311 // Register the pattern downstream
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700312 halStatus = sme_WowlAddBcastPattern( hHal, &localPattern, sessionId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700313 if ( !HAL_STATUS_SUCCESS( halStatus ) )
314 {
315 // Add failed, so invalidate the local storage
316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700317 "sme_WowlAddBcastPattern failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 kfree(g_hdd_wowl_ptrns[first_empty_slot]);
319 g_hdd_wowl_ptrns[first_empty_slot] = NULL;
320 }
321
322 dump_hdd_wowl_ptrn(&localPattern);
323
324 next_ptrn:
325 if (*ptrn == WOWL_INTER_PTRN_TOKENIZER)
326 {
327 ptrn += 1; // move past the tokenizer
328 len = find_ptrn_len(ptrn);
329 continue;
330 }
331 else
332 break;
333 }
334
335 return VOS_TRUE;
336}
337
338/**============================================================================
339 @brief hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern
340
341 @param ptrn : [in] pointer to the pattern string to be removed
342
343 @return : FALSE if any errors encountered
344 : TRUE otherwise
345 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700346v_BOOL_t hdd_del_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn)
Jeff Johnson295189b2012-06-20 16:38:30 -0700347{
348 tSirWowlDelBcastPtrn delPattern;
349 unsigned char id;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700350 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 v_BOOL_t patternFound = VOS_FALSE;
352 eHalStatus halStatus;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700353 v_U8_t sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700354
355 // Detect pattern
356 for (id=0; id<WOWL_MAX_PTRNS_ALLOWED && g_hdd_wowl_ptrns[id] != NULL; id++)
357 {
358 if(!strcmp(ptrn, g_hdd_wowl_ptrns[id]))
359 {
360 patternFound = VOS_TRUE;
361 break;
362 }
363 }
364
365 // If pattern present, remove it from downstream
366 if(patternFound)
367 {
368 delPattern.ucPatternId = id;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700369 halStatus = sme_WowlDelBcastPattern( hHal, &delPattern, sessionId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 if ( HAL_STATUS_SUCCESS( halStatus ) )
371 {
372 // Remove from local storage as well
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
374 "Deleted pattern with id %d [%s]", id, g_hdd_wowl_ptrns[id]);
375
376 kfree(g_hdd_wowl_ptrns[id]);
377 g_hdd_wowl_ptrns[id] = NULL;
378 return VOS_TRUE;
379 }
380 }
381 return VOS_FALSE;
382}
383
384/**============================================================================
Yue Ma0d4891e2013-08-06 17:01:45 -0700385 @brief hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern
Yue Maddad6a72013-11-19 12:40:59 -0800386 sent from debugfs interface
Yue Ma0d4891e2013-08-06 17:01:45 -0700387
388 @param pAdapter : [in] pointer to the adapter
389 pattern_idx : [in] index of the pattern to be added
390 pattern_offset : [in] offset of the pattern in the frame payload
391 pattern_buf : [in] pointer to the pattern hex string to be added
Yue Maddad6a72013-11-19 12:40:59 -0800392 pattern_mask : [in] pointer to the pattern mask hex string
Yue Ma0d4891e2013-08-06 17:01:45 -0700393
394 @return : FALSE if any errors encountered
395 : TRUE otherwise
396 ===========================================================================*/
397v_BOOL_t hdd_add_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx,
Yue Maddad6a72013-11-19 12:40:59 -0800398 v_U8_t pattern_offset, char *pattern_buf,
399 char *pattern_mask)
Yue Ma0d4891e2013-08-06 17:01:45 -0700400{
401 tSirWowlAddBcastPtrn localPattern;
402 eHalStatus halStatus;
403 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
404 v_U8_t sessionId = pAdapter->sessionId;
Yue Maddad6a72013-11-19 12:40:59 -0800405 v_U16_t pattern_len, mask_len, i;
Yue Ma0d4891e2013-08-06 17:01:45 -0700406
407 if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1))
408 {
409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
410 "%s: WoW pattern index %d is out of range (0 ~ %d).",
411 __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
412
413 return VOS_FALSE;
414 }
415
416 pattern_len = strlen(pattern_buf);
417
418 /* Since the pattern is a hex string, 2 characters represent 1 byte. */
419 if (pattern_len % 2)
420 {
421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
422 "%s: Malformed WoW pattern!", __func__);
423
424 return VOS_FALSE;
425 }
426 else
427 pattern_len >>= 1;
428
429 if (!pattern_len || pattern_len > WOWL_PTRN_MAX_SIZE)
430 {
431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
432 "%s: WoW pattern length %d is out of range (1 ~ %d).",
433 __func__, pattern_len, WOWL_PTRN_MAX_SIZE);
434
435 return VOS_FALSE;
436 }
437
438 localPattern.ucPatternId = pattern_idx;
439 localPattern.ucPatternByteOffset = pattern_offset;
440 localPattern.ucPatternSize = pattern_len;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800441 if (localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE) {
442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
443 "%s: WoW pattern size (%d) greater than max (%d)",
444 __func__, localPattern.ucPatternSize,
445 SIR_WOWL_BCAST_PATTERN_MAX_SIZE);
446 return VOS_FALSE;
447 }
Yue Ma0d4891e2013-08-06 17:01:45 -0700448 /* Extract the pattern */
449 for (i = 0; i < localPattern.ucPatternSize; i++)
450 {
451 localPattern.ucPattern[i] =
452 (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]);
453
454 /* Skip to next byte */
455 pattern_buf += 2;
456 }
457
Yue Maddad6a72013-11-19 12:40:59 -0800458 /* Get pattern mask size by pattern length */
459 localPattern.ucPatternMaskSize = pattern_len >> 3;
Yue Ma0d4891e2013-08-06 17:01:45 -0700460 if (pattern_len % 8)
Yue Ma0d4891e2013-08-06 17:01:45 -0700461 localPattern.ucPatternMaskSize += 1;
Yue Maddad6a72013-11-19 12:40:59 -0800462
463 mask_len = strlen(pattern_mask);
464 if ((mask_len % 2) || (localPattern.ucPatternMaskSize != (mask_len >> 1)))
465 {
466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
467 "%s: Malformed WoW pattern mask!", __func__);
468
469 return VOS_FALSE;
470 }
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -0800471 if (localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE) {
472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
473 "%s: WoW pattern mask size (%d) greater than max (%d)",
474 __func__, localPattern.ucPatternMaskSize, WOWL_PTRN_MASK_MAX_SIZE);
475 return VOS_FALSE;
476 }
Yue Maddad6a72013-11-19 12:40:59 -0800477 /* Extract the pattern mask */
478 for (i = 0; i < localPattern.ucPatternMaskSize; i++)
479 {
480 localPattern.ucPatternMask[i] =
481 (hdd_parse_hex(pattern_mask[0]) << 4) + hdd_parse_hex(pattern_mask[1]);
482
483 /* Skip to next byte */
484 pattern_mask += 2;
Yue Ma0d4891e2013-08-06 17:01:45 -0700485 }
486
487 /* Register the pattern downstream */
488 halStatus = sme_WowlAddBcastPattern(hHal, &localPattern, sessionId);
489
490 if (!HAL_STATUS_SUCCESS(halStatus))
491 {
492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700493 "%s: sme_WowlAddBcastPattern failed with error code (%d).",
Yue Ma0d4891e2013-08-06 17:01:45 -0700494 __func__, halStatus);
495
496 return VOS_FALSE;
497 }
498
Yue Ma0d4891e2013-08-06 17:01:45 -0700499 /* All is good. */
500 if (!g_hdd_wowl_ptrns_debugfs[pattern_idx])
501 {
502 g_hdd_wowl_ptrns_debugfs[pattern_idx] = 1;
503 g_hdd_wowl_ptrns_count++;
504 }
505
506 dump_hdd_wowl_ptrn(&localPattern);
507
508 return VOS_TRUE;
509}
510
511/**============================================================================
512 @brief hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern
Yue Maddad6a72013-11-19 12:40:59 -0800513 sent from debugfs interface
Yue Ma0d4891e2013-08-06 17:01:45 -0700514
515 @param pAdapter : [in] pointer to the adapter
516 pattern_idx : [in] index of the pattern to be removed
517
518 @return : FALSE if any errors encountered
519 : TRUE otherwise
520 ===========================================================================*/
521v_BOOL_t hdd_del_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx)
522{
523 tSirWowlDelBcastPtrn delPattern;
524 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
525 eHalStatus halStatus;
526 v_U8_t sessionId = pAdapter->sessionId;
527
528 if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1))
529 {
530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
531 "%s: WoW pattern index %d is not in the range (0 ~ %d).",
532 __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1);
533
534 return VOS_FALSE;
535 }
536
537 if (!g_hdd_wowl_ptrns_debugfs[pattern_idx])
538 {
539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
540 "%s: WoW pattern %d is not in the table.",
541 __func__, pattern_idx);
542
543 return VOS_FALSE;
544 }
545
546 delPattern.ucPatternId = pattern_idx;
547 halStatus = sme_WowlDelBcastPattern(hHal, &delPattern, sessionId);
548
549 if (!HAL_STATUS_SUCCESS(halStatus))
550 {
551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700552 "%s: sme_WowlDelBcastPattern failed with error code (%d).",
Yue Ma0d4891e2013-08-06 17:01:45 -0700553 __func__, halStatus);
554
555 return VOS_FALSE;
556 }
557
558 g_hdd_wowl_ptrns_debugfs[pattern_idx] = 0;
559 g_hdd_wowl_ptrns_count--;
560
Yue Ma0d4891e2013-08-06 17:01:45 -0700561 return VOS_TRUE;
562}
563
564/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -0700565 @brief hdd_enter_wowl() - Function which will enable WoWL. Atleast one
566 of MP and PBM must be enabled
567
568 @param enable_mp : [in] Whether to enable magic packet WoWL mode
569 @param enable_pbm : [in] Whether to enable pattern byte matching WoWL mode
570
571 @return : FALSE if any errors encountered
572 : TRUE otherwise
573 ===========================================================================*/
Kumar Anand42277932014-03-29 21:09:21 -0700574v_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 -0700575{
576 tSirSmeWowlEnterParams wowParams;
577 eHalStatus halStatus;
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700578 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700579
Kumar Anand42277932014-03-29 21:09:21 -0700580 vos_mem_zero( &wowParams, sizeof( tSirSmeWowlEnterParams ) );
581
Jeff Johnson295189b2012-06-20 16:38:30 -0700582 wowParams.ucPatternFilteringEnable = enable_pbm;
583 wowParams.ucMagicPktEnable = enable_mp;
584 if(enable_mp)
585 {
586 vos_copy_macaddr( (v_MACADDR_t *)&(wowParams.magicPtrn),
587 &(pAdapter->macAddressCurrent) );
588 }
589
Kumar Anand42277932014-03-29 21:09:21 -0700590#ifdef WLAN_WAKEUP_EVENTS
591 wowParams.ucWoWEAPIDRequestEnable = VOS_TRUE;
592 wowParams.ucWoWEAPOL4WayEnable = VOS_TRUE;
593 wowParams.ucWowNetScanOffloadMatch = VOS_TRUE;
594 wowParams.ucWowGTKRekeyError = VOS_TRUE;
595 wowParams.ucWoWBSSConnLoss = VOS_TRUE;
596#endif // WLAN_WAKEUP_EVENTS
597
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 // Request to put Libra into WoWL
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700599 halStatus = sme_EnterWowl( hHal, hdd_wowl_callback,
Kumar Anandaca924e2013-07-22 14:35:34 -0700600 pAdapter,
601#ifdef WLAN_WAKEUP_EVENTS
602 hdd_wowl_wakeIndication_callback,
603 pAdapter,
604#endif // WLAN_WAKEUP_EVENTS
605 &wowParams, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700606
607 if ( !HAL_STATUS_SUCCESS( halStatus ) )
608 {
609 if ( eHAL_STATUS_PMC_PENDING != halStatus )
610 {
611 // We failed to enter WoWL
612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700613 "sme_EnterWowl failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700614 return VOS_FALSE;
615 }
616 }
617 return VOS_TRUE;
618}
619
620/**============================================================================
621 @brief hdd_exit_wowl() - Function which will disable WoWL
622
c_hpothu01484c02014-05-16 14:05:15 +0530623 @param wowlExitSrc: To know is wowl exiting because of wakeup pkt or user
624 explicitly disabling WoWL
Jeff Johnson295189b2012-06-20 16:38:30 -0700625 @return : FALSE if any errors encountered
626 : TRUE otherwise
627 ===========================================================================*/
c_hpothu01484c02014-05-16 14:05:15 +0530628v_BOOL_t hdd_exit_wowl (hdd_adapter_t*pAdapter, tWowlExitSource wowlExitSrc)
Jeff Johnson295189b2012-06-20 16:38:30 -0700629{
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700630 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700631 eHalStatus halStatus;
632
c_hpothu01484c02014-05-16 14:05:15 +0530633 halStatus = sme_ExitWowl( hHal, wowlExitSrc );
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 if ( !HAL_STATUS_SUCCESS( halStatus ) )
635 {
636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700637 "sme_ExitWowl failed with error code (%d)", halStatus );
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 return VOS_FALSE;
639 }
640
641 return VOS_TRUE;
642}
643
644/**============================================================================
645 @brief hdd_init_wowl() - Init function which will initialize the WoWL module
646 and perform any required intial configuration
647
648 @return : FALSE if any errors encountered
649 : TRUE otherwise
650 ===========================================================================*/
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700651v_BOOL_t hdd_init_wowl (hdd_adapter_t*pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700652{
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700653 hdd_context_t *pHddCtx = NULL;
654 pHddCtx = pAdapter->pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700655
656 memset(g_hdd_wowl_ptrns, 0, sizeof(g_hdd_wowl_ptrns));
657
658 //Add any statically configured patterns
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -0700659 hdd_add_wowl_ptrn(pAdapter, pHddCtx->cfg_ini->wowlPattern);
Jeff Johnson295189b2012-06-20 16:38:30 -0700660
661 return VOS_TRUE;
662}