blob: 2b72780349ce8416728c9ac2d646a5567a9e7b12 [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;
168
169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
170 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
171
172 g_full_pwr_status = eHAL_STATUS_FAILURE;
173 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
174 eSME_FULL_PWR_NEEDED_BY_HDD);
175
176 if(status == eHAL_STATUS_PMC_PENDING)
177 {
178 //Block on a completion variable. Can't wait forever though
179 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
180 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
181 status = g_full_pwr_status;
182 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
183 {
184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
185 VOS_ASSERT(0);
186 goto failure;
187 }
188 }
189 else if(status != eHAL_STATUS_SUCCESS)
190 {
191 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
192 __func__, status);
193 VOS_ASSERT(0);
194 goto failure;
195 }
196 else
197 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
198
199failure:
200 //No blocking to reduce latency. No other device should be depending on WLAN
201 //to finish resume and WLAN won't be instantly on after resume
202 return status;
203}
204
205
206//Helper routine to put the chip into standby
207VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
208{
209 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
210 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
211
212 //Disable IMPS/BMPS as we do not want the device to enter any power
213 //save mode on its own during suspend sequence
214 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
215 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
216
217 //Note we do not disable queues unnecessarily. Queues should already be disabled
218 //if STA is disconnected or the queue will be disabled as and when disconnect
219 //happens because of standby procedure.
220
221 //Ensure that device is in full power first. There is scope for optimization
222 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
223 //Core s/w needs to be optimized to handle this. Until then we request full
224 //power before issuing request for standby.
225 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
226 g_full_pwr_status = eHAL_STATUS_FAILURE;
227 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
228 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
229
230 if(halStatus == eHAL_STATUS_PMC_PENDING)
231 {
232 //Block on a completion variable. Can't wait forever though
233 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
234 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
235 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
236 {
237 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
238 VOS_ASSERT(0);
239 vosStatus = VOS_STATUS_E_FAILURE;
240 goto failure;
241 }
242 }
243 else if(halStatus != eHAL_STATUS_SUCCESS)
244 {
245 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
246 __func__, halStatus);
247 VOS_ASSERT(0);
248 vosStatus = VOS_STATUS_E_FAILURE;
249 goto failure;
250 }
251
252 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
253 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
254 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
255 }
256
257 //Request standby. Standby will cause the STA to disassociate first. TX queues
258 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
259 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
260 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
261 //when there are concurrent sessions.
262 INIT_COMPLETION(pHddCtx->standby_comp_var);
263 g_standby_status = eHAL_STATUS_FAILURE;
264 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
265
266 if (halStatus == eHAL_STATUS_PMC_PENDING)
267 {
268 //Wait till WLAN device enters standby mode
269 wait_for_completion_timeout(&pHddCtx->standby_comp_var,
270 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
271 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
272 {
273 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
274 VOS_ASSERT(0);
275 vosStatus = VOS_STATUS_E_FAILURE;
276 goto failure;
277 }
278 }
279 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
280 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
281 __func__, halStatus);
282 VOS_ASSERT(0);
283 vosStatus = VOS_STATUS_E_FAILURE;
284 goto failure;
285 }
286 else
287 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
288
289failure:
290 //Restore IMPS config
291 if(pHddCtx->cfg_ini->fIsImpsEnabled)
292 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
293
294 //Restore BMPS config
295 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
296 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
297
298 return vosStatus;
299}
300
301
302//Helper routine for Deep sleep entry
303VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
304{
305 eHalStatus halStatus;
306 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
307 vos_call_status_type callType;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 //Stop the Interface TX queue.
310 netif_tx_disable(pAdapter->dev);
311 netif_carrier_off(pAdapter->dev);
312
313 //Disable IMPS,BMPS as we do not want the device to enter any power
314 //save mode on it own during suspend sequence
315 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
316 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
317
318 //Ensure that device is in full power as we will touch H/W during vos_Stop
319 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
320 g_full_pwr_status = eHAL_STATUS_FAILURE;
321 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
322 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
323
324 if(halStatus == eHAL_STATUS_PMC_PENDING)
325 {
326 //Block on a completion variable. Can't wait forever though
327 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
328 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
329 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
331 VOS_ASSERT(0);
332 }
333 }
334 else if(halStatus != eHAL_STATUS_SUCCESS)
335 {
336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
337 VOS_ASSERT(0);
338 }
339
340 //Issue a disconnect. This is required to inform the supplicant that
341 //STA is getting disassociated and for GUI to be updated properly
342 INIT_COMPLETION(pAdapter->disconnect_comp_var);
343 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
344
345 //Success implies disconnect command got queued up successfully
346 if(halStatus == eHAL_STATUS_SUCCESS)
347 {
348 //Block on a completion variable. Can't wait forever though.
349 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
350 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
351 }
352
353
354 //None of the steps should fail after this. Continue even in case of failure
355 vosStatus = vos_stop( pHddCtx->pvosContext );
356 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
357
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 vosStatus = vos_chipAssertDeepSleep( &callType, NULL, NULL );
359 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
360
361 //Vote off any PMIC voltage supplies
362 vosStatus = vos_chipPowerDown(NULL, NULL, NULL);
363
Jeff Johnson295189b2012-06-20 16:38:30 -0700364 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
365
366 //Restore IMPS config
367 if(pHddCtx->cfg_ini->fIsImpsEnabled)
368 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
369
370 //Restore BMPS config
371 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
372 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
373
Jeff Johnson295189b2012-06-20 16:38:30 -0700374 return vosStatus;
375}
376
377VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
378{
379 VOS_STATUS vosStatus;
380 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700381
382 //Power Up Libra WLAN card first if not already powered up
383 vosStatus = vos_chipPowerUp(NULL,NULL,NULL);
384 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
385 {
386 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
387 "exiting", __func__);
388 goto err_deep_sleep;
389 }
390
Jeff Johnson295189b2012-06-20 16:38:30 -0700391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
392 "%s: calling hdd_set_sme_config",__func__);
393 vosStatus = hdd_set_sme_config( pHddCtx );
394 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
395 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
396 {
397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
398 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700399 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700400 }
401
402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
403 "%s: calling vos_start",__func__);
404 vosStatus = vos_start( pHddCtx->pvosContext );
405 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
406 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
407 {
408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
409 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700410 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700411 }
412
413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
414 "%s: calling hdd_post_voss_start_config",__func__);
415 vosStatus = hdd_post_voss_start_config( pHddCtx );
416 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
417 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
418 {
419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
420 "%s: Failed in hdd_post_voss_start_config",__func__);
421 goto err_voss_stop;
422 }
423
424
425 //Open a SME session for future operation
426 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700427 (tANI_U8 *)&pAdapter->macAddressCurrent,
428 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700429 if ( !HAL_STATUS_SUCCESS( halStatus ) )
430 {
431 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08lx]",
432 halStatus, halStatus );
433 goto err_voss_stop;
434
435 }
436
437 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
438
439 //Trigger the initial scan
440 hdd_wlan_initial_scan(pHddCtx);
441
442 return VOS_STATUS_SUCCESS;
443
444err_voss_stop:
445 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700446err_deep_sleep:
447 return VOS_STATUS_E_FAILURE;
448
449}
450
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530451/*
452 * Function: hdd_conf_hostoffload
453 * Central function to configure the supported offloads,
454 * either enable or disable them.
455 */
456void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
457{
458 hdd_context_t *pHddCtx = NULL;
459 v_CONTEXT_t *pVosContext = NULL;
460 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
461
462 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
463 fenable);
464
465 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
466
467 if (NULL == pVosContext)
468 {
469 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
470 return;
471 }
472
473 //Get the HDD context.
474 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
475
476 if (NULL == pHddCtx)
477 {
478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
479 return;
480 }
481
482 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
483 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
484 {
485 if (fenable)
486 {
487 if (eConnectionState_Associated ==
488 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
489 {
490 if ((pHddCtx->cfg_ini->fhostArpOffload))
491 {
492 /*
493 * Configure the ARP Offload.
494 * Even if it fails we have to reconfigure the MC/BC
495 * filter flag as we want RIVA not to drop BroadCast
496 * Packets
497 */
498 hddLog(VOS_TRACE_LEVEL_INFO,
499 FL("Calling ARP Offload with flag: %d"), fenable);
500 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
501 pHddCtx->configuredMcastBcastFilter &=
502 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
503
504 if (!VOS_IS_STATUS_SUCCESS(vstatus))
505 {
506 hddLog(VOS_TRACE_LEVEL_ERROR,
507 "Failed to enable ARPOFfloadFeature %d",
508 vstatus);
509 }
510 }
511 //Configure GTK_OFFLOAD
512#ifdef WLAN_FEATURE_GTK_OFFLOAD
513 hdd_conf_gtk_offload(pAdapter, fenable);
514#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530515
516#ifdef WLAN_NS_OFFLOAD
517 if (pHddCtx->cfg_ini->fhostNSOffload)
518 {
519 /*
520 * Configure the NS Offload.
521 * Even if it fails we have to reconfigure the MC/BC filter flag
522 * as we want RIVA not to drop Multicast Packets
523 */
524
525 hddLog(VOS_TRACE_LEVEL_INFO,
526 FL("Calling NS Offload with flag: %d"), fenable);
527 hdd_conf_ns_offload(pAdapter, fenable);
528 pHddCtx->configuredMcastBcastFilter &=
529 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
530 }
531#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530532 }
533 }
534 else
535 {
536 //Disable ARPOFFLOAD
537 if (pHddCtx->cfg_ini->fhostArpOffload)
538 {
539 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
540 if (!VOS_IS_STATUS_SUCCESS(vstatus))
541 {
542 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530543 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530544 }
545 }
546 //Disable GTK_OFFLOAD
547#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530548 hdd_conf_gtk_offload(pAdapter, fenable);
549#endif
550
551#ifdef WLAN_NS_OFFLOAD
552 //Disable NSOFFLOAD
553 if (pHddCtx->cfg_ini->fhostNSOffload)
554 {
555 hdd_conf_ns_offload(pAdapter, fenable);
556 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530557#endif
558 }
559 }
560 return;
561}
562
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530563#ifdef WLAN_NS_OFFLOAD
564void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
565{
566 struct inet6_dev *in6_dev;
567 struct inet6_ifaddr *ifp;
568 struct list_head *p;
569 tANI_U8 selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN] = {{0,}};
570 tANI_BOOLEAN selfIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0};
571 tSirHostOffloadReq offLoadRequest;
572
573 int i =0;
574 eHalStatus returnStatus;
575
576 ENTER();
577 if (fenable)
578 {
579 in6_dev = __in6_dev_get(pAdapter->dev);
580 if (NULL != in6_dev)
581 {
582 //read_lock_bh(&in6_dev->lock);
583 list_for_each(p, &in6_dev->addr_list)
584 {
585 ifp = list_entry(p, struct inet6_ifaddr, if_list);
586 switch(ipv6_addr_src_scope(&ifp->addr))
587 {
588 case IPV6_ADDR_SCOPE_LINKLOCAL:
589 vos_mem_copy(&selfIPv6Addr[0], &ifp->addr.s6_addr,
590 sizeof(ifp->addr.s6_addr));
591 selfIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
592 break;
593 case IPV6_ADDR_SCOPE_GLOBAL:
594 vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr,
595 sizeof(ifp->addr.s6_addr));
596 selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID;;
597 break;
598 default:
599 hddLog(LOGE, "The Scope %d is not supported",
600 ipv6_addr_src_scope(&ifp->addr));
601 }
602
603 }
604 //read_unlock_bh(&in6_dev->lock);
605 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
606 for (i =0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
607 {
608 if (selfIPv6AddrValid[i])
609 {
610 //Filling up the request structure
611 /* Filling the selfIPv6Addr with solicited address
612 * A Solicited-Node multicast address is created by
613 * taking the last 24 bits of a unicast or anycast
614 * address and appending them to the prefix
615 *
616 * FF02:0000:0000:0000:0000:0001:FFXX:XX
617 *
618 * here XX is the unicast/anycast bits
619 */
620 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
621 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
622 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
623 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
624 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = selfIPv6Addr[i][13];
625 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = selfIPv6Addr[i][14];
626 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = selfIPv6Addr[i][15];
627 offLoadRequest.nsOffloadInfo.slotIdx = i;
628
629 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
630 &selfIPv6Addr[i][0], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
631 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
632 &pAdapter->macAddressCurrent.bytes,
633 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
634
635 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
636 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
637 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
638
639 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
640 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
641 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
642
643 hddLog (VOS_TRACE_LEVEL_INFO,
644 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
645 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
646 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
647
648 //Configure the Firmware with this
649 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
650 pAdapter->sessionId, &offLoadRequest);
651 if(eHAL_STATUS_SUCCESS != returnStatus)
652 {
653 hddLog(VOS_TRACE_LEVEL_ERROR,
654 FL("Failed to enable HostOffload feature with status: %d"),
655 returnStatus);
656 }
657 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
658 }
659 }
660 }
661 else
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("IPv6 dev does not exist. Failed to request NSOffload"));
665 return;
666 }
667 }
668 else
669 {
670 //Disable NSOffload
671 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
672 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
673 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
674
675 if (eHAL_STATUS_SUCCESS !=
676 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
677 pAdapter->sessionId, &offLoadRequest))
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
680 "NSOffload feature"));
681 }
682 }
683 return;
684}
685#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530686VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700687{
688 struct in_ifaddr **ifap = NULL;
689 struct in_ifaddr *ifa = NULL;
690 struct in_device *in_dev;
691 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800693 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700694
695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700696
Jeff Johnson295189b2012-06-20 16:38:30 -0700697 if(fenable)
698 {
699 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
700 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530701 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 ifap = &ifa->ifa_next)
703 {
704 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
705 {
706 break; /* found */
707 }
708 }
709 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 if(ifa && ifa->ifa_local)
711 {
712 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
713 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
714
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700716
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530717 if((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
718 pHddCtx->configuredMcastBcastFilter) ||
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700719 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530720 pHddCtx->configuredMcastBcastFilter))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700721 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530722 offLoadRequest.enableOrDisable =
723 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700724 }
725
726 //converting u32 to IPV4 address
727 for(i = 0 ; i < 4; i++)
728 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530729 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 (ifa->ifa_local >> (i*8) ) & 0xFF ;
731 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530732 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 offLoadRequest.params.hostIpv4Addr[0],
734 offLoadRequest.params.hostIpv4Addr[1],
735 offLoadRequest.params.hostIpv4Addr[2],
736 offLoadRequest.params.hostIpv4Addr[3]);
737
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530738 if (eHAL_STATUS_SUCCESS !=
739 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
740 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700741 {
742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
743 "feature\n", __func__);
744 return VOS_STATUS_E_FAILURE;
745 }
746 return VOS_STATUS_SUCCESS;
747 }
748 else
749 {
750 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned \n", __func__);
751 return VOS_STATUS_E_AGAIN;
752 }
753 }
754 else
755 {
756 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
757 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
758 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
759
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530760 if (eHAL_STATUS_SUCCESS !=
761 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
762 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700763 {
764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
765 "offload feature\n", __func__);
766 return VOS_STATUS_E_FAILURE;
767 }
768 return VOS_STATUS_SUCCESS;
769 }
770}
771
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530772/*
773 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530774 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530775*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530776void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530777 tANI_U8 *pMcBcFilter)
778{
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530779 if (NULL == pHddCtx)
780 {
781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
782 return;
783 }
784
785 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
786 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530787 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530788 /* ARP offload is enabled, do not block bcast packets at RXP
789 * Will be using Bitmasking to reset the filter. As we have
790 * disable Broadcast filtering, Anding with the negation
791 * of Broadcast BIT
792 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530793 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530794 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530795
796#ifdef WLAN_NS_OFFLOAD
797 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530798 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530799 /* NS offload is enabled, do not block mcast packets at RXP
800 * Will be using Bitmasking to reset the filter. As we have
801 * disable Multicast filtering, Anding with the negation
802 * of Multicast BIT
803 */
804 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530805 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530806#endif
807
808 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530809}
810
Jeff Johnson295189b2012-06-20 16:38:30 -0700811void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
812{
813 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700814 tpSirWlanSetRxpFilters wlanRxpFilterParam =
815 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
816 if(NULL == wlanRxpFilterParam)
817 {
818 hddLog(VOS_TRACE_LEVEL_FATAL,
819 "%s: vos_mem_alloc failed ", __func__);
820 return;
821 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 hddLog(VOS_TRACE_LEVEL_INFO,
823 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530824 if (TRUE == setfilter)
825 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530826 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530827 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530828 }
829 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530830 {
831 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530832 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530833 pHddCtx->configuredMcastBcastFilter;
834 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530835
Jeff Johnson295189b2012-06-20 16:38:30 -0700836 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -0700838 if (eHAL_STATUS_SUCCESS != halStatus)
839 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
841 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
842}
843
Jeff Johnson295189b2012-06-20 16:38:30 -0700844static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
845 hdd_adapter_t *pAdapter)
846{
847 eHalStatus halStatus = eHAL_STATUS_FAILURE;
848 tpSirWlanSuspendParam wlanSuspendParam =
849 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
850
Amar Singhal49fdfd52013-08-13 13:25:12 -0700851 pHddCtx->sus_res_mcastbcast_filter =
852 pHddCtx->configuredMcastBcastFilter;
853
Jeff Johnson295189b2012-06-20 16:38:30 -0700854 if(NULL == wlanSuspendParam)
855 {
856 hddLog(VOS_TRACE_LEVEL_FATAL,
857 "%s: vos_mem_alloc failed ", __func__);
858 return;
859 }
860
861 hddLog(VOS_TRACE_LEVEL_INFO,
862 "%s: send wlan suspend indication", __func__);
863
864 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
865 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530866 //Configure supported OffLoads
867 hdd_conf_hostoffload(pAdapter, TRUE);
868 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700869
870#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530871 /* During suspend, configure MC Addr list filter to the firmware
872 * function takes care of checking necessary conditions before
873 * configuring.
874 */
875 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700876#endif
877 }
878
879 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
880 if(eHAL_STATUS_SUCCESS == halStatus)
881 {
882 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -0700883 } else {
884 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700885 }
886}
887
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530888static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700889{
Chilam Ngc4244af2013-04-01 15:37:32 -0700890 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -0800891 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -0700892 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -0700893
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530894 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 "%s: send wlan resume indication", __func__);
896
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530897 if (pHddCtx->hdd_mcastbcast_filter_set == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700898 {
Chilam Ngc4244af2013-04-01 15:37:32 -0700899 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
900
901 if(NULL == wlanResumeParam)
902 {
903 hddLog(VOS_TRACE_LEVEL_FATAL,
904 "%s: vos_mem_alloc failed ", __func__);
905 return;
906 }
907
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530908 //Disable supported OffLoads
909 hdd_conf_hostoffload(pAdapter, FALSE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530910
911 wlanResumeParam->configuredMcstBcstFilterSetting =
912 pHddCtx->configuredMcastBcastFilter;
Chilam Ngc4244af2013-04-01 15:37:32 -0700913 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
914 if (eHAL_STATUS_SUCCESS != halStatus)
915 vos_mem_free(wlanResumeParam);
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530916 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700917 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700918
Amar Singhal49fdfd52013-08-13 13:25:12 -0700919 pHddCtx->configuredMcastBcastFilter =
920 pHddCtx->sus_res_mcastbcast_filter;
921
Chilam Ngc4244af2013-04-01 15:37:32 -0700922
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530923#ifdef WLAN_FEATURE_PACKET_FILTERING
924 /* Filer was applied during suspend inditication
925 * clear it when we resume.
926 */
927 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700928#endif
929}
Jeff Johnson295189b2012-06-20 16:38:30 -0700930
Jeff Johnson295189b2012-06-20 16:38:30 -0700931//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800932void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -0700933{
934 hdd_context_t *pHddCtx = NULL;
935 v_CONTEXT_t pVosContext = NULL;
936
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530938 hdd_adapter_t *pAdapter = NULL;
939 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +0530940 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800941
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
943
944 //Get the global VOSS context.
945 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
946 if(!pVosContext) {
947 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
948 return;
949 }
950
951 //Get the HDD context.
952 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
953
954 if(!pHddCtx) {
955 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
956 return;
957 }
958
959 if (pHddCtx->isLogpInProgress) {
960 hddLog(VOS_TRACE_LEVEL_ERROR,
961 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
962 return;
963 }
964
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530965 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700966 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
967 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
968 {
969 pAdapter = pAdapterNode->pAdapter;
Leo Chang9056f462013-08-01 19:21:11 -0700970
971#ifdef FEATURE_WLAN_LPHB
972 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
973 (pHddCtx->lphbEnableReq.enable))
974 {
975 tSirLPHBReq *hb_params = NULL;
976
977 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
978 if (NULL == hb_params)
979 {
980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
981 "%s: hb_params alloc failed", __func__);
982 }
983 else
984 {
985 eHalStatus smeStatus;
986
987 hb_params->cmd = LPHB_SET_EN_PARAMS_INDID;
988 hb_params->params.lphbEnableReq.enable =
989 pHddCtx->lphbEnableReq.enable;
990 hb_params->params.lphbEnableReq.item =
991 pHddCtx->lphbEnableReq.item;
992 hb_params->params.lphbEnableReq.session =
993 pHddCtx->lphbEnableReq.session;
994 /* If WLAN is suspend state, send enable command immediately */
995 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
996 hb_params,
997 NULL);
998 if (eHAL_STATUS_SUCCESS != smeStatus)
999 {
1000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1001 "LPHB Config Fail, disable");
1002 pHddCtx->lphbEnableReq.enable = 0;
1003 vos_mem_free(hb_params);
1004 }
1005 }
1006 }
1007#endif /* FEATURE_WLAN_LPHB */
1008
Jeff Johnson295189b2012-06-20 16:38:30 -07001009 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001010 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1012
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001013 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001014 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1015 pAdapterNode = pNext;
1016 continue;
1017 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301018 /* Avoid multiple enter/exit BMPS in this while loop using
1019 * hdd_enter_bmps flag
1020 */
1021 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1022 {
1023 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001024
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301025 /* If device was already in BMPS, and dynamic DTIM is set,
1026 * exit(set the device to full power) and enter BMPS again
1027 * to reflect new DTIM value */
1028 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1029
1030 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1031
1032 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001034#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1035 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1036 {
1037 //stop the interface before putting the chip to standby
1038 netif_tx_disable(pAdapter->dev);
1039 netif_carrier_off(pAdapter->dev);
1040 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301041 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1043 {
1044 //Execute deep sleep procedure
1045 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1046 }
1047#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301048
1049 /*Suspend notification sent down to driver*/
1050 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1051
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301052 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1053 pAdapterNode = pNext;
1054 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301055 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301056
Jeff Johnson295189b2012-06-20 16:38:30 -07001057#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1058 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1059 {
1060 hdd_enter_standby(pHddCtx);
1061 }
1062#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001063
1064 return;
1065}
1066
1067static void hdd_PowerStateChangedCB
1068(
1069 v_PVOID_t callbackContext,
1070 tPmcState newState
1071)
1072{
1073 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 /* if the driver was not in BMPS during early suspend,
1075 * the dynamic DTIM is now updated at Riva */
1076 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1077 && pHddCtx->cfg_ini->enableDynamicDTIM
1078 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1079 {
1080 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1081 }
1082 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301083 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 spin_unlock(&pHddCtx->filter_lock);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001085 pHddCtx->sus_res_mcastbcast_filter = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001087 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1089 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001090 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001091 spin_unlock(&pHddCtx->filter_lock);
1092}
1093
1094
1095
1096void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1097{
1098 v_CONTEXT_t pVosContext;
1099 tHalHandle smeContext;
1100
1101 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1102 if (NULL == pVosContext)
1103 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001104 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 return;
1106 }
1107 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1108 if (NULL == smeContext)
1109 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001110 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001111 return;
1112 }
1113
1114 spin_lock_init(&pHddCtx->filter_lock);
1115 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1116 pHddCtx->cfg_ini->nEnableSuspend)
1117 {
1118 pmcRegisterDeviceStateUpdateInd(smeContext,
1119 hdd_PowerStateChangedCB, pHddCtx);
1120 }
1121}
1122
1123void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1124{
1125 v_CONTEXT_t pVosContext;
1126 tHalHandle smeContext;
1127
1128 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1129 if (NULL == pVosContext)
1130 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001131 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 return;
1133 }
1134 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1135 if (NULL == smeContext)
1136 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001137 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001138 return;
1139 }
1140
1141 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1142 pHddCtx->cfg_ini->nEnableSuspend)
1143 {
1144 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1145 }
1146}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301147
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301148#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301149void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301150{
1151 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301152 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301153 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1154
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301155 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301156 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301157 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1158 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1159 {
1160 vos_mem_copy(&hddGtkOffloadReqParams,
1161 &pHddStaCtx->gtkOffloadReqParams,
1162 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301163
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301164 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1165 &hddGtkOffloadReqParams, pAdapter->sessionId);
1166 if (eHAL_STATUS_SUCCESS != ret)
1167 {
1168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1169 "%s: sme_SetGTKOffload failed, returned %d",
1170 __func__, ret);
1171 return;
1172 }
1173
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1175 "%s: sme_SetGTKOffload successfull", __func__);
1176 }
1177
1178 }
1179 else
1180 {
1181 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1182 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1183 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1184 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1185 {
1186
1187 /* Host driver has previously offloaded GTK rekey */
1188 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301189 wlan_hdd_cfg80211_update_replayCounterCallback,
1190 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301191 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301192
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301193 {
1194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1195 "%s: sme_GetGTKOffload failed, returned %d",
1196 __func__, ret);
1197 return;
1198 }
1199 else
1200 {
1201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1202 "%s: sme_GetGTKOffload successful",
1203 __func__);
1204
1205 /* Sending GTK offload dissable */
1206 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1207 sizeof (tSirGtkOffloadParams));
1208 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1209 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301210 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301211 if (eHAL_STATUS_SUCCESS != ret)
1212 {
1213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1214 "%s: failed to dissable GTK offload, returned %d",
1215 __func__, ret);
1216 return;
1217 }
1218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1219 "%s: successfully dissabled GTK offload request to HAL",
1220 __func__);
1221 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301222 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301223 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301224 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301225}
1226#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001227
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001228void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001229{
1230 hdd_context_t *pHddCtx = NULL;
1231 hdd_adapter_t *pAdapter = NULL;
1232 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1233 VOS_STATUS status;
1234 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001235
Jeff Johnson295189b2012-06-20 16:38:30 -07001236 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1237
1238 //Get the global VOSS context.
1239 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1240 if(!pVosContext) {
1241 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1242 return;
1243 }
1244
1245 //Get the HDD context.
1246 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1247
1248 if(!pHddCtx) {
1249 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1250 return;
1251 }
1252
1253 if (pHddCtx->isLogpInProgress) {
1254 hddLog(VOS_TRACE_LEVEL_INFO,
1255 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1256 return;
1257 }
1258
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 pHddCtx->hdd_wlan_suspended = FALSE;
1260 /*loop through all adapters. Concurrency */
1261 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1262
1263 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1264 {
1265 pAdapter = pAdapterNode->pAdapter;
1266 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001267 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001268 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001269 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001270 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1271 pAdapterNode = pNext;
1272 continue;
1273 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301274
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301275
Jeff Johnson295189b2012-06-20 16:38:30 -07001276#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1277 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1278 {
1279 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1280 hdd_exit_deep_sleep(pAdapter);
1281 }
1282#endif
1283
1284 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1285 {
1286 /*Switch back to DTIM 1*/
1287 tSirSetPowerParamsReq powerRequest = { 0 };
1288
1289 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1290 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001291 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001292
1293 /*Disabled ModulatedDTIM if enabled on suspend*/
1294 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1295 powerRequest.uDTIMPeriod = 0;
1296
1297 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1298 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1299 NULL, eANI_BOOLEAN_FALSE);
1300 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1301 NULL, eANI_BOOLEAN_FALSE);
1302
1303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1304 "Switch to DTIM%d \n",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001305 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001306
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301307 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1308 {
1309 /* put the device into full power */
1310 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001311
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301312 /* put the device back into BMPS */
1313 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001314
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301315 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 }
1318
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301319 hdd_conf_resume_ind(pAdapter);
Leo Chang9056f462013-08-01 19:21:11 -07001320
1321#ifdef FEATURE_WLAN_LPHB
1322 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
1323 (pHddCtx->lphbEnableReq.enable))
1324 {
1325 tSirLPHBReq *hb_params = NULL;
1326
1327 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
1328 if (NULL == hb_params)
1329 {
1330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1331 "%s: hb_params alloc failed", __func__);
1332 }
1333 else
1334 {
1335 eHalStatus smeStatus;
1336
1337 hb_params->cmd = LPHB_SET_EN_PARAMS_INDID;
1338 hb_params->params.lphbEnableReq.enable = 0;
1339 hb_params->params.lphbEnableReq.item =
1340 pHddCtx->lphbEnableReq.item;
1341 hb_params->params.lphbEnableReq.session =
1342 pHddCtx->lphbEnableReq.session;
1343 /* If WLAN is suspend state, send enable command immediately */
1344 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
1345 hb_params,
1346 NULL);
1347 if (eHAL_STATUS_SUCCESS != smeStatus)
1348 {
1349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1350 "LPHB Config Fail, disable");
1351 pHddCtx->lphbEnableReq.enable = 0;
1352 vos_mem_free(hb_params);
1353 }
1354 }
1355 }
1356#endif /* FEATURE_WLAN_LPHB */
1357
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1359 pAdapterNode = pNext;
1360 }
1361
1362#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1363 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1364 {
1365 hdd_exit_standby(pHddCtx);
1366 }
1367#endif
1368
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 return;
1370}
1371
Jeff Johnson295189b2012-06-20 16:38:30 -07001372VOS_STATUS hdd_wlan_reset_initialization(void)
1373{
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 v_CONTEXT_t pVosContext = NULL;
1375
1376 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1377
1378 //Get the global VOSS context.
1379 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1380 if(!pVosContext)
1381 {
1382 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1383 return VOS_STATUS_E_FAILURE;
1384 }
1385
1386 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1387
1388 // Prevent the phone from going to sleep
1389 hdd_prevent_suspend();
1390
Jeff Johnson295189b2012-06-20 16:38:30 -07001391 return VOS_STATUS_SUCCESS;
1392}
1393
1394
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001395/*
1396 * Based on the ioctl command recieved by HDD, put WLAN driver
1397 * into the quiet mode. This is the same as the early suspend
1398 * notification that driver used to listen
1399 */
1400void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001401{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001402 if (suspend)
1403 hdd_suspend_wlan();
1404 else
1405 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001406}
1407
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001408static void hdd_ssr_timer_init(void)
1409{
1410 init_timer(&ssr_timer);
1411}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001412
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001413static void hdd_ssr_timer_del(void)
1414{
1415 del_timer(&ssr_timer);
1416 ssr_timer_started = false;
1417}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001418
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001419static void hdd_ssr_timer_cb(unsigned long data)
1420{
1421 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001422
1423#ifdef WCN_PRONTO
1424 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1425 wcnss_pronto_log_debug_regs();
1426#endif
1427
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001428 VOS_BUG(0);
1429}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001430
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001431static void hdd_ssr_timer_start(int msec)
1432{
1433 if(ssr_timer_started)
1434 {
1435 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1436 ,__func__);
1437 }
1438 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1439 ssr_timer.function = hdd_ssr_timer_cb;
1440 add_timer(&ssr_timer);
1441 ssr_timer_started = true;
1442}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001443
Jeff Johnson295189b2012-06-20 16:38:30 -07001444/* the HDD interface to WLAN driver shutdown,
1445 * the primary shutdown function in SSR
1446 */
1447VOS_STATUS hdd_wlan_shutdown(void)
1448{
1449 VOS_STATUS vosStatus;
1450 v_CONTEXT_t pVosContext = NULL;
1451 hdd_context_t *pHddCtx = NULL;
1452 pVosSchedContext vosSchedContext = NULL;
1453
1454 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1455
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001456 /* if re-init never happens, then do SSR1 */
1457 hdd_ssr_timer_init();
1458 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1459
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 /* Get the global VOSS context. */
1461 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1462 if(!pVosContext) {
1463 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1464 return VOS_STATUS_E_FAILURE;
1465 }
1466 /* Get the HDD context. */
1467 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1468 if(!pHddCtx) {
1469 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1470 return VOS_STATUS_E_FAILURE;
1471 }
1472 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001473 /* DeRegister with platform driver as client for Suspend/Resume */
1474 vosStatus = hddDeregisterPmOps(pHddCtx);
1475 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1476 {
1477 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1478 }
1479
1480 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1481 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1482 {
1483 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1484 }
1485
1486 /* Disable IMPS/BMPS as we do not want the device to enter any power
1487 * save mode on its own during reset sequence
1488 */
1489 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1490 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1491 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1492
1493 vosSchedContext = get_vos_sched_ctxt();
1494
1495 /* Wakeup all driver threads */
1496 if(TRUE == pHddCtx->isMcThreadSuspended){
1497 complete(&vosSchedContext->ResumeMcEvent);
1498 pHddCtx->isMcThreadSuspended= FALSE;
1499 }
1500 if(TRUE == pHddCtx->isTxThreadSuspended){
1501 complete(&vosSchedContext->ResumeTxEvent);
1502 pHddCtx->isTxThreadSuspended= FALSE;
1503 }
1504 if(TRUE == pHddCtx->isRxThreadSuspended){
1505 complete(&vosSchedContext->ResumeRxEvent);
1506 pHddCtx->isRxThreadSuspended= FALSE;
1507 }
1508 /* Reset the Suspend Variable */
1509 pHddCtx->isWlanSuspended = FALSE;
1510
1511 /* Stop all the threads; we do not want any messages to be a processed,
1512 * any more and the best way to ensure that is to terminate the threads
1513 * gracefully.
1514 */
1515 /* Wait for MC to exit */
1516 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1517 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1518 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1519 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1520 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1521
1522 /* Wait for TX to exit */
1523 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1524 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1525 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1526 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1527 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1528
1529 /* Wait for RX to exit */
1530 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1531 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1532 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1533 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1534 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1535
1536#ifdef WLAN_BTAMP_FEATURE
1537 vosStatus = WLANBAP_Stop(pVosContext);
1538 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1539 {
1540 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1541 "%s: Failed to stop BAP",__func__);
1542 }
1543#endif //WLAN_BTAMP_FEATURE
1544 vosStatus = vos_wda_shutdown(pVosContext);
1545 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1546
1547 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1548 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1549 * on threads being running to process the SYS Stop
1550 */
1551 vosStatus = sme_Stop(pHddCtx->hHal, TRUE);
1552 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1553
1554 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1555 /* Stop MAC (PE and HAL) */
1556 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1557 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1558
1559 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1560 /* Stop TL */
1561 vosStatus = WLANTL_Stop(pVosContext);
1562 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1563
Jeff Johnson295189b2012-06-20 16:38:30 -07001564 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1566 /* Clean up message queues of TX and MC thread */
1567 vos_sched_flush_mc_mqs(vosSchedContext);
1568 vos_sched_flush_tx_mqs(vosSchedContext);
1569 vos_sched_flush_rx_mqs(vosSchedContext);
1570
1571 /* Deinit all the TX and MC queues */
1572 vos_sched_deinit_mqs(vosSchedContext);
1573 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1574
1575 /* shutdown VOSS */
1576 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301577
1578 /*mac context has already been released in mac_close call
1579 so setting it to NULL in hdd context*/
1580 pHddCtx->hHal = (tHalHandle)NULL;
1581
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 if (free_riva_power_on_lock("wlan"))
1583 {
1584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1585 __func__);
1586 }
1587 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1588 ,__func__);
1589 return VOS_STATUS_SUCCESS;
1590}
1591
1592
1593
1594/* the HDD interface to WLAN driver re-init.
1595 * This is called to initialize/start WLAN driver after a shutdown.
1596 */
1597VOS_STATUS hdd_wlan_re_init(void)
1598{
1599 VOS_STATUS vosStatus;
1600 v_CONTEXT_t pVosContext = NULL;
1601 hdd_context_t *pHddCtx = NULL;
1602 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001603#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1604 int max_retries = 0;
1605#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001606#ifdef WLAN_BTAMP_FEATURE
1607 hdd_config_t *pConfig = NULL;
1608 WLANBAP_ConfigType btAmpConfig;
1609#endif
1610
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001611 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001612 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001613
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001614#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1615 /* wait until WCNSS driver downloads NV */
1616 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1617 msleep(1000);
1618 }
1619 if (max_retries >= 5) {
1620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1621 goto err_re_init;
1622 }
1623#endif
1624
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001625 /* The driver should always be initialized in STA mode after SSR */
1626 hdd_set_conparam(0);
1627
Jeff Johnson295189b2012-06-20 16:38:30 -07001628 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1629 vosStatus = vos_open(&pVosContext, 0);
1630 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1631 {
1632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1633 goto err_re_init;
1634 }
1635
1636 /* Get the HDD context. */
1637 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1638 if(!pHddCtx)
1639 {
1640 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1641 goto err_vosclose;
1642 }
1643
1644 /* Save the hal context in Adapter */
1645 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1646 if ( NULL == pHddCtx->hHal )
1647 {
1648 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1649 goto err_vosclose;
1650 }
1651
1652 /* Set the SME configuration parameters. */
1653 vosStatus = hdd_set_sme_config(pHddCtx);
1654 if ( VOS_STATUS_SUCCESS != vosStatus )
1655 {
1656 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1657 goto err_vosclose;
1658 }
1659
1660 /* Initialize the WMM module */
1661 vosStatus = hdd_wmm_init(pHddCtx);
1662 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1663 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001664 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 goto err_vosclose;
1666 }
1667
1668 vosStatus = vos_preStart( pHddCtx->pvosContext );
1669 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1670 {
1671 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1672 goto err_vosclose;
1673 }
1674
1675 /* In the integrated architecture we update the configuration from
1676 the INI file and from NV before vOSS has been started so that
1677 the final contents are available to send down to the cCPU */
1678 /* Apply the cfg.ini to cfg.dat */
1679 if (FALSE == hdd_update_config_dat(pHddCtx))
1680 {
1681 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1682 goto err_vosclose;
1683 }
1684
1685 /* Set the MAC Address, currently this is used by HAL to add self sta.
1686 * Remove this once self sta is added as part of session open. */
1687 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1688 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1689 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1690 if (!HAL_STATUS_SUCCESS(halStatus))
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1693 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1694 goto err_vosclose;
1695 }
1696
1697 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1698 Note: Firmware image will be read and downloaded inside vos_start API */
1699 vosStatus = vos_start( pVosContext );
1700 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1701 {
1702 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1703 goto err_vosclose;
1704 }
1705
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001706 /* Exchange capability info between Host and FW and also get versioning info from FW */
1707 hdd_exchange_version_and_caps(pHddCtx);
1708
Jeff Johnson295189b2012-06-20 16:38:30 -07001709 vosStatus = hdd_post_voss_start_config( pHddCtx );
1710 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1711 {
1712 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1713 __func__);
1714 goto err_vosstop;
1715 }
1716
1717#ifdef WLAN_BTAMP_FEATURE
1718 vosStatus = WLANBAP_Open(pVosContext);
1719 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1720 {
1721 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1722 "%s: Failed to open BAP",__func__);
1723 goto err_vosstop;
1724 }
1725 vosStatus = BSL_Init(pVosContext);
1726 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1727 {
1728 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1729 "%s: Failed to Init BSL",__func__);
1730 goto err_bap_close;
1731 }
1732 vosStatus = WLANBAP_Start(pVosContext);
1733 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1734 {
1735 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1736 "%s: Failed to start TL",__func__);
1737 goto err_bap_close;
1738 }
1739 pConfig = pHddCtx->cfg_ini;
1740 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1741 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1742#endif //WLAN_BTAMP_FEATURE
1743
1744 /* Restart all adapters */
1745 hdd_start_all_adapters(pHddCtx);
1746 pHddCtx->isLogpInProgress = FALSE;
1747 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001749
1750 /* Register with platform driver as client for Suspend/Resume */
1751 vosStatus = hddRegisterPmOps(pHddCtx);
1752 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1753 {
1754 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1755 goto err_bap_stop;
1756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001757 /* Allow the phone to go to sleep */
1758 hdd_allow_suspend();
1759 /* register for riva power on lock */
1760 if (req_riva_power_on_lock("wlan"))
1761 {
1762 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1763 __func__);
1764 goto err_unregister_pmops;
1765 }
1766 goto success;
1767
1768err_unregister_pmops:
1769 hddDeregisterPmOps(pHddCtx);
1770
1771err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001772#ifdef CONFIG_HAS_EARLYSUSPEND
1773 hdd_unregister_mcast_bcast_filter(pHddCtx);
1774#endif
1775 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001776#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001777 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001778#endif
1779
1780#ifdef WLAN_BTAMP_FEATURE
1781err_bap_close:
1782 WLANBAP_Close(pVosContext);
1783#endif
1784
1785err_vosstop:
1786 vos_stop(pVosContext);
1787
1788err_vosclose:
1789 vos_close(pVosContext);
1790 vos_sched_close(pVosContext);
1791 if (pHddCtx)
1792 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 /* Unregister the Net Device Notifier */
1794 unregister_netdevice_notifier(&hdd_netdev_notifier);
1795 /* Clean up HDD Nlink Service */
1796 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07001797#ifdef WLAN_KD_READY_NOTIFIER
1798 nl_srv_exit(pHddCtx->ptt_pid);
1799#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07001801#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 /* Free up dynamically allocated members inside HDD Adapter */
1803 kfree(pHddCtx->cfg_ini);
1804 pHddCtx->cfg_ini= NULL;
1805
Jeff Johnson295189b2012-06-20 16:38:30 -07001806 wiphy_unregister(pHddCtx->wiphy);
1807 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 }
1809 vos_preClose(&pVosContext);
1810
1811#ifdef MEMORY_DEBUG
1812 vos_mem_exit();
1813#endif
1814
1815err_re_init:
1816 /* Allow the phone to go to sleep */
1817 hdd_allow_suspend();
Sameer Thalappil451ebb92013-06-28 15:49:58 -07001818 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001819 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001820
1821success:
1822 /* Trigger replay of BTC events */
1823 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1824 return VOS_STATUS_SUCCESS;
1825}