blob: 18634ececf7299c7d942f75c48aa95ed1b775723 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08005 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006/**=============================================================================
7* wlan_hdd_early_suspend.c
8*
9* \brief power management functions
10*
11* Description
12* Copyright 2009 (c) Qualcomm, Incorporated.
13* All Rights Reserved.
14* Qualcomm Confidential and Proprietary.
15*
16==============================================================================**/
17/* $HEADER$ */
18
19/**-----------------------------------------------------------------------------
20* Include files
21* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070022
23#include <linux/pm.h>
24#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070025#include <wlan_hdd_includes.h>
26#include <wlan_qct_driver.h>
27#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070028
29#include "halTypes.h"
30#include "sme_Api.h"
31#include <vos_api.h>
32#include "vos_power.h"
33#include <vos_sched.h>
34#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070035#include <wlan_qct_sys.h>
36#include <wlan_btc_svc.h>
37#include <wlan_nlink_common.h>
38#include <wlan_hdd_main.h>
39#include <wlan_hdd_assoc.h>
40#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070041#include <wlan_nlink_srv.h>
42#include <wlan_hdd_misc.h>
43
Jeff Johnson295189b2012-06-20 16:38:30 -070044#include <linux/semaphore.h>
45#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070046#include "cfgApi.h"
47
48#ifdef WLAN_BTAMP_FEATURE
49#include "bapApi.h"
50#include "bap_hdd_main.h"
51#include "bap_hdd_misc.h"
52#endif
53
Jeff Johnsone7245742012-09-05 17:12:55 -070054#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070055#include <linux/inetdevice.h>
56#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053057#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053058#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070059/**-----------------------------------------------------------------------------
60* Preprocessor definitions and constants
61* ----------------------------------------------------------------------------*/
62
63/**-----------------------------------------------------------------------------
64* Type declarations
65* ----------------------------------------------------------------------------*/
66
67/**-----------------------------------------------------------------------------
68* Function and variables declarations
69* ----------------------------------------------------------------------------*/
70#include "wlan_hdd_power.h"
71#include "wlan_hdd_packet_filtering.h"
72
Sameer Thalappile5637f42013-08-07 15:46:55 -070073#define HDD_SSR_BRING_UP_TIME 180000
Jeff Johnson295189b2012-06-20 16:38:30 -070074
75static eHalStatus g_full_pwr_status;
76static eHalStatus g_standby_status;
77
78extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
79extern VOS_STATUS vos_chipExitDeepSleepVREGHandler(
80 vos_call_status_type* status,
81 vos_power_cb_type callback,
82 v_PVOID_t user_data);
83extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070084
85extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -070086extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -070087
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -070088static struct timer_list ssr_timer;
89static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -070090
91//Callback invoked by PMC to report status of standby request
92void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
93{
94 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
95 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
96 g_standby_status = status;
97
98 if(eHAL_STATUS_SUCCESS == status)
99 {
100 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
101 }
102 else
103 {
104 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
105 }
106
107 complete(&pHddCtx->standby_comp_var);
108}
109
110//Callback invoked by PMC to report status of full power request
111void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
112{
113 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
114 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
115 g_full_pwr_status = status;
116
117 if(eHAL_STATUS_SUCCESS == status)
118 {
119 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
120 }
121 else
122 {
123 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
124 }
125
126 complete(&pHddCtx->full_pwr_comp_var);
127}
128
129eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
130{
131 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530132 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700133
134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
135 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
136
137 g_full_pwr_status = eHAL_STATUS_FAILURE;
138 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
139 eSME_FULL_PWR_NEEDED_BY_HDD);
140
141 if(status == eHAL_STATUS_PMC_PENDING)
142 {
143 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530144 ret = wait_for_completion_interruptible_timeout(
145 &pHddCtx->full_pwr_comp_var,
146 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
147 if (0 >= ret)
148 {
149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
150 __func__, ret);
151 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700152 status = g_full_pwr_status;
153 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
154 {
155 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
156 VOS_ASSERT(0);
157 goto failure;
158 }
159 }
160 else if(status != eHAL_STATUS_SUCCESS)
161 {
162 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
163 __func__, status);
164 VOS_ASSERT(0);
165 goto failure;
166 }
167 else
168 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
169
170failure:
171 //No blocking to reduce latency. No other device should be depending on WLAN
172 //to finish resume and WLAN won't be instantly on after resume
173 return status;
174}
175
176
177//Helper routine to put the chip into standby
178VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
179{
180 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
181 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530182 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700183
184 //Disable IMPS/BMPS as we do not want the device to enter any power
185 //save mode on its own during suspend sequence
186 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
187 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
188
189 //Note we do not disable queues unnecessarily. Queues should already be disabled
190 //if STA is disconnected or the queue will be disabled as and when disconnect
191 //happens because of standby procedure.
192
193 //Ensure that device is in full power first. There is scope for optimization
194 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
195 //Core s/w needs to be optimized to handle this. Until then we request full
196 //power before issuing request for standby.
197 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
198 g_full_pwr_status = eHAL_STATUS_FAILURE;
199 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
200 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
201
202 if(halStatus == eHAL_STATUS_PMC_PENDING)
203 {
204 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530205 ret = wait_for_completion_interruptible_timeout(
206 &pHddCtx->full_pwr_comp_var,
207 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
208 if (0 >= ret)
209 {
210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
211 __func__, ret);
212 }
213
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
215 {
216 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
217 VOS_ASSERT(0);
218 vosStatus = VOS_STATUS_E_FAILURE;
219 goto failure;
220 }
221 }
222 else if(halStatus != eHAL_STATUS_SUCCESS)
223 {
224 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
225 __func__, halStatus);
226 VOS_ASSERT(0);
227 vosStatus = VOS_STATUS_E_FAILURE;
228 goto failure;
229 }
230
231 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
232 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
233 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
234 }
235
236 //Request standby. Standby will cause the STA to disassociate first. TX queues
237 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
238 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
239 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
240 //when there are concurrent sessions.
241 INIT_COMPLETION(pHddCtx->standby_comp_var);
242 g_standby_status = eHAL_STATUS_FAILURE;
243 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
244
245 if (halStatus == eHAL_STATUS_PMC_PENDING)
246 {
247 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530248 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700249 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530250 if (0 >= ret)
251 {
252 hddLog(VOS_TRACE_LEVEL_ERROR,
253 FL("wait on standby_comp_var failed %ld"), ret);
254 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
256 {
257 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
258 VOS_ASSERT(0);
259 vosStatus = VOS_STATUS_E_FAILURE;
260 goto failure;
261 }
262 }
263 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
264 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
265 __func__, halStatus);
266 VOS_ASSERT(0);
267 vosStatus = VOS_STATUS_E_FAILURE;
268 goto failure;
269 }
270 else
271 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
272
273failure:
274 //Restore IMPS config
275 if(pHddCtx->cfg_ini->fIsImpsEnabled)
276 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
277
278 //Restore BMPS config
279 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
280 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
281
282 return vosStatus;
283}
284
285
286//Helper routine for Deep sleep entry
287VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
288{
289 eHalStatus halStatus;
290 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
291 vos_call_status_type callType;
c_hpothuffdb5272013-10-02 16:42:35 +0530292 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800293
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 //Stop the Interface TX queue.
295 netif_tx_disable(pAdapter->dev);
296 netif_carrier_off(pAdapter->dev);
297
298 //Disable IMPS,BMPS as we do not want the device to enter any power
299 //save mode on it own during suspend sequence
300 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
301 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
302
303 //Ensure that device is in full power as we will touch H/W during vos_Stop
304 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
305 g_full_pwr_status = eHAL_STATUS_FAILURE;
306 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
307 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
308
309 if(halStatus == eHAL_STATUS_PMC_PENDING)
310 {
311 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530312 ret = wait_for_completion_interruptible_timeout(
313 &pHddCtx->full_pwr_comp_var,
314 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
315 if (0 >= ret)
316 {
317 hddLog(VOS_TRACE_LEVEL_ERROR,
318 FL("wait on full_pwr_comp_var failed %ld"), ret);
319 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
321 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
322 VOS_ASSERT(0);
323 }
324 }
325 else if(halStatus != eHAL_STATUS_SUCCESS)
326 {
327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
328 VOS_ASSERT(0);
329 }
330
331 //Issue a disconnect. This is required to inform the supplicant that
332 //STA is getting disassociated and for GUI to be updated properly
333 INIT_COMPLETION(pAdapter->disconnect_comp_var);
334 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
335
336 //Success implies disconnect command got queued up successfully
337 if(halStatus == eHAL_STATUS_SUCCESS)
338 {
339 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530340 ret = wait_for_completion_interruptible_timeout(
341 &pAdapter->disconnect_comp_var,
342 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
343 if (0 >= ret)
344 {
345 hddLog(VOS_TRACE_LEVEL_ERROR,
346 FL("wait on disconnect_comp_var failed %ld"), ret);
347 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700348 }
349
350
351 //None of the steps should fail after this. Continue even in case of failure
352 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530353 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
354 {
355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
356 __func__, vosStatus);
357 VOS_ASSERT(0);
358 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700359
Jeff Johnson295189b2012-06-20 16:38:30 -0700360 vosStatus = vos_chipAssertDeepSleep( &callType, NULL, NULL );
c_hpothuffdb5272013-10-02 16:42:35 +0530361 if( VOS_IS_STATUS_SUCCESS( vosStatus ))
362 {
363 hddLog(VOS_TRACE_LEVEL_ERROR,
364 FL("vos_chipAssertDeepSleep return failed %d"), vosStatus);
365 VOS_ASSERT(0);
366 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700367
368 //Vote off any PMIC voltage supplies
369 vosStatus = vos_chipPowerDown(NULL, NULL, NULL);
c_hpothuffdb5272013-10-02 16:42:35 +0530370 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
371 {
372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_chipPowerDown return failed %d",
373 __func__, vosStatus);
374 VOS_ASSERT(0);
375 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700376
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
378
379 //Restore IMPS config
380 if(pHddCtx->cfg_ini->fIsImpsEnabled)
381 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
382
383 //Restore BMPS config
384 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
385 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
386
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 return vosStatus;
388}
389
390VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
391{
392 VOS_STATUS vosStatus;
393 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700394
395 //Power Up Libra WLAN card first if not already powered up
396 vosStatus = vos_chipPowerUp(NULL,NULL,NULL);
397 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
398 {
c_hpothuffdb5272013-10-02 16:42:35 +0530399 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN not Powered Up."
Jeff Johnson295189b2012-06-20 16:38:30 -0700400 "exiting", __func__);
401 goto err_deep_sleep;
402 }
403
Jeff Johnson295189b2012-06-20 16:38:30 -0700404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
405 "%s: calling hdd_set_sme_config",__func__);
406 vosStatus = hdd_set_sme_config( pHddCtx );
407 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
408 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
409 {
410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
411 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700412 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700413 }
414
415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
416 "%s: calling vos_start",__func__);
417 vosStatus = vos_start( pHddCtx->pvosContext );
418 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
419 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
420 {
421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
422 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700423 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700424 }
425
426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
427 "%s: calling hdd_post_voss_start_config",__func__);
428 vosStatus = hdd_post_voss_start_config( pHddCtx );
429 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
430 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
431 {
432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
433 "%s: Failed in hdd_post_voss_start_config",__func__);
434 goto err_voss_stop;
435 }
436
437
438 //Open a SME session for future operation
439 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700440 (tANI_U8 *)&pAdapter->macAddressCurrent,
441 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700442 if ( !HAL_STATUS_SUCCESS( halStatus ) )
443 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700444 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700445 halStatus, halStatus );
446 goto err_voss_stop;
447
448 }
449
450 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
451
452 //Trigger the initial scan
453 hdd_wlan_initial_scan(pHddCtx);
454
455 return VOS_STATUS_SUCCESS;
456
457err_voss_stop:
458 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700459err_deep_sleep:
460 return VOS_STATUS_E_FAILURE;
461
462}
463
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530464/*
465 * Function: hdd_conf_hostoffload
466 * Central function to configure the supported offloads,
467 * either enable or disable them.
468 */
469void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
470{
471 hdd_context_t *pHddCtx = NULL;
472 v_CONTEXT_t *pVosContext = NULL;
473 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
474
475 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
476 fenable);
477
478 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
479
480 if (NULL == pVosContext)
481 {
482 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
483 return;
484 }
485
486 //Get the HDD context.
487 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
488
489 if (NULL == pHddCtx)
490 {
491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
492 return;
493 }
494
495 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
496 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
497 {
498 if (fenable)
499 {
500 if (eConnectionState_Associated ==
501 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
502 {
503 if ((pHddCtx->cfg_ini->fhostArpOffload))
504 {
505 /*
506 * Configure the ARP Offload.
507 * Even if it fails we have to reconfigure the MC/BC
508 * filter flag as we want RIVA not to drop BroadCast
509 * Packets
510 */
511 hddLog(VOS_TRACE_LEVEL_INFO,
512 FL("Calling ARP Offload with flag: %d"), fenable);
513 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
514 pHddCtx->configuredMcastBcastFilter &=
515 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
516
517 if (!VOS_IS_STATUS_SUCCESS(vstatus))
518 {
519 hddLog(VOS_TRACE_LEVEL_ERROR,
520 "Failed to enable ARPOFfloadFeature %d",
521 vstatus);
522 }
523 }
524 //Configure GTK_OFFLOAD
525#ifdef WLAN_FEATURE_GTK_OFFLOAD
526 hdd_conf_gtk_offload(pAdapter, fenable);
527#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530528
529#ifdef WLAN_NS_OFFLOAD
530 if (pHddCtx->cfg_ini->fhostNSOffload)
531 {
532 /*
533 * Configure the NS Offload.
534 * Even if it fails we have to reconfigure the MC/BC filter flag
535 * as we want RIVA not to drop Multicast Packets
536 */
537
538 hddLog(VOS_TRACE_LEVEL_INFO,
539 FL("Calling NS Offload with flag: %d"), fenable);
540 hdd_conf_ns_offload(pAdapter, fenable);
541 pHddCtx->configuredMcastBcastFilter &=
542 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
543 }
544#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530545 }
546 }
547 else
548 {
549 //Disable ARPOFFLOAD
550 if (pHddCtx->cfg_ini->fhostArpOffload)
551 {
552 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
553 if (!VOS_IS_STATUS_SUCCESS(vstatus))
554 {
555 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530556 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530557 }
558 }
559 //Disable GTK_OFFLOAD
560#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530561 hdd_conf_gtk_offload(pAdapter, fenable);
562#endif
563
564#ifdef WLAN_NS_OFFLOAD
565 //Disable NSOFFLOAD
566 if (pHddCtx->cfg_ini->fhostNSOffload)
567 {
568 hdd_conf_ns_offload(pAdapter, fenable);
569 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530570#endif
571 }
572 }
573 return;
574}
575
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530576#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530577void hdd_ipv6_notifier_work_queue(struct work_struct *work)
578{
579 hdd_adapter_t* pAdapter =
580 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
581 hdd_context_t *pHddCtx;
582 int status;
583
584 hddLog(LOG1, FL("Reconfiguring NS Offload"));
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530585
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530586 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
587 status = wlan_hdd_validate_context(pHddCtx);
588 if (0 != status)
589 {
590 hddLog(LOGE, FL("HDD context is invalid"));
591 return;
592 }
593
Deepthi Gowri5933f402014-01-23 17:48:24 +0530594 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
595 {
596 pHddCtx->sus_res_mcastbcast_filter =
597 pHddCtx->configuredMcastBcastFilter;
598 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
599 }
600
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530601 if ((eConnectionState_Associated ==
602 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530603 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530604 {
605 // This invocation being part of the IPv6 registration callback,
606 // we are passing second parameter as 2 to avoid registration
607 // of IPv6 notifier again.
608 hdd_conf_ns_offload(pAdapter, 2);
609 }
610}
611
612static int wlan_hdd_ipv6_changed(struct notifier_block *nb,
613 unsigned long data, void *arg)
614{
615 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
616 struct net_device *ndev = ifa->idev->dev;
617 hdd_adapter_t *pAdapter =
618 container_of(nb, struct hdd_adapter_s, ipv6_notifier);
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530619 hdd_context_t *pHddCtx;
620 int status;
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530621
622 if (pAdapter && pAdapter->dev == ndev)
623 {
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530624 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
625 status = wlan_hdd_validate_context(pHddCtx);
626 if (0 != status)
627 {
628 hddLog(LOGE, FL("HDD context is invalid"));
629 return NOTIFY_DONE;
630 }
631
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530632 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
633 }
634
635 return NOTIFY_DONE;
636}
637
638/**----------------------------------------------------------------------------
639
640 \brief hdd_conf_ns_offload() - Configure NS offload
641
642 Called during SUSPEND to configure the NS offload (MC BC filter) which
643 reduces power consumption.
644
645 \param - pAdapter - Adapter context for which NS offload is to be configured
646 \param - fenable - 0 - disable.
647 1 - enable. (with IPv6 notifier registration)
648 2 - enable. (without IPv6 notifier registration)
649
650 \return - void
651
652 ---------------------------------------------------------------------------*/
653void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530654{
655 struct inet6_dev *in6_dev;
656 struct inet6_ifaddr *ifp;
657 struct list_head *p;
658 tANI_U8 selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN] = {{0,}};
659 tANI_BOOLEAN selfIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0};
660 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530661 hdd_context_t *pHddCtx;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530662
663 int i =0;
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530664 int ret =0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530665 eHalStatus returnStatus;
666
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530667 ENTER();
668 hddLog(LOG1, FL(" fenable = %d"), fenable);
669
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530670 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
671
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530672 if (fenable)
673 {
674 in6_dev = __in6_dev_get(pAdapter->dev);
675 if (NULL != in6_dev)
676 {
677 //read_lock_bh(&in6_dev->lock);
678 list_for_each(p, &in6_dev->addr_list)
679 {
680 ifp = list_entry(p, struct inet6_ifaddr, if_list);
681 switch(ipv6_addr_src_scope(&ifp->addr))
682 {
683 case IPV6_ADDR_SCOPE_LINKLOCAL:
684 vos_mem_copy(&selfIPv6Addr[0], &ifp->addr.s6_addr,
685 sizeof(ifp->addr.s6_addr));
686 selfIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530687 hddLog (VOS_TRACE_LEVEL_INFO,
688 "Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6",
689 selfIPv6Addr[0]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530690 break;
691 case IPV6_ADDR_SCOPE_GLOBAL:
692 vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr,
693 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530694 selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID;
695 hddLog (VOS_TRACE_LEVEL_INFO,
696 "Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6",
697 selfIPv6Addr[1]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530698 break;
699 default:
700 hddLog(LOGE, "The Scope %d is not supported",
701 ipv6_addr_src_scope(&ifp->addr));
702 }
703
704 }
705 //read_unlock_bh(&in6_dev->lock);
706 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
707 for (i =0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
708 {
709 if (selfIPv6AddrValid[i])
710 {
711 //Filling up the request structure
712 /* Filling the selfIPv6Addr with solicited address
713 * A Solicited-Node multicast address is created by
714 * taking the last 24 bits of a unicast or anycast
715 * address and appending them to the prefix
716 *
717 * FF02:0000:0000:0000:0000:0001:FFXX:XX
718 *
719 * here XX is the unicast/anycast bits
720 */
721 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
722 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
723 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
724 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
725 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = selfIPv6Addr[i][13];
726 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = selfIPv6Addr[i][14];
727 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = selfIPv6Addr[i][15];
728 offLoadRequest.nsOffloadInfo.slotIdx = i;
729
730 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
731 &selfIPv6Addr[i][0], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
732 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
733 &pAdapter->macAddressCurrent.bytes,
734 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
735
736 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
737 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
738 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
739
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530740 hddLog (VOS_TRACE_LEVEL_INFO,
741 "configuredMcastBcastFilter: %d",pHddCtx->configuredMcastBcastFilter);
742
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530743 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
744 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
745 pHddCtx->sus_res_mcastbcast_filter) ||
746 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
747 pHddCtx->sus_res_mcastbcast_filter)))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530748 {
749 hddLog (VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800750 "Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE");
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530751 offLoadRequest.enableOrDisable =
752 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
753 }
754
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530755 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
756 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
757 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
758
759 hddLog (VOS_TRACE_LEVEL_INFO,
760 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
761 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
762 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
763
764 //Configure the Firmware with this
765 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
766 pAdapter->sessionId, &offLoadRequest);
767 if(eHAL_STATUS_SUCCESS != returnStatus)
768 {
769 hddLog(VOS_TRACE_LEVEL_ERROR,
770 FL("Failed to enable HostOffload feature with status: %d"),
771 returnStatus);
772 }
773 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
774 }
775 }
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530776 if (fenable == 1 && !pAdapter->ipv6_notifier_registered)
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530777 {
778 // Register IPv6 notifier to notify if any change in IP
779 // So that we can reconfigure the offload parameters
780 pAdapter->ipv6_notifier.notifier_call =
781 wlan_hdd_ipv6_changed;
782 ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier);
783 if (ret)
784 {
785 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
786 }
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530787 else
788 {
789 hddLog(LOG1, FL("Registered IPv6 notifier"));
790 pAdapter->ipv6_notifier_registered = true;
791 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530792 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530793 }
794 else
795 {
796 hddLog(VOS_TRACE_LEVEL_ERROR,
797 FL("IPv6 dev does not exist. Failed to request NSOffload"));
798 return;
799 }
800 }
801 else
802 {
803 //Disable NSOffload
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530804 if (pAdapter->ipv6_notifier_registered)
805 {
806 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
807 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
808 pAdapter->ipv6_notifier_registered = false;
809 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530810 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
811 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
812 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
813
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530814 //Disable NSOffload on all slots
815 for (i = 0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
816 {
817 offLoadRequest.nsOffloadInfo.slotIdx = i;
818 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530819 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
820 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530821 {
822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disable NSOflload"
823 " on slot %d"), i);
824 }
825 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530826 }
827 return;
828}
829#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530830
831void hdd_ipv4_notifier_work_queue(struct work_struct *work)
832{
833 hdd_adapter_t* pAdapter =
834 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
835 hdd_context_t *pHddCtx;
836 int status;
837
838 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
839 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
840 status = wlan_hdd_validate_context(pHddCtx);
841 if (0 != status)
842 {
843 hddLog(LOGE, FL("HDD context is invalid"));
844 return;
845 }
846
Deepthi Gowri5933f402014-01-23 17:48:24 +0530847 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
848 {
849 pHddCtx->sus_res_mcastbcast_filter =
850 pHddCtx->configuredMcastBcastFilter;
851 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
852 }
853
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530854 if ((eConnectionState_Associated ==
855 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530856 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530857 {
858 // This invocation being part of the IPv4 registration callback,
859 // we are passing second parameter as 2 to avoid registration
860 // of IPv4 notifier again.
861 hdd_conf_arp_offload(pAdapter, 2);
862 }
863}
864
865static int wlan_hdd_ipv4_changed(struct notifier_block *nb,
866 unsigned long data, void *arg)
867{
868 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
869 struct in_ifaddr **ifap = NULL;
870 struct in_device *in_dev;
871
872 struct net_device *ndev = ifa->ifa_dev->dev;
873 hdd_adapter_t *pAdapter =
874 container_of(nb, struct hdd_adapter_s, ipv4_notifier);
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530875 hdd_context_t *pHddCtx;
876 int status;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530877 if (pAdapter && pAdapter->dev == ndev)
878 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530879 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
880 status = wlan_hdd_validate_context(pHddCtx);
881 if (0 != status)
882 {
883 hddLog(LOGE, FL("HDD context is invalid"));
884 return NOTIFY_DONE;
885 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530886 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
887 {
888 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
889 ifap = &ifa->ifa_next)
890 {
891 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
892 {
893 break; /* found */
894 }
895 }
896 }
897 if(ifa && ifa->ifa_local)
898 {
899 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
900 }
901 }
902
903 return NOTIFY_DONE;
904}
905
906/**----------------------------------------------------------------------------
907
908 \brief hdd_conf_arp_offload() - Configure ARP offload
909
910 Called during SUSPEND to configure the ARP offload (MC BC filter) which
911 reduces power consumption.
912
913 \param - pAdapter -Adapter context for which ARP offload is to be configured
914 \param - fenable - 0 - disable.
915 1 - enable. (with IPv4 notifier registration)
916 2 - enable. (without IPv4 notifier registration)
917
918 \return -
919 VOS_STATUS_SUCCESS - on successful operation
920 VOS_STATUS_E_FAILURE - on failure of operation
921-----------------------------------------------------------------------------*/
922VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700923{
924 struct in_ifaddr **ifap = NULL;
925 struct in_ifaddr *ifa = NULL;
926 struct in_device *in_dev;
927 int i = 0;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530928 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700929 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800930 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700931
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530932 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -0700933
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 if(fenable)
935 {
936 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
937 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530938 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700939 ifap = &ifa->ifa_next)
940 {
941 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
942 {
943 break; /* found */
944 }
945 }
946 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700947 if(ifa && ifa->ifa_local)
948 {
949 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
950 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
951
Arif Hussain6d2a3322013-11-17 19:50:10 -0800952 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700953
Amar Singhald53568e2013-09-26 11:03:45 -0700954 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
955 pHddCtx->sus_res_mcastbcast_filter) ||
956 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
957 pHddCtx->sus_res_mcastbcast_filter)) &&
958 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700959 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530960 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -0700961 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
962 hddLog(VOS_TRACE_LEVEL_INFO,
963 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 }
Amar Singhald53568e2013-09-26 11:03:45 -0700965
966 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
967 offLoadRequest.enableOrDisable);
968
Jeff Johnson295189b2012-06-20 16:38:30 -0700969 //converting u32 to IPV4 address
970 for(i = 0 ; i < 4; i++)
971 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530972 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 (ifa->ifa_local >> (i*8) ) & 0xFF ;
974 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530975 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700976 offLoadRequest.params.hostIpv4Addr[0],
977 offLoadRequest.params.hostIpv4Addr[1],
978 offLoadRequest.params.hostIpv4Addr[2],
979 offLoadRequest.params.hostIpv4Addr[3]);
980
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530981 if (eHAL_STATUS_SUCCESS !=
982 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
983 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700984 {
985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -0800986 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 return VOS_STATUS_E_FAILURE;
988 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 }
990 else
991 {
Agarwal Ashish971c2882013-10-30 20:11:12 +0530992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
993 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -0700994 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530995
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530996 if (fenable == 1 && !pAdapter->ipv4_notifier_registered)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530997 {
998 // Register IPv4 notifier to notify if any change in IP
999 // So that we can reconfigure the offload parameters
1000 pAdapter->ipv4_notifier.notifier_call =
1001 wlan_hdd_ipv4_changed;
1002 ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier);
1003 if (ret)
1004 {
1005 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
1006 }
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301007 else
1008 {
1009 hddLog(LOG1, FL("Registered IPv4 notifier"));
1010 pAdapter->ipv4_notifier_registered = true;
1011 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301012 }
1013 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001014 }
1015 else
1016 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301017 if (pAdapter->ipv4_notifier_registered)
1018 {
1019 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
1020 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
1021 pAdapter->ipv4_notifier_registered = false;
1022 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1024 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1025 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1026
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301027 if (eHAL_STATUS_SUCCESS !=
1028 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1029 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001030 {
1031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001032 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001033 return VOS_STATUS_E_FAILURE;
1034 }
1035 return VOS_STATUS_SUCCESS;
1036 }
1037}
1038
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301039/*
1040 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301041 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301042*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301043void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301044 tANI_U8 *pMcBcFilter)
1045{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301046 if (NULL == pHddCtx)
1047 {
1048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1049 return;
1050 }
1051
1052 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1053 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301054 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301055 /* ARP offload is enabled, do not block bcast packets at RXP
1056 * Will be using Bitmasking to reset the filter. As we have
1057 * disable Broadcast filtering, Anding with the negation
1058 * of Broadcast BIT
1059 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301060 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301061 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301062
1063#ifdef WLAN_NS_OFFLOAD
1064 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301065 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301066 /* NS offload is enabled, do not block mcast packets at RXP
1067 * Will be using Bitmasking to reset the filter. As we have
1068 * disable Multicast filtering, Anding with the negation
1069 * of Multicast BIT
1070 */
1071 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301072 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301073#endif
1074
1075 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301076}
1077
Jeff Johnson295189b2012-06-20 16:38:30 -07001078void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1079{
1080 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1082 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1083 if(NULL == wlanRxpFilterParam)
1084 {
1085 hddLog(VOS_TRACE_LEVEL_FATAL,
1086 "%s: vos_mem_alloc failed ", __func__);
1087 return;
1088 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001089 hddLog(VOS_TRACE_LEVEL_INFO,
1090 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301091 if (TRUE == setfilter)
1092 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301093 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301094 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301095 }
1096 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301097 {
1098 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301099 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301100 pHddCtx->configuredMcastBcastFilter;
1101 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301102
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -07001105 if (eHAL_STATUS_SUCCESS != halStatus)
1106 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1108 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1109}
1110
Jeff Johnson295189b2012-06-20 16:38:30 -07001111static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1112 hdd_adapter_t *pAdapter)
1113{
1114 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1115 tpSirWlanSuspendParam wlanSuspendParam =
1116 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1117
Amar Singhald53568e2013-09-26 11:03:45 -07001118 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1119 pHddCtx->sus_res_mcastbcast_filter =
1120 pHddCtx->configuredMcastBcastFilter;
1121 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1122 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1123 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1124 pHddCtx->configuredMcastBcastFilter);
1125
1126 }
1127
Amar Singhal49fdfd52013-08-13 13:25:12 -07001128
Jeff Johnson295189b2012-06-20 16:38:30 -07001129 if(NULL == wlanSuspendParam)
1130 {
1131 hddLog(VOS_TRACE_LEVEL_FATAL,
1132 "%s: vos_mem_alloc failed ", __func__);
1133 return;
1134 }
1135
Amar Singhald53568e2013-09-26 11:03:45 -07001136 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 "%s: send wlan suspend indication", __func__);
1138
1139 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1140 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301141 //Configure supported OffLoads
1142 hdd_conf_hostoffload(pAdapter, TRUE);
1143 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001144
1145#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301146 /* During suspend, configure MC Addr list filter to the firmware
1147 * function takes care of checking necessary conditions before
1148 * configuring.
1149 */
1150 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001151#endif
1152 }
1153
1154 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1155 if(eHAL_STATUS_SUCCESS == halStatus)
1156 {
1157 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001158 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301159 hddLog(VOS_TRACE_LEVEL_ERROR,
1160 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001161 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 }
1163}
1164
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301165static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001166{
Chilam Ngc4244af2013-04-01 15:37:32 -07001167 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001168 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001169 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001170
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301171 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001172 "%s: send wlan resume indication", __func__);
1173
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301174 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1175
1176 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001177 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301178 hddLog(VOS_TRACE_LEVEL_FATAL,
1179 "%s: memory allocation failed for wlanResumeParam ", __func__);
1180 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001182
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301183 //Disable supported OffLoads
1184 hdd_conf_hostoffload(pAdapter, FALSE);
1185
1186 wlanResumeParam->configuredMcstBcstFilterSetting =
1187 pHddCtx->configuredMcastBcastFilter;
1188 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1189 if (eHAL_STATUS_SUCCESS != halStatus)
1190 {
c_hpothuffdb5272013-10-02 16:42:35 +05301191 hddLog(VOS_TRACE_LEVEL_ERROR,
1192 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301193 vos_mem_free(wlanResumeParam);
1194 }
1195
1196 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1197
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001198 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1199 pHddCtx->configuredMcastBcastFilter =
1200 pHddCtx->sus_res_mcastbcast_filter;
1201 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1202 }
Amar Singhald53568e2013-09-26 11:03:45 -07001203
1204 hddLog(VOS_TRACE_LEVEL_INFO,
1205 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1206 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1207 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001208
Chilam Ngc4244af2013-04-01 15:37:32 -07001209
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301210#ifdef WLAN_FEATURE_PACKET_FILTERING
1211 /* Filer was applied during suspend inditication
1212 * clear it when we resume.
1213 */
1214 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001215#endif
1216}
Jeff Johnson295189b2012-06-20 16:38:30 -07001217
Jeff Johnson295189b2012-06-20 16:38:30 -07001218//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001219void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001220{
1221 hdd_context_t *pHddCtx = NULL;
1222 v_CONTEXT_t pVosContext = NULL;
1223
Jeff Johnson295189b2012-06-20 16:38:30 -07001224 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301225 hdd_adapter_t *pAdapter = NULL;
1226 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301227 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001228
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1230
1231 //Get the global VOSS context.
1232 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1233 if(!pVosContext) {
1234 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1235 return;
1236 }
1237
1238 //Get the HDD context.
1239 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1240
1241 if(!pHddCtx) {
1242 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1243 return;
1244 }
1245
1246 if (pHddCtx->isLogpInProgress) {
1247 hddLog(VOS_TRACE_LEVEL_ERROR,
1248 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1249 return;
1250 }
1251
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301252 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001253 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1254 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1255 {
1256 pAdapter = pAdapterNode->pAdapter;
1257 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001258 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1260
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001261 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001262 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1263 pAdapterNode = pNext;
1264 continue;
1265 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301266 /* Avoid multiple enter/exit BMPS in this while loop using
1267 * hdd_enter_bmps flag
1268 */
1269 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1270 {
1271 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001272
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301273 /* If device was already in BMPS, and dynamic DTIM is set,
1274 * exit(set the device to full power) and enter BMPS again
1275 * to reflect new DTIM value */
1276 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1277
1278 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1279
1280 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001282#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1283 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1284 {
1285 //stop the interface before putting the chip to standby
1286 netif_tx_disable(pAdapter->dev);
1287 netif_carrier_off(pAdapter->dev);
1288 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301289 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001290 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1291 {
1292 //Execute deep sleep procedure
1293 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1294 }
1295#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301296
1297 /*Suspend notification sent down to driver*/
1298 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1299
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301300 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1301 pAdapterNode = pNext;
1302 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301303 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301304
Jeff Johnson295189b2012-06-20 16:38:30 -07001305#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1306 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1307 {
1308 hdd_enter_standby(pHddCtx);
1309 }
1310#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001311
1312 return;
1313}
1314
1315static void hdd_PowerStateChangedCB
1316(
1317 v_PVOID_t callbackContext,
1318 tPmcState newState
1319)
1320{
1321 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 /* if the driver was not in BMPS during early suspend,
1323 * the dynamic DTIM is now updated at Riva */
1324 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1325 && pHddCtx->cfg_ini->enableDynamicDTIM
1326 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1327 {
1328 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1329 }
1330 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301331 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1332 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001333 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301334 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1335 {
Amar Singhald53568e2013-09-26 11:03:45 -07001336 pHddCtx->sus_res_mcastbcast_filter =
1337 pHddCtx->configuredMcastBcastFilter;
1338 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1339
1340 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1341 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1342 pHddCtx->configuredMcastBcastFilter);
1343 hddLog(VOS_TRACE_LEVEL_INFO,
1344 "offload: calling hdd_conf_mcastbcast_filter");
1345
1346 }
1347
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001349 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1350 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1351 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001352 else
Mihir Shete793209f2014-01-06 11:01:12 +05301353 {
1354 /* Android framework can send resume request when the WCN chip is
1355 * in IMPS mode. When the chip exits IMPS mode the firmware will
1356 * restore all the registers to the state they were before the chip
1357 * entered IMPS and so our hardware filter settings confgured by the
1358 * resume request will be lost. So reconfigure the filters on detecting
1359 * a change in the power state of the WCN chip.
1360 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301361 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301362 if (IMPS != newState)
1363 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301364 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301365 if (FALSE == pHddCtx->hdd_wlan_suspended)
1366 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301367 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301368 hddLog(VOS_TRACE_LEVEL_INFO,
1369 "Not in IMPS/BMPS and suspended state");
1370 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1371 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301372 else
1373 {
1374 spin_unlock(&pHddCtx->filter_lock);
1375 }
Mihir Shete793209f2014-01-06 11:01:12 +05301376 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301377 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001378}
1379
1380
1381
1382void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1383{
1384 v_CONTEXT_t pVosContext;
1385 tHalHandle smeContext;
1386
1387 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1388 if (NULL == pVosContext)
1389 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001390 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001391 return;
1392 }
1393 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1394 if (NULL == smeContext)
1395 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001396 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001397 return;
1398 }
1399
1400 spin_lock_init(&pHddCtx->filter_lock);
1401 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1402 pHddCtx->cfg_ini->nEnableSuspend)
1403 {
1404 pmcRegisterDeviceStateUpdateInd(smeContext,
1405 hdd_PowerStateChangedCB, pHddCtx);
1406 }
1407}
1408
1409void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1410{
1411 v_CONTEXT_t pVosContext;
1412 tHalHandle smeContext;
1413
1414 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1415 if (NULL == pVosContext)
1416 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001417 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001418 return;
1419 }
1420 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1421 if (NULL == smeContext)
1422 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001423 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001424 return;
1425 }
1426
1427 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1428 pHddCtx->cfg_ini->nEnableSuspend)
1429 {
1430 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1431 }
1432}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301433
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301434#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301435void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301436{
1437 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301438 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1440
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301441 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301442 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301443 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1444 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1445 {
1446 vos_mem_copy(&hddGtkOffloadReqParams,
1447 &pHddStaCtx->gtkOffloadReqParams,
1448 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301449
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301450 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1451 &hddGtkOffloadReqParams, pAdapter->sessionId);
1452 if (eHAL_STATUS_SUCCESS != ret)
1453 {
1454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1455 "%s: sme_SetGTKOffload failed, returned %d",
1456 __func__, ret);
1457 return;
1458 }
1459
1460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1461 "%s: sme_SetGTKOffload successfull", __func__);
1462 }
1463
1464 }
1465 else
1466 {
1467 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1468 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1469 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1470 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1471 {
1472
1473 /* Host driver has previously offloaded GTK rekey */
1474 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301475 wlan_hdd_cfg80211_update_replayCounterCallback,
1476 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301477 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301478
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301479 {
1480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1481 "%s: sme_GetGTKOffload failed, returned %d",
1482 __func__, ret);
1483 return;
1484 }
1485 else
1486 {
1487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1488 "%s: sme_GetGTKOffload successful",
1489 __func__);
1490
1491 /* Sending GTK offload dissable */
1492 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1493 sizeof (tSirGtkOffloadParams));
1494 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1495 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301496 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301497 if (eHAL_STATUS_SUCCESS != ret)
1498 {
1499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1500 "%s: failed to dissable GTK offload, returned %d",
1501 __func__, ret);
1502 return;
1503 }
1504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1505 "%s: successfully dissabled GTK offload request to HAL",
1506 __func__);
1507 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301508 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301509 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301510 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301511}
1512#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001513
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001514void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001515{
1516 hdd_context_t *pHddCtx = NULL;
1517 hdd_adapter_t *pAdapter = NULL;
1518 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1519 VOS_STATUS status;
1520 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001521
Jeff Johnson295189b2012-06-20 16:38:30 -07001522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1523
1524 //Get the global VOSS context.
1525 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1526 if(!pVosContext) {
1527 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1528 return;
1529 }
1530
1531 //Get the HDD context.
1532 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1533
1534 if(!pHddCtx) {
1535 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1536 return;
1537 }
1538
Agarwal Ashish971c2882013-10-30 20:11:12 +05301539 if (pHddCtx->isLogpInProgress)
1540 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001541 hddLog(VOS_TRACE_LEVEL_INFO,
1542 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1543 return;
1544 }
1545
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 pHddCtx->hdd_wlan_suspended = FALSE;
1547 /*loop through all adapters. Concurrency */
1548 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1549
1550 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1551 {
1552 pAdapter = pAdapterNode->pAdapter;
1553 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001554 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001555 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001556 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001557 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1558 pAdapterNode = pNext;
1559 continue;
1560 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301561
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301562
Jeff Johnson295189b2012-06-20 16:38:30 -07001563#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1564 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1565 {
1566 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1567 hdd_exit_deep_sleep(pAdapter);
1568 }
1569#endif
1570
1571 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1572 {
1573 /*Switch back to DTIM 1*/
1574 tSirSetPowerParamsReq powerRequest = { 0 };
1575
1576 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1577 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001578 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001579
1580 /*Disabled ModulatedDTIM if enabled on suspend*/
1581 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1582 powerRequest.uDTIMPeriod = 0;
1583
1584 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1585 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1586 NULL, eANI_BOOLEAN_FALSE);
1587 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1588 NULL, eANI_BOOLEAN_FALSE);
1589
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001591 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001592 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001593
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301594 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1595 {
1596 /* put the device into full power */
1597 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001598
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301599 /* put the device back into BMPS */
1600 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001601
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301602 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001604 }
1605
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301606 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1608 pAdapterNode = pNext;
1609 }
1610
1611#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1612 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1613 {
1614 hdd_exit_standby(pHddCtx);
1615 }
1616#endif
1617
Jeff Johnson295189b2012-06-20 16:38:30 -07001618 return;
1619}
1620
Jeff Johnson295189b2012-06-20 16:38:30 -07001621VOS_STATUS hdd_wlan_reset_initialization(void)
1622{
Jeff Johnson295189b2012-06-20 16:38:30 -07001623 v_CONTEXT_t pVosContext = NULL;
1624
1625 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1626
1627 //Get the global VOSS context.
1628 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1629 if(!pVosContext)
1630 {
1631 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1632 return VOS_STATUS_E_FAILURE;
1633 }
1634
1635 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1636
1637 // Prevent the phone from going to sleep
1638 hdd_prevent_suspend();
1639
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 return VOS_STATUS_SUCCESS;
1641}
1642
1643
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001644/*
1645 * Based on the ioctl command recieved by HDD, put WLAN driver
1646 * into the quiet mode. This is the same as the early suspend
1647 * notification that driver used to listen
1648 */
1649void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001650{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001651 if (suspend)
1652 hdd_suspend_wlan();
1653 else
1654 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001655}
1656
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001657static void hdd_ssr_timer_init(void)
1658{
1659 init_timer(&ssr_timer);
1660}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001661
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001662static void hdd_ssr_timer_del(void)
1663{
1664 del_timer(&ssr_timer);
1665 ssr_timer_started = false;
1666}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001667
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001668static void hdd_ssr_timer_cb(unsigned long data)
1669{
1670 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001671
1672#ifdef WCN_PRONTO
1673 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1674 wcnss_pronto_log_debug_regs();
1675#endif
1676
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001677 VOS_BUG(0);
1678}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001679
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001680static void hdd_ssr_timer_start(int msec)
1681{
1682 if(ssr_timer_started)
1683 {
1684 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1685 ,__func__);
1686 }
1687 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1688 ssr_timer.function = hdd_ssr_timer_cb;
1689 add_timer(&ssr_timer);
1690 ssr_timer_started = true;
1691}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001692
Jeff Johnson295189b2012-06-20 16:38:30 -07001693/* the HDD interface to WLAN driver shutdown,
1694 * the primary shutdown function in SSR
1695 */
1696VOS_STATUS hdd_wlan_shutdown(void)
1697{
1698 VOS_STATUS vosStatus;
1699 v_CONTEXT_t pVosContext = NULL;
1700 hdd_context_t *pHddCtx = NULL;
1701 pVosSchedContext vosSchedContext = NULL;
c_hpothuffdb5272013-10-02 16:42:35 +05301702 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001703
1704 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1705
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001706 /* if re-init never happens, then do SSR1 */
1707 hdd_ssr_timer_init();
1708 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1709
Jeff Johnson295189b2012-06-20 16:38:30 -07001710 /* Get the global VOSS context. */
1711 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1712 if(!pVosContext) {
1713 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1714 return VOS_STATUS_E_FAILURE;
1715 }
1716 /* Get the HDD context. */
1717 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1718 if(!pHddCtx) {
1719 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1720 return VOS_STATUS_E_FAILURE;
1721 }
c_hpothud662a352013-12-26 15:09:12 +05301722
1723 //Stop the traffic monitor timer
1724 if ( VOS_TIMER_STATE_RUNNING ==
1725 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1726 {
1727 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1728 }
1729
Jeff Johnson295189b2012-06-20 16:38:30 -07001730 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 /* DeRegister with platform driver as client for Suspend/Resume */
1732 vosStatus = hddDeregisterPmOps(pHddCtx);
1733 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1734 {
1735 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1736 }
1737
1738 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1739 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1740 {
1741 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1742 }
1743
1744 /* Disable IMPS/BMPS as we do not want the device to enter any power
1745 * save mode on its own during reset sequence
1746 */
1747 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1748 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1749 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1750
1751 vosSchedContext = get_vos_sched_ctxt();
1752
1753 /* Wakeup all driver threads */
1754 if(TRUE == pHddCtx->isMcThreadSuspended){
1755 complete(&vosSchedContext->ResumeMcEvent);
1756 pHddCtx->isMcThreadSuspended= FALSE;
1757 }
1758 if(TRUE == pHddCtx->isTxThreadSuspended){
1759 complete(&vosSchedContext->ResumeTxEvent);
1760 pHddCtx->isTxThreadSuspended= FALSE;
1761 }
1762 if(TRUE == pHddCtx->isRxThreadSuspended){
1763 complete(&vosSchedContext->ResumeRxEvent);
1764 pHddCtx->isRxThreadSuspended= FALSE;
1765 }
1766 /* Reset the Suspend Variable */
1767 pHddCtx->isWlanSuspended = FALSE;
1768
1769 /* Stop all the threads; we do not want any messages to be a processed,
1770 * any more and the best way to ensure that is to terminate the threads
1771 * gracefully.
1772 */
1773 /* Wait for MC to exit */
1774 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1775 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1776 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1777 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301778 ret = wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1779 if (0 >= ret)
1780 {
1781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on McShutdown failed %ld",
1782 __func__, ret);
1783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001784
1785 /* Wait for TX to exit */
1786 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1787 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1788 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1789 wake_up_interruptible(&vosSchedContext->txWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301790 ret = wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1791 if (0 >= ret)
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on TxShutdown failed %ld",
1794 __func__, ret);
1795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001796
1797 /* Wait for RX to exit */
1798 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1799 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1800 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1801 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301802
1803 ret = wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1804 if (0 >= ret)
1805 {
1806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on RxShutdown failed %ld",
1807 __func__, ret);
1808 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001809
1810#ifdef WLAN_BTAMP_FEATURE
1811 vosStatus = WLANBAP_Stop(pVosContext);
1812 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1813 {
1814 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1815 "%s: Failed to stop BAP",__func__);
1816 }
1817#endif //WLAN_BTAMP_FEATURE
1818 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301819 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1820 {
1821 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1822 "%s: Failed to stop wda %d", __func__, vosStatus);
1823 VOS_ASSERT(0);
1824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001825
1826 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1827 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1828 * on threads being running to process the SYS Stop
1829 */
Kiet Lama72a2322013-11-15 11:18:11 +05301830 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301831 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1834 "%s: Failed to stop sme %d", __func__, vosStatus);
1835 VOS_ASSERT(0);
1836 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001837
1838 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1839 /* Stop MAC (PE and HAL) */
1840 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301841 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1842 {
1843 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1844 "%s: Failed to stop mac %d", __func__, vosStatus);
1845 VOS_ASSERT(0);
1846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001847
1848 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1849 /* Stop TL */
1850 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301851 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1852 {
1853 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1854 "%s: Failed to stop TL %d", __func__, vosStatus);
1855 VOS_ASSERT(0);
1856 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001857
Jeff Johnson295189b2012-06-20 16:38:30 -07001858 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1860 /* Clean up message queues of TX and MC thread */
1861 vos_sched_flush_mc_mqs(vosSchedContext);
1862 vos_sched_flush_tx_mqs(vosSchedContext);
1863 vos_sched_flush_rx_mqs(vosSchedContext);
1864
1865 /* Deinit all the TX and MC queues */
1866 vos_sched_deinit_mqs(vosSchedContext);
1867 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1868
1869 /* shutdown VOSS */
1870 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301871
1872 /*mac context has already been released in mac_close call
1873 so setting it to NULL in hdd context*/
1874 pHddCtx->hHal = (tHalHandle)NULL;
1875
Jeff Johnson295189b2012-06-20 16:38:30 -07001876 if (free_riva_power_on_lock("wlan"))
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1879 __func__);
1880 }
1881 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1882 ,__func__);
1883 return VOS_STATUS_SUCCESS;
1884}
1885
1886
1887
1888/* the HDD interface to WLAN driver re-init.
1889 * This is called to initialize/start WLAN driver after a shutdown.
1890 */
1891VOS_STATUS hdd_wlan_re_init(void)
1892{
1893 VOS_STATUS vosStatus;
1894 v_CONTEXT_t pVosContext = NULL;
1895 hdd_context_t *pHddCtx = NULL;
1896 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001897#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1898 int max_retries = 0;
1899#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001900#ifdef WLAN_BTAMP_FEATURE
1901 hdd_config_t *pConfig = NULL;
1902 WLANBAP_ConfigType btAmpConfig;
1903#endif
1904
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001905 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001906 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001907
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001908#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1909 /* wait until WCNSS driver downloads NV */
1910 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1911 msleep(1000);
1912 }
1913 if (max_retries >= 5) {
1914 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1915 goto err_re_init;
1916 }
1917#endif
1918
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001919 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
1920
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001921 /* The driver should always be initialized in STA mode after SSR */
1922 hdd_set_conparam(0);
1923
Jeff Johnson295189b2012-06-20 16:38:30 -07001924 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1925 vosStatus = vos_open(&pVosContext, 0);
1926 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1927 {
1928 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1929 goto err_re_init;
1930 }
1931
1932 /* Get the HDD context. */
1933 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1934 if(!pHddCtx)
1935 {
1936 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1937 goto err_vosclose;
1938 }
1939
1940 /* Save the hal context in Adapter */
1941 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1942 if ( NULL == pHddCtx->hHal )
1943 {
1944 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1945 goto err_vosclose;
1946 }
1947
1948 /* Set the SME configuration parameters. */
1949 vosStatus = hdd_set_sme_config(pHddCtx);
1950 if ( VOS_STATUS_SUCCESS != vosStatus )
1951 {
1952 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1953 goto err_vosclose;
1954 }
1955
1956 /* Initialize the WMM module */
1957 vosStatus = hdd_wmm_init(pHddCtx);
1958 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1959 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001960 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001961 goto err_vosclose;
1962 }
1963
1964 vosStatus = vos_preStart( pHddCtx->pvosContext );
1965 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1966 {
1967 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1968 goto err_vosclose;
1969 }
1970
1971 /* In the integrated architecture we update the configuration from
1972 the INI file and from NV before vOSS has been started so that
1973 the final contents are available to send down to the cCPU */
1974 /* Apply the cfg.ini to cfg.dat */
1975 if (FALSE == hdd_update_config_dat(pHddCtx))
1976 {
1977 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1978 goto err_vosclose;
1979 }
1980
1981 /* Set the MAC Address, currently this is used by HAL to add self sta.
1982 * Remove this once self sta is added as part of session open. */
1983 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1984 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1985 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1986 if (!HAL_STATUS_SUCCESS(halStatus))
1987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1989 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1990 goto err_vosclose;
1991 }
1992
1993 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1994 Note: Firmware image will be read and downloaded inside vos_start API */
1995 vosStatus = vos_start( pVosContext );
1996 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1997 {
1998 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1999 goto err_vosclose;
2000 }
2001
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002002 /* Exchange capability info between Host and FW and also get versioning info from FW */
2003 hdd_exchange_version_and_caps(pHddCtx);
2004
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 vosStatus = hdd_post_voss_start_config( pHddCtx );
2006 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2007 {
2008 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2009 __func__);
2010 goto err_vosstop;
2011 }
2012
2013#ifdef WLAN_BTAMP_FEATURE
2014 vosStatus = WLANBAP_Open(pVosContext);
2015 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2016 {
2017 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2018 "%s: Failed to open BAP",__func__);
2019 goto err_vosstop;
2020 }
2021 vosStatus = BSL_Init(pVosContext);
2022 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2023 {
2024 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2025 "%s: Failed to Init BSL",__func__);
2026 goto err_bap_close;
2027 }
2028 vosStatus = WLANBAP_Start(pVosContext);
2029 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2030 {
2031 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2032 "%s: Failed to start TL",__func__);
2033 goto err_bap_close;
2034 }
2035 pConfig = pHddCtx->cfg_ini;
2036 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2037 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2038#endif //WLAN_BTAMP_FEATURE
2039
2040 /* Restart all adapters */
2041 hdd_start_all_adapters(pHddCtx);
2042 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002043 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002044 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002046
2047 /* Register with platform driver as client for Suspend/Resume */
2048 vosStatus = hddRegisterPmOps(pHddCtx);
2049 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2050 {
2051 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2052 goto err_bap_stop;
2053 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 /* Allow the phone to go to sleep */
2055 hdd_allow_suspend();
2056 /* register for riva power on lock */
2057 if (req_riva_power_on_lock("wlan"))
2058 {
2059 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2060 __func__);
2061 goto err_unregister_pmops;
2062 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002063 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 goto success;
2065
2066err_unregister_pmops:
2067 hddDeregisterPmOps(pHddCtx);
2068
2069err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002070#ifdef CONFIG_HAS_EARLYSUSPEND
2071 hdd_unregister_mcast_bcast_filter(pHddCtx);
2072#endif
2073 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002074#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002075 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002076#endif
2077
2078#ifdef WLAN_BTAMP_FEATURE
2079err_bap_close:
2080 WLANBAP_Close(pVosContext);
2081#endif
2082
2083err_vosstop:
2084 vos_stop(pVosContext);
2085
2086err_vosclose:
2087 vos_close(pVosContext);
2088 vos_sched_close(pVosContext);
2089 if (pHddCtx)
2090 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 /* Unregister the Net Device Notifier */
2092 unregister_netdevice_notifier(&hdd_netdev_notifier);
2093 /* Clean up HDD Nlink Service */
2094 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002095#ifdef WLAN_KD_READY_NOTIFIER
2096 nl_srv_exit(pHddCtx->ptt_pid);
2097#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002099#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 /* Free up dynamically allocated members inside HDD Adapter */
2101 kfree(pHddCtx->cfg_ini);
2102 pHddCtx->cfg_ini= NULL;
2103
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 wiphy_unregister(pHddCtx->wiphy);
2105 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 }
2107 vos_preClose(&pVosContext);
2108
2109#ifdef MEMORY_DEBUG
2110 vos_mem_exit();
2111#endif
2112
2113err_re_init:
2114 /* Allow the phone to go to sleep */
2115 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002116 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002117 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002118 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002119
2120success:
2121 /* Trigger replay of BTC events */
2122 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2123 return VOS_STATUS_SUCCESS;
2124}