blob: efe7413877fbe86186143608113dee3234f4b3b2 [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
Sameer Thalappile5637f42013-08-07 15:46:55 -0700109#define HDD_SSR_BRING_UP_TIME 180000
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;
c_hpothuffdb5272013-10-02 16:42:35 +0530168 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700169
170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
171 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
172
173 g_full_pwr_status = eHAL_STATUS_FAILURE;
174 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
175 eSME_FULL_PWR_NEEDED_BY_HDD);
176
177 if(status == eHAL_STATUS_PMC_PENDING)
178 {
179 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530180 ret = wait_for_completion_interruptible_timeout(
181 &pHddCtx->full_pwr_comp_var,
182 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
183 if (0 >= ret)
184 {
185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
186 __func__, ret);
187 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700188 status = g_full_pwr_status;
189 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
190 {
191 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
192 VOS_ASSERT(0);
193 goto failure;
194 }
195 }
196 else if(status != eHAL_STATUS_SUCCESS)
197 {
198 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
199 __func__, status);
200 VOS_ASSERT(0);
201 goto failure;
202 }
203 else
204 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
205
206failure:
207 //No blocking to reduce latency. No other device should be depending on WLAN
208 //to finish resume and WLAN won't be instantly on after resume
209 return status;
210}
211
212
213//Helper routine to put the chip into standby
214VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
215{
216 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
217 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530218 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700219
220 //Disable IMPS/BMPS as we do not want the device to enter any power
221 //save mode on its own during suspend sequence
222 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
223 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
224
225 //Note we do not disable queues unnecessarily. Queues should already be disabled
226 //if STA is disconnected or the queue will be disabled as and when disconnect
227 //happens because of standby procedure.
228
229 //Ensure that device is in full power first. There is scope for optimization
230 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
231 //Core s/w needs to be optimized to handle this. Until then we request full
232 //power before issuing request for standby.
233 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
234 g_full_pwr_status = eHAL_STATUS_FAILURE;
235 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
236 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
237
238 if(halStatus == eHAL_STATUS_PMC_PENDING)
239 {
240 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530241 ret = wait_for_completion_interruptible_timeout(
242 &pHddCtx->full_pwr_comp_var,
243 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
244 if (0 >= ret)
245 {
246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
247 __func__, ret);
248 }
249
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
251 {
252 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
253 VOS_ASSERT(0);
254 vosStatus = VOS_STATUS_E_FAILURE;
255 goto failure;
256 }
257 }
258 else if(halStatus != eHAL_STATUS_SUCCESS)
259 {
260 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
261 __func__, halStatus);
262 VOS_ASSERT(0);
263 vosStatus = VOS_STATUS_E_FAILURE;
264 goto failure;
265 }
266
267 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
268 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
269 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
270 }
271
272 //Request standby. Standby will cause the STA to disassociate first. TX queues
273 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
274 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
275 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
276 //when there are concurrent sessions.
277 INIT_COMPLETION(pHddCtx->standby_comp_var);
278 g_standby_status = eHAL_STATUS_FAILURE;
279 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
280
281 if (halStatus == eHAL_STATUS_PMC_PENDING)
282 {
283 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530284 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700285 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530286 if (0 >= ret)
287 {
288 hddLog(VOS_TRACE_LEVEL_ERROR,
289 FL("wait on standby_comp_var failed %ld"), ret);
290 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700291 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
292 {
293 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
294 VOS_ASSERT(0);
295 vosStatus = VOS_STATUS_E_FAILURE;
296 goto failure;
297 }
298 }
299 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
300 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
301 __func__, halStatus);
302 VOS_ASSERT(0);
303 vosStatus = VOS_STATUS_E_FAILURE;
304 goto failure;
305 }
306 else
307 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
308
309failure:
310 //Restore IMPS config
311 if(pHddCtx->cfg_ini->fIsImpsEnabled)
312 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
313
314 //Restore BMPS config
315 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
316 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
317
318 return vosStatus;
319}
320
321
322//Helper routine for Deep sleep entry
323VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
324{
325 eHalStatus halStatus;
326 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
327 vos_call_status_type callType;
c_hpothuffdb5272013-10-02 16:42:35 +0530328 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800329
Jeff Johnson295189b2012-06-20 16:38:30 -0700330 //Stop the Interface TX queue.
331 netif_tx_disable(pAdapter->dev);
332 netif_carrier_off(pAdapter->dev);
333
334 //Disable IMPS,BMPS as we do not want the device to enter any power
335 //save mode on it own during suspend sequence
336 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
337 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
338
339 //Ensure that device is in full power as we will touch H/W during vos_Stop
340 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
341 g_full_pwr_status = eHAL_STATUS_FAILURE;
342 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
343 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
344
345 if(halStatus == eHAL_STATUS_PMC_PENDING)
346 {
347 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530348 ret = wait_for_completion_interruptible_timeout(
349 &pHddCtx->full_pwr_comp_var,
350 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
351 if (0 >= ret)
352 {
353 hddLog(VOS_TRACE_LEVEL_ERROR,
354 FL("wait on full_pwr_comp_var failed %ld"), ret);
355 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
357 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
358 VOS_ASSERT(0);
359 }
360 }
361 else if(halStatus != eHAL_STATUS_SUCCESS)
362 {
363 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
364 VOS_ASSERT(0);
365 }
366
367 //Issue a disconnect. This is required to inform the supplicant that
368 //STA is getting disassociated and for GUI to be updated properly
369 INIT_COMPLETION(pAdapter->disconnect_comp_var);
370 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
371
372 //Success implies disconnect command got queued up successfully
373 if(halStatus == eHAL_STATUS_SUCCESS)
374 {
375 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530376 ret = wait_for_completion_interruptible_timeout(
377 &pAdapter->disconnect_comp_var,
378 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
379 if (0 >= ret)
380 {
381 hddLog(VOS_TRACE_LEVEL_ERROR,
382 FL("wait on disconnect_comp_var failed %ld"), ret);
383 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 }
385
386
387 //None of the steps should fail after this. Continue even in case of failure
388 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530389 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
390 {
391 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
392 __func__, vosStatus);
393 VOS_ASSERT(0);
394 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700395
Jeff Johnson295189b2012-06-20 16:38:30 -0700396 vosStatus = vos_chipAssertDeepSleep( &callType, NULL, NULL );
c_hpothuffdb5272013-10-02 16:42:35 +0530397 if( VOS_IS_STATUS_SUCCESS( vosStatus ))
398 {
399 hddLog(VOS_TRACE_LEVEL_ERROR,
400 FL("vos_chipAssertDeepSleep return failed %d"), vosStatus);
401 VOS_ASSERT(0);
402 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700403
404 //Vote off any PMIC voltage supplies
405 vosStatus = vos_chipPowerDown(NULL, NULL, NULL);
c_hpothuffdb5272013-10-02 16:42:35 +0530406 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
407 {
408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_chipPowerDown return failed %d",
409 __func__, vosStatus);
410 VOS_ASSERT(0);
411 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700412
Jeff Johnson295189b2012-06-20 16:38:30 -0700413 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
414
415 //Restore IMPS config
416 if(pHddCtx->cfg_ini->fIsImpsEnabled)
417 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
418
419 //Restore BMPS config
420 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
421 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
422
Jeff Johnson295189b2012-06-20 16:38:30 -0700423 return vosStatus;
424}
425
426VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
427{
428 VOS_STATUS vosStatus;
429 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700430
431 //Power Up Libra WLAN card first if not already powered up
432 vosStatus = vos_chipPowerUp(NULL,NULL,NULL);
433 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
434 {
c_hpothuffdb5272013-10-02 16:42:35 +0530435 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN not Powered Up."
Jeff Johnson295189b2012-06-20 16:38:30 -0700436 "exiting", __func__);
437 goto err_deep_sleep;
438 }
439
Jeff Johnson295189b2012-06-20 16:38:30 -0700440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
441 "%s: calling hdd_set_sme_config",__func__);
442 vosStatus = hdd_set_sme_config( pHddCtx );
443 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
444 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
445 {
446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
447 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700448 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700449 }
450
451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
452 "%s: calling vos_start",__func__);
453 vosStatus = vos_start( pHddCtx->pvosContext );
454 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
455 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
456 {
457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
458 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700459 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700460 }
461
462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
463 "%s: calling hdd_post_voss_start_config",__func__);
464 vosStatus = hdd_post_voss_start_config( pHddCtx );
465 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
466 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
467 {
468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
469 "%s: Failed in hdd_post_voss_start_config",__func__);
470 goto err_voss_stop;
471 }
472
473
474 //Open a SME session for future operation
475 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700476 (tANI_U8 *)&pAdapter->macAddressCurrent,
477 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700478 if ( !HAL_STATUS_SUCCESS( halStatus ) )
479 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700480 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700481 halStatus, halStatus );
482 goto err_voss_stop;
483
484 }
485
486 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
487
488 //Trigger the initial scan
489 hdd_wlan_initial_scan(pHddCtx);
490
491 return VOS_STATUS_SUCCESS;
492
493err_voss_stop:
494 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700495err_deep_sleep:
496 return VOS_STATUS_E_FAILURE;
497
498}
499
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530500/*
501 * Function: hdd_conf_hostoffload
502 * Central function to configure the supported offloads,
503 * either enable or disable them.
504 */
505void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
506{
507 hdd_context_t *pHddCtx = NULL;
508 v_CONTEXT_t *pVosContext = NULL;
509 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
510
511 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
512 fenable);
513
514 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
515
516 if (NULL == pVosContext)
517 {
518 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
519 return;
520 }
521
522 //Get the HDD context.
523 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
524
525 if (NULL == pHddCtx)
526 {
527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
528 return;
529 }
530
531 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
532 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
533 {
534 if (fenable)
535 {
536 if (eConnectionState_Associated ==
537 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
538 {
539 if ((pHddCtx->cfg_ini->fhostArpOffload))
540 {
541 /*
542 * Configure the ARP Offload.
543 * Even if it fails we have to reconfigure the MC/BC
544 * filter flag as we want RIVA not to drop BroadCast
545 * Packets
546 */
547 hddLog(VOS_TRACE_LEVEL_INFO,
548 FL("Calling ARP Offload with flag: %d"), fenable);
549 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
550 pHddCtx->configuredMcastBcastFilter &=
551 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
552
553 if (!VOS_IS_STATUS_SUCCESS(vstatus))
554 {
555 hddLog(VOS_TRACE_LEVEL_ERROR,
556 "Failed to enable ARPOFfloadFeature %d",
557 vstatus);
558 }
559 }
560 //Configure GTK_OFFLOAD
561#ifdef WLAN_FEATURE_GTK_OFFLOAD
562 hdd_conf_gtk_offload(pAdapter, fenable);
563#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530564
565#ifdef WLAN_NS_OFFLOAD
566 if (pHddCtx->cfg_ini->fhostNSOffload)
567 {
568 /*
569 * Configure the NS Offload.
570 * Even if it fails we have to reconfigure the MC/BC filter flag
571 * as we want RIVA not to drop Multicast Packets
572 */
573
574 hddLog(VOS_TRACE_LEVEL_INFO,
575 FL("Calling NS Offload with flag: %d"), fenable);
576 hdd_conf_ns_offload(pAdapter, fenable);
577 pHddCtx->configuredMcastBcastFilter &=
578 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
579 }
580#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530581 }
582 }
583 else
584 {
585 //Disable ARPOFFLOAD
586 if (pHddCtx->cfg_ini->fhostArpOffload)
587 {
588 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
589 if (!VOS_IS_STATUS_SUCCESS(vstatus))
590 {
591 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530592 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530593 }
594 }
595 //Disable GTK_OFFLOAD
596#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530597 hdd_conf_gtk_offload(pAdapter, fenable);
598#endif
599
600#ifdef WLAN_NS_OFFLOAD
601 //Disable NSOFFLOAD
602 if (pHddCtx->cfg_ini->fhostNSOffload)
603 {
604 hdd_conf_ns_offload(pAdapter, fenable);
605 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530606#endif
607 }
608 }
609 return;
610}
611
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530612#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530613void hdd_ipv6_notifier_work_queue(struct work_struct *work)
614{
615 hdd_adapter_t* pAdapter =
616 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
617 hdd_context_t *pHddCtx;
618 int status;
619
620 hddLog(LOG1, FL("Reconfiguring NS Offload"));
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530621
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530622 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
623 status = wlan_hdd_validate_context(pHddCtx);
624 if (0 != status)
625 {
626 hddLog(LOGE, FL("HDD context is invalid"));
627 return;
628 }
629
Deepthi Gowri5933f402014-01-23 17:48:24 +0530630 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
631 {
632 pHddCtx->sus_res_mcastbcast_filter =
633 pHddCtx->configuredMcastBcastFilter;
634 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
635 }
636
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530637 if ((eConnectionState_Associated ==
638 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530639 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530640 {
641 // This invocation being part of the IPv6 registration callback,
642 // we are passing second parameter as 2 to avoid registration
643 // of IPv6 notifier again.
644 hdd_conf_ns_offload(pAdapter, 2);
645 }
646}
647
648static int wlan_hdd_ipv6_changed(struct notifier_block *nb,
649 unsigned long data, void *arg)
650{
651 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
652 struct net_device *ndev = ifa->idev->dev;
653 hdd_adapter_t *pAdapter =
654 container_of(nb, struct hdd_adapter_s, ipv6_notifier);
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530655 hdd_context_t *pHddCtx;
656 int status;
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530657
658 if (pAdapter && pAdapter->dev == ndev)
659 {
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
661 status = wlan_hdd_validate_context(pHddCtx);
662 if (0 != status)
663 {
664 hddLog(LOGE, FL("HDD context is invalid"));
665 return NOTIFY_DONE;
666 }
667
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530668 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
669 }
670
671 return NOTIFY_DONE;
672}
673
674/**----------------------------------------------------------------------------
675
676 \brief hdd_conf_ns_offload() - Configure NS offload
677
678 Called during SUSPEND to configure the NS offload (MC BC filter) which
679 reduces power consumption.
680
681 \param - pAdapter - Adapter context for which NS offload is to be configured
682 \param - fenable - 0 - disable.
683 1 - enable. (with IPv6 notifier registration)
684 2 - enable. (without IPv6 notifier registration)
685
686 \return - void
687
688 ---------------------------------------------------------------------------*/
689void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530690{
691 struct inet6_dev *in6_dev;
692 struct inet6_ifaddr *ifp;
693 struct list_head *p;
694 tANI_U8 selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN] = {{0,}};
695 tANI_BOOLEAN selfIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0};
696 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530697 hdd_context_t *pHddCtx;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530698
699 int i =0;
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530700 int ret =0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530701 eHalStatus returnStatus;
702
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530703 ENTER();
704 hddLog(LOG1, FL(" fenable = %d"), fenable);
705
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530706 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
707
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530708 if (fenable)
709 {
710 in6_dev = __in6_dev_get(pAdapter->dev);
711 if (NULL != in6_dev)
712 {
713 //read_lock_bh(&in6_dev->lock);
714 list_for_each(p, &in6_dev->addr_list)
715 {
716 ifp = list_entry(p, struct inet6_ifaddr, if_list);
717 switch(ipv6_addr_src_scope(&ifp->addr))
718 {
719 case IPV6_ADDR_SCOPE_LINKLOCAL:
720 vos_mem_copy(&selfIPv6Addr[0], &ifp->addr.s6_addr,
721 sizeof(ifp->addr.s6_addr));
722 selfIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530723 hddLog (VOS_TRACE_LEVEL_INFO,
724 "Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6",
725 selfIPv6Addr[0]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530726 break;
727 case IPV6_ADDR_SCOPE_GLOBAL:
728 vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr,
729 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530730 selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID;
731 hddLog (VOS_TRACE_LEVEL_INFO,
732 "Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6",
733 selfIPv6Addr[1]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530734 break;
735 default:
736 hddLog(LOGE, "The Scope %d is not supported",
737 ipv6_addr_src_scope(&ifp->addr));
738 }
739
740 }
741 //read_unlock_bh(&in6_dev->lock);
742 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
743 for (i =0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
744 {
745 if (selfIPv6AddrValid[i])
746 {
747 //Filling up the request structure
748 /* Filling the selfIPv6Addr with solicited address
749 * A Solicited-Node multicast address is created by
750 * taking the last 24 bits of a unicast or anycast
751 * address and appending them to the prefix
752 *
753 * FF02:0000:0000:0000:0000:0001:FFXX:XX
754 *
755 * here XX is the unicast/anycast bits
756 */
757 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
758 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
759 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
760 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
761 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = selfIPv6Addr[i][13];
762 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = selfIPv6Addr[i][14];
763 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = selfIPv6Addr[i][15];
764 offLoadRequest.nsOffloadInfo.slotIdx = i;
765
766 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
767 &selfIPv6Addr[i][0], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
768 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
769 &pAdapter->macAddressCurrent.bytes,
770 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
771
772 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
773 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
774 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
775
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530776 hddLog (VOS_TRACE_LEVEL_INFO,
777 "configuredMcastBcastFilter: %d",pHddCtx->configuredMcastBcastFilter);
778
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530779 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
780 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
781 pHddCtx->sus_res_mcastbcast_filter) ||
782 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
783 pHddCtx->sus_res_mcastbcast_filter)))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530784 {
785 hddLog (VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800786 "Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE");
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530787 offLoadRequest.enableOrDisable =
788 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
789 }
790
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530791 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
792 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
793 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
794
795 hddLog (VOS_TRACE_LEVEL_INFO,
796 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
797 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
798 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
799
800 //Configure the Firmware with this
801 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
802 pAdapter->sessionId, &offLoadRequest);
803 if(eHAL_STATUS_SUCCESS != returnStatus)
804 {
805 hddLog(VOS_TRACE_LEVEL_ERROR,
806 FL("Failed to enable HostOffload feature with status: %d"),
807 returnStatus);
808 }
809 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
810 }
811 }
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530812 if (fenable == 1 && !pAdapter->ipv6_notifier_registered)
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530813 {
814 // Register IPv6 notifier to notify if any change in IP
815 // So that we can reconfigure the offload parameters
816 pAdapter->ipv6_notifier.notifier_call =
817 wlan_hdd_ipv6_changed;
818 ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier);
819 if (ret)
820 {
821 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
822 }
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530823 else
824 {
825 hddLog(LOG1, FL("Registered IPv6 notifier"));
826 pAdapter->ipv6_notifier_registered = true;
827 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530828 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530829 }
830 else
831 {
832 hddLog(VOS_TRACE_LEVEL_ERROR,
833 FL("IPv6 dev does not exist. Failed to request NSOffload"));
834 return;
835 }
836 }
837 else
838 {
839 //Disable NSOffload
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530840 if (pAdapter->ipv6_notifier_registered)
841 {
842 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
843 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
844 pAdapter->ipv6_notifier_registered = false;
845 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530846 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
847 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
848 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
849
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530850 //Disable NSOffload on all slots
851 for (i = 0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
852 {
853 offLoadRequest.nsOffloadInfo.slotIdx = i;
854 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530855 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
856 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disable NSOflload"
859 " on slot %d"), i);
860 }
861 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530862 }
863 return;
864}
865#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530866
867void hdd_ipv4_notifier_work_queue(struct work_struct *work)
868{
869 hdd_adapter_t* pAdapter =
870 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
871 hdd_context_t *pHddCtx;
872 int status;
873
874 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
875 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
876 status = wlan_hdd_validate_context(pHddCtx);
877 if (0 != status)
878 {
879 hddLog(LOGE, FL("HDD context is invalid"));
880 return;
881 }
882
Deepthi Gowri5933f402014-01-23 17:48:24 +0530883 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
884 {
885 pHddCtx->sus_res_mcastbcast_filter =
886 pHddCtx->configuredMcastBcastFilter;
887 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
888 }
889
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530890 if ((eConnectionState_Associated ==
891 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530892 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530893 {
894 // This invocation being part of the IPv4 registration callback,
895 // we are passing second parameter as 2 to avoid registration
896 // of IPv4 notifier again.
897 hdd_conf_arp_offload(pAdapter, 2);
898 }
899}
900
901static int wlan_hdd_ipv4_changed(struct notifier_block *nb,
902 unsigned long data, void *arg)
903{
904 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
905 struct in_ifaddr **ifap = NULL;
906 struct in_device *in_dev;
907
908 struct net_device *ndev = ifa->ifa_dev->dev;
909 hdd_adapter_t *pAdapter =
910 container_of(nb, struct hdd_adapter_s, ipv4_notifier);
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530911 hdd_context_t *pHddCtx;
912 int status;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530913 if (pAdapter && pAdapter->dev == ndev)
914 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530915 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
916 status = wlan_hdd_validate_context(pHddCtx);
917 if (0 != status)
918 {
919 hddLog(LOGE, FL("HDD context is invalid"));
920 return NOTIFY_DONE;
921 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530922 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
923 {
924 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
925 ifap = &ifa->ifa_next)
926 {
927 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
928 {
929 break; /* found */
930 }
931 }
932 }
933 if(ifa && ifa->ifa_local)
934 {
935 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
936 }
937 }
938
939 return NOTIFY_DONE;
940}
941
942/**----------------------------------------------------------------------------
943
944 \brief hdd_conf_arp_offload() - Configure ARP offload
945
946 Called during SUSPEND to configure the ARP offload (MC BC filter) which
947 reduces power consumption.
948
949 \param - pAdapter -Adapter context for which ARP offload is to be configured
950 \param - fenable - 0 - disable.
951 1 - enable. (with IPv4 notifier registration)
952 2 - enable. (without IPv4 notifier registration)
953
954 \return -
955 VOS_STATUS_SUCCESS - on successful operation
956 VOS_STATUS_E_FAILURE - on failure of operation
957-----------------------------------------------------------------------------*/
958VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700959{
960 struct in_ifaddr **ifap = NULL;
961 struct in_ifaddr *ifa = NULL;
962 struct in_device *in_dev;
963 int i = 0;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530964 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800966 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700967
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530968 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -0700969
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 if(fenable)
971 {
972 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
973 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530974 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700975 ifap = &ifa->ifa_next)
976 {
977 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
978 {
979 break; /* found */
980 }
981 }
982 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700983 if(ifa && ifa->ifa_local)
984 {
985 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
986 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
987
Arif Hussain6d2a3322013-11-17 19:50:10 -0800988 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700989
Amar Singhald53568e2013-09-26 11:03:45 -0700990 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
991 pHddCtx->sus_res_mcastbcast_filter) ||
992 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
993 pHddCtx->sus_res_mcastbcast_filter)) &&
994 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700995 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530996 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -0700997 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
998 hddLog(VOS_TRACE_LEVEL_INFO,
999 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 }
Amar Singhald53568e2013-09-26 11:03:45 -07001001
1002 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1003 offLoadRequest.enableOrDisable);
1004
Jeff Johnson295189b2012-06-20 16:38:30 -07001005 //converting u32 to IPV4 address
1006 for(i = 0 ; i < 4; i++)
1007 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301008 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001009 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1010 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301011 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 offLoadRequest.params.hostIpv4Addr[0],
1013 offLoadRequest.params.hostIpv4Addr[1],
1014 offLoadRequest.params.hostIpv4Addr[2],
1015 offLoadRequest.params.hostIpv4Addr[3]);
1016
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301017 if (eHAL_STATUS_SUCCESS !=
1018 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1019 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001020 {
1021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001022 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 return VOS_STATUS_E_FAILURE;
1024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001025 }
1026 else
1027 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1029 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001030 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301031
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301032 if (fenable == 1 && !pAdapter->ipv4_notifier_registered)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301033 {
1034 // Register IPv4 notifier to notify if any change in IP
1035 // So that we can reconfigure the offload parameters
1036 pAdapter->ipv4_notifier.notifier_call =
1037 wlan_hdd_ipv4_changed;
1038 ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier);
1039 if (ret)
1040 {
1041 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
1042 }
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301043 else
1044 {
1045 hddLog(LOG1, FL("Registered IPv4 notifier"));
1046 pAdapter->ipv4_notifier_registered = true;
1047 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301048 }
1049 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 }
1051 else
1052 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301053 if (pAdapter->ipv4_notifier_registered)
1054 {
1055 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
1056 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
1057 pAdapter->ipv4_notifier_registered = false;
1058 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001059 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1060 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1061 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1062
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301063 if (eHAL_STATUS_SUCCESS !=
1064 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1065 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001066 {
1067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001068 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001069 return VOS_STATUS_E_FAILURE;
1070 }
1071 return VOS_STATUS_SUCCESS;
1072 }
1073}
1074
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301075/*
1076 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301077 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301078*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301079void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301080 tANI_U8 *pMcBcFilter)
1081{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301082 if (NULL == pHddCtx)
1083 {
1084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1085 return;
1086 }
1087
1088 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1089 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301090 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301091 /* ARP offload is enabled, do not block bcast packets at RXP
1092 * Will be using Bitmasking to reset the filter. As we have
1093 * disable Broadcast filtering, Anding with the negation
1094 * of Broadcast BIT
1095 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301096 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301097 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301098
1099#ifdef WLAN_NS_OFFLOAD
1100 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301101 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301102 /* NS offload is enabled, do not block mcast packets at RXP
1103 * Will be using Bitmasking to reset the filter. As we have
1104 * disable Multicast filtering, Anding with the negation
1105 * of Multicast BIT
1106 */
1107 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301108 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301109#endif
1110
1111 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301112}
1113
Jeff Johnson295189b2012-06-20 16:38:30 -07001114void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1115{
1116 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1118 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1119 if(NULL == wlanRxpFilterParam)
1120 {
1121 hddLog(VOS_TRACE_LEVEL_FATAL,
1122 "%s: vos_mem_alloc failed ", __func__);
1123 return;
1124 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001125 hddLog(VOS_TRACE_LEVEL_INFO,
1126 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301127 if (TRUE == setfilter)
1128 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301129 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301130 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301131 }
1132 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301133 {
1134 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301135 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301136 pHddCtx->configuredMcastBcastFilter;
1137 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301138
Jeff Johnson295189b2012-06-20 16:38:30 -07001139 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001140 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -07001141 if (eHAL_STATUS_SUCCESS != halStatus)
1142 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001143 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1144 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1145}
1146
Jeff Johnson295189b2012-06-20 16:38:30 -07001147static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1148 hdd_adapter_t *pAdapter)
1149{
1150 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1151 tpSirWlanSuspendParam wlanSuspendParam =
1152 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1153
Amar Singhald53568e2013-09-26 11:03:45 -07001154 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1155 pHddCtx->sus_res_mcastbcast_filter =
1156 pHddCtx->configuredMcastBcastFilter;
1157 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1158 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1159 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1160 pHddCtx->configuredMcastBcastFilter);
1161
1162 }
1163
Amar Singhal49fdfd52013-08-13 13:25:12 -07001164
Jeff Johnson295189b2012-06-20 16:38:30 -07001165 if(NULL == wlanSuspendParam)
1166 {
1167 hddLog(VOS_TRACE_LEVEL_FATAL,
1168 "%s: vos_mem_alloc failed ", __func__);
1169 return;
1170 }
1171
Amar Singhald53568e2013-09-26 11:03:45 -07001172 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 "%s: send wlan suspend indication", __func__);
1174
1175 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1176 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301177 //Configure supported OffLoads
1178 hdd_conf_hostoffload(pAdapter, TRUE);
1179 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001180
1181#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301182 /* During suspend, configure MC Addr list filter to the firmware
1183 * function takes care of checking necessary conditions before
1184 * configuring.
1185 */
1186 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001187#endif
1188 }
1189
1190 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1191 if(eHAL_STATUS_SUCCESS == halStatus)
1192 {
1193 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001194 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301195 hddLog(VOS_TRACE_LEVEL_ERROR,
1196 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001197 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 }
1199}
1200
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301201static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001202{
Chilam Ngc4244af2013-04-01 15:37:32 -07001203 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001204 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001205 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001206
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301207 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001208 "%s: send wlan resume indication", __func__);
1209
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301210 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1211
1212 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001213 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301214 hddLog(VOS_TRACE_LEVEL_FATAL,
1215 "%s: memory allocation failed for wlanResumeParam ", __func__);
1216 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001218
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301219 //Disable supported OffLoads
1220 hdd_conf_hostoffload(pAdapter, FALSE);
1221
1222 wlanResumeParam->configuredMcstBcstFilterSetting =
1223 pHddCtx->configuredMcastBcastFilter;
1224 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1225 if (eHAL_STATUS_SUCCESS != halStatus)
1226 {
c_hpothuffdb5272013-10-02 16:42:35 +05301227 hddLog(VOS_TRACE_LEVEL_ERROR,
1228 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301229 vos_mem_free(wlanResumeParam);
1230 }
1231
1232 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1233
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001234 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1235 pHddCtx->configuredMcastBcastFilter =
1236 pHddCtx->sus_res_mcastbcast_filter;
1237 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1238 }
Amar Singhald53568e2013-09-26 11:03:45 -07001239
1240 hddLog(VOS_TRACE_LEVEL_INFO,
1241 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1242 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1243 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001244
Chilam Ngc4244af2013-04-01 15:37:32 -07001245
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301246#ifdef WLAN_FEATURE_PACKET_FILTERING
1247 /* Filer was applied during suspend inditication
1248 * clear it when we resume.
1249 */
1250 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001251#endif
1252}
Jeff Johnson295189b2012-06-20 16:38:30 -07001253
Jeff Johnson295189b2012-06-20 16:38:30 -07001254//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001255void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001256{
1257 hdd_context_t *pHddCtx = NULL;
1258 v_CONTEXT_t pVosContext = NULL;
1259
Jeff Johnson295189b2012-06-20 16:38:30 -07001260 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301261 hdd_adapter_t *pAdapter = NULL;
1262 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301263 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001264
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1266
1267 //Get the global VOSS context.
1268 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1269 if(!pVosContext) {
1270 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1271 return;
1272 }
1273
1274 //Get the HDD context.
1275 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1276
1277 if(!pHddCtx) {
1278 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1279 return;
1280 }
1281
1282 if (pHddCtx->isLogpInProgress) {
1283 hddLog(VOS_TRACE_LEVEL_ERROR,
1284 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1285 return;
1286 }
1287
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301288 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001289 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1290 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1291 {
1292 pAdapter = pAdapterNode->pAdapter;
1293 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001294 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001295 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1296
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001297 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001298 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1299 pAdapterNode = pNext;
1300 continue;
1301 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301302 /* Avoid multiple enter/exit BMPS in this while loop using
1303 * hdd_enter_bmps flag
1304 */
1305 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1306 {
1307 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001308
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301309 /* If device was already in BMPS, and dynamic DTIM is set,
1310 * exit(set the device to full power) and enter BMPS again
1311 * to reflect new DTIM value */
1312 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1313
1314 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1315
1316 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1317 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001318#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1319 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1320 {
1321 //stop the interface before putting the chip to standby
1322 netif_tx_disable(pAdapter->dev);
1323 netif_carrier_off(pAdapter->dev);
1324 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301325 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001326 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1327 {
1328 //Execute deep sleep procedure
1329 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1330 }
1331#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301332
1333 /*Suspend notification sent down to driver*/
1334 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1335
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301336 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1337 pAdapterNode = pNext;
1338 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301339 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301340
Jeff Johnson295189b2012-06-20 16:38:30 -07001341#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1342 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1343 {
1344 hdd_enter_standby(pHddCtx);
1345 }
1346#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001347
1348 return;
1349}
1350
1351static void hdd_PowerStateChangedCB
1352(
1353 v_PVOID_t callbackContext,
1354 tPmcState newState
1355)
1356{
1357 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 /* if the driver was not in BMPS during early suspend,
1359 * the dynamic DTIM is now updated at Riva */
1360 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1361 && pHddCtx->cfg_ini->enableDynamicDTIM
1362 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1363 {
1364 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1365 }
1366 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301367 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1368 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301370 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1371 {
Amar Singhald53568e2013-09-26 11:03:45 -07001372 pHddCtx->sus_res_mcastbcast_filter =
1373 pHddCtx->configuredMcastBcastFilter;
1374 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1375
1376 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1377 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1378 pHddCtx->configuredMcastBcastFilter);
1379 hddLog(VOS_TRACE_LEVEL_INFO,
1380 "offload: calling hdd_conf_mcastbcast_filter");
1381
1382 }
1383
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001385 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1387 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001388 else
Mihir Shete793209f2014-01-06 11:01:12 +05301389 {
1390 /* Android framework can send resume request when the WCN chip is
1391 * in IMPS mode. When the chip exits IMPS mode the firmware will
1392 * restore all the registers to the state they were before the chip
1393 * entered IMPS and so our hardware filter settings confgured by the
1394 * resume request will be lost. So reconfigure the filters on detecting
1395 * a change in the power state of the WCN chip.
1396 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301397 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301398 if (IMPS != newState)
1399 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301400 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301401 if (FALSE == pHddCtx->hdd_wlan_suspended)
1402 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301403 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301404 hddLog(VOS_TRACE_LEVEL_INFO,
1405 "Not in IMPS/BMPS and suspended state");
1406 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1407 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301408 else
1409 {
1410 spin_unlock(&pHddCtx->filter_lock);
1411 }
Mihir Shete793209f2014-01-06 11:01:12 +05301412 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001414}
1415
1416
1417
1418void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1419{
1420 v_CONTEXT_t pVosContext;
1421 tHalHandle smeContext;
1422
1423 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1424 if (NULL == pVosContext)
1425 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001426 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001427 return;
1428 }
1429 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1430 if (NULL == smeContext)
1431 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001432 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001433 return;
1434 }
1435
1436 spin_lock_init(&pHddCtx->filter_lock);
1437 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1438 pHddCtx->cfg_ini->nEnableSuspend)
1439 {
1440 pmcRegisterDeviceStateUpdateInd(smeContext,
1441 hdd_PowerStateChangedCB, pHddCtx);
1442 }
1443}
1444
1445void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1446{
1447 v_CONTEXT_t pVosContext;
1448 tHalHandle smeContext;
1449
1450 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1451 if (NULL == pVosContext)
1452 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001453 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001454 return;
1455 }
1456 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1457 if (NULL == smeContext)
1458 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001459 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 return;
1461 }
1462
1463 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1464 pHddCtx->cfg_ini->nEnableSuspend)
1465 {
1466 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1467 }
1468}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301469
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301470#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301471void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301472{
1473 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301474 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301475 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1476
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301477 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301478 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301479 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1480 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1481 {
1482 vos_mem_copy(&hddGtkOffloadReqParams,
1483 &pHddStaCtx->gtkOffloadReqParams,
1484 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301485
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301486 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1487 &hddGtkOffloadReqParams, pAdapter->sessionId);
1488 if (eHAL_STATUS_SUCCESS != ret)
1489 {
1490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1491 "%s: sme_SetGTKOffload failed, returned %d",
1492 __func__, ret);
1493 return;
1494 }
1495
1496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1497 "%s: sme_SetGTKOffload successfull", __func__);
1498 }
1499
1500 }
1501 else
1502 {
1503 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1504 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1505 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1506 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1507 {
1508
1509 /* Host driver has previously offloaded GTK rekey */
1510 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301511 wlan_hdd_cfg80211_update_replayCounterCallback,
1512 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301513 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301514
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301515 {
1516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1517 "%s: sme_GetGTKOffload failed, returned %d",
1518 __func__, ret);
1519 return;
1520 }
1521 else
1522 {
1523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1524 "%s: sme_GetGTKOffload successful",
1525 __func__);
1526
1527 /* Sending GTK offload dissable */
1528 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1529 sizeof (tSirGtkOffloadParams));
1530 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1531 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301532 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301533 if (eHAL_STATUS_SUCCESS != ret)
1534 {
1535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1536 "%s: failed to dissable GTK offload, returned %d",
1537 __func__, ret);
1538 return;
1539 }
1540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1541 "%s: successfully dissabled GTK offload request to HAL",
1542 __func__);
1543 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301544 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301545 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301546 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301547}
1548#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001549
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001550void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001551{
1552 hdd_context_t *pHddCtx = NULL;
1553 hdd_adapter_t *pAdapter = NULL;
1554 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1555 VOS_STATUS status;
1556 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001557
Jeff Johnson295189b2012-06-20 16:38:30 -07001558 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1559
1560 //Get the global VOSS context.
1561 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1562 if(!pVosContext) {
1563 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1564 return;
1565 }
1566
1567 //Get the HDD context.
1568 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1569
1570 if(!pHddCtx) {
1571 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1572 return;
1573 }
1574
Agarwal Ashish971c2882013-10-30 20:11:12 +05301575 if (pHddCtx->isLogpInProgress)
1576 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001577 hddLog(VOS_TRACE_LEVEL_INFO,
1578 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1579 return;
1580 }
1581
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 pHddCtx->hdd_wlan_suspended = FALSE;
1583 /*loop through all adapters. Concurrency */
1584 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1585
1586 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1587 {
1588 pAdapter = pAdapterNode->pAdapter;
1589 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001590 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001591 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001592 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001593 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1594 pAdapterNode = pNext;
1595 continue;
1596 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301597
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301598
Jeff Johnson295189b2012-06-20 16:38:30 -07001599#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1600 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1601 {
1602 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1603 hdd_exit_deep_sleep(pAdapter);
1604 }
1605#endif
1606
1607 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1608 {
1609 /*Switch back to DTIM 1*/
1610 tSirSetPowerParamsReq powerRequest = { 0 };
1611
1612 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1613 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001614 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001615
1616 /*Disabled ModulatedDTIM if enabled on suspend*/
1617 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1618 powerRequest.uDTIMPeriod = 0;
1619
1620 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1621 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1622 NULL, eANI_BOOLEAN_FALSE);
1623 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1624 NULL, eANI_BOOLEAN_FALSE);
1625
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001627 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001628 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001629
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301630 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1631 {
1632 /* put the device into full power */
1633 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001634
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301635 /* put the device back into BMPS */
1636 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001637
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301638 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 }
1641
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301642 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1644 pAdapterNode = pNext;
1645 }
1646
1647#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1648 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1649 {
1650 hdd_exit_standby(pHddCtx);
1651 }
1652#endif
1653
Jeff Johnson295189b2012-06-20 16:38:30 -07001654 return;
1655}
1656
Jeff Johnson295189b2012-06-20 16:38:30 -07001657VOS_STATUS hdd_wlan_reset_initialization(void)
1658{
Jeff Johnson295189b2012-06-20 16:38:30 -07001659 v_CONTEXT_t pVosContext = NULL;
1660
1661 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1662
1663 //Get the global VOSS context.
1664 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1665 if(!pVosContext)
1666 {
1667 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1668 return VOS_STATUS_E_FAILURE;
1669 }
1670
1671 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1672
1673 // Prevent the phone from going to sleep
1674 hdd_prevent_suspend();
1675
Jeff Johnson295189b2012-06-20 16:38:30 -07001676 return VOS_STATUS_SUCCESS;
1677}
1678
1679
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001680/*
1681 * Based on the ioctl command recieved by HDD, put WLAN driver
1682 * into the quiet mode. This is the same as the early suspend
1683 * notification that driver used to listen
1684 */
1685void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001686{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001687 if (suspend)
1688 hdd_suspend_wlan();
1689 else
1690 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001691}
1692
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001693static void hdd_ssr_timer_init(void)
1694{
1695 init_timer(&ssr_timer);
1696}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001697
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001698static void hdd_ssr_timer_del(void)
1699{
1700 del_timer(&ssr_timer);
1701 ssr_timer_started = false;
1702}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001703
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001704static void hdd_ssr_timer_cb(unsigned long data)
1705{
1706 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001707
1708#ifdef WCN_PRONTO
1709 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1710 wcnss_pronto_log_debug_regs();
1711#endif
1712
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001713 VOS_BUG(0);
1714}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001715
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001716static void hdd_ssr_timer_start(int msec)
1717{
1718 if(ssr_timer_started)
1719 {
1720 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1721 ,__func__);
1722 }
1723 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1724 ssr_timer.function = hdd_ssr_timer_cb;
1725 add_timer(&ssr_timer);
1726 ssr_timer_started = true;
1727}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001728
Jeff Johnson295189b2012-06-20 16:38:30 -07001729/* the HDD interface to WLAN driver shutdown,
1730 * the primary shutdown function in SSR
1731 */
1732VOS_STATUS hdd_wlan_shutdown(void)
1733{
1734 VOS_STATUS vosStatus;
1735 v_CONTEXT_t pVosContext = NULL;
1736 hdd_context_t *pHddCtx = NULL;
1737 pVosSchedContext vosSchedContext = NULL;
c_hpothuffdb5272013-10-02 16:42:35 +05301738 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001739
1740 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1741
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001742 /* if re-init never happens, then do SSR1 */
1743 hdd_ssr_timer_init();
1744 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1745
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 /* Get the global VOSS context. */
1747 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1748 if(!pVosContext) {
1749 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1750 return VOS_STATUS_E_FAILURE;
1751 }
1752 /* Get the HDD context. */
1753 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1754 if(!pHddCtx) {
1755 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1756 return VOS_STATUS_E_FAILURE;
1757 }
c_hpothud662a352013-12-26 15:09:12 +05301758
1759 //Stop the traffic monitor timer
1760 if ( VOS_TIMER_STATE_RUNNING ==
1761 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1762 {
1763 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1764 }
1765
Jeff Johnson295189b2012-06-20 16:38:30 -07001766 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001767 /* DeRegister with platform driver as client for Suspend/Resume */
1768 vosStatus = hddDeregisterPmOps(pHddCtx);
1769 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1770 {
1771 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1772 }
1773
1774 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1775 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1776 {
1777 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1778 }
1779
1780 /* Disable IMPS/BMPS as we do not want the device to enter any power
1781 * save mode on its own during reset sequence
1782 */
1783 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1784 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1785 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1786
1787 vosSchedContext = get_vos_sched_ctxt();
1788
1789 /* Wakeup all driver threads */
1790 if(TRUE == pHddCtx->isMcThreadSuspended){
1791 complete(&vosSchedContext->ResumeMcEvent);
1792 pHddCtx->isMcThreadSuspended= FALSE;
1793 }
1794 if(TRUE == pHddCtx->isTxThreadSuspended){
1795 complete(&vosSchedContext->ResumeTxEvent);
1796 pHddCtx->isTxThreadSuspended= FALSE;
1797 }
1798 if(TRUE == pHddCtx->isRxThreadSuspended){
1799 complete(&vosSchedContext->ResumeRxEvent);
1800 pHddCtx->isRxThreadSuspended= FALSE;
1801 }
1802 /* Reset the Suspend Variable */
1803 pHddCtx->isWlanSuspended = FALSE;
1804
1805 /* Stop all the threads; we do not want any messages to be a processed,
1806 * any more and the best way to ensure that is to terminate the threads
1807 * gracefully.
1808 */
1809 /* Wait for MC to exit */
1810 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1811 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1812 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1813 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301814 ret = wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1815 if (0 >= ret)
1816 {
1817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on McShutdown failed %ld",
1818 __func__, ret);
1819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001820
1821 /* Wait for TX to exit */
1822 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1823 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1824 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1825 wake_up_interruptible(&vosSchedContext->txWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301826 ret = wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1827 if (0 >= ret)
1828 {
1829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on TxShutdown failed %ld",
1830 __func__, ret);
1831 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001832
1833 /* Wait for RX to exit */
1834 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1835 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1836 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1837 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301838
1839 ret = wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1840 if (0 >= ret)
1841 {
1842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on RxShutdown failed %ld",
1843 __func__, ret);
1844 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001845
1846#ifdef WLAN_BTAMP_FEATURE
1847 vosStatus = WLANBAP_Stop(pVosContext);
1848 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1849 {
1850 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1851 "%s: Failed to stop BAP",__func__);
1852 }
1853#endif //WLAN_BTAMP_FEATURE
1854 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301855 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1856 {
1857 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1858 "%s: Failed to stop wda %d", __func__, vosStatus);
1859 VOS_ASSERT(0);
1860 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001861
1862 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1863 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1864 * on threads being running to process the SYS Stop
1865 */
Kiet Lama72a2322013-11-15 11:18:11 +05301866 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301867 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1868 {
1869 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1870 "%s: Failed to stop sme %d", __func__, vosStatus);
1871 VOS_ASSERT(0);
1872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001873
1874 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1875 /* Stop MAC (PE and HAL) */
1876 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301877 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1878 {
1879 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1880 "%s: Failed to stop mac %d", __func__, vosStatus);
1881 VOS_ASSERT(0);
1882 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001883
1884 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1885 /* Stop TL */
1886 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301887 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1888 {
1889 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1890 "%s: Failed to stop TL %d", __func__, vosStatus);
1891 VOS_ASSERT(0);
1892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001893
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1896 /* Clean up message queues of TX and MC thread */
1897 vos_sched_flush_mc_mqs(vosSchedContext);
1898 vos_sched_flush_tx_mqs(vosSchedContext);
1899 vos_sched_flush_rx_mqs(vosSchedContext);
1900
1901 /* Deinit all the TX and MC queues */
1902 vos_sched_deinit_mqs(vosSchedContext);
1903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1904
1905 /* shutdown VOSS */
1906 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301907
1908 /*mac context has already been released in mac_close call
1909 so setting it to NULL in hdd context*/
1910 pHddCtx->hHal = (tHalHandle)NULL;
1911
Jeff Johnson295189b2012-06-20 16:38:30 -07001912 if (free_riva_power_on_lock("wlan"))
1913 {
1914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1915 __func__);
1916 }
1917 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1918 ,__func__);
1919 return VOS_STATUS_SUCCESS;
1920}
1921
1922
1923
1924/* the HDD interface to WLAN driver re-init.
1925 * This is called to initialize/start WLAN driver after a shutdown.
1926 */
1927VOS_STATUS hdd_wlan_re_init(void)
1928{
1929 VOS_STATUS vosStatus;
1930 v_CONTEXT_t pVosContext = NULL;
1931 hdd_context_t *pHddCtx = NULL;
1932 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001933#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1934 int max_retries = 0;
1935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001936#ifdef WLAN_BTAMP_FEATURE
1937 hdd_config_t *pConfig = NULL;
1938 WLANBAP_ConfigType btAmpConfig;
1939#endif
1940
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001941 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001942 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001943
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001944#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1945 /* wait until WCNSS driver downloads NV */
1946 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1947 msleep(1000);
1948 }
1949 if (max_retries >= 5) {
1950 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1951 goto err_re_init;
1952 }
1953#endif
1954
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001955 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
1956
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001957 /* The driver should always be initialized in STA mode after SSR */
1958 hdd_set_conparam(0);
1959
Jeff Johnson295189b2012-06-20 16:38:30 -07001960 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1961 vosStatus = vos_open(&pVosContext, 0);
1962 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1963 {
1964 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1965 goto err_re_init;
1966 }
1967
1968 /* Get the HDD context. */
1969 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1970 if(!pHddCtx)
1971 {
1972 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1973 goto err_vosclose;
1974 }
1975
1976 /* Save the hal context in Adapter */
1977 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1978 if ( NULL == pHddCtx->hHal )
1979 {
1980 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1981 goto err_vosclose;
1982 }
1983
1984 /* Set the SME configuration parameters. */
1985 vosStatus = hdd_set_sme_config(pHddCtx);
1986 if ( VOS_STATUS_SUCCESS != vosStatus )
1987 {
1988 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1989 goto err_vosclose;
1990 }
1991
1992 /* Initialize the WMM module */
1993 vosStatus = hdd_wmm_init(pHddCtx);
1994 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1995 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001996 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 goto err_vosclose;
1998 }
1999
2000 vosStatus = vos_preStart( pHddCtx->pvosContext );
2001 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2002 {
2003 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2004 goto err_vosclose;
2005 }
2006
2007 /* In the integrated architecture we update the configuration from
2008 the INI file and from NV before vOSS has been started so that
2009 the final contents are available to send down to the cCPU */
2010 /* Apply the cfg.ini to cfg.dat */
2011 if (FALSE == hdd_update_config_dat(pHddCtx))
2012 {
2013 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2014 goto err_vosclose;
2015 }
2016
2017 /* Set the MAC Address, currently this is used by HAL to add self sta.
2018 * Remove this once self sta is added as part of session open. */
2019 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2020 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2021 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2022 if (!HAL_STATUS_SUCCESS(halStatus))
2023 {
2024 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2025 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2026 goto err_vosclose;
2027 }
2028
2029 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2030 Note: Firmware image will be read and downloaded inside vos_start API */
2031 vosStatus = vos_start( pVosContext );
2032 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2033 {
2034 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2035 goto err_vosclose;
2036 }
2037
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002038 /* Exchange capability info between Host and FW and also get versioning info from FW */
2039 hdd_exchange_version_and_caps(pHddCtx);
2040
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 vosStatus = hdd_post_voss_start_config( pHddCtx );
2042 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2043 {
2044 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2045 __func__);
2046 goto err_vosstop;
2047 }
2048
2049#ifdef WLAN_BTAMP_FEATURE
2050 vosStatus = WLANBAP_Open(pVosContext);
2051 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2052 {
2053 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2054 "%s: Failed to open BAP",__func__);
2055 goto err_vosstop;
2056 }
2057 vosStatus = BSL_Init(pVosContext);
2058 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2059 {
2060 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2061 "%s: Failed to Init BSL",__func__);
2062 goto err_bap_close;
2063 }
2064 vosStatus = WLANBAP_Start(pVosContext);
2065 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2066 {
2067 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2068 "%s: Failed to start TL",__func__);
2069 goto err_bap_close;
2070 }
2071 pConfig = pHddCtx->cfg_ini;
2072 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2073 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2074#endif //WLAN_BTAMP_FEATURE
2075
2076 /* Restart all adapters */
2077 hdd_start_all_adapters(pHddCtx);
2078 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002079 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002082
2083 /* Register with platform driver as client for Suspend/Resume */
2084 vosStatus = hddRegisterPmOps(pHddCtx);
2085 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2086 {
2087 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2088 goto err_bap_stop;
2089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 /* Allow the phone to go to sleep */
2091 hdd_allow_suspend();
2092 /* register for riva power on lock */
2093 if (req_riva_power_on_lock("wlan"))
2094 {
2095 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2096 __func__);
2097 goto err_unregister_pmops;
2098 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002099 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 goto success;
2101
2102err_unregister_pmops:
2103 hddDeregisterPmOps(pHddCtx);
2104
2105err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002106#ifdef CONFIG_HAS_EARLYSUSPEND
2107 hdd_unregister_mcast_bcast_filter(pHddCtx);
2108#endif
2109 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002110#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002111 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002112#endif
2113
2114#ifdef WLAN_BTAMP_FEATURE
2115err_bap_close:
2116 WLANBAP_Close(pVosContext);
2117#endif
2118
2119err_vosstop:
2120 vos_stop(pVosContext);
2121
2122err_vosclose:
2123 vos_close(pVosContext);
2124 vos_sched_close(pVosContext);
2125 if (pHddCtx)
2126 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 /* Unregister the Net Device Notifier */
2128 unregister_netdevice_notifier(&hdd_netdev_notifier);
2129 /* Clean up HDD Nlink Service */
2130 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002131#ifdef WLAN_KD_READY_NOTIFIER
2132 nl_srv_exit(pHddCtx->ptt_pid);
2133#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002134 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002135#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002136 /* Free up dynamically allocated members inside HDD Adapter */
2137 kfree(pHddCtx->cfg_ini);
2138 pHddCtx->cfg_ini= NULL;
2139
Jeff Johnson295189b2012-06-20 16:38:30 -07002140 wiphy_unregister(pHddCtx->wiphy);
2141 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002142 }
2143 vos_preClose(&pVosContext);
2144
2145#ifdef MEMORY_DEBUG
2146 vos_mem_exit();
2147#endif
2148
2149err_re_init:
2150 /* Allow the phone to go to sleep */
2151 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002152 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002153 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002154 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002155
2156success:
2157 /* Trigger replay of BTC events */
2158 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2159 return VOS_STATUS_SUCCESS;
2160}