blob: 359597232587e5b1dbc762335b514261e581d543 [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;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530592 hddLog (VOS_TRACE_LEVEL_INFO,
593 "Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6",
594 selfIPv6Addr[0]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530595 break;
596 case IPV6_ADDR_SCOPE_GLOBAL:
597 vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr,
598 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530599 selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID;
600 hddLog (VOS_TRACE_LEVEL_INFO,
601 "Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6",
602 selfIPv6Addr[1]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530603 break;
604 default:
605 hddLog(LOGE, "The Scope %d is not supported",
606 ipv6_addr_src_scope(&ifp->addr));
607 }
608
609 }
610 //read_unlock_bh(&in6_dev->lock);
611 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
612 for (i =0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
613 {
614 if (selfIPv6AddrValid[i])
615 {
616 //Filling up the request structure
617 /* Filling the selfIPv6Addr with solicited address
618 * A Solicited-Node multicast address is created by
619 * taking the last 24 bits of a unicast or anycast
620 * address and appending them to the prefix
621 *
622 * FF02:0000:0000:0000:0000:0001:FFXX:XX
623 *
624 * here XX is the unicast/anycast bits
625 */
626 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
627 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
628 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
629 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
630 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = selfIPv6Addr[i][13];
631 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = selfIPv6Addr[i][14];
632 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = selfIPv6Addr[i][15];
633 offLoadRequest.nsOffloadInfo.slotIdx = i;
634
635 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
636 &selfIPv6Addr[i][0], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
637 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
638 &pAdapter->macAddressCurrent.bytes,
639 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
640
641 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
642 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
643 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
644
645 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
646 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
647 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
648
649 hddLog (VOS_TRACE_LEVEL_INFO,
650 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
651 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
652 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
653
654 //Configure the Firmware with this
655 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
656 pAdapter->sessionId, &offLoadRequest);
657 if(eHAL_STATUS_SUCCESS != returnStatus)
658 {
659 hddLog(VOS_TRACE_LEVEL_ERROR,
660 FL("Failed to enable HostOffload feature with status: %d"),
661 returnStatus);
662 }
663 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
664 }
665 }
666 }
667 else
668 {
669 hddLog(VOS_TRACE_LEVEL_ERROR,
670 FL("IPv6 dev does not exist. Failed to request NSOffload"));
671 return;
672 }
673 }
674 else
675 {
676 //Disable NSOffload
677 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
678 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
679 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
680
681 if (eHAL_STATUS_SUCCESS !=
682 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
683 pAdapter->sessionId, &offLoadRequest))
684 {
685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
686 "NSOffload feature"));
687 }
688 }
689 return;
690}
691#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530692VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700693{
694 struct in_ifaddr **ifap = NULL;
695 struct in_ifaddr *ifa = NULL;
696 struct in_device *in_dev;
697 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700698 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800699 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700700
701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700702
Jeff Johnson295189b2012-06-20 16:38:30 -0700703 if(fenable)
704 {
705 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
706 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530707 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700708 ifap = &ifa->ifa_next)
709 {
710 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
711 {
712 break; /* found */
713 }
714 }
715 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700716 if(ifa && ifa->ifa_local)
717 {
718 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
719 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
720
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530721 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700722
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530723 if((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
724 pHddCtx->configuredMcastBcastFilter) ||
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700725 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530726 pHddCtx->configuredMcastBcastFilter))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700727 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530728 offLoadRequest.enableOrDisable =
729 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 }
731
732 //converting u32 to IPV4 address
733 for(i = 0 ; i < 4; i++)
734 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530735 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700736 (ifa->ifa_local >> (i*8) ) & 0xFF ;
737 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530738 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700739 offLoadRequest.params.hostIpv4Addr[0],
740 offLoadRequest.params.hostIpv4Addr[1],
741 offLoadRequest.params.hostIpv4Addr[2],
742 offLoadRequest.params.hostIpv4Addr[3]);
743
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530744 if (eHAL_STATUS_SUCCESS !=
745 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
746 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700747 {
748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
749 "feature\n", __func__);
750 return VOS_STATUS_E_FAILURE;
751 }
752 return VOS_STATUS_SUCCESS;
753 }
754 else
755 {
756 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned \n", __func__);
757 return VOS_STATUS_E_AGAIN;
758 }
759 }
760 else
761 {
762 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
763 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
764 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
765
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530766 if (eHAL_STATUS_SUCCESS !=
767 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
768 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700769 {
770 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
771 "offload feature\n", __func__);
772 return VOS_STATUS_E_FAILURE;
773 }
774 return VOS_STATUS_SUCCESS;
775 }
776}
777
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530778/*
779 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530780 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530781*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530782void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530783 tANI_U8 *pMcBcFilter)
784{
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530785 if (NULL == pHddCtx)
786 {
787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
788 return;
789 }
790
791 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
792 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530793 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530794 /* ARP offload is enabled, do not block bcast packets at RXP
795 * Will be using Bitmasking to reset the filter. As we have
796 * disable Broadcast filtering, Anding with the negation
797 * of Broadcast BIT
798 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530799 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530800 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530801
802#ifdef WLAN_NS_OFFLOAD
803 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530804 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530805 /* NS offload is enabled, do not block mcast packets at RXP
806 * Will be using Bitmasking to reset the filter. As we have
807 * disable Multicast filtering, Anding with the negation
808 * of Multicast BIT
809 */
810 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530811 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530812#endif
813
814 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530815}
816
Jeff Johnson295189b2012-06-20 16:38:30 -0700817void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
818{
819 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700820 tpSirWlanSetRxpFilters wlanRxpFilterParam =
821 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
822 if(NULL == wlanRxpFilterParam)
823 {
824 hddLog(VOS_TRACE_LEVEL_FATAL,
825 "%s: vos_mem_alloc failed ", __func__);
826 return;
827 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700828 hddLog(VOS_TRACE_LEVEL_INFO,
829 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530830 if (TRUE == setfilter)
831 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530832 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530833 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530834 }
835 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530836 {
837 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530838 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530839 pHddCtx->configuredMcastBcastFilter;
840 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530841
Jeff Johnson295189b2012-06-20 16:38:30 -0700842 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700843 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -0700844 if (eHAL_STATUS_SUCCESS != halStatus)
845 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700846 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
847 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
848}
849
Jeff Johnson295189b2012-06-20 16:38:30 -0700850static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
851 hdd_adapter_t *pAdapter)
852{
853 eHalStatus halStatus = eHAL_STATUS_FAILURE;
854 tpSirWlanSuspendParam wlanSuspendParam =
855 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
856
Amar Singhal49fdfd52013-08-13 13:25:12 -0700857 pHddCtx->sus_res_mcastbcast_filter =
858 pHddCtx->configuredMcastBcastFilter;
859
Jeff Johnson295189b2012-06-20 16:38:30 -0700860 if(NULL == wlanSuspendParam)
861 {
862 hddLog(VOS_TRACE_LEVEL_FATAL,
863 "%s: vos_mem_alloc failed ", __func__);
864 return;
865 }
866
867 hddLog(VOS_TRACE_LEVEL_INFO,
868 "%s: send wlan suspend indication", __func__);
869
870 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
871 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530872 //Configure supported OffLoads
873 hdd_conf_hostoffload(pAdapter, TRUE);
874 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700875
876#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530877 /* During suspend, configure MC Addr list filter to the firmware
878 * function takes care of checking necessary conditions before
879 * configuring.
880 */
881 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700882#endif
883 }
884
885 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
886 if(eHAL_STATUS_SUCCESS == halStatus)
887 {
888 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -0700889 } else {
890 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 }
892}
893
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530894static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700895{
Chilam Ngc4244af2013-04-01 15:37:32 -0700896 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -0800897 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -0700898 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -0700899
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530900 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 "%s: send wlan resume indication", __func__);
902
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530903 if (pHddCtx->hdd_mcastbcast_filter_set == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700904 {
Chilam Ngc4244af2013-04-01 15:37:32 -0700905 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
906
907 if(NULL == wlanResumeParam)
908 {
909 hddLog(VOS_TRACE_LEVEL_FATAL,
910 "%s: vos_mem_alloc failed ", __func__);
911 return;
912 }
913
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530914 //Disable supported OffLoads
915 hdd_conf_hostoffload(pAdapter, FALSE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530916
917 wlanResumeParam->configuredMcstBcstFilterSetting =
918 pHddCtx->configuredMcastBcastFilter;
Chilam Ngc4244af2013-04-01 15:37:32 -0700919 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
920 if (eHAL_STATUS_SUCCESS != halStatus)
921 vos_mem_free(wlanResumeParam);
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530922 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700924
Amar Singhal49fdfd52013-08-13 13:25:12 -0700925 pHddCtx->configuredMcastBcastFilter =
926 pHddCtx->sus_res_mcastbcast_filter;
927
Chilam Ngc4244af2013-04-01 15:37:32 -0700928
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530929#ifdef WLAN_FEATURE_PACKET_FILTERING
930 /* Filer was applied during suspend inditication
931 * clear it when we resume.
932 */
933 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700934#endif
935}
Jeff Johnson295189b2012-06-20 16:38:30 -0700936
Jeff Johnson295189b2012-06-20 16:38:30 -0700937//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800938void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -0700939{
940 hdd_context_t *pHddCtx = NULL;
941 v_CONTEXT_t pVosContext = NULL;
942
Jeff Johnson295189b2012-06-20 16:38:30 -0700943 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530944 hdd_adapter_t *pAdapter = NULL;
945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +0530946 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800947
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
949
950 //Get the global VOSS context.
951 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
952 if(!pVosContext) {
953 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
954 return;
955 }
956
957 //Get the HDD context.
958 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
959
960 if(!pHddCtx) {
961 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
962 return;
963 }
964
965 if (pHddCtx->isLogpInProgress) {
966 hddLog(VOS_TRACE_LEVEL_ERROR,
967 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
968 return;
969 }
970
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530971 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
973 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
974 {
975 pAdapter = pAdapterNode->pAdapter;
Leo Chang9056f462013-08-01 19:21:11 -0700976
977#ifdef FEATURE_WLAN_LPHB
978 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
979 (pHddCtx->lphbEnableReq.enable))
980 {
981 tSirLPHBReq *hb_params = NULL;
982
983 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
984 if (NULL == hb_params)
985 {
986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
987 "%s: hb_params alloc failed", __func__);
988 }
989 else
990 {
991 eHalStatus smeStatus;
992
993 hb_params->cmd = LPHB_SET_EN_PARAMS_INDID;
994 hb_params->params.lphbEnableReq.enable =
995 pHddCtx->lphbEnableReq.enable;
996 hb_params->params.lphbEnableReq.item =
997 pHddCtx->lphbEnableReq.item;
998 hb_params->params.lphbEnableReq.session =
999 pHddCtx->lphbEnableReq.session;
1000 /* If WLAN is suspend state, send enable command immediately */
1001 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
1002 hb_params,
1003 NULL);
1004 if (eHAL_STATUS_SUCCESS != smeStatus)
1005 {
1006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1007 "LPHB Config Fail, disable");
1008 pHddCtx->lphbEnableReq.enable = 0;
1009 vos_mem_free(hb_params);
1010 }
1011 }
1012 }
1013#endif /* FEATURE_WLAN_LPHB */
1014
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001016 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001017 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1018
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001019 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001020 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1021 pAdapterNode = pNext;
1022 continue;
1023 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301024 /* Avoid multiple enter/exit BMPS in this while loop using
1025 * hdd_enter_bmps flag
1026 */
1027 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1028 {
1029 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001030
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301031 /* If device was already in BMPS, and dynamic DTIM is set,
1032 * exit(set the device to full power) and enter BMPS again
1033 * to reflect new DTIM value */
1034 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1035
1036 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1037
1038 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001040#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1041 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1042 {
1043 //stop the interface before putting the chip to standby
1044 netif_tx_disable(pAdapter->dev);
1045 netif_carrier_off(pAdapter->dev);
1046 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301047 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1049 {
1050 //Execute deep sleep procedure
1051 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1052 }
1053#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301054
1055 /*Suspend notification sent down to driver*/
1056 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1057
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301058 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1059 pAdapterNode = pNext;
1060 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301061 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301062
Jeff Johnson295189b2012-06-20 16:38:30 -07001063#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1064 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1065 {
1066 hdd_enter_standby(pHddCtx);
1067 }
1068#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001069
1070 return;
1071}
1072
1073static void hdd_PowerStateChangedCB
1074(
1075 v_PVOID_t callbackContext,
1076 tPmcState newState
1077)
1078{
1079 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001080 /* if the driver was not in BMPS during early suspend,
1081 * the dynamic DTIM is now updated at Riva */
1082 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1083 && pHddCtx->cfg_ini->enableDynamicDTIM
1084 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1085 {
1086 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1087 }
1088 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301089 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 spin_unlock(&pHddCtx->filter_lock);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001091 pHddCtx->sus_res_mcastbcast_filter = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001092 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1095 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001096 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 spin_unlock(&pHddCtx->filter_lock);
1098}
1099
1100
1101
1102void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1103{
1104 v_CONTEXT_t pVosContext;
1105 tHalHandle smeContext;
1106
1107 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1108 if (NULL == pVosContext)
1109 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001110 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001111 return;
1112 }
1113 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1114 if (NULL == smeContext)
1115 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001116 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 return;
1118 }
1119
1120 spin_lock_init(&pHddCtx->filter_lock);
1121 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1122 pHddCtx->cfg_ini->nEnableSuspend)
1123 {
1124 pmcRegisterDeviceStateUpdateInd(smeContext,
1125 hdd_PowerStateChangedCB, pHddCtx);
1126 }
1127}
1128
1129void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1130{
1131 v_CONTEXT_t pVosContext;
1132 tHalHandle smeContext;
1133
1134 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1135 if (NULL == pVosContext)
1136 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001137 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001138 return;
1139 }
1140 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1141 if (NULL == smeContext)
1142 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001143 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 return;
1145 }
1146
1147 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1148 pHddCtx->cfg_ini->nEnableSuspend)
1149 {
1150 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1151 }
1152}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301153
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301154#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301155void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301156{
1157 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301158 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301159 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1160
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301161 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301162 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301163 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1164 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1165 {
1166 vos_mem_copy(&hddGtkOffloadReqParams,
1167 &pHddStaCtx->gtkOffloadReqParams,
1168 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301169
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301170 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1171 &hddGtkOffloadReqParams, pAdapter->sessionId);
1172 if (eHAL_STATUS_SUCCESS != ret)
1173 {
1174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1175 "%s: sme_SetGTKOffload failed, returned %d",
1176 __func__, ret);
1177 return;
1178 }
1179
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1181 "%s: sme_SetGTKOffload successfull", __func__);
1182 }
1183
1184 }
1185 else
1186 {
1187 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1188 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1189 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1190 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1191 {
1192
1193 /* Host driver has previously offloaded GTK rekey */
1194 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301195 wlan_hdd_cfg80211_update_replayCounterCallback,
1196 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301197 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301198
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: sme_GetGTKOffload failed, returned %d",
1202 __func__, ret);
1203 return;
1204 }
1205 else
1206 {
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1208 "%s: sme_GetGTKOffload successful",
1209 __func__);
1210
1211 /* Sending GTK offload dissable */
1212 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1213 sizeof (tSirGtkOffloadParams));
1214 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1215 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301216 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301217 if (eHAL_STATUS_SUCCESS != ret)
1218 {
1219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1220 "%s: failed to dissable GTK offload, returned %d",
1221 __func__, ret);
1222 return;
1223 }
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1225 "%s: successfully dissabled GTK offload request to HAL",
1226 __func__);
1227 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301228 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301229 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301230 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301231}
1232#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001233
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001234void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001235{
1236 hdd_context_t *pHddCtx = NULL;
1237 hdd_adapter_t *pAdapter = NULL;
1238 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1239 VOS_STATUS status;
1240 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001241
Jeff Johnson295189b2012-06-20 16:38:30 -07001242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1243
1244 //Get the global VOSS context.
1245 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1246 if(!pVosContext) {
1247 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1248 return;
1249 }
1250
1251 //Get the HDD context.
1252 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1253
1254 if(!pHddCtx) {
1255 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1256 return;
1257 }
1258
1259 if (pHddCtx->isLogpInProgress) {
1260 hddLog(VOS_TRACE_LEVEL_INFO,
1261 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1262 return;
1263 }
1264
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 pHddCtx->hdd_wlan_suspended = FALSE;
1266 /*loop through all adapters. Concurrency */
1267 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1268
1269 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1270 {
1271 pAdapter = pAdapterNode->pAdapter;
1272 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001273 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001274 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001275 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1277 pAdapterNode = pNext;
1278 continue;
1279 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301280
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301281
Jeff Johnson295189b2012-06-20 16:38:30 -07001282#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1283 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1284 {
1285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1286 hdd_exit_deep_sleep(pAdapter);
1287 }
1288#endif
1289
1290 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1291 {
1292 /*Switch back to DTIM 1*/
1293 tSirSetPowerParamsReq powerRequest = { 0 };
1294
1295 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1296 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001297 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001298
1299 /*Disabled ModulatedDTIM if enabled on suspend*/
1300 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1301 powerRequest.uDTIMPeriod = 0;
1302
1303 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1304 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1305 NULL, eANI_BOOLEAN_FALSE);
1306 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1307 NULL, eANI_BOOLEAN_FALSE);
1308
1309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1310 "Switch to DTIM%d \n",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001311 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001312
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301313 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1314 {
1315 /* put the device into full power */
1316 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001317
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301318 /* put the device back into BMPS */
1319 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001320
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301321 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1322 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 }
1324
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301325 hdd_conf_resume_ind(pAdapter);
Leo Chang9056f462013-08-01 19:21:11 -07001326
1327#ifdef FEATURE_WLAN_LPHB
1328 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
1329 (pHddCtx->lphbEnableReq.enable))
1330 {
1331 tSirLPHBReq *hb_params = NULL;
1332
1333 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
1334 if (NULL == hb_params)
1335 {
1336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1337 "%s: hb_params alloc failed", __func__);
1338 }
1339 else
1340 {
1341 eHalStatus smeStatus;
1342
1343 hb_params->cmd = LPHB_SET_EN_PARAMS_INDID;
1344 hb_params->params.lphbEnableReq.enable = 0;
1345 hb_params->params.lphbEnableReq.item =
1346 pHddCtx->lphbEnableReq.item;
1347 hb_params->params.lphbEnableReq.session =
1348 pHddCtx->lphbEnableReq.session;
1349 /* If WLAN is suspend state, send enable command immediately */
1350 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
1351 hb_params,
1352 NULL);
1353 if (eHAL_STATUS_SUCCESS != smeStatus)
1354 {
1355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1356 "LPHB Config Fail, disable");
1357 pHddCtx->lphbEnableReq.enable = 0;
1358 vos_mem_free(hb_params);
1359 }
1360 }
1361 }
1362#endif /* FEATURE_WLAN_LPHB */
1363
Jeff Johnson295189b2012-06-20 16:38:30 -07001364 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1365 pAdapterNode = pNext;
1366 }
1367
1368#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1369 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1370 {
1371 hdd_exit_standby(pHddCtx);
1372 }
1373#endif
1374
Jeff Johnson295189b2012-06-20 16:38:30 -07001375 return;
1376}
1377
Jeff Johnson295189b2012-06-20 16:38:30 -07001378VOS_STATUS hdd_wlan_reset_initialization(void)
1379{
Jeff Johnson295189b2012-06-20 16:38:30 -07001380 v_CONTEXT_t pVosContext = NULL;
1381
1382 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1383
1384 //Get the global VOSS context.
1385 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1386 if(!pVosContext)
1387 {
1388 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1389 return VOS_STATUS_E_FAILURE;
1390 }
1391
1392 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1393
1394 // Prevent the phone from going to sleep
1395 hdd_prevent_suspend();
1396
Jeff Johnson295189b2012-06-20 16:38:30 -07001397 return VOS_STATUS_SUCCESS;
1398}
1399
1400
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001401/*
1402 * Based on the ioctl command recieved by HDD, put WLAN driver
1403 * into the quiet mode. This is the same as the early suspend
1404 * notification that driver used to listen
1405 */
1406void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001407{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001408 if (suspend)
1409 hdd_suspend_wlan();
1410 else
1411 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001412}
1413
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001414static void hdd_ssr_timer_init(void)
1415{
1416 init_timer(&ssr_timer);
1417}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001418
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001419static void hdd_ssr_timer_del(void)
1420{
1421 del_timer(&ssr_timer);
1422 ssr_timer_started = false;
1423}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001424
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001425static void hdd_ssr_timer_cb(unsigned long data)
1426{
1427 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001428
1429#ifdef WCN_PRONTO
1430 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1431 wcnss_pronto_log_debug_regs();
1432#endif
1433
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001434 VOS_BUG(0);
1435}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001436
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001437static void hdd_ssr_timer_start(int msec)
1438{
1439 if(ssr_timer_started)
1440 {
1441 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1442 ,__func__);
1443 }
1444 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1445 ssr_timer.function = hdd_ssr_timer_cb;
1446 add_timer(&ssr_timer);
1447 ssr_timer_started = true;
1448}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001449
Jeff Johnson295189b2012-06-20 16:38:30 -07001450/* the HDD interface to WLAN driver shutdown,
1451 * the primary shutdown function in SSR
1452 */
1453VOS_STATUS hdd_wlan_shutdown(void)
1454{
1455 VOS_STATUS vosStatus;
1456 v_CONTEXT_t pVosContext = NULL;
1457 hdd_context_t *pHddCtx = NULL;
1458 pVosSchedContext vosSchedContext = NULL;
1459
1460 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1461
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001462 /* if re-init never happens, then do SSR1 */
1463 hdd_ssr_timer_init();
1464 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1465
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 /* Get the global VOSS context. */
1467 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1468 if(!pVosContext) {
1469 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1470 return VOS_STATUS_E_FAILURE;
1471 }
1472 /* Get the HDD context. */
1473 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1474 if(!pHddCtx) {
1475 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1476 return VOS_STATUS_E_FAILURE;
1477 }
1478 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001479 /* DeRegister with platform driver as client for Suspend/Resume */
1480 vosStatus = hddDeregisterPmOps(pHddCtx);
1481 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1482 {
1483 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1484 }
1485
1486 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1487 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1488 {
1489 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1490 }
1491
1492 /* Disable IMPS/BMPS as we do not want the device to enter any power
1493 * save mode on its own during reset sequence
1494 */
1495 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1496 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1497 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1498
1499 vosSchedContext = get_vos_sched_ctxt();
1500
1501 /* Wakeup all driver threads */
1502 if(TRUE == pHddCtx->isMcThreadSuspended){
1503 complete(&vosSchedContext->ResumeMcEvent);
1504 pHddCtx->isMcThreadSuspended= FALSE;
1505 }
1506 if(TRUE == pHddCtx->isTxThreadSuspended){
1507 complete(&vosSchedContext->ResumeTxEvent);
1508 pHddCtx->isTxThreadSuspended= FALSE;
1509 }
1510 if(TRUE == pHddCtx->isRxThreadSuspended){
1511 complete(&vosSchedContext->ResumeRxEvent);
1512 pHddCtx->isRxThreadSuspended= FALSE;
1513 }
1514 /* Reset the Suspend Variable */
1515 pHddCtx->isWlanSuspended = FALSE;
1516
1517 /* Stop all the threads; we do not want any messages to be a processed,
1518 * any more and the best way to ensure that is to terminate the threads
1519 * gracefully.
1520 */
1521 /* Wait for MC to exit */
1522 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1523 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1524 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1525 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1526 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1527
1528 /* Wait for TX to exit */
1529 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1530 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1531 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1532 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1533 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1534
1535 /* Wait for RX to exit */
1536 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1537 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1538 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1539 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1540 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1541
1542#ifdef WLAN_BTAMP_FEATURE
1543 vosStatus = WLANBAP_Stop(pVosContext);
1544 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1545 {
1546 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1547 "%s: Failed to stop BAP",__func__);
1548 }
1549#endif //WLAN_BTAMP_FEATURE
1550 vosStatus = vos_wda_shutdown(pVosContext);
1551 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1552
1553 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1554 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1555 * on threads being running to process the SYS Stop
1556 */
1557 vosStatus = sme_Stop(pHddCtx->hHal, TRUE);
1558 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1559
1560 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1561 /* Stop MAC (PE and HAL) */
1562 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1563 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1564
1565 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1566 /* Stop TL */
1567 vosStatus = WLANTL_Stop(pVosContext);
1568 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1569
Jeff Johnson295189b2012-06-20 16:38:30 -07001570 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1572 /* Clean up message queues of TX and MC thread */
1573 vos_sched_flush_mc_mqs(vosSchedContext);
1574 vos_sched_flush_tx_mqs(vosSchedContext);
1575 vos_sched_flush_rx_mqs(vosSchedContext);
1576
1577 /* Deinit all the TX and MC queues */
1578 vos_sched_deinit_mqs(vosSchedContext);
1579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1580
1581 /* shutdown VOSS */
1582 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301583
1584 /*mac context has already been released in mac_close call
1585 so setting it to NULL in hdd context*/
1586 pHddCtx->hHal = (tHalHandle)NULL;
1587
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 if (free_riva_power_on_lock("wlan"))
1589 {
1590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1591 __func__);
1592 }
1593 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1594 ,__func__);
1595 return VOS_STATUS_SUCCESS;
1596}
1597
1598
1599
1600/* the HDD interface to WLAN driver re-init.
1601 * This is called to initialize/start WLAN driver after a shutdown.
1602 */
1603VOS_STATUS hdd_wlan_re_init(void)
1604{
1605 VOS_STATUS vosStatus;
1606 v_CONTEXT_t pVosContext = NULL;
1607 hdd_context_t *pHddCtx = NULL;
1608 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001609#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1610 int max_retries = 0;
1611#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001612#ifdef WLAN_BTAMP_FEATURE
1613 hdd_config_t *pConfig = NULL;
1614 WLANBAP_ConfigType btAmpConfig;
1615#endif
1616
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001617 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001618 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001619
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001620#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1621 /* wait until WCNSS driver downloads NV */
1622 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1623 msleep(1000);
1624 }
1625 if (max_retries >= 5) {
1626 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1627 goto err_re_init;
1628 }
1629#endif
1630
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001631 /* The driver should always be initialized in STA mode after SSR */
1632 hdd_set_conparam(0);
1633
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1635 vosStatus = vos_open(&pVosContext, 0);
1636 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1637 {
1638 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1639 goto err_re_init;
1640 }
1641
1642 /* Get the HDD context. */
1643 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1644 if(!pHddCtx)
1645 {
1646 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1647 goto err_vosclose;
1648 }
1649
1650 /* Save the hal context in Adapter */
1651 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1652 if ( NULL == pHddCtx->hHal )
1653 {
1654 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1655 goto err_vosclose;
1656 }
1657
1658 /* Set the SME configuration parameters. */
1659 vosStatus = hdd_set_sme_config(pHddCtx);
1660 if ( VOS_STATUS_SUCCESS != vosStatus )
1661 {
1662 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1663 goto err_vosclose;
1664 }
1665
1666 /* Initialize the WMM module */
1667 vosStatus = hdd_wmm_init(pHddCtx);
1668 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1669 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001670 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 goto err_vosclose;
1672 }
1673
1674 vosStatus = vos_preStart( pHddCtx->pvosContext );
1675 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1676 {
1677 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1678 goto err_vosclose;
1679 }
1680
1681 /* In the integrated architecture we update the configuration from
1682 the INI file and from NV before vOSS has been started so that
1683 the final contents are available to send down to the cCPU */
1684 /* Apply the cfg.ini to cfg.dat */
1685 if (FALSE == hdd_update_config_dat(pHddCtx))
1686 {
1687 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1688 goto err_vosclose;
1689 }
1690
1691 /* Set the MAC Address, currently this is used by HAL to add self sta.
1692 * Remove this once self sta is added as part of session open. */
1693 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1694 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1695 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1696 if (!HAL_STATUS_SUCCESS(halStatus))
1697 {
1698 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1699 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1700 goto err_vosclose;
1701 }
1702
1703 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1704 Note: Firmware image will be read and downloaded inside vos_start API */
1705 vosStatus = vos_start( pVosContext );
1706 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1707 {
1708 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1709 goto err_vosclose;
1710 }
1711
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001712 /* Exchange capability info between Host and FW and also get versioning info from FW */
1713 hdd_exchange_version_and_caps(pHddCtx);
1714
Jeff Johnson295189b2012-06-20 16:38:30 -07001715 vosStatus = hdd_post_voss_start_config( pHddCtx );
1716 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1717 {
1718 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1719 __func__);
1720 goto err_vosstop;
1721 }
1722
1723#ifdef WLAN_BTAMP_FEATURE
1724 vosStatus = WLANBAP_Open(pVosContext);
1725 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1726 {
1727 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1728 "%s: Failed to open BAP",__func__);
1729 goto err_vosstop;
1730 }
1731 vosStatus = BSL_Init(pVosContext);
1732 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1733 {
1734 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1735 "%s: Failed to Init BSL",__func__);
1736 goto err_bap_close;
1737 }
1738 vosStatus = WLANBAP_Start(pVosContext);
1739 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1740 {
1741 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1742 "%s: Failed to start TL",__func__);
1743 goto err_bap_close;
1744 }
1745 pConfig = pHddCtx->cfg_ini;
1746 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1747 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1748#endif //WLAN_BTAMP_FEATURE
1749
1750 /* Restart all adapters */
1751 hdd_start_all_adapters(pHddCtx);
1752 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07001753 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001754 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001755 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001756
1757 /* Register with platform driver as client for Suspend/Resume */
1758 vosStatus = hddRegisterPmOps(pHddCtx);
1759 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1760 {
1761 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1762 goto err_bap_stop;
1763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001764 /* Allow the phone to go to sleep */
1765 hdd_allow_suspend();
1766 /* register for riva power on lock */
1767 if (req_riva_power_on_lock("wlan"))
1768 {
1769 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1770 __func__);
1771 goto err_unregister_pmops;
1772 }
1773 goto success;
1774
1775err_unregister_pmops:
1776 hddDeregisterPmOps(pHddCtx);
1777
1778err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001779#ifdef CONFIG_HAS_EARLYSUSPEND
1780 hdd_unregister_mcast_bcast_filter(pHddCtx);
1781#endif
1782 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001783#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001784 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001785#endif
1786
1787#ifdef WLAN_BTAMP_FEATURE
1788err_bap_close:
1789 WLANBAP_Close(pVosContext);
1790#endif
1791
1792err_vosstop:
1793 vos_stop(pVosContext);
1794
1795err_vosclose:
1796 vos_close(pVosContext);
1797 vos_sched_close(pVosContext);
1798 if (pHddCtx)
1799 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 /* Unregister the Net Device Notifier */
1801 unregister_netdevice_notifier(&hdd_netdev_notifier);
1802 /* Clean up HDD Nlink Service */
1803 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07001804#ifdef WLAN_KD_READY_NOTIFIER
1805 nl_srv_exit(pHddCtx->ptt_pid);
1806#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001807 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07001808#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07001809 /* Free up dynamically allocated members inside HDD Adapter */
1810 kfree(pHddCtx->cfg_ini);
1811 pHddCtx->cfg_ini= NULL;
1812
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 wiphy_unregister(pHddCtx->wiphy);
1814 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001815 }
1816 vos_preClose(&pVosContext);
1817
1818#ifdef MEMORY_DEBUG
1819 vos_mem_exit();
1820#endif
1821
1822err_re_init:
1823 /* Allow the phone to go to sleep */
1824 hdd_allow_suspend();
Sameer Thalappil451ebb92013-06-28 15:49:58 -07001825 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001826 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001827
1828success:
1829 /* Trigger replay of BTC events */
1830 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1831 return VOS_STATUS_SUCCESS;
1832}