blob: 53a894778d135bb61e5fd30ac90607be4b6d19ef [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;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530572 hdd_context_t *pHddCtx;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530573
574 int i =0;
575 eHalStatus returnStatus;
576
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530577 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
578
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530579 ENTER();
580 if (fenable)
581 {
582 in6_dev = __in6_dev_get(pAdapter->dev);
583 if (NULL != in6_dev)
584 {
585 //read_lock_bh(&in6_dev->lock);
586 list_for_each(p, &in6_dev->addr_list)
587 {
588 ifp = list_entry(p, struct inet6_ifaddr, if_list);
589 switch(ipv6_addr_src_scope(&ifp->addr))
590 {
591 case IPV6_ADDR_SCOPE_LINKLOCAL:
592 vos_mem_copy(&selfIPv6Addr[0], &ifp->addr.s6_addr,
593 sizeof(ifp->addr.s6_addr));
594 selfIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530595 hddLog (VOS_TRACE_LEVEL_INFO,
596 "Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6",
597 selfIPv6Addr[0]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530598 break;
599 case IPV6_ADDR_SCOPE_GLOBAL:
600 vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr,
601 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530602 selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID;
603 hddLog (VOS_TRACE_LEVEL_INFO,
604 "Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6",
605 selfIPv6Addr[1]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530606 break;
607 default:
608 hddLog(LOGE, "The Scope %d is not supported",
609 ipv6_addr_src_scope(&ifp->addr));
610 }
611
612 }
613 //read_unlock_bh(&in6_dev->lock);
614 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
615 for (i =0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
616 {
617 if (selfIPv6AddrValid[i])
618 {
619 //Filling up the request structure
620 /* Filling the selfIPv6Addr with solicited address
621 * A Solicited-Node multicast address is created by
622 * taking the last 24 bits of a unicast or anycast
623 * address and appending them to the prefix
624 *
625 * FF02:0000:0000:0000:0000:0001:FFXX:XX
626 *
627 * here XX is the unicast/anycast bits
628 */
629 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
630 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
631 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
632 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
633 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = selfIPv6Addr[i][13];
634 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = selfIPv6Addr[i][14];
635 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = selfIPv6Addr[i][15];
636 offLoadRequest.nsOffloadInfo.slotIdx = i;
637
638 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
639 &selfIPv6Addr[i][0], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
640 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
641 &pAdapter->macAddressCurrent.bytes,
642 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
643
644 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
645 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
646 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
647
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530648 hddLog (VOS_TRACE_LEVEL_INFO,
649 "configuredMcastBcastFilter: %d",pHddCtx->configuredMcastBcastFilter);
650
651 if((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
652 pHddCtx->configuredMcastBcastFilter) ||
653 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
654 pHddCtx->configuredMcastBcastFilter))
655 {
656 hddLog (VOS_TRACE_LEVEL_INFO,
657 "Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE \n", __func__);
658 offLoadRequest.enableOrDisable =
659 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
660 }
661
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530662 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
663 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
664 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
665
666 hddLog (VOS_TRACE_LEVEL_INFO,
667 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
668 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
669 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
670
671 //Configure the Firmware with this
672 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
673 pAdapter->sessionId, &offLoadRequest);
674 if(eHAL_STATUS_SUCCESS != returnStatus)
675 {
676 hddLog(VOS_TRACE_LEVEL_ERROR,
677 FL("Failed to enable HostOffload feature with status: %d"),
678 returnStatus);
679 }
680 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
681 }
682 }
683 }
684 else
685 {
686 hddLog(VOS_TRACE_LEVEL_ERROR,
687 FL("IPv6 dev does not exist. Failed to request NSOffload"));
688 return;
689 }
690 }
691 else
692 {
693 //Disable NSOffload
694 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
695 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
696 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
697
698 if (eHAL_STATUS_SUCCESS !=
699 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
700 pAdapter->sessionId, &offLoadRequest))
701 {
702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
703 "NSOffload feature"));
704 }
705 }
706 return;
707}
708#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530709VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700710{
711 struct in_ifaddr **ifap = NULL;
712 struct in_ifaddr *ifa = NULL;
713 struct in_device *in_dev;
714 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700715 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800716 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700717
718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700719
Jeff Johnson295189b2012-06-20 16:38:30 -0700720 if(fenable)
721 {
722 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
723 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530724 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 ifap = &ifa->ifa_next)
726 {
727 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
728 {
729 break; /* found */
730 }
731 }
732 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 if(ifa && ifa->ifa_local)
734 {
735 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
736 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
737
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530738 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700739
Amar Singhald53568e2013-09-26 11:03:45 -0700740 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
741 pHddCtx->sus_res_mcastbcast_filter) ||
742 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
743 pHddCtx->sus_res_mcastbcast_filter)) &&
744 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700745 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530746 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -0700747 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
748 hddLog(VOS_TRACE_LEVEL_INFO,
749 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -0700750 }
Amar Singhald53568e2013-09-26 11:03:45 -0700751
752 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
753 offLoadRequest.enableOrDisable);
754
Jeff Johnson295189b2012-06-20 16:38:30 -0700755 //converting u32 to IPV4 address
756 for(i = 0 ; i < 4; i++)
757 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530758 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700759 (ifa->ifa_local >> (i*8) ) & 0xFF ;
760 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530761 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700762 offLoadRequest.params.hostIpv4Addr[0],
763 offLoadRequest.params.hostIpv4Addr[1],
764 offLoadRequest.params.hostIpv4Addr[2],
765 offLoadRequest.params.hostIpv4Addr[3]);
766
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530767 if (eHAL_STATUS_SUCCESS !=
768 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
769 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700770 {
771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
772 "feature\n", __func__);
773 return VOS_STATUS_E_FAILURE;
774 }
775 return VOS_STATUS_SUCCESS;
776 }
777 else
778 {
779 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned \n", __func__);
780 return VOS_STATUS_E_AGAIN;
781 }
782 }
783 else
784 {
785 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
786 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
787 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
788
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530789 if (eHAL_STATUS_SUCCESS !=
790 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
791 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700792 {
793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
794 "offload feature\n", __func__);
795 return VOS_STATUS_E_FAILURE;
796 }
797 return VOS_STATUS_SUCCESS;
798 }
799}
800
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530801/*
802 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530803 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530804*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530805void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530806 tANI_U8 *pMcBcFilter)
807{
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530808 if (NULL == pHddCtx)
809 {
810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
811 return;
812 }
813
814 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
815 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530816 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530817 /* ARP offload is enabled, do not block bcast packets at RXP
818 * Will be using Bitmasking to reset the filter. As we have
819 * disable Broadcast filtering, Anding with the negation
820 * of Broadcast BIT
821 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530822 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530823 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530824
825#ifdef WLAN_NS_OFFLOAD
826 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530827 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530828 /* NS offload is enabled, do not block mcast packets at RXP
829 * Will be using Bitmasking to reset the filter. As we have
830 * disable Multicast filtering, Anding with the negation
831 * of Multicast BIT
832 */
833 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530834 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530835#endif
836
837 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530838}
839
Jeff Johnson295189b2012-06-20 16:38:30 -0700840void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
841{
842 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700843 tpSirWlanSetRxpFilters wlanRxpFilterParam =
844 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
845 if(NULL == wlanRxpFilterParam)
846 {
847 hddLog(VOS_TRACE_LEVEL_FATAL,
848 "%s: vos_mem_alloc failed ", __func__);
849 return;
850 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700851 hddLog(VOS_TRACE_LEVEL_INFO,
852 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530853 if (TRUE == setfilter)
854 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530855 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530856 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530857 }
858 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530859 {
860 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530861 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530862 pHddCtx->configuredMcastBcastFilter;
863 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530864
Jeff Johnson295189b2012-06-20 16:38:30 -0700865 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -0700867 if (eHAL_STATUS_SUCCESS != halStatus)
868 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700869 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
870 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
871}
872
Jeff Johnson295189b2012-06-20 16:38:30 -0700873static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
874 hdd_adapter_t *pAdapter)
875{
876 eHalStatus halStatus = eHAL_STATUS_FAILURE;
877 tpSirWlanSuspendParam wlanSuspendParam =
878 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
879
Amar Singhald53568e2013-09-26 11:03:45 -0700880 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
881 pHddCtx->sus_res_mcastbcast_filter =
882 pHddCtx->configuredMcastBcastFilter;
883 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
884 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
885 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
886 pHddCtx->configuredMcastBcastFilter);
887
888 }
889
Amar Singhal49fdfd52013-08-13 13:25:12 -0700890
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 if(NULL == wlanSuspendParam)
892 {
893 hddLog(VOS_TRACE_LEVEL_FATAL,
894 "%s: vos_mem_alloc failed ", __func__);
895 return;
896 }
897
Amar Singhald53568e2013-09-26 11:03:45 -0700898 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700899 "%s: send wlan suspend indication", __func__);
900
901 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
902 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530903 //Configure supported OffLoads
904 hdd_conf_hostoffload(pAdapter, TRUE);
905 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700906
907#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530908 /* During suspend, configure MC Addr list filter to the firmware
909 * function takes care of checking necessary conditions before
910 * configuring.
911 */
912 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700913#endif
914 }
915
916 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
917 if(eHAL_STATUS_SUCCESS == halStatus)
918 {
919 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -0700920 } else {
921 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 }
923}
924
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530925static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700926{
Chilam Ngc4244af2013-04-01 15:37:32 -0700927 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -0800928 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -0700929 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -0700930
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530931 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 "%s: send wlan resume indication", __func__);
933
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +0530934 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
935
936 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +0530938 hddLog(VOS_TRACE_LEVEL_FATAL,
939 "%s: memory allocation failed for wlanResumeParam ", __func__);
940 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700941 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700942
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +0530943 //Disable supported OffLoads
944 hdd_conf_hostoffload(pAdapter, FALSE);
945
946 wlanResumeParam->configuredMcstBcstFilterSetting =
947 pHddCtx->configuredMcastBcastFilter;
948 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
949 if (eHAL_STATUS_SUCCESS != halStatus)
950 {
951 vos_mem_free(wlanResumeParam);
952 }
953
954 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
955
Amar Singhal49fdfd52013-08-13 13:25:12 -0700956 pHddCtx->configuredMcastBcastFilter =
957 pHddCtx->sus_res_mcastbcast_filter;
Amar Singhald53568e2013-09-26 11:03:45 -0700958 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
959
960 hddLog(VOS_TRACE_LEVEL_INFO,
961 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
962 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
963 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -0700964
Chilam Ngc4244af2013-04-01 15:37:32 -0700965
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530966#ifdef WLAN_FEATURE_PACKET_FILTERING
967 /* Filer was applied during suspend inditication
968 * clear it when we resume.
969 */
970 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700971#endif
972}
Jeff Johnson295189b2012-06-20 16:38:30 -0700973
Jeff Johnson295189b2012-06-20 16:38:30 -0700974//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800975void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -0700976{
977 hdd_context_t *pHddCtx = NULL;
978 v_CONTEXT_t pVosContext = NULL;
979
Jeff Johnson295189b2012-06-20 16:38:30 -0700980 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530981 hdd_adapter_t *pAdapter = NULL;
982 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +0530983 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800984
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
986
987 //Get the global VOSS context.
988 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
989 if(!pVosContext) {
990 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
991 return;
992 }
993
994 //Get the HDD context.
995 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
996
997 if(!pHddCtx) {
998 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
999 return;
1000 }
1001
1002 if (pHddCtx->isLogpInProgress) {
1003 hddLog(VOS_TRACE_LEVEL_ERROR,
1004 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1005 return;
1006 }
1007
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301008 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001009 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1010 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1011 {
1012 pAdapter = pAdapterNode->pAdapter;
1013 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001014 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1016
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001017 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1019 pAdapterNode = pNext;
1020 continue;
1021 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301022 /* Avoid multiple enter/exit BMPS in this while loop using
1023 * hdd_enter_bmps flag
1024 */
1025 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1026 {
1027 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001028
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301029 /* If device was already in BMPS, and dynamic DTIM is set,
1030 * exit(set the device to full power) and enter BMPS again
1031 * to reflect new DTIM value */
1032 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1033
1034 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1035
1036 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001038#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1039 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1040 {
1041 //stop the interface before putting the chip to standby
1042 netif_tx_disable(pAdapter->dev);
1043 netif_carrier_off(pAdapter->dev);
1044 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301045 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1047 {
1048 //Execute deep sleep procedure
1049 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1050 }
1051#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301052
1053 /*Suspend notification sent down to driver*/
1054 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1055
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301056 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1057 pAdapterNode = pNext;
1058 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301059 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301060
Jeff Johnson295189b2012-06-20 16:38:30 -07001061#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1062 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1063 {
1064 hdd_enter_standby(pHddCtx);
1065 }
1066#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001067
1068 return;
1069}
1070
1071static void hdd_PowerStateChangedCB
1072(
1073 v_PVOID_t callbackContext,
1074 tPmcState newState
1075)
1076{
1077 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 /* if the driver was not in BMPS during early suspend,
1079 * the dynamic DTIM is now updated at Riva */
1080 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1081 && pHddCtx->cfg_ini->enableDynamicDTIM
1082 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1083 {
1084 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1085 }
1086 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301087 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001088 spin_unlock(&pHddCtx->filter_lock);
Amar Singhald53568e2013-09-26 11:03:45 -07001089 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1090 pHddCtx->sus_res_mcastbcast_filter =
1091 pHddCtx->configuredMcastBcastFilter;
1092 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1093
1094 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1095 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1096 pHddCtx->configuredMcastBcastFilter);
1097 hddLog(VOS_TRACE_LEVEL_INFO,
1098 "offload: calling hdd_conf_mcastbcast_filter");
1099
1100 }
1101
Jeff Johnson295189b2012-06-20 16:38:30 -07001102 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1105 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001106 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 spin_unlock(&pHddCtx->filter_lock);
1108}
1109
1110
1111
1112void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1113{
1114 v_CONTEXT_t pVosContext;
1115 tHalHandle smeContext;
1116
1117 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1118 if (NULL == pVosContext)
1119 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001120 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001121 return;
1122 }
1123 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1124 if (NULL == smeContext)
1125 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001126 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001127 return;
1128 }
1129
1130 spin_lock_init(&pHddCtx->filter_lock);
1131 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1132 pHddCtx->cfg_ini->nEnableSuspend)
1133 {
1134 pmcRegisterDeviceStateUpdateInd(smeContext,
1135 hdd_PowerStateChangedCB, pHddCtx);
1136 }
1137}
1138
1139void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1140{
1141 v_CONTEXT_t pVosContext;
1142 tHalHandle smeContext;
1143
1144 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1145 if (NULL == pVosContext)
1146 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001147 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001148 return;
1149 }
1150 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1151 if (NULL == smeContext)
1152 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001153 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001154 return;
1155 }
1156
1157 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1158 pHddCtx->cfg_ini->nEnableSuspend)
1159 {
1160 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1161 }
1162}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301163
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301164#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301165void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301166{
1167 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301168 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301169 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1170
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301171 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301172 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301173 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1174 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1175 {
1176 vos_mem_copy(&hddGtkOffloadReqParams,
1177 &pHddStaCtx->gtkOffloadReqParams,
1178 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301179
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301180 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1181 &hddGtkOffloadReqParams, pAdapter->sessionId);
1182 if (eHAL_STATUS_SUCCESS != ret)
1183 {
1184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1185 "%s: sme_SetGTKOffload failed, returned %d",
1186 __func__, ret);
1187 return;
1188 }
1189
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1191 "%s: sme_SetGTKOffload successfull", __func__);
1192 }
1193
1194 }
1195 else
1196 {
1197 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1198 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1199 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1200 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1201 {
1202
1203 /* Host driver has previously offloaded GTK rekey */
1204 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301205 wlan_hdd_cfg80211_update_replayCounterCallback,
1206 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301207 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301208
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301209 {
1210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1211 "%s: sme_GetGTKOffload failed, returned %d",
1212 __func__, ret);
1213 return;
1214 }
1215 else
1216 {
1217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1218 "%s: sme_GetGTKOffload successful",
1219 __func__);
1220
1221 /* Sending GTK offload dissable */
1222 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1223 sizeof (tSirGtkOffloadParams));
1224 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1225 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301226 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301227 if (eHAL_STATUS_SUCCESS != ret)
1228 {
1229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1230 "%s: failed to dissable GTK offload, returned %d",
1231 __func__, ret);
1232 return;
1233 }
1234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1235 "%s: successfully dissabled GTK offload request to HAL",
1236 __func__);
1237 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301238 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301239 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301240 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301241}
1242#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001243
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001244void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001245{
1246 hdd_context_t *pHddCtx = NULL;
1247 hdd_adapter_t *pAdapter = NULL;
1248 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1249 VOS_STATUS status;
1250 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001251
Jeff Johnson295189b2012-06-20 16:38:30 -07001252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1253
1254 //Get the global VOSS context.
1255 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1256 if(!pVosContext) {
1257 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1258 return;
1259 }
1260
1261 //Get the HDD context.
1262 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1263
1264 if(!pHddCtx) {
1265 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1266 return;
1267 }
1268
1269 if (pHddCtx->isLogpInProgress) {
1270 hddLog(VOS_TRACE_LEVEL_INFO,
1271 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1272 return;
1273 }
1274
Jeff Johnson295189b2012-06-20 16:38:30 -07001275 pHddCtx->hdd_wlan_suspended = FALSE;
1276 /*loop through all adapters. Concurrency */
1277 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1278
1279 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1280 {
1281 pAdapter = pAdapterNode->pAdapter;
1282 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001283 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001285 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001286 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1287 pAdapterNode = pNext;
1288 continue;
1289 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301290
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301291
Jeff Johnson295189b2012-06-20 16:38:30 -07001292#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1293 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1294 {
1295 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1296 hdd_exit_deep_sleep(pAdapter);
1297 }
1298#endif
1299
1300 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1301 {
1302 /*Switch back to DTIM 1*/
1303 tSirSetPowerParamsReq powerRequest = { 0 };
1304
1305 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1306 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001307 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001308
1309 /*Disabled ModulatedDTIM if enabled on suspend*/
1310 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1311 powerRequest.uDTIMPeriod = 0;
1312
1313 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1314 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1315 NULL, eANI_BOOLEAN_FALSE);
1316 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1317 NULL, eANI_BOOLEAN_FALSE);
1318
1319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1320 "Switch to DTIM%d \n",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001321 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001322
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301323 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1324 {
1325 /* put the device into full power */
1326 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001327
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301328 /* put the device back into BMPS */
1329 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001330
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301331 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001333 }
1334
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301335 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001336 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1337 pAdapterNode = pNext;
1338 }
1339
1340#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1341 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1342 {
1343 hdd_exit_standby(pHddCtx);
1344 }
1345#endif
1346
Jeff Johnson295189b2012-06-20 16:38:30 -07001347 return;
1348}
1349
Jeff Johnson295189b2012-06-20 16:38:30 -07001350VOS_STATUS hdd_wlan_reset_initialization(void)
1351{
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 v_CONTEXT_t pVosContext = NULL;
1353
1354 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1355
1356 //Get the global VOSS context.
1357 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1358 if(!pVosContext)
1359 {
1360 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1361 return VOS_STATUS_E_FAILURE;
1362 }
1363
1364 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1365
1366 // Prevent the phone from going to sleep
1367 hdd_prevent_suspend();
1368
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 return VOS_STATUS_SUCCESS;
1370}
1371
1372
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001373/*
1374 * Based on the ioctl command recieved by HDD, put WLAN driver
1375 * into the quiet mode. This is the same as the early suspend
1376 * notification that driver used to listen
1377 */
1378void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001379{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001380 if (suspend)
1381 hdd_suspend_wlan();
1382 else
1383 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001384}
1385
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001386static void hdd_ssr_timer_init(void)
1387{
1388 init_timer(&ssr_timer);
1389}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001390
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001391static void hdd_ssr_timer_del(void)
1392{
1393 del_timer(&ssr_timer);
1394 ssr_timer_started = false;
1395}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001396
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001397static void hdd_ssr_timer_cb(unsigned long data)
1398{
1399 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001400
1401#ifdef WCN_PRONTO
1402 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1403 wcnss_pronto_log_debug_regs();
1404#endif
1405
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001406 VOS_BUG(0);
1407}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001408
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001409static void hdd_ssr_timer_start(int msec)
1410{
1411 if(ssr_timer_started)
1412 {
1413 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1414 ,__func__);
1415 }
1416 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1417 ssr_timer.function = hdd_ssr_timer_cb;
1418 add_timer(&ssr_timer);
1419 ssr_timer_started = true;
1420}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001421
Jeff Johnson295189b2012-06-20 16:38:30 -07001422/* the HDD interface to WLAN driver shutdown,
1423 * the primary shutdown function in SSR
1424 */
1425VOS_STATUS hdd_wlan_shutdown(void)
1426{
1427 VOS_STATUS vosStatus;
1428 v_CONTEXT_t pVosContext = NULL;
1429 hdd_context_t *pHddCtx = NULL;
1430 pVosSchedContext vosSchedContext = NULL;
1431
1432 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1433
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001434 /* if re-init never happens, then do SSR1 */
1435 hdd_ssr_timer_init();
1436 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1437
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 /* Get the global VOSS context. */
1439 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1440 if(!pVosContext) {
1441 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1442 return VOS_STATUS_E_FAILURE;
1443 }
1444 /* Get the HDD context. */
1445 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1446 if(!pHddCtx) {
1447 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1448 return VOS_STATUS_E_FAILURE;
1449 }
1450 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001451 /* DeRegister with platform driver as client for Suspend/Resume */
1452 vosStatus = hddDeregisterPmOps(pHddCtx);
1453 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1454 {
1455 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1456 }
1457
1458 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1459 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1460 {
1461 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1462 }
1463
1464 /* Disable IMPS/BMPS as we do not want the device to enter any power
1465 * save mode on its own during reset sequence
1466 */
1467 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1468 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1469 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1470
1471 vosSchedContext = get_vos_sched_ctxt();
1472
1473 /* Wakeup all driver threads */
1474 if(TRUE == pHddCtx->isMcThreadSuspended){
1475 complete(&vosSchedContext->ResumeMcEvent);
1476 pHddCtx->isMcThreadSuspended= FALSE;
1477 }
1478 if(TRUE == pHddCtx->isTxThreadSuspended){
1479 complete(&vosSchedContext->ResumeTxEvent);
1480 pHddCtx->isTxThreadSuspended= FALSE;
1481 }
1482 if(TRUE == pHddCtx->isRxThreadSuspended){
1483 complete(&vosSchedContext->ResumeRxEvent);
1484 pHddCtx->isRxThreadSuspended= FALSE;
1485 }
1486 /* Reset the Suspend Variable */
1487 pHddCtx->isWlanSuspended = FALSE;
1488
1489 /* Stop all the threads; we do not want any messages to be a processed,
1490 * any more and the best way to ensure that is to terminate the threads
1491 * gracefully.
1492 */
1493 /* Wait for MC to exit */
1494 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1495 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1496 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1497 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1498 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1499
1500 /* Wait for TX to exit */
1501 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1502 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1503 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1504 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1505 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1506
1507 /* Wait for RX to exit */
1508 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1509 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1510 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1511 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1512 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1513
1514#ifdef WLAN_BTAMP_FEATURE
1515 vosStatus = WLANBAP_Stop(pVosContext);
1516 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1517 {
1518 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1519 "%s: Failed to stop BAP",__func__);
1520 }
1521#endif //WLAN_BTAMP_FEATURE
1522 vosStatus = vos_wda_shutdown(pVosContext);
1523 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1524
1525 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1526 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1527 * on threads being running to process the SYS Stop
1528 */
1529 vosStatus = sme_Stop(pHddCtx->hHal, TRUE);
1530 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1531
1532 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1533 /* Stop MAC (PE and HAL) */
1534 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1535 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1536
1537 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1538 /* Stop TL */
1539 vosStatus = WLANTL_Stop(pVosContext);
1540 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1541
Jeff Johnson295189b2012-06-20 16:38:30 -07001542 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1544 /* Clean up message queues of TX and MC thread */
1545 vos_sched_flush_mc_mqs(vosSchedContext);
1546 vos_sched_flush_tx_mqs(vosSchedContext);
1547 vos_sched_flush_rx_mqs(vosSchedContext);
1548
1549 /* Deinit all the TX and MC queues */
1550 vos_sched_deinit_mqs(vosSchedContext);
1551 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1552
1553 /* shutdown VOSS */
1554 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301555
1556 /*mac context has already been released in mac_close call
1557 so setting it to NULL in hdd context*/
1558 pHddCtx->hHal = (tHalHandle)NULL;
1559
Jeff Johnson295189b2012-06-20 16:38:30 -07001560 if (free_riva_power_on_lock("wlan"))
1561 {
1562 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1563 __func__);
1564 }
1565 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1566 ,__func__);
1567 return VOS_STATUS_SUCCESS;
1568}
1569
1570
1571
1572/* the HDD interface to WLAN driver re-init.
1573 * This is called to initialize/start WLAN driver after a shutdown.
1574 */
1575VOS_STATUS hdd_wlan_re_init(void)
1576{
1577 VOS_STATUS vosStatus;
1578 v_CONTEXT_t pVosContext = NULL;
1579 hdd_context_t *pHddCtx = NULL;
1580 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001581#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1582 int max_retries = 0;
1583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001584#ifdef WLAN_BTAMP_FEATURE
1585 hdd_config_t *pConfig = NULL;
1586 WLANBAP_ConfigType btAmpConfig;
1587#endif
1588
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001589 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001590 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001591
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001592#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1593 /* wait until WCNSS driver downloads NV */
1594 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1595 msleep(1000);
1596 }
1597 if (max_retries >= 5) {
1598 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1599 goto err_re_init;
1600 }
1601#endif
1602
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001603 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
1604
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001605 /* The driver should always be initialized in STA mode after SSR */
1606 hdd_set_conparam(0);
1607
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1609 vosStatus = vos_open(&pVosContext, 0);
1610 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1611 {
1612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1613 goto err_re_init;
1614 }
1615
1616 /* Get the HDD context. */
1617 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1618 if(!pHddCtx)
1619 {
1620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1621 goto err_vosclose;
1622 }
1623
1624 /* Save the hal context in Adapter */
1625 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1626 if ( NULL == pHddCtx->hHal )
1627 {
1628 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1629 goto err_vosclose;
1630 }
1631
1632 /* Set the SME configuration parameters. */
1633 vosStatus = hdd_set_sme_config(pHddCtx);
1634 if ( VOS_STATUS_SUCCESS != vosStatus )
1635 {
1636 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1637 goto err_vosclose;
1638 }
1639
1640 /* Initialize the WMM module */
1641 vosStatus = hdd_wmm_init(pHddCtx);
1642 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1643 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001644 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001645 goto err_vosclose;
1646 }
1647
1648 vosStatus = vos_preStart( pHddCtx->pvosContext );
1649 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1650 {
1651 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1652 goto err_vosclose;
1653 }
1654
1655 /* In the integrated architecture we update the configuration from
1656 the INI file and from NV before vOSS has been started so that
1657 the final contents are available to send down to the cCPU */
1658 /* Apply the cfg.ini to cfg.dat */
1659 if (FALSE == hdd_update_config_dat(pHddCtx))
1660 {
1661 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1662 goto err_vosclose;
1663 }
1664
1665 /* Set the MAC Address, currently this is used by HAL to add self sta.
1666 * Remove this once self sta is added as part of session open. */
1667 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1668 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1669 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1670 if (!HAL_STATUS_SUCCESS(halStatus))
1671 {
1672 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1673 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1674 goto err_vosclose;
1675 }
1676
1677 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1678 Note: Firmware image will be read and downloaded inside vos_start API */
1679 vosStatus = vos_start( pVosContext );
1680 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1681 {
1682 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1683 goto err_vosclose;
1684 }
1685
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001686 /* Exchange capability info between Host and FW and also get versioning info from FW */
1687 hdd_exchange_version_and_caps(pHddCtx);
1688
Jeff Johnson295189b2012-06-20 16:38:30 -07001689 vosStatus = hdd_post_voss_start_config( pHddCtx );
1690 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1691 {
1692 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1693 __func__);
1694 goto err_vosstop;
1695 }
1696
1697#ifdef WLAN_BTAMP_FEATURE
1698 vosStatus = WLANBAP_Open(pVosContext);
1699 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1700 {
1701 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1702 "%s: Failed to open BAP",__func__);
1703 goto err_vosstop;
1704 }
1705 vosStatus = BSL_Init(pVosContext);
1706 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1707 {
1708 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1709 "%s: Failed to Init BSL",__func__);
1710 goto err_bap_close;
1711 }
1712 vosStatus = WLANBAP_Start(pVosContext);
1713 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1714 {
1715 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1716 "%s: Failed to start TL",__func__);
1717 goto err_bap_close;
1718 }
1719 pConfig = pHddCtx->cfg_ini;
1720 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1721 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1722#endif //WLAN_BTAMP_FEATURE
1723
1724 /* Restart all adapters */
1725 hdd_start_all_adapters(pHddCtx);
1726 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07001727 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001728 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001730
1731 /* Register with platform driver as client for Suspend/Resume */
1732 vosStatus = hddRegisterPmOps(pHddCtx);
1733 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1734 {
1735 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1736 goto err_bap_stop;
1737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001738 /* Allow the phone to go to sleep */
1739 hdd_allow_suspend();
1740 /* register for riva power on lock */
1741 if (req_riva_power_on_lock("wlan"))
1742 {
1743 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1744 __func__);
1745 goto err_unregister_pmops;
1746 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001747 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 goto success;
1749
1750err_unregister_pmops:
1751 hddDeregisterPmOps(pHddCtx);
1752
1753err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001754#ifdef CONFIG_HAS_EARLYSUSPEND
1755 hdd_unregister_mcast_bcast_filter(pHddCtx);
1756#endif
1757 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001758#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001759 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001760#endif
1761
1762#ifdef WLAN_BTAMP_FEATURE
1763err_bap_close:
1764 WLANBAP_Close(pVosContext);
1765#endif
1766
1767err_vosstop:
1768 vos_stop(pVosContext);
1769
1770err_vosclose:
1771 vos_close(pVosContext);
1772 vos_sched_close(pVosContext);
1773 if (pHddCtx)
1774 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001775 /* Unregister the Net Device Notifier */
1776 unregister_netdevice_notifier(&hdd_netdev_notifier);
1777 /* Clean up HDD Nlink Service */
1778 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07001779#ifdef WLAN_KD_READY_NOTIFIER
1780 nl_srv_exit(pHddCtx->ptt_pid);
1781#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07001783#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07001784 /* Free up dynamically allocated members inside HDD Adapter */
1785 kfree(pHddCtx->cfg_ini);
1786 pHddCtx->cfg_ini= NULL;
1787
Jeff Johnson295189b2012-06-20 16:38:30 -07001788 wiphy_unregister(pHddCtx->wiphy);
1789 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 }
1791 vos_preClose(&pVosContext);
1792
1793#ifdef MEMORY_DEBUG
1794 vos_mem_exit();
1795#endif
1796
1797err_re_init:
1798 /* Allow the phone to go to sleep */
1799 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001800 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07001801 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001802 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001803
1804success:
1805 /* Trigger replay of BTC events */
1806 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1807 return VOS_STATUS_SUCCESS;
1808}