blob: d87592697b08adf68fe9929f3c8fe780965cc572 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -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.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**=============================================================================
43* wlan_hdd_early_suspend.c
44*
45* \brief power management functions
46*
47* Description
48* Copyright 2009 (c) Qualcomm, Incorporated.
49* All Rights Reserved.
50* Qualcomm Confidential and Proprietary.
51*
52==============================================================================**/
53/* $HEADER$ */
54
55/**-----------------------------------------------------------------------------
56* Include files
57* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/pm.h>
60#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070061#include <wlan_hdd_includes.h>
62#include <wlan_qct_driver.h>
63#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064
65#include "halTypes.h"
66#include "sme_Api.h"
67#include <vos_api.h>
68#include "vos_power.h"
69#include <vos_sched.h>
70#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#include <wlan_qct_sys.h>
72#include <wlan_btc_svc.h>
73#include <wlan_nlink_common.h>
74#include <wlan_hdd_main.h>
75#include <wlan_hdd_assoc.h>
76#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070077#include <wlan_nlink_srv.h>
78#include <wlan_hdd_misc.h>
79
Jeff Johnson295189b2012-06-20 16:38:30 -070080#include <linux/semaphore.h>
81#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include "cfgApi.h"
83
84#ifdef WLAN_BTAMP_FEATURE
85#include "bapApi.h"
86#include "bap_hdd_main.h"
87#include "bap_hdd_misc.h"
88#endif
89
Jeff Johnsone7245742012-09-05 17:12:55 -070090#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070091#include <linux/inetdevice.h>
92#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053093#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053094#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070095/**-----------------------------------------------------------------------------
96* Preprocessor definitions and constants
97* ----------------------------------------------------------------------------*/
98
99/**-----------------------------------------------------------------------------
100* Type declarations
101* ----------------------------------------------------------------------------*/
102
103/**-----------------------------------------------------------------------------
104* Function and variables declarations
105* ----------------------------------------------------------------------------*/
106#include "wlan_hdd_power.h"
107#include "wlan_hdd_packet_filtering.h"
108
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700109#define HDD_SSR_BRING_UP_TIME 10000
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111static eHalStatus g_full_pwr_status;
112static eHalStatus g_standby_status;
113
114extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
115extern VOS_STATUS vos_chipExitDeepSleepVREGHandler(
116 vos_call_status_type* status,
117 vos_power_cb_type callback,
118 v_PVOID_t user_data);
119extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700120
121extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700122extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700124static struct timer_list ssr_timer;
125static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700126
127//Callback invoked by PMC to report status of standby request
128void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
129{
130 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
131 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
132 g_standby_status = status;
133
134 if(eHAL_STATUS_SUCCESS == status)
135 {
136 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
137 }
138 else
139 {
140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
141 }
142
143 complete(&pHddCtx->standby_comp_var);
144}
145
146//Callback invoked by PMC to report status of full power request
147void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
148{
149 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
150 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
151 g_full_pwr_status = status;
152
153 if(eHAL_STATUS_SUCCESS == status)
154 {
155 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
156 }
157 else
158 {
159 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
160 }
161
162 complete(&pHddCtx->full_pwr_comp_var);
163}
164
165eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
166{
167 eHalStatus status = VOS_STATUS_SUCCESS;
168
169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
170 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
171
172 g_full_pwr_status = eHAL_STATUS_FAILURE;
173 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
174 eSME_FULL_PWR_NEEDED_BY_HDD);
175
176 if(status == eHAL_STATUS_PMC_PENDING)
177 {
178 //Block on a completion variable. Can't wait forever though
179 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
180 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
181 status = g_full_pwr_status;
182 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
183 {
184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
185 VOS_ASSERT(0);
186 goto failure;
187 }
188 }
189 else if(status != eHAL_STATUS_SUCCESS)
190 {
191 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
192 __func__, status);
193 VOS_ASSERT(0);
194 goto failure;
195 }
196 else
197 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
198
199failure:
200 //No blocking to reduce latency. No other device should be depending on WLAN
201 //to finish resume and WLAN won't be instantly on after resume
202 return status;
203}
204
205
206//Helper routine to put the chip into standby
207VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
208{
209 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
210 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
211
212 //Disable IMPS/BMPS as we do not want the device to enter any power
213 //save mode on its own during suspend sequence
214 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
215 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
216
217 //Note we do not disable queues unnecessarily. Queues should already be disabled
218 //if STA is disconnected or the queue will be disabled as and when disconnect
219 //happens because of standby procedure.
220
221 //Ensure that device is in full power first. There is scope for optimization
222 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
223 //Core s/w needs to be optimized to handle this. Until then we request full
224 //power before issuing request for standby.
225 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
226 g_full_pwr_status = eHAL_STATUS_FAILURE;
227 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
228 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
229
230 if(halStatus == eHAL_STATUS_PMC_PENDING)
231 {
232 //Block on a completion variable. Can't wait forever though
233 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
234 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
235 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
236 {
237 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
238 VOS_ASSERT(0);
239 vosStatus = VOS_STATUS_E_FAILURE;
240 goto failure;
241 }
242 }
243 else if(halStatus != eHAL_STATUS_SUCCESS)
244 {
245 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
246 __func__, halStatus);
247 VOS_ASSERT(0);
248 vosStatus = VOS_STATUS_E_FAILURE;
249 goto failure;
250 }
251
252 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
253 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
254 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
255 }
256
257 //Request standby. Standby will cause the STA to disassociate first. TX queues
258 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
259 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
260 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
261 //when there are concurrent sessions.
262 INIT_COMPLETION(pHddCtx->standby_comp_var);
263 g_standby_status = eHAL_STATUS_FAILURE;
264 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
265
266 if (halStatus == eHAL_STATUS_PMC_PENDING)
267 {
268 //Wait till WLAN device enters standby mode
269 wait_for_completion_timeout(&pHddCtx->standby_comp_var,
270 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
271 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
272 {
273 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
274 VOS_ASSERT(0);
275 vosStatus = VOS_STATUS_E_FAILURE;
276 goto failure;
277 }
278 }
279 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
280 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
281 __func__, halStatus);
282 VOS_ASSERT(0);
283 vosStatus = VOS_STATUS_E_FAILURE;
284 goto failure;
285 }
286 else
287 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
288
289failure:
290 //Restore IMPS config
291 if(pHddCtx->cfg_ini->fIsImpsEnabled)
292 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
293
294 //Restore BMPS config
295 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
296 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
297
298 return vosStatus;
299}
300
301
302//Helper routine for Deep sleep entry
303VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
304{
305 eHalStatus halStatus;
306 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
307 vos_call_status_type callType;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 //Stop the Interface TX queue.
310 netif_tx_disable(pAdapter->dev);
311 netif_carrier_off(pAdapter->dev);
312
313 //Disable IMPS,BMPS as we do not want the device to enter any power
314 //save mode on it own during suspend sequence
315 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
316 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
317
318 //Ensure that device is in full power as we will touch H/W during vos_Stop
319 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
320 g_full_pwr_status = eHAL_STATUS_FAILURE;
321 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
322 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
323
324 if(halStatus == eHAL_STATUS_PMC_PENDING)
325 {
326 //Block on a completion variable. Can't wait forever though
327 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
328 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
329 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
331 VOS_ASSERT(0);
332 }
333 }
334 else if(halStatus != eHAL_STATUS_SUCCESS)
335 {
336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
337 VOS_ASSERT(0);
338 }
339
340 //Issue a disconnect. This is required to inform the supplicant that
341 //STA is getting disassociated and for GUI to be updated properly
342 INIT_COMPLETION(pAdapter->disconnect_comp_var);
343 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
344
345 //Success implies disconnect command got queued up successfully
346 if(halStatus == eHAL_STATUS_SUCCESS)
347 {
348 //Block on a completion variable. Can't wait forever though.
349 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
350 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
351 }
352
353
354 //None of the steps should fail after this. Continue even in case of failure
355 vosStatus = vos_stop( pHddCtx->pvosContext );
356 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
357
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 vosStatus = vos_chipAssertDeepSleep( &callType, NULL, NULL );
359 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
360
361 //Vote off any PMIC voltage supplies
362 vosStatus = vos_chipPowerDown(NULL, NULL, NULL);
363
Jeff Johnson295189b2012-06-20 16:38:30 -0700364 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
365
366 //Restore IMPS config
367 if(pHddCtx->cfg_ini->fIsImpsEnabled)
368 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
369
370 //Restore BMPS config
371 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
372 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
373
Jeff Johnson295189b2012-06-20 16:38:30 -0700374 return vosStatus;
375}
376
377VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
378{
379 VOS_STATUS vosStatus;
380 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700381
382 //Power Up Libra WLAN card first if not already powered up
383 vosStatus = vos_chipPowerUp(NULL,NULL,NULL);
384 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
385 {
386 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
387 "exiting", __func__);
388 goto err_deep_sleep;
389 }
390
Jeff Johnson295189b2012-06-20 16:38:30 -0700391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
392 "%s: calling hdd_set_sme_config",__func__);
393 vosStatus = hdd_set_sme_config( pHddCtx );
394 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
395 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
396 {
397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
398 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700399 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700400 }
401
402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
403 "%s: calling vos_start",__func__);
404 vosStatus = vos_start( pHddCtx->pvosContext );
405 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
406 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
407 {
408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
409 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700410 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700411 }
412
413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
414 "%s: calling hdd_post_voss_start_config",__func__);
415 vosStatus = hdd_post_voss_start_config( pHddCtx );
416 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
417 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
418 {
419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
420 "%s: Failed in hdd_post_voss_start_config",__func__);
421 goto err_voss_stop;
422 }
423
424
425 //Open a SME session for future operation
426 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700427 (tANI_U8 *)&pAdapter->macAddressCurrent,
428 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700429 if ( !HAL_STATUS_SUCCESS( halStatus ) )
430 {
431 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08lx]",
432 halStatus, halStatus );
433 goto err_voss_stop;
434
435 }
436
437 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
438
439 //Trigger the initial scan
440 hdd_wlan_initial_scan(pHddCtx);
441
442 return VOS_STATUS_SUCCESS;
443
444err_voss_stop:
445 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700446err_deep_sleep:
447 return VOS_STATUS_E_FAILURE;
448
449}
450
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530451/*
452 * Function: hdd_conf_hostoffload
453 * Central function to configure the supported offloads,
454 * either enable or disable them.
455 */
456void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
457{
458 hdd_context_t *pHddCtx = NULL;
459 v_CONTEXT_t *pVosContext = NULL;
460 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
461
462 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
463 fenable);
464
465 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
466
467 if (NULL == pVosContext)
468 {
469 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
470 return;
471 }
472
473 //Get the HDD context.
474 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
475
476 if (NULL == pHddCtx)
477 {
478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
479 return;
480 }
481
482 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
483 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
484 {
485 if (fenable)
486 {
487 if (eConnectionState_Associated ==
488 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
489 {
490 if ((pHddCtx->cfg_ini->fhostArpOffload))
491 {
492 /*
493 * Configure the ARP Offload.
494 * Even if it fails we have to reconfigure the MC/BC
495 * filter flag as we want RIVA not to drop BroadCast
496 * Packets
497 */
498 hddLog(VOS_TRACE_LEVEL_INFO,
499 FL("Calling ARP Offload with flag: %d"), fenable);
500 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
501 pHddCtx->configuredMcastBcastFilter &=
502 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
503
504 if (!VOS_IS_STATUS_SUCCESS(vstatus))
505 {
506 hddLog(VOS_TRACE_LEVEL_ERROR,
507 "Failed to enable ARPOFfloadFeature %d",
508 vstatus);
509 }
510 }
511 //Configure GTK_OFFLOAD
512#ifdef WLAN_FEATURE_GTK_OFFLOAD
513 hdd_conf_gtk_offload(pAdapter, fenable);
514#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530515
516#ifdef WLAN_NS_OFFLOAD
517 if (pHddCtx->cfg_ini->fhostNSOffload)
518 {
519 /*
520 * Configure the NS Offload.
521 * Even if it fails we have to reconfigure the MC/BC filter flag
522 * as we want RIVA not to drop Multicast Packets
523 */
524
525 hddLog(VOS_TRACE_LEVEL_INFO,
526 FL("Calling NS Offload with flag: %d"), fenable);
527 hdd_conf_ns_offload(pAdapter, fenable);
528 pHddCtx->configuredMcastBcastFilter &=
529 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
530 }
531#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530532 }
533 }
534 else
535 {
536 //Disable ARPOFFLOAD
537 if (pHddCtx->cfg_ini->fhostArpOffload)
538 {
539 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
540 if (!VOS_IS_STATUS_SUCCESS(vstatus))
541 {
542 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530543 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530544 }
545 }
546 //Disable GTK_OFFLOAD
547#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530548 hdd_conf_gtk_offload(pAdapter, fenable);
549#endif
550
551#ifdef WLAN_NS_OFFLOAD
552 //Disable NSOFFLOAD
553 if (pHddCtx->cfg_ini->fhostNSOffload)
554 {
555 hdd_conf_ns_offload(pAdapter, fenable);
556 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530557#endif
558 }
559 }
560 return;
561}
562
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530563#ifdef WLAN_NS_OFFLOAD
564void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
565{
566 struct inet6_dev *in6_dev;
567 struct inet6_ifaddr *ifp;
568 struct list_head *p;
569 tANI_U8 selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN] = {{0,}};
570 tANI_BOOLEAN selfIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0};
571 tSirHostOffloadReq offLoadRequest;
572
573 int i =0;
574 eHalStatus returnStatus;
575
576 ENTER();
577 if (fenable)
578 {
579 in6_dev = __in6_dev_get(pAdapter->dev);
580 if (NULL != in6_dev)
581 {
582 //read_lock_bh(&in6_dev->lock);
583 list_for_each(p, &in6_dev->addr_list)
584 {
585 ifp = list_entry(p, struct inet6_ifaddr, if_list);
586 switch(ipv6_addr_src_scope(&ifp->addr))
587 {
588 case IPV6_ADDR_SCOPE_LINKLOCAL:
589 vos_mem_copy(&selfIPv6Addr[0], &ifp->addr.s6_addr,
590 sizeof(ifp->addr.s6_addr));
591 selfIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
592 break;
593 case IPV6_ADDR_SCOPE_GLOBAL:
594 vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr,
595 sizeof(ifp->addr.s6_addr));
596 selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID;;
597 break;
598 default:
599 hddLog(LOGE, "The Scope %d is not supported",
600 ipv6_addr_src_scope(&ifp->addr));
601 }
602
603 }
604 //read_unlock_bh(&in6_dev->lock);
605 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
606 for (i =0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
607 {
608 if (selfIPv6AddrValid[i])
609 {
610 //Filling up the request structure
611 /* Filling the selfIPv6Addr with solicited address
612 * A Solicited-Node multicast address is created by
613 * taking the last 24 bits of a unicast or anycast
614 * address and appending them to the prefix
615 *
616 * FF02:0000:0000:0000:0000:0001:FFXX:XX
617 *
618 * here XX is the unicast/anycast bits
619 */
620 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
621 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
622 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
623 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
624 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = selfIPv6Addr[i][13];
625 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = selfIPv6Addr[i][14];
626 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = selfIPv6Addr[i][15];
627 offLoadRequest.nsOffloadInfo.slotIdx = i;
628
629 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
630 &selfIPv6Addr[i][0], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
631 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
632 &pAdapter->macAddressCurrent.bytes,
633 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
634
635 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
636 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
637 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
638
639 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
640 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
641 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
642
643 hddLog (VOS_TRACE_LEVEL_INFO,
644 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
645 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
646 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
647
648 //Configure the Firmware with this
649 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
650 pAdapter->sessionId, &offLoadRequest);
651 if(eHAL_STATUS_SUCCESS != returnStatus)
652 {
653 hddLog(VOS_TRACE_LEVEL_ERROR,
654 FL("Failed to enable HostOffload feature with status: %d"),
655 returnStatus);
656 }
657 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
658 }
659 }
660 }
661 else
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("IPv6 dev does not exist. Failed to request NSOffload"));
665 return;
666 }
667 }
668 else
669 {
670 //Disable NSOffload
671 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
672 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
673 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
674
675 if (eHAL_STATUS_SUCCESS !=
676 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
677 pAdapter->sessionId, &offLoadRequest))
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
680 "NSOffload feature"));
681 }
682 }
683 return;
684}
685#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530686VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700687{
688 struct in_ifaddr **ifap = NULL;
689 struct in_ifaddr *ifa = NULL;
690 struct in_device *in_dev;
691 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800693 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700694
695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700696
Jeff Johnson295189b2012-06-20 16:38:30 -0700697 if(fenable)
698 {
699 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
700 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530701 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 ifap = &ifa->ifa_next)
703 {
704 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
705 {
706 break; /* found */
707 }
708 }
709 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 if(ifa && ifa->ifa_local)
711 {
712 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
713 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
714
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700716
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530717 if((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
718 pHddCtx->configuredMcastBcastFilter) ||
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700719 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530720 pHddCtx->configuredMcastBcastFilter))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700721 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530722 offLoadRequest.enableOrDisable =
723 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700724 }
725
726 //converting u32 to IPV4 address
727 for(i = 0 ; i < 4; i++)
728 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530729 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 (ifa->ifa_local >> (i*8) ) & 0xFF ;
731 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530732 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 offLoadRequest.params.hostIpv4Addr[0],
734 offLoadRequest.params.hostIpv4Addr[1],
735 offLoadRequest.params.hostIpv4Addr[2],
736 offLoadRequest.params.hostIpv4Addr[3]);
737
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530738 if (eHAL_STATUS_SUCCESS !=
739 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
740 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700741 {
742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
743 "feature\n", __func__);
744 return VOS_STATUS_E_FAILURE;
745 }
746 return VOS_STATUS_SUCCESS;
747 }
748 else
749 {
750 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned \n", __func__);
751 return VOS_STATUS_E_AGAIN;
752 }
753 }
754 else
755 {
756 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
757 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
758 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
759
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530760 if (eHAL_STATUS_SUCCESS !=
761 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
762 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700763 {
764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
765 "offload feature\n", __func__);
766 return VOS_STATUS_E_FAILURE;
767 }
768 return VOS_STATUS_SUCCESS;
769 }
770}
771
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530772/*
773 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530774 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530775*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530776void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530777 tANI_U8 *pMcBcFilter)
778{
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530779 if (NULL == pHddCtx)
780 {
781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
782 return;
783 }
784
785 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
786 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530787 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530788 /* ARP offload is enabled, do not block bcast packets at RXP
789 * Will be using Bitmasking to reset the filter. As we have
790 * disable Broadcast filtering, Anding with the negation
791 * of Broadcast BIT
792 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530793 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530794 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530795
796#ifdef WLAN_NS_OFFLOAD
797 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530798 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530799 /* NS offload is enabled, do not block mcast packets at RXP
800 * Will be using Bitmasking to reset the filter. As we have
801 * disable Multicast filtering, Anding with the negation
802 * of Multicast BIT
803 */
804 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530805 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530806#endif
807
808 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530809}
810
Jeff Johnson295189b2012-06-20 16:38:30 -0700811void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
812{
813 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700814 tpSirWlanSetRxpFilters wlanRxpFilterParam =
815 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
816 if(NULL == wlanRxpFilterParam)
817 {
818 hddLog(VOS_TRACE_LEVEL_FATAL,
819 "%s: vos_mem_alloc failed ", __func__);
820 return;
821 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 hddLog(VOS_TRACE_LEVEL_INFO,
823 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530824 if (TRUE == setfilter)
825 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530826 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530827 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530828 }
829 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530830 {
831 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530832 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530833 pHddCtx->configuredMcastBcastFilter;
834 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530835
Jeff Johnson295189b2012-06-20 16:38:30 -0700836 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -0700838 if (eHAL_STATUS_SUCCESS != halStatus)
839 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
841 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
842}
843
Jeff Johnson295189b2012-06-20 16:38:30 -0700844static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
845 hdd_adapter_t *pAdapter)
846{
847 eHalStatus halStatus = eHAL_STATUS_FAILURE;
848 tpSirWlanSuspendParam wlanSuspendParam =
849 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
850
851 if(NULL == wlanSuspendParam)
852 {
853 hddLog(VOS_TRACE_LEVEL_FATAL,
854 "%s: vos_mem_alloc failed ", __func__);
855 return;
856 }
857
858 hddLog(VOS_TRACE_LEVEL_INFO,
859 "%s: send wlan suspend indication", __func__);
860
861 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
862 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530863 //Configure supported OffLoads
864 hdd_conf_hostoffload(pAdapter, TRUE);
865 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700866
867#ifdef WLAN_FEATURE_PACKET_FILTERING
868 if (pHddCtx->cfg_ini->isMcAddrListFilter)
869 {
870 /*Multicast addr list filter is enabled during suspend*/
871 if (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
872 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530873 && pAdapter->mc_addr_list.mc_cnt
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 && (eConnectionState_Associated ==
875 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
876 {
877 /*set the filter*/
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530878 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700879 }
880 }
881#endif
882 }
883
884 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
885 if(eHAL_STATUS_SUCCESS == halStatus)
886 {
887 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -0700888 } else {
889 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 }
891}
892
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530893static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700894{
Chilam Ngc4244af2013-04-01 15:37:32 -0700895 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -0800896 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -0700897 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -0700898
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530899 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700900 "%s: send wlan resume indication", __func__);
901
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530902 if (pHddCtx->hdd_mcastbcast_filter_set == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700903 {
Chilam Ngc4244af2013-04-01 15:37:32 -0700904 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
905
906 if(NULL == wlanResumeParam)
907 {
908 hddLog(VOS_TRACE_LEVEL_FATAL,
909 "%s: vos_mem_alloc failed ", __func__);
910 return;
911 }
912
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530913 //Disable supported OffLoads
914 hdd_conf_hostoffload(pAdapter, FALSE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530915
916 wlanResumeParam->configuredMcstBcstFilterSetting =
917 pHddCtx->configuredMcastBcastFilter;
Chilam Ngc4244af2013-04-01 15:37:32 -0700918 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
919 if (eHAL_STATUS_SUCCESS != halStatus)
920 vos_mem_free(wlanResumeParam);
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530921 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700923
Chilam Ngc4244af2013-04-01 15:37:32 -0700924
Jeff Johnson295189b2012-06-20 16:38:30 -0700925#ifdef WLAN_FEATURE_PACKET_FILTERING
926 if (pHddCtx->cfg_ini->isMcAddrListFilter)
927 {
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530928 /*Multicast addr filtering is enabled*/
929 if (pAdapter->mc_addr_list.isFilterApplied)
Jeff Johnson295189b2012-06-20 16:38:30 -0700930 {
931 /*Filter applied during suspend mode*/
932 /*Clear it here*/
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530933 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 }
935 }
936#endif
937}
Jeff Johnson295189b2012-06-20 16:38:30 -0700938
Jeff Johnson295189b2012-06-20 16:38:30 -0700939//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800940void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -0700941{
942 hdd_context_t *pHddCtx = NULL;
943 v_CONTEXT_t pVosContext = NULL;
944
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530946 hdd_adapter_t *pAdapter = NULL;
947 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +0530948 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800949
Jeff Johnson295189b2012-06-20 16:38:30 -0700950 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
951
952 //Get the global VOSS context.
953 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
954 if(!pVosContext) {
955 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
956 return;
957 }
958
959 //Get the HDD context.
960 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
961
962 if(!pHddCtx) {
963 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
964 return;
965 }
966
967 if (pHddCtx->isLogpInProgress) {
968 hddLog(VOS_TRACE_LEVEL_ERROR,
969 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
970 return;
971 }
972
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530973 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700974 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
975 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
976 {
977 pAdapter = pAdapterNode->pAdapter;
978 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -0700979 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -0700980 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
981
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -0700982 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -0700983 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
984 pAdapterNode = pNext;
985 continue;
986 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +0530987 /* Avoid multiple enter/exit BMPS in this while loop using
988 * hdd_enter_bmps flag
989 */
990 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
991 {
992 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700993
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +0530994 /* If device was already in BMPS, and dynamic DTIM is set,
995 * exit(set the device to full power) and enter BMPS again
996 * to reflect new DTIM value */
997 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
998
999 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1000
1001 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1002 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001003#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1004 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1005 {
1006 //stop the interface before putting the chip to standby
1007 netif_tx_disable(pAdapter->dev);
1008 netif_carrier_off(pAdapter->dev);
1009 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301010 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1012 {
1013 //Execute deep sleep procedure
1014 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1015 }
1016#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301017
1018 /*Suspend notification sent down to driver*/
1019 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1020
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301021 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1022 pAdapterNode = pNext;
1023 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301024 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301025
Jeff Johnson295189b2012-06-20 16:38:30 -07001026#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1027 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1028 {
1029 hdd_enter_standby(pHddCtx);
1030 }
1031#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001032
1033 return;
1034}
1035
1036static void hdd_PowerStateChangedCB
1037(
1038 v_PVOID_t callbackContext,
1039 tPmcState newState
1040)
1041{
1042 hdd_context_t *pHddCtx = callbackContext;
1043
1044 /* if the driver was not in BMPS during early suspend,
1045 * the dynamic DTIM is now updated at Riva */
1046 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1047 && pHddCtx->cfg_ini->enableDynamicDTIM
1048 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1049 {
1050 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1051 }
1052 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301053 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 spin_unlock(&pHddCtx->filter_lock);
1055 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001056 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1058 }
1059 else
1060 spin_unlock(&pHddCtx->filter_lock);
1061}
1062
1063
1064
1065void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1066{
1067 v_CONTEXT_t pVosContext;
1068 tHalHandle smeContext;
1069
1070 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1071 if (NULL == pVosContext)
1072 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001073 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 return;
1075 }
1076 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1077 if (NULL == smeContext)
1078 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001079 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001080 return;
1081 }
1082
1083 spin_lock_init(&pHddCtx->filter_lock);
1084 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1085 pHddCtx->cfg_ini->nEnableSuspend)
1086 {
1087 pmcRegisterDeviceStateUpdateInd(smeContext,
1088 hdd_PowerStateChangedCB, pHddCtx);
1089 }
1090}
1091
1092void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1093{
1094 v_CONTEXT_t pVosContext;
1095 tHalHandle smeContext;
1096
1097 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1098 if (NULL == pVosContext)
1099 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001100 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 return;
1102 }
1103 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1104 if (NULL == smeContext)
1105 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001106 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 return;
1108 }
1109
1110 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1111 pHddCtx->cfg_ini->nEnableSuspend)
1112 {
1113 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1114 }
1115}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301116
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301117#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301118void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301119{
1120 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301121 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301122 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1123
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301124 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301125 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301126 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1127 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1128 {
1129 vos_mem_copy(&hddGtkOffloadReqParams,
1130 &pHddStaCtx->gtkOffloadReqParams,
1131 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301132
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301133 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1134 &hddGtkOffloadReqParams, pAdapter->sessionId);
1135 if (eHAL_STATUS_SUCCESS != ret)
1136 {
1137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1138 "%s: sme_SetGTKOffload failed, returned %d",
1139 __func__, ret);
1140 return;
1141 }
1142
1143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1144 "%s: sme_SetGTKOffload successfull", __func__);
1145 }
1146
1147 }
1148 else
1149 {
1150 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1151 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1152 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1153 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1154 {
1155
1156 /* Host driver has previously offloaded GTK rekey */
1157 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301158 wlan_hdd_cfg80211_update_replayCounterCallback,
1159 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301160 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301161
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301162 {
1163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1164 "%s: sme_GetGTKOffload failed, returned %d",
1165 __func__, ret);
1166 return;
1167 }
1168 else
1169 {
1170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1171 "%s: sme_GetGTKOffload successful",
1172 __func__);
1173
1174 /* Sending GTK offload dissable */
1175 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1176 sizeof (tSirGtkOffloadParams));
1177 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1178 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301179 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301180 if (eHAL_STATUS_SUCCESS != ret)
1181 {
1182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1183 "%s: failed to dissable GTK offload, returned %d",
1184 __func__, ret);
1185 return;
1186 }
1187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1188 "%s: successfully dissabled GTK offload request to HAL",
1189 __func__);
1190 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301191 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301192 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301193 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301194}
1195#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001196
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001197void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001198{
1199 hdd_context_t *pHddCtx = NULL;
1200 hdd_adapter_t *pAdapter = NULL;
1201 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1202 VOS_STATUS status;
1203 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001204
Jeff Johnson295189b2012-06-20 16:38:30 -07001205 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1206
1207 //Get the global VOSS context.
1208 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1209 if(!pVosContext) {
1210 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1211 return;
1212 }
1213
1214 //Get the HDD context.
1215 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1216
1217 if(!pHddCtx) {
1218 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1219 return;
1220 }
1221
1222 if (pHddCtx->isLogpInProgress) {
1223 hddLog(VOS_TRACE_LEVEL_INFO,
1224 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1225 return;
1226 }
1227
Jeff Johnson295189b2012-06-20 16:38:30 -07001228 pHddCtx->hdd_wlan_suspended = FALSE;
1229 /*loop through all adapters. Concurrency */
1230 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1231
1232 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1233 {
1234 pAdapter = pAdapterNode->pAdapter;
1235 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001236 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001237 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001238 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1240 pAdapterNode = pNext;
1241 continue;
1242 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301243
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301244
Jeff Johnson295189b2012-06-20 16:38:30 -07001245#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1246 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1247 {
1248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1249 hdd_exit_deep_sleep(pAdapter);
1250 }
1251#endif
1252
1253 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1254 {
1255 /*Switch back to DTIM 1*/
1256 tSirSetPowerParamsReq powerRequest = { 0 };
1257
1258 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1259 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001260 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001261
1262 /*Disabled ModulatedDTIM if enabled on suspend*/
1263 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1264 powerRequest.uDTIMPeriod = 0;
1265
1266 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1267 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1268 NULL, eANI_BOOLEAN_FALSE);
1269 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1270 NULL, eANI_BOOLEAN_FALSE);
1271
1272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1273 "Switch to DTIM%d \n",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001274 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001275
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301276 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1277 {
1278 /* put the device into full power */
1279 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001280
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301281 /* put the device back into BMPS */
1282 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001283
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301284 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1285 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001286 }
1287
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301288 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001289 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1290 pAdapterNode = pNext;
1291 }
1292
1293#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1294 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1295 {
1296 hdd_exit_standby(pHddCtx);
1297 }
1298#endif
1299
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 return;
1301}
1302
Jeff Johnson295189b2012-06-20 16:38:30 -07001303VOS_STATUS hdd_wlan_reset_initialization(void)
1304{
Jeff Johnson295189b2012-06-20 16:38:30 -07001305 v_CONTEXT_t pVosContext = NULL;
1306
1307 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1308
1309 //Get the global VOSS context.
1310 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1311 if(!pVosContext)
1312 {
1313 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1314 return VOS_STATUS_E_FAILURE;
1315 }
1316
1317 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1318
1319 // Prevent the phone from going to sleep
1320 hdd_prevent_suspend();
1321
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 return VOS_STATUS_SUCCESS;
1323}
1324
1325
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001326/*
1327 * Based on the ioctl command recieved by HDD, put WLAN driver
1328 * into the quiet mode. This is the same as the early suspend
1329 * notification that driver used to listen
1330 */
1331void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001332{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001333 if (suspend)
1334 hdd_suspend_wlan();
1335 else
1336 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001337}
1338
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001339static void hdd_ssr_timer_init(void)
1340{
1341 init_timer(&ssr_timer);
1342}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001343
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001344static void hdd_ssr_timer_del(void)
1345{
1346 del_timer(&ssr_timer);
1347 ssr_timer_started = false;
1348}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001349
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001350static void hdd_ssr_timer_cb(unsigned long data)
1351{
1352 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
1353 VOS_BUG(0);
1354}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001355
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001356static void hdd_ssr_timer_start(int msec)
1357{
1358 if(ssr_timer_started)
1359 {
1360 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1361 ,__func__);
1362 }
1363 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1364 ssr_timer.function = hdd_ssr_timer_cb;
1365 add_timer(&ssr_timer);
1366 ssr_timer_started = true;
1367}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001368
Jeff Johnson295189b2012-06-20 16:38:30 -07001369/* the HDD interface to WLAN driver shutdown,
1370 * the primary shutdown function in SSR
1371 */
1372VOS_STATUS hdd_wlan_shutdown(void)
1373{
1374 VOS_STATUS vosStatus;
1375 v_CONTEXT_t pVosContext = NULL;
1376 hdd_context_t *pHddCtx = NULL;
1377 pVosSchedContext vosSchedContext = NULL;
1378
1379 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1380
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001381 /* if re-init never happens, then do SSR1 */
1382 hdd_ssr_timer_init();
1383 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1384
Jeff Johnson295189b2012-06-20 16:38:30 -07001385 /* Get the global VOSS context. */
1386 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1387 if(!pVosContext) {
1388 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1389 return VOS_STATUS_E_FAILURE;
1390 }
1391 /* Get the HDD context. */
1392 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1393 if(!pHddCtx) {
1394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1395 return VOS_STATUS_E_FAILURE;
1396 }
1397 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001398 /* DeRegister with platform driver as client for Suspend/Resume */
1399 vosStatus = hddDeregisterPmOps(pHddCtx);
1400 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1401 {
1402 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1403 }
1404
1405 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1406 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1407 {
1408 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1409 }
1410
1411 /* Disable IMPS/BMPS as we do not want the device to enter any power
1412 * save mode on its own during reset sequence
1413 */
1414 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1415 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1416 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1417
1418 vosSchedContext = get_vos_sched_ctxt();
1419
1420 /* Wakeup all driver threads */
1421 if(TRUE == pHddCtx->isMcThreadSuspended){
1422 complete(&vosSchedContext->ResumeMcEvent);
1423 pHddCtx->isMcThreadSuspended= FALSE;
1424 }
1425 if(TRUE == pHddCtx->isTxThreadSuspended){
1426 complete(&vosSchedContext->ResumeTxEvent);
1427 pHddCtx->isTxThreadSuspended= FALSE;
1428 }
1429 if(TRUE == pHddCtx->isRxThreadSuspended){
1430 complete(&vosSchedContext->ResumeRxEvent);
1431 pHddCtx->isRxThreadSuspended= FALSE;
1432 }
1433 /* Reset the Suspend Variable */
1434 pHddCtx->isWlanSuspended = FALSE;
1435
1436 /* Stop all the threads; we do not want any messages to be a processed,
1437 * any more and the best way to ensure that is to terminate the threads
1438 * gracefully.
1439 */
1440 /* Wait for MC to exit */
1441 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1442 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1443 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1444 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1445 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1446
1447 /* Wait for TX to exit */
1448 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1449 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1450 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1451 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1452 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1453
1454 /* Wait for RX to exit */
1455 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1456 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1457 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1458 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1459 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1460
1461#ifdef WLAN_BTAMP_FEATURE
1462 vosStatus = WLANBAP_Stop(pVosContext);
1463 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1464 {
1465 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1466 "%s: Failed to stop BAP",__func__);
1467 }
1468#endif //WLAN_BTAMP_FEATURE
1469 vosStatus = vos_wda_shutdown(pVosContext);
1470 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1471
1472 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1473 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1474 * on threads being running to process the SYS Stop
1475 */
1476 vosStatus = sme_Stop(pHddCtx->hHal, TRUE);
1477 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1478
1479 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1480 /* Stop MAC (PE and HAL) */
1481 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1482 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1483
1484 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1485 /* Stop TL */
1486 vosStatus = WLANTL_Stop(pVosContext);
1487 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1488
Jeff Johnson295189b2012-06-20 16:38:30 -07001489 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001490 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1491 /* Clean up message queues of TX and MC thread */
1492 vos_sched_flush_mc_mqs(vosSchedContext);
1493 vos_sched_flush_tx_mqs(vosSchedContext);
1494 vos_sched_flush_rx_mqs(vosSchedContext);
1495
1496 /* Deinit all the TX and MC queues */
1497 vos_sched_deinit_mqs(vosSchedContext);
1498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1499
1500 /* shutdown VOSS */
1501 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301502
1503 /*mac context has already been released in mac_close call
1504 so setting it to NULL in hdd context*/
1505 pHddCtx->hHal = (tHalHandle)NULL;
1506
Jeff Johnson295189b2012-06-20 16:38:30 -07001507 if (free_riva_power_on_lock("wlan"))
1508 {
1509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1510 __func__);
1511 }
1512 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1513 ,__func__);
1514 return VOS_STATUS_SUCCESS;
1515}
1516
1517
1518
1519/* the HDD interface to WLAN driver re-init.
1520 * This is called to initialize/start WLAN driver after a shutdown.
1521 */
1522VOS_STATUS hdd_wlan_re_init(void)
1523{
1524 VOS_STATUS vosStatus;
1525 v_CONTEXT_t pVosContext = NULL;
1526 hdd_context_t *pHddCtx = NULL;
1527 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001528#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1529 int max_retries = 0;
1530#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001531#ifdef WLAN_BTAMP_FEATURE
1532 hdd_config_t *pConfig = NULL;
1533 WLANBAP_ConfigType btAmpConfig;
1534#endif
1535
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001536 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001537 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001538
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001539#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1540 /* wait until WCNSS driver downloads NV */
1541 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1542 msleep(1000);
1543 }
1544 if (max_retries >= 5) {
1545 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1546 goto err_re_init;
1547 }
1548#endif
1549
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001550 /* The driver should always be initialized in STA mode after SSR */
1551 hdd_set_conparam(0);
1552
Jeff Johnson295189b2012-06-20 16:38:30 -07001553 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1554 vosStatus = vos_open(&pVosContext, 0);
1555 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1556 {
1557 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1558 goto err_re_init;
1559 }
1560
1561 /* Get the HDD context. */
1562 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1563 if(!pHddCtx)
1564 {
1565 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1566 goto err_vosclose;
1567 }
1568
1569 /* Save the hal context in Adapter */
1570 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1571 if ( NULL == pHddCtx->hHal )
1572 {
1573 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1574 goto err_vosclose;
1575 }
1576
1577 /* Set the SME configuration parameters. */
1578 vosStatus = hdd_set_sme_config(pHddCtx);
1579 if ( VOS_STATUS_SUCCESS != vosStatus )
1580 {
1581 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1582 goto err_vosclose;
1583 }
1584
1585 /* Initialize the WMM module */
1586 vosStatus = hdd_wmm_init(pHddCtx);
1587 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1588 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001589 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001590 goto err_vosclose;
1591 }
1592
1593 vosStatus = vos_preStart( pHddCtx->pvosContext );
1594 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1595 {
1596 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1597 goto err_vosclose;
1598 }
1599
1600 /* In the integrated architecture we update the configuration from
1601 the INI file and from NV before vOSS has been started so that
1602 the final contents are available to send down to the cCPU */
1603 /* Apply the cfg.ini to cfg.dat */
1604 if (FALSE == hdd_update_config_dat(pHddCtx))
1605 {
1606 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1607 goto err_vosclose;
1608 }
1609
1610 /* Set the MAC Address, currently this is used by HAL to add self sta.
1611 * Remove this once self sta is added as part of session open. */
1612 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1613 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1614 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1615 if (!HAL_STATUS_SUCCESS(halStatus))
1616 {
1617 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1618 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1619 goto err_vosclose;
1620 }
1621
1622 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1623 Note: Firmware image will be read and downloaded inside vos_start API */
1624 vosStatus = vos_start( pVosContext );
1625 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1626 {
1627 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1628 goto err_vosclose;
1629 }
1630
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001631 /* Exchange capability info between Host and FW and also get versioning info from FW */
1632 hdd_exchange_version_and_caps(pHddCtx);
1633
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 vosStatus = hdd_post_voss_start_config( pHddCtx );
1635 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1636 {
1637 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1638 __func__);
1639 goto err_vosstop;
1640 }
1641
1642#ifdef WLAN_BTAMP_FEATURE
1643 vosStatus = WLANBAP_Open(pVosContext);
1644 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1645 {
1646 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1647 "%s: Failed to open BAP",__func__);
1648 goto err_vosstop;
1649 }
1650 vosStatus = BSL_Init(pVosContext);
1651 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1652 {
1653 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1654 "%s: Failed to Init BSL",__func__);
1655 goto err_bap_close;
1656 }
1657 vosStatus = WLANBAP_Start(pVosContext);
1658 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1659 {
1660 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1661 "%s: Failed to start TL",__func__);
1662 goto err_bap_close;
1663 }
1664 pConfig = pHddCtx->cfg_ini;
1665 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1666 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1667#endif //WLAN_BTAMP_FEATURE
1668
1669 /* Restart all adapters */
1670 hdd_start_all_adapters(pHddCtx);
1671 pHddCtx->isLogpInProgress = FALSE;
1672 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001674
1675 /* Register with platform driver as client for Suspend/Resume */
1676 vosStatus = hddRegisterPmOps(pHddCtx);
1677 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1678 {
1679 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1680 goto err_bap_stop;
1681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001682 /* Allow the phone to go to sleep */
1683 hdd_allow_suspend();
1684 /* register for riva power on lock */
1685 if (req_riva_power_on_lock("wlan"))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1688 __func__);
1689 goto err_unregister_pmops;
1690 }
1691 goto success;
1692
1693err_unregister_pmops:
1694 hddDeregisterPmOps(pHddCtx);
1695
1696err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001697#ifdef CONFIG_HAS_EARLYSUSPEND
1698 hdd_unregister_mcast_bcast_filter(pHddCtx);
1699#endif
1700 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001701#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001702 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001703#endif
1704
1705#ifdef WLAN_BTAMP_FEATURE
1706err_bap_close:
1707 WLANBAP_Close(pVosContext);
1708#endif
1709
1710err_vosstop:
1711 vos_stop(pVosContext);
1712
1713err_vosclose:
1714 vos_close(pVosContext);
1715 vos_sched_close(pVosContext);
1716 if (pHddCtx)
1717 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001718 /* Unregister the Net Device Notifier */
1719 unregister_netdevice_notifier(&hdd_netdev_notifier);
1720 /* Clean up HDD Nlink Service */
1721 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1722 nl_srv_exit();
Jeff Johnson295189b2012-06-20 16:38:30 -07001723 /* Free up dynamically allocated members inside HDD Adapter */
1724 kfree(pHddCtx->cfg_ini);
1725 pHddCtx->cfg_ini= NULL;
1726
Jeff Johnson295189b2012-06-20 16:38:30 -07001727 wiphy_unregister(pHddCtx->wiphy);
1728 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 }
1730 vos_preClose(&pVosContext);
1731
1732#ifdef MEMORY_DEBUG
1733 vos_mem_exit();
1734#endif
1735
1736err_re_init:
1737 /* Allow the phone to go to sleep */
1738 hdd_allow_suspend();
Sameer Thalappil451ebb92013-06-28 15:49:58 -07001739 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001740 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001741
1742success:
1743 /* Trigger replay of BTC events */
1744 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1745 return VOS_STATUS_SUCCESS;
1746}