blob: e67f1f56f6b85af9af07e98e4a5e4e467889f56b [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
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530651 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
652 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
653 pHddCtx->sus_res_mcastbcast_filter) ||
654 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
655 pHddCtx->sus_res_mcastbcast_filter)))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530656 {
657 hddLog (VOS_TRACE_LEVEL_INFO,
658 "Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE \n", __func__);
659 offLoadRequest.enableOrDisable =
660 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
661 }
662
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530663 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
664 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
665 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
666
667 hddLog (VOS_TRACE_LEVEL_INFO,
668 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
669 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
670 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
671
672 //Configure the Firmware with this
673 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
674 pAdapter->sessionId, &offLoadRequest);
675 if(eHAL_STATUS_SUCCESS != returnStatus)
676 {
677 hddLog(VOS_TRACE_LEVEL_ERROR,
678 FL("Failed to enable HostOffload feature with status: %d"),
679 returnStatus);
680 }
681 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
682 }
683 }
684 }
685 else
686 {
687 hddLog(VOS_TRACE_LEVEL_ERROR,
688 FL("IPv6 dev does not exist. Failed to request NSOffload"));
689 return;
690 }
691 }
692 else
693 {
694 //Disable NSOffload
695 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
696 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
697 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
698
699 if (eHAL_STATUS_SUCCESS !=
700 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
701 pAdapter->sessionId, &offLoadRequest))
702 {
703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
704 "NSOffload feature"));
705 }
706 }
707 return;
708}
709#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530710VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700711{
712 struct in_ifaddr **ifap = NULL;
713 struct in_ifaddr *ifa = NULL;
714 struct in_device *in_dev;
715 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700716 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800717 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700718
719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700720
Jeff Johnson295189b2012-06-20 16:38:30 -0700721 if(fenable)
722 {
723 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
724 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530725 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700726 ifap = &ifa->ifa_next)
727 {
728 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
729 {
730 break; /* found */
731 }
732 }
733 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700734 if(ifa && ifa->ifa_local)
735 {
736 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
737 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
738
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700740
Amar Singhald53568e2013-09-26 11:03:45 -0700741 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
742 pHddCtx->sus_res_mcastbcast_filter) ||
743 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
744 pHddCtx->sus_res_mcastbcast_filter)) &&
745 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700746 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530747 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -0700748 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
749 hddLog(VOS_TRACE_LEVEL_INFO,
750 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -0700751 }
Amar Singhald53568e2013-09-26 11:03:45 -0700752
753 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
754 offLoadRequest.enableOrDisable);
755
Jeff Johnson295189b2012-06-20 16:38:30 -0700756 //converting u32 to IPV4 address
757 for(i = 0 ; i < 4; i++)
758 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530759 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700760 (ifa->ifa_local >> (i*8) ) & 0xFF ;
761 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530762 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700763 offLoadRequest.params.hostIpv4Addr[0],
764 offLoadRequest.params.hostIpv4Addr[1],
765 offLoadRequest.params.hostIpv4Addr[2],
766 offLoadRequest.params.hostIpv4Addr[3]);
767
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530768 if (eHAL_STATUS_SUCCESS !=
769 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
770 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700771 {
772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
773 "feature\n", __func__);
774 return VOS_STATUS_E_FAILURE;
775 }
776 return VOS_STATUS_SUCCESS;
777 }
778 else
779 {
780 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned \n", __func__);
781 return VOS_STATUS_E_AGAIN;
782 }
783 }
784 else
785 {
786 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
787 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
788 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
789
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530790 if (eHAL_STATUS_SUCCESS !=
791 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
792 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700793 {
794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
795 "offload feature\n", __func__);
796 return VOS_STATUS_E_FAILURE;
797 }
798 return VOS_STATUS_SUCCESS;
799 }
800}
801
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530802/*
803 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530804 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530805*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530806void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530807 tANI_U8 *pMcBcFilter)
808{
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530809 if (NULL == pHddCtx)
810 {
811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
812 return;
813 }
814
815 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
816 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530817 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530818 /* ARP offload is enabled, do not block bcast packets at RXP
819 * Will be using Bitmasking to reset the filter. As we have
820 * disable Broadcast filtering, Anding with the negation
821 * of Broadcast BIT
822 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530823 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530824 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530825
826#ifdef WLAN_NS_OFFLOAD
827 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530828 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530829 /* NS offload is enabled, do not block mcast packets at RXP
830 * Will be using Bitmasking to reset the filter. As we have
831 * disable Multicast filtering, Anding with the negation
832 * of Multicast BIT
833 */
834 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530835 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530836#endif
837
838 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530839}
840
Jeff Johnson295189b2012-06-20 16:38:30 -0700841void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
842{
843 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 tpSirWlanSetRxpFilters wlanRxpFilterParam =
845 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
846 if(NULL == wlanRxpFilterParam)
847 {
848 hddLog(VOS_TRACE_LEVEL_FATAL,
849 "%s: vos_mem_alloc failed ", __func__);
850 return;
851 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700852 hddLog(VOS_TRACE_LEVEL_INFO,
853 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530854 if (TRUE == setfilter)
855 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530856 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530857 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530858 }
859 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530860 {
861 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530862 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530863 pHddCtx->configuredMcastBcastFilter;
864 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530865
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700867 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -0700868 if (eHAL_STATUS_SUCCESS != halStatus)
869 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700870 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
871 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
872}
873
Jeff Johnson295189b2012-06-20 16:38:30 -0700874static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
875 hdd_adapter_t *pAdapter)
876{
877 eHalStatus halStatus = eHAL_STATUS_FAILURE;
878 tpSirWlanSuspendParam wlanSuspendParam =
879 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
880
Amar Singhald53568e2013-09-26 11:03:45 -0700881 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
882 pHddCtx->sus_res_mcastbcast_filter =
883 pHddCtx->configuredMcastBcastFilter;
884 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
885 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
886 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
887 pHddCtx->configuredMcastBcastFilter);
888
889 }
890
Amar Singhal49fdfd52013-08-13 13:25:12 -0700891
Jeff Johnson295189b2012-06-20 16:38:30 -0700892 if(NULL == wlanSuspendParam)
893 {
894 hddLog(VOS_TRACE_LEVEL_FATAL,
895 "%s: vos_mem_alloc failed ", __func__);
896 return;
897 }
898
Amar Singhald53568e2013-09-26 11:03:45 -0700899 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700900 "%s: send wlan suspend indication", __func__);
901
902 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
903 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530904 //Configure supported OffLoads
905 hdd_conf_hostoffload(pAdapter, TRUE);
906 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700907
908#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530909 /* During suspend, configure MC Addr list filter to the firmware
910 * function takes care of checking necessary conditions before
911 * configuring.
912 */
913 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700914#endif
915 }
916
917 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
918 if(eHAL_STATUS_SUCCESS == halStatus)
919 {
920 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -0700921 } else {
922 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 }
924}
925
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530926static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700927{
Chilam Ngc4244af2013-04-01 15:37:32 -0700928 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -0800929 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -0700930 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -0700931
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530932 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 "%s: send wlan resume indication", __func__);
934
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +0530935 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
936
937 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -0700938 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +0530939 hddLog(VOS_TRACE_LEVEL_FATAL,
940 "%s: memory allocation failed for wlanResumeParam ", __func__);
941 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700943
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +0530944 //Disable supported OffLoads
945 hdd_conf_hostoffload(pAdapter, FALSE);
946
947 wlanResumeParam->configuredMcstBcstFilterSetting =
948 pHddCtx->configuredMcastBcastFilter;
949 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
950 if (eHAL_STATUS_SUCCESS != halStatus)
951 {
952 vos_mem_free(wlanResumeParam);
953 }
954
955 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
956
Amar Singhal49fdfd52013-08-13 13:25:12 -0700957 pHddCtx->configuredMcastBcastFilter =
958 pHddCtx->sus_res_mcastbcast_filter;
Amar Singhald53568e2013-09-26 11:03:45 -0700959 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
960
961 hddLog(VOS_TRACE_LEVEL_INFO,
962 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
963 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
964 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -0700965
Chilam Ngc4244af2013-04-01 15:37:32 -0700966
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530967#ifdef WLAN_FEATURE_PACKET_FILTERING
968 /* Filer was applied during suspend inditication
969 * clear it when we resume.
970 */
971 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700972#endif
973}
Jeff Johnson295189b2012-06-20 16:38:30 -0700974
Jeff Johnson295189b2012-06-20 16:38:30 -0700975//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800976void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -0700977{
978 hdd_context_t *pHddCtx = NULL;
979 v_CONTEXT_t pVosContext = NULL;
980
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +0530982 hdd_adapter_t *pAdapter = NULL;
983 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +0530984 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800985
Jeff Johnson295189b2012-06-20 16:38:30 -0700986 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
987
988 //Get the global VOSS context.
989 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
990 if(!pVosContext) {
991 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
992 return;
993 }
994
995 //Get the HDD context.
996 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
997
998 if(!pHddCtx) {
999 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1000 return;
1001 }
1002
1003 if (pHddCtx->isLogpInProgress) {
1004 hddLog(VOS_TRACE_LEVEL_ERROR,
1005 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1006 return;
1007 }
1008
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301009 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001010 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1011 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1012 {
1013 pAdapter = pAdapterNode->pAdapter;
1014 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001015 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001016 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1017
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001018 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001019 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1020 pAdapterNode = pNext;
1021 continue;
1022 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301023 /* Avoid multiple enter/exit BMPS in this while loop using
1024 * hdd_enter_bmps flag
1025 */
1026 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1027 {
1028 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001029
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301030 /* If device was already in BMPS, and dynamic DTIM is set,
1031 * exit(set the device to full power) and enter BMPS again
1032 * to reflect new DTIM value */
1033 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1034
1035 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1036
1037 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1038 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001039#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1040 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1041 {
1042 //stop the interface before putting the chip to standby
1043 netif_tx_disable(pAdapter->dev);
1044 netif_carrier_off(pAdapter->dev);
1045 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301046 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001047 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1048 {
1049 //Execute deep sleep procedure
1050 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1051 }
1052#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301053
1054 /*Suspend notification sent down to driver*/
1055 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1056
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301057 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1058 pAdapterNode = pNext;
1059 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301060 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301061
Jeff Johnson295189b2012-06-20 16:38:30 -07001062#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1063 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1064 {
1065 hdd_enter_standby(pHddCtx);
1066 }
1067#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001068
1069 return;
1070}
1071
1072static void hdd_PowerStateChangedCB
1073(
1074 v_PVOID_t callbackContext,
1075 tPmcState newState
1076)
1077{
1078 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001079 /* if the driver was not in BMPS during early suspend,
1080 * the dynamic DTIM is now updated at Riva */
1081 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1082 && pHddCtx->cfg_ini->enableDynamicDTIM
1083 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1084 {
1085 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1086 }
1087 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301088 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001089 spin_unlock(&pHddCtx->filter_lock);
Amar Singhald53568e2013-09-26 11:03:45 -07001090 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1091 pHddCtx->sus_res_mcastbcast_filter =
1092 pHddCtx->configuredMcastBcastFilter;
1093 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1094
1095 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1096 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1097 pHddCtx->configuredMcastBcastFilter);
1098 hddLog(VOS_TRACE_LEVEL_INFO,
1099 "offload: calling hdd_conf_mcastbcast_filter");
1100
1101 }
1102
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1106 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001107 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 spin_unlock(&pHddCtx->filter_lock);
1109}
1110
1111
1112
1113void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1114{
1115 v_CONTEXT_t pVosContext;
1116 tHalHandle smeContext;
1117
1118 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1119 if (NULL == pVosContext)
1120 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001121 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001122 return;
1123 }
1124 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1125 if (NULL == smeContext)
1126 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001127 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001128 return;
1129 }
1130
1131 spin_lock_init(&pHddCtx->filter_lock);
1132 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1133 pHddCtx->cfg_ini->nEnableSuspend)
1134 {
1135 pmcRegisterDeviceStateUpdateInd(smeContext,
1136 hdd_PowerStateChangedCB, pHddCtx);
1137 }
1138}
1139
1140void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1141{
1142 v_CONTEXT_t pVosContext;
1143 tHalHandle smeContext;
1144
1145 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1146 if (NULL == pVosContext)
1147 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001148 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 return;
1150 }
1151 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1152 if (NULL == smeContext)
1153 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001154 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 return;
1156 }
1157
1158 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1159 pHddCtx->cfg_ini->nEnableSuspend)
1160 {
1161 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1162 }
1163}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301164
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301165#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301166void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301167{
1168 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301169 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301170 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1171
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301172 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301173 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301174 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1175 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1176 {
1177 vos_mem_copy(&hddGtkOffloadReqParams,
1178 &pHddStaCtx->gtkOffloadReqParams,
1179 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301180
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301181 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1182 &hddGtkOffloadReqParams, pAdapter->sessionId);
1183 if (eHAL_STATUS_SUCCESS != ret)
1184 {
1185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1186 "%s: sme_SetGTKOffload failed, returned %d",
1187 __func__, ret);
1188 return;
1189 }
1190
1191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1192 "%s: sme_SetGTKOffload successfull", __func__);
1193 }
1194
1195 }
1196 else
1197 {
1198 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1199 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1200 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1201 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1202 {
1203
1204 /* Host driver has previously offloaded GTK rekey */
1205 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301206 wlan_hdd_cfg80211_update_replayCounterCallback,
1207 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301208 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301209
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301210 {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1212 "%s: sme_GetGTKOffload failed, returned %d",
1213 __func__, ret);
1214 return;
1215 }
1216 else
1217 {
1218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1219 "%s: sme_GetGTKOffload successful",
1220 __func__);
1221
1222 /* Sending GTK offload dissable */
1223 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1224 sizeof (tSirGtkOffloadParams));
1225 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1226 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301227 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301228 if (eHAL_STATUS_SUCCESS != ret)
1229 {
1230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1231 "%s: failed to dissable GTK offload, returned %d",
1232 __func__, ret);
1233 return;
1234 }
1235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1236 "%s: successfully dissabled GTK offload request to HAL",
1237 __func__);
1238 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301239 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301240 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301241 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301242}
1243#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001244
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001245void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001246{
1247 hdd_context_t *pHddCtx = NULL;
1248 hdd_adapter_t *pAdapter = NULL;
1249 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1250 VOS_STATUS status;
1251 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001252
Jeff Johnson295189b2012-06-20 16:38:30 -07001253 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1254
1255 //Get the global VOSS context.
1256 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1257 if(!pVosContext) {
1258 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1259 return;
1260 }
1261
1262 //Get the HDD context.
1263 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1264
1265 if(!pHddCtx) {
1266 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1267 return;
1268 }
1269
1270 if (pHddCtx->isLogpInProgress) {
1271 hddLog(VOS_TRACE_LEVEL_INFO,
1272 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1273 return;
1274 }
1275
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 pHddCtx->hdd_wlan_suspended = FALSE;
1277 /*loop through all adapters. Concurrency */
1278 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1279
1280 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1281 {
1282 pAdapter = pAdapterNode->pAdapter;
1283 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001284 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001285 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001286 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001287 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1288 pAdapterNode = pNext;
1289 continue;
1290 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301291
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301292
Jeff Johnson295189b2012-06-20 16:38:30 -07001293#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1294 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1297 hdd_exit_deep_sleep(pAdapter);
1298 }
1299#endif
1300
1301 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1302 {
1303 /*Switch back to DTIM 1*/
1304 tSirSetPowerParamsReq powerRequest = { 0 };
1305
1306 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1307 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001308 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001309
1310 /*Disabled ModulatedDTIM if enabled on suspend*/
1311 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1312 powerRequest.uDTIMPeriod = 0;
1313
1314 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1315 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1316 NULL, eANI_BOOLEAN_FALSE);
1317 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1318 NULL, eANI_BOOLEAN_FALSE);
1319
1320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1321 "Switch to DTIM%d \n",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001322 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001323
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301324 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1325 {
1326 /* put the device into full power */
1327 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001328
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301329 /* put the device back into BMPS */
1330 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001331
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301332 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001334 }
1335
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301336 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1338 pAdapterNode = pNext;
1339 }
1340
1341#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1342 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1343 {
1344 hdd_exit_standby(pHddCtx);
1345 }
1346#endif
1347
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 return;
1349}
1350
Jeff Johnson295189b2012-06-20 16:38:30 -07001351VOS_STATUS hdd_wlan_reset_initialization(void)
1352{
Jeff Johnson295189b2012-06-20 16:38:30 -07001353 v_CONTEXT_t pVosContext = NULL;
1354
1355 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1356
1357 //Get the global VOSS context.
1358 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1359 if(!pVosContext)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1362 return VOS_STATUS_E_FAILURE;
1363 }
1364
1365 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1366
1367 // Prevent the phone from going to sleep
1368 hdd_prevent_suspend();
1369
Jeff Johnson295189b2012-06-20 16:38:30 -07001370 return VOS_STATUS_SUCCESS;
1371}
1372
1373
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001374/*
1375 * Based on the ioctl command recieved by HDD, put WLAN driver
1376 * into the quiet mode. This is the same as the early suspend
1377 * notification that driver used to listen
1378 */
1379void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001380{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001381 if (suspend)
1382 hdd_suspend_wlan();
1383 else
1384 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001385}
1386
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001387static void hdd_ssr_timer_init(void)
1388{
1389 init_timer(&ssr_timer);
1390}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001391
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001392static void hdd_ssr_timer_del(void)
1393{
1394 del_timer(&ssr_timer);
1395 ssr_timer_started = false;
1396}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001397
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001398static void hdd_ssr_timer_cb(unsigned long data)
1399{
1400 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001401
1402#ifdef WCN_PRONTO
1403 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1404 wcnss_pronto_log_debug_regs();
1405#endif
1406
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001407 VOS_BUG(0);
1408}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001409
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001410static void hdd_ssr_timer_start(int msec)
1411{
1412 if(ssr_timer_started)
1413 {
1414 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1415 ,__func__);
1416 }
1417 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1418 ssr_timer.function = hdd_ssr_timer_cb;
1419 add_timer(&ssr_timer);
1420 ssr_timer_started = true;
1421}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001422
Jeff Johnson295189b2012-06-20 16:38:30 -07001423/* the HDD interface to WLAN driver shutdown,
1424 * the primary shutdown function in SSR
1425 */
1426VOS_STATUS hdd_wlan_shutdown(void)
1427{
1428 VOS_STATUS vosStatus;
1429 v_CONTEXT_t pVosContext = NULL;
1430 hdd_context_t *pHddCtx = NULL;
1431 pVosSchedContext vosSchedContext = NULL;
1432
1433 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1434
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001435 /* if re-init never happens, then do SSR1 */
1436 hdd_ssr_timer_init();
1437 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1438
Jeff Johnson295189b2012-06-20 16:38:30 -07001439 /* Get the global VOSS context. */
1440 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1441 if(!pVosContext) {
1442 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1443 return VOS_STATUS_E_FAILURE;
1444 }
1445 /* Get the HDD context. */
1446 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1447 if(!pHddCtx) {
1448 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1449 return VOS_STATUS_E_FAILURE;
1450 }
1451 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 /* DeRegister with platform driver as client for Suspend/Resume */
1453 vosStatus = hddDeregisterPmOps(pHddCtx);
1454 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1455 {
1456 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1457 }
1458
1459 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1460 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1461 {
1462 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1463 }
1464
1465 /* Disable IMPS/BMPS as we do not want the device to enter any power
1466 * save mode on its own during reset sequence
1467 */
1468 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1469 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1470 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1471
1472 vosSchedContext = get_vos_sched_ctxt();
1473
1474 /* Wakeup all driver threads */
1475 if(TRUE == pHddCtx->isMcThreadSuspended){
1476 complete(&vosSchedContext->ResumeMcEvent);
1477 pHddCtx->isMcThreadSuspended= FALSE;
1478 }
1479 if(TRUE == pHddCtx->isTxThreadSuspended){
1480 complete(&vosSchedContext->ResumeTxEvent);
1481 pHddCtx->isTxThreadSuspended= FALSE;
1482 }
1483 if(TRUE == pHddCtx->isRxThreadSuspended){
1484 complete(&vosSchedContext->ResumeRxEvent);
1485 pHddCtx->isRxThreadSuspended= FALSE;
1486 }
1487 /* Reset the Suspend Variable */
1488 pHddCtx->isWlanSuspended = FALSE;
1489
1490 /* Stop all the threads; we do not want any messages to be a processed,
1491 * any more and the best way to ensure that is to terminate the threads
1492 * gracefully.
1493 */
1494 /* Wait for MC to exit */
1495 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1496 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1497 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1498 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1499 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1500
1501 /* Wait for TX to exit */
1502 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1503 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1504 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1505 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1506 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1507
1508 /* Wait for RX to exit */
1509 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1510 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1511 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1512 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1513 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1514
1515#ifdef WLAN_BTAMP_FEATURE
1516 vosStatus = WLANBAP_Stop(pVosContext);
1517 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1518 {
1519 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1520 "%s: Failed to stop BAP",__func__);
1521 }
1522#endif //WLAN_BTAMP_FEATURE
1523 vosStatus = vos_wda_shutdown(pVosContext);
1524 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1525
1526 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1527 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1528 * on threads being running to process the SYS Stop
1529 */
1530 vosStatus = sme_Stop(pHddCtx->hHal, TRUE);
1531 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1532
1533 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1534 /* Stop MAC (PE and HAL) */
1535 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1536 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1537
1538 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1539 /* Stop TL */
1540 vosStatus = WLANTL_Stop(pVosContext);
1541 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1542
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001544 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1545 /* Clean up message queues of TX and MC thread */
1546 vos_sched_flush_mc_mqs(vosSchedContext);
1547 vos_sched_flush_tx_mqs(vosSchedContext);
1548 vos_sched_flush_rx_mqs(vosSchedContext);
1549
1550 /* Deinit all the TX and MC queues */
1551 vos_sched_deinit_mqs(vosSchedContext);
1552 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1553
1554 /* shutdown VOSS */
1555 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301556
1557 /*mac context has already been released in mac_close call
1558 so setting it to NULL in hdd context*/
1559 pHddCtx->hHal = (tHalHandle)NULL;
1560
Jeff Johnson295189b2012-06-20 16:38:30 -07001561 if (free_riva_power_on_lock("wlan"))
1562 {
1563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1564 __func__);
1565 }
1566 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1567 ,__func__);
1568 return VOS_STATUS_SUCCESS;
1569}
1570
1571
1572
1573/* the HDD interface to WLAN driver re-init.
1574 * This is called to initialize/start WLAN driver after a shutdown.
1575 */
1576VOS_STATUS hdd_wlan_re_init(void)
1577{
1578 VOS_STATUS vosStatus;
1579 v_CONTEXT_t pVosContext = NULL;
1580 hdd_context_t *pHddCtx = NULL;
1581 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001582#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1583 int max_retries = 0;
1584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001585#ifdef WLAN_BTAMP_FEATURE
1586 hdd_config_t *pConfig = NULL;
1587 WLANBAP_ConfigType btAmpConfig;
1588#endif
1589
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001590 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001591 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001592
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001593#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1594 /* wait until WCNSS driver downloads NV */
1595 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1596 msleep(1000);
1597 }
1598 if (max_retries >= 5) {
1599 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1600 goto err_re_init;
1601 }
1602#endif
1603
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001604 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
1605
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001606 /* The driver should always be initialized in STA mode after SSR */
1607 hdd_set_conparam(0);
1608
Jeff Johnson295189b2012-06-20 16:38:30 -07001609 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1610 vosStatus = vos_open(&pVosContext, 0);
1611 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1612 {
1613 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1614 goto err_re_init;
1615 }
1616
1617 /* Get the HDD context. */
1618 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1619 if(!pHddCtx)
1620 {
1621 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1622 goto err_vosclose;
1623 }
1624
1625 /* Save the hal context in Adapter */
1626 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1627 if ( NULL == pHddCtx->hHal )
1628 {
1629 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1630 goto err_vosclose;
1631 }
1632
1633 /* Set the SME configuration parameters. */
1634 vosStatus = hdd_set_sme_config(pHddCtx);
1635 if ( VOS_STATUS_SUCCESS != vosStatus )
1636 {
1637 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1638 goto err_vosclose;
1639 }
1640
1641 /* Initialize the WMM module */
1642 vosStatus = hdd_wmm_init(pHddCtx);
1643 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1644 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001645 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001646 goto err_vosclose;
1647 }
1648
1649 vosStatus = vos_preStart( pHddCtx->pvosContext );
1650 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1651 {
1652 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1653 goto err_vosclose;
1654 }
1655
1656 /* In the integrated architecture we update the configuration from
1657 the INI file and from NV before vOSS has been started so that
1658 the final contents are available to send down to the cCPU */
1659 /* Apply the cfg.ini to cfg.dat */
1660 if (FALSE == hdd_update_config_dat(pHddCtx))
1661 {
1662 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1663 goto err_vosclose;
1664 }
1665
1666 /* Set the MAC Address, currently this is used by HAL to add self sta.
1667 * Remove this once self sta is added as part of session open. */
1668 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1669 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1670 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1671 if (!HAL_STATUS_SUCCESS(halStatus))
1672 {
1673 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1674 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1675 goto err_vosclose;
1676 }
1677
1678 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1679 Note: Firmware image will be read and downloaded inside vos_start API */
1680 vosStatus = vos_start( pVosContext );
1681 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1682 {
1683 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1684 goto err_vosclose;
1685 }
1686
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001687 /* Exchange capability info between Host and FW and also get versioning info from FW */
1688 hdd_exchange_version_and_caps(pHddCtx);
1689
Jeff Johnson295189b2012-06-20 16:38:30 -07001690 vosStatus = hdd_post_voss_start_config( pHddCtx );
1691 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1692 {
1693 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1694 __func__);
1695 goto err_vosstop;
1696 }
1697
1698#ifdef WLAN_BTAMP_FEATURE
1699 vosStatus = WLANBAP_Open(pVosContext);
1700 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1701 {
1702 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1703 "%s: Failed to open BAP",__func__);
1704 goto err_vosstop;
1705 }
1706 vosStatus = BSL_Init(pVosContext);
1707 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1708 {
1709 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1710 "%s: Failed to Init BSL",__func__);
1711 goto err_bap_close;
1712 }
1713 vosStatus = WLANBAP_Start(pVosContext);
1714 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1715 {
1716 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1717 "%s: Failed to start TL",__func__);
1718 goto err_bap_close;
1719 }
1720 pConfig = pHddCtx->cfg_ini;
1721 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1722 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1723#endif //WLAN_BTAMP_FEATURE
1724
1725 /* Restart all adapters */
1726 hdd_start_all_adapters(pHddCtx);
1727 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07001728 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001730 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001731
1732 /* Register with platform driver as client for Suspend/Resume */
1733 vosStatus = hddRegisterPmOps(pHddCtx);
1734 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1735 {
1736 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1737 goto err_bap_stop;
1738 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 /* Allow the phone to go to sleep */
1740 hdd_allow_suspend();
1741 /* register for riva power on lock */
1742 if (req_riva_power_on_lock("wlan"))
1743 {
1744 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1745 __func__);
1746 goto err_unregister_pmops;
1747 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001748 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001749 goto success;
1750
1751err_unregister_pmops:
1752 hddDeregisterPmOps(pHddCtx);
1753
1754err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001755#ifdef CONFIG_HAS_EARLYSUSPEND
1756 hdd_unregister_mcast_bcast_filter(pHddCtx);
1757#endif
1758 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001759#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001760 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001761#endif
1762
1763#ifdef WLAN_BTAMP_FEATURE
1764err_bap_close:
1765 WLANBAP_Close(pVosContext);
1766#endif
1767
1768err_vosstop:
1769 vos_stop(pVosContext);
1770
1771err_vosclose:
1772 vos_close(pVosContext);
1773 vos_sched_close(pVosContext);
1774 if (pHddCtx)
1775 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001776 /* Unregister the Net Device Notifier */
1777 unregister_netdevice_notifier(&hdd_netdev_notifier);
1778 /* Clean up HDD Nlink Service */
1779 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07001780#ifdef WLAN_KD_READY_NOTIFIER
1781 nl_srv_exit(pHddCtx->ptt_pid);
1782#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07001784#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07001785 /* Free up dynamically allocated members inside HDD Adapter */
1786 kfree(pHddCtx->cfg_ini);
1787 pHddCtx->cfg_ini= NULL;
1788
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 wiphy_unregister(pHddCtx->wiphy);
1790 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001791 }
1792 vos_preClose(&pVosContext);
1793
1794#ifdef MEMORY_DEBUG
1795 vos_mem_exit();
1796#endif
1797
1798err_re_init:
1799 /* Allow the phone to go to sleep */
1800 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001801 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07001802 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001803 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001804
1805success:
1806 /* Trigger replay of BTC events */
1807 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1808 return VOS_STATUS_SUCCESS;
1809}