blob: c15199c60a1f6bac05713d1181b1dbe3a39f3583 [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
80#ifdef WLAN_SOFTAP_FEATURE
81#include <linux/semaphore.h>
82#include <wlan_hdd_hostapd.h>
83#endif
84#include "cfgApi.h"
85
86#ifdef WLAN_BTAMP_FEATURE
87#include "bapApi.h"
88#include "bap_hdd_main.h"
89#include "bap_hdd_misc.h"
90#endif
91
Jeff Johnsone7245742012-09-05 17:12:55 -070092#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070093#include <linux/inetdevice.h>
94#include <wlan_hdd_cfg.h>
95/**-----------------------------------------------------------------------------
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
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700109#define HDD_SSR_BRING_UP_TIME 10000
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;
122#ifdef WLAN_SOFTAP_FEATURE
123extern tVOS_CON_MODE hdd_get_conparam ( void );
124#endif
125
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700126static struct timer_list ssr_timer;
127static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129//Callback invoked by PMC to report status of standby request
130void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
131{
132 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
133 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
134 g_standby_status = status;
135
136 if(eHAL_STATUS_SUCCESS == status)
137 {
138 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
139 }
140 else
141 {
142 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
143 }
144
145 complete(&pHddCtx->standby_comp_var);
146}
147
148//Callback invoked by PMC to report status of full power request
149void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
150{
151 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
153 g_full_pwr_status = status;
154
155 if(eHAL_STATUS_SUCCESS == status)
156 {
157 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
158 }
159 else
160 {
161 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
162 }
163
164 complete(&pHddCtx->full_pwr_comp_var);
165}
166
167eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
168{
169 eHalStatus status = VOS_STATUS_SUCCESS;
170
171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
172 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
173
174 g_full_pwr_status = eHAL_STATUS_FAILURE;
175 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
176 eSME_FULL_PWR_NEEDED_BY_HDD);
177
178 if(status == eHAL_STATUS_PMC_PENDING)
179 {
180 //Block on a completion variable. Can't wait forever though
181 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
182 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
183 status = g_full_pwr_status;
184 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
185 {
186 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
187 VOS_ASSERT(0);
188 goto failure;
189 }
190 }
191 else if(status != eHAL_STATUS_SUCCESS)
192 {
193 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
194 __func__, status);
195 VOS_ASSERT(0);
196 goto failure;
197 }
198 else
199 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
200
201failure:
202 //No blocking to reduce latency. No other device should be depending on WLAN
203 //to finish resume and WLAN won't be instantly on after resume
204 return status;
205}
206
207
208//Helper routine to put the chip into standby
209VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
210{
211 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
212 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
213
214 //Disable IMPS/BMPS as we do not want the device to enter any power
215 //save mode on its own during suspend sequence
216 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
217 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
218
219 //Note we do not disable queues unnecessarily. Queues should already be disabled
220 //if STA is disconnected or the queue will be disabled as and when disconnect
221 //happens because of standby procedure.
222
223 //Ensure that device is in full power first. There is scope for optimization
224 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
225 //Core s/w needs to be optimized to handle this. Until then we request full
226 //power before issuing request for standby.
227 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
228 g_full_pwr_status = eHAL_STATUS_FAILURE;
229 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
230 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
231
232 if(halStatus == eHAL_STATUS_PMC_PENDING)
233 {
234 //Block on a completion variable. Can't wait forever though
235 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
236 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
237 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
238 {
239 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
240 VOS_ASSERT(0);
241 vosStatus = VOS_STATUS_E_FAILURE;
242 goto failure;
243 }
244 }
245 else if(halStatus != eHAL_STATUS_SUCCESS)
246 {
247 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
248 __func__, halStatus);
249 VOS_ASSERT(0);
250 vosStatus = VOS_STATUS_E_FAILURE;
251 goto failure;
252 }
253
254 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
255 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
256 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
257 }
258
259 //Request standby. Standby will cause the STA to disassociate first. TX queues
260 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
261 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
262 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
263 //when there are concurrent sessions.
264 INIT_COMPLETION(pHddCtx->standby_comp_var);
265 g_standby_status = eHAL_STATUS_FAILURE;
266 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
267
268 if (halStatus == eHAL_STATUS_PMC_PENDING)
269 {
270 //Wait till WLAN device enters standby mode
271 wait_for_completion_timeout(&pHddCtx->standby_comp_var,
272 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
273 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
274 {
275 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
276 VOS_ASSERT(0);
277 vosStatus = VOS_STATUS_E_FAILURE;
278 goto failure;
279 }
280 }
281 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
283 __func__, halStatus);
284 VOS_ASSERT(0);
285 vosStatus = VOS_STATUS_E_FAILURE;
286 goto failure;
287 }
288 else
289 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
290
291failure:
292 //Restore IMPS config
293 if(pHddCtx->cfg_ini->fIsImpsEnabled)
294 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
295
296 //Restore BMPS config
297 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
298 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
299
300 return vosStatus;
301}
302
303
304//Helper routine for Deep sleep entry
305VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
306{
307 eHalStatus halStatus;
308 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
309 vos_call_status_type callType;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800310
Jeff Johnson295189b2012-06-20 16:38:30 -0700311 //Stop the Interface TX queue.
312 netif_tx_disable(pAdapter->dev);
313 netif_carrier_off(pAdapter->dev);
314
315 //Disable IMPS,BMPS as we do not want the device to enter any power
316 //save mode on it own during suspend sequence
317 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
318 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
319
320 //Ensure that device is in full power as we will touch H/W during vos_Stop
321 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
322 g_full_pwr_status = eHAL_STATUS_FAILURE;
323 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
324 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
325
326 if(halStatus == eHAL_STATUS_PMC_PENDING)
327 {
328 //Block on a completion variable. Can't wait forever though
329 wait_for_completion_interruptible_timeout(&pHddCtx->full_pwr_comp_var,
330 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
331 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
332 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
333 VOS_ASSERT(0);
334 }
335 }
336 else if(halStatus != eHAL_STATUS_SUCCESS)
337 {
338 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
339 VOS_ASSERT(0);
340 }
341
342 //Issue a disconnect. This is required to inform the supplicant that
343 //STA is getting disassociated and for GUI to be updated properly
344 INIT_COMPLETION(pAdapter->disconnect_comp_var);
345 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
346
347 //Success implies disconnect command got queued up successfully
348 if(halStatus == eHAL_STATUS_SUCCESS)
349 {
350 //Block on a completion variable. Can't wait forever though.
351 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
352 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
353 }
354
355
356 //None of the steps should fail after this. Continue even in case of failure
357 vosStatus = vos_stop( pHddCtx->pvosContext );
358 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
359
Jeff Johnson295189b2012-06-20 16:38:30 -0700360 vosStatus = vos_chipAssertDeepSleep( &callType, NULL, NULL );
361 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
362
363 //Vote off any PMIC voltage supplies
364 vosStatus = vos_chipPowerDown(NULL, NULL, NULL);
365
Jeff Johnson295189b2012-06-20 16:38:30 -0700366 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
367
368 //Restore IMPS config
369 if(pHddCtx->cfg_ini->fIsImpsEnabled)
370 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
371
372 //Restore BMPS config
373 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
374 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
375
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 return vosStatus;
377}
378
379VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
380{
381 VOS_STATUS vosStatus;
382 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700383
384 //Power Up Libra WLAN card first if not already powered up
385 vosStatus = vos_chipPowerUp(NULL,NULL,NULL);
386 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
387 {
388 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
389 "exiting", __func__);
390 goto err_deep_sleep;
391 }
392
Jeff Johnson295189b2012-06-20 16:38:30 -0700393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
394 "%s: calling hdd_set_sme_config",__func__);
395 vosStatus = hdd_set_sme_config( pHddCtx );
396 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
397 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
398 {
399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
400 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700401 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700402 }
403
404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
405 "%s: calling vos_start",__func__);
406 vosStatus = vos_start( pHddCtx->pvosContext );
407 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
408 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
409 {
410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
411 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700412 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700413 }
414
415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
416 "%s: calling hdd_post_voss_start_config",__func__);
417 vosStatus = hdd_post_voss_start_config( pHddCtx );
418 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
419 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
420 {
421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
422 "%s: Failed in hdd_post_voss_start_config",__func__);
423 goto err_voss_stop;
424 }
425
426
427 //Open a SME session for future operation
428 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
429 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId );
430 if ( !HAL_STATUS_SUCCESS( halStatus ) )
431 {
432 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08lx]",
433 halStatus, halStatus );
434 goto err_voss_stop;
435
436 }
437
438 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
439
440 //Trigger the initial scan
441 hdd_wlan_initial_scan(pHddCtx);
442
443 return VOS_STATUS_SUCCESS;
444
445err_voss_stop:
446 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700447err_deep_sleep:
448 return VOS_STATUS_E_FAILURE;
449
450}
451
Yathish9f22e662012-12-10 14:21:35 -0800452VOS_STATUS hdd_conf_hostarpoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700453{
454 struct in_ifaddr **ifap = NULL;
455 struct in_ifaddr *ifa = NULL;
456 struct in_device *in_dev;
457 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700458 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800459 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700460
461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700462
Jeff Johnson295189b2012-06-20 16:38:30 -0700463 if(fenable)
464 {
465 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
466 {
467 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
468 ifap = &ifa->ifa_next)
469 {
470 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
471 {
472 break; /* found */
473 }
474 }
475 }
476
477 if(ifa && ifa->ifa_local)
478 {
479 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
480 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
481
482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Enabled \n", __func__);
483
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700484 if(pHddCtx->dynamic_mcbc_filter.enableCfg)
Jeff Johnson295189b2012-06-20 16:38:30 -0700485 {
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700486 if((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
487 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting) ||
488 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
489 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting))
490 {
491 offLoadRequest.enableOrDisable =
492 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
493 }
494 }
495 else if((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
496 pHddCtx->cfg_ini->mcastBcastFilterSetting ) ||
497 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
498 pHddCtx->cfg_ini->mcastBcastFilterSetting))
499 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700500 offLoadRequest.enableOrDisable =
501 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
502 }
503
504 //converting u32 to IPV4 address
505 for(i = 0 ; i < 4; i++)
506 {
507 offLoadRequest.params.hostIpv4Addr[i] =
508 (ifa->ifa_local >> (i*8) ) & 0xFF ;
509 }
510 hddLog(VOS_TRACE_LEVEL_WARN, " Enable SME HostOffload: %d.%d.%d.%d",
511 offLoadRequest.params.hostIpv4Addr[0],
512 offLoadRequest.params.hostIpv4Addr[1],
513 offLoadRequest.params.hostIpv4Addr[2],
514 offLoadRequest.params.hostIpv4Addr[3]);
515
516 if (eHAL_STATUS_SUCCESS !=
Jeff Johnsone7245742012-09-05 17:12:55 -0700517 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
518 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700519 {
520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
521 "feature\n", __func__);
522 return VOS_STATUS_E_FAILURE;
523 }
524 return VOS_STATUS_SUCCESS;
525 }
526 else
527 {
528 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned \n", __func__);
529 return VOS_STATUS_E_AGAIN;
530 }
531 }
532 else
533 {
534 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
535 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
536 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
537
Jeff Johnsone7245742012-09-05 17:12:55 -0700538 if (eHAL_STATUS_SUCCESS != sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
539 &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700540 {
541 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
542 "offload feature\n", __func__);
543 return VOS_STATUS_E_FAILURE;
544 }
545 return VOS_STATUS_SUCCESS;
546 }
547}
548
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530549/*
550 * This function is called before setting mcbc filters
551 * to modify filter value considering ARP
552*/
553void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx, v_BOOL_t arpFlag,
554 tANI_U8 *pMcBcFilter)
555{
556 if (TRUE == arpFlag)
557 {
558 /*ARP offload is enabled, do not block bcast packets at RXP*/
559 if (pHddCtx->dynamic_mcbc_filter.enableCfg)
560 {
561 if ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
562 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting))
563 {
564 *pMcBcFilter = HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST;
565 }
566 else if ((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
567 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting))
568 {
569 *pMcBcFilter = HDD_MCASTBCASTFILTER_FILTER_NONE;
570 }
571 else
572 {
573 *pMcBcFilter = pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting;
574 }
575
576 pHddCtx->dynamic_mcbc_filter.enableSuspend = TRUE;
577 pHddCtx->dynamic_mcbc_filter.mcBcFilterSuspend = *pMcBcFilter;
578 }
579 else
580 {
581 if (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
582 pHddCtx->cfg_ini->mcastBcastFilterSetting)
583 {
584 *pMcBcFilter = HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST;
585 }
586 else if (HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
587 pHddCtx->cfg_ini->mcastBcastFilterSetting)
588 {
589 *pMcBcFilter = HDD_MCASTBCASTFILTER_FILTER_NONE;
590 }
591 else
592 {
593 *pMcBcFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
594 }
595
596 pHddCtx->dynamic_mcbc_filter.enableSuspend = FALSE;
597 }
598 }
599 else
600 {
601 if (pHddCtx->dynamic_mcbc_filter.enableCfg)
602 {
603 *pMcBcFilter = pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting;
604 pHddCtx->dynamic_mcbc_filter.enableSuspend = TRUE;
605 }
606 else
607 {
608 pHddCtx->dynamic_mcbc_filter.enableSuspend = FALSE;
609 *pMcBcFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
610 }
611 }
612}
613
Jeff Johnson295189b2012-06-20 16:38:30 -0700614void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
615{
616 eHalStatus halStatus = eHAL_STATUS_FAILURE;
617#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
618 tpAniSirGlobal pMac = (tpAniSirGlobal) vos_get_context(VOS_MODULE_ID_SME, pHddCtx->pvosContext);
619#else
620 tpSirWlanSetRxpFilters wlanRxpFilterParam =
621 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
622 if(NULL == wlanRxpFilterParam)
623 {
624 hddLog(VOS_TRACE_LEVEL_FATAL,
625 "%s: vos_mem_alloc failed ", __func__);
626 return;
627 }
628#endif
629 hddLog(VOS_TRACE_LEVEL_INFO,
630 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
631#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
632 if ( pMac )
633 {
634 halStatus = halRxp_configureRxpFilterMcstBcst( pMac, setfilter);
635 }
636 else
637 {
638 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pMac is initialised to NULL",__func__ );
639 }
640#else
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530641 if (TRUE == setfilter)
642 {
643 if (pHddCtx->cfg_ini->fhostArpOffload)
644 {
645 hdd_mcbc_filter_modification(pHddCtx, TRUE,
646 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
647 }
648 else
649 {
650 hdd_mcbc_filter_modification(pHddCtx, FALSE,
651 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
652 }
653 }
654 else
655 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
656 pHddCtx->cfg_ini->mcastBcastFilterSetting;
657
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
660#endif
661 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
662 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
663}
664
665#ifdef FEATURE_WLAN_INTEGRATED_SOC
666static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
667 hdd_adapter_t *pAdapter)
668{
669 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudi51d87f72012-09-24 12:05:23 -0700670 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700671 tpSirWlanSuspendParam wlanSuspendParam =
672 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
673
674 if(NULL == wlanSuspendParam)
675 {
676 hddLog(VOS_TRACE_LEVEL_FATAL,
677 "%s: vos_mem_alloc failed ", __func__);
678 return;
679 }
680
681 hddLog(VOS_TRACE_LEVEL_INFO,
682 "%s: send wlan suspend indication", __func__);
683
684 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
685 {
686 if((pHddCtx->cfg_ini->fhostArpOffload) &&
687 (eConnectionState_Associated ==
688 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
689 {
Yathish9f22e662012-12-10 14:21:35 -0800690 vstatus = hdd_conf_hostarpoffload(pAdapter, TRUE);
Jeff Johnson43971f52012-07-17 12:26:56 -0700691 if (!VOS_IS_STATUS_SUCCESS(vstatus))
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 {
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530693 hdd_mcbc_filter_modification(pHddCtx, FALSE,
694 &wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -0700695 hddLog(VOS_TRACE_LEVEL_INFO,
696 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
Jeff Johnson43971f52012-07-17 12:26:56 -0700697 __func__, vstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700698 }
Jeff Johnson43971f52012-07-17 12:26:56 -0700699 else
700 {
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530701 hdd_mcbc_filter_modification(pHddCtx, TRUE,
702 &wlanSuspendParam->configuredMcstBcstFilterSetting);
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700703 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700704 }
705 else
706 {
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530707 hdd_mcbc_filter_modification(pHddCtx, FALSE,
708 &wlanSuspendParam->configuredMcstBcstFilterSetting);
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700709 if(pHddCtx->dynamic_mcbc_filter.enableCfg)
710 {
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700711 pHddCtx->dynamic_mcbc_filter.mcBcFilterSuspend =
Jeff Johnson43971f52012-07-17 12:26:56 -0700712 wlanSuspendParam->configuredMcstBcstFilterSetting;
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700713 }
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700714 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700715
716#ifdef WLAN_FEATURE_PACKET_FILTERING
717 if (pHddCtx->cfg_ini->isMcAddrListFilter)
718 {
719 /*Multicast addr list filter is enabled during suspend*/
720 if (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
721 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530722 && pAdapter->mc_addr_list.mc_cnt
Jeff Johnson295189b2012-06-20 16:38:30 -0700723 && (eConnectionState_Associated ==
724 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
725 {
726 /*set the filter*/
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530727 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700728 }
729 }
730#endif
731 }
732
733 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
734 if(eHAL_STATUS_SUCCESS == halStatus)
735 {
736 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
737 }
738}
739
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530740static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700741{
Jeff Johnson43971f52012-07-17 12:26:56 -0700742 VOS_STATUS vstatus;
Yathish9f22e662012-12-10 14:21:35 -0800743 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700744 tpSirWlanResumeParam wlanResumeParam =
745 vos_mem_malloc(sizeof(tSirWlanResumeParam));
746
747 if(NULL == wlanResumeParam)
748 {
749 hddLog(VOS_TRACE_LEVEL_FATAL,
750 "%s: vos_mem_alloc failed ", __func__);
751 return;
752 }
753
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530754 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700755 "%s: send wlan resume indication", __func__);
756
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530757 if (pHddCtx->hdd_mcastbcast_filter_set == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700758 {
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530759 if (pHddCtx->cfg_ini->fhostArpOffload)
Jeff Johnson295189b2012-06-20 16:38:30 -0700760 {
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530761 vstatus = hdd_conf_hostarpoffload(pAdapter, FALSE);
762 if (!VOS_IS_STATUS_SUCCESS(vstatus))
763 {
764 hddLog(VOS_TRACE_LEVEL_INFO, "%s:Failed to disable ARPOFFLOAD "
765 "Feature %d\n", __func__, vstatus);
766 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 }
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530768 if (pHddCtx->dynamic_mcbc_filter.enableSuspend)
769 {
770 wlanResumeParam->configuredMcstBcstFilterSetting =
771 pHddCtx->dynamic_mcbc_filter.mcBcFilterSuspend;
772 }
773 else
774 {
775 wlanResumeParam->configuredMcstBcstFilterSetting =
776 pHddCtx->cfg_ini->mcastBcastFilterSetting;
777 }
778 sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
779 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700780 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700781
782#ifdef WLAN_FEATURE_PACKET_FILTERING
783 if (pHddCtx->cfg_ini->isMcAddrListFilter)
784 {
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530785 /*Multicast addr filtering is enabled*/
786 if (pAdapter->mc_addr_list.isFilterApplied)
Jeff Johnson295189b2012-06-20 16:38:30 -0700787 {
788 /*Filter applied during suspend mode*/
789 /*Clear it here*/
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530790 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700791 }
792 }
793#endif
794}
795#endif
796
Jeff Johnson295189b2012-06-20 16:38:30 -0700797//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800798void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -0700799{
800 hdd_context_t *pHddCtx = NULL;
801 v_CONTEXT_t pVosContext = NULL;
802
803 hdd_adapter_t *pAdapter = NULL;
804 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
805 VOS_STATUS status;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800806
Jeff Johnson295189b2012-06-20 16:38:30 -0700807 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
808
809 //Get the global VOSS context.
810 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
811 if(!pVosContext) {
812 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
813 return;
814 }
815
816 //Get the HDD context.
817 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
818
819 if(!pHddCtx) {
820 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
821 return;
822 }
823
824 if (pHddCtx->isLogpInProgress) {
825 hddLog(VOS_TRACE_LEVEL_ERROR,
826 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
827 return;
828 }
829
Jeff Johnson295189b2012-06-20 16:38:30 -0700830 /*loop through all adapters. TBD fix for Concurrency */
831 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
832 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
833 {
834 pAdapter = pAdapterNode->pAdapter;
835 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -0700836 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
838
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -0700839 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
841 pAdapterNode = pNext;
842 continue;
843 }
844
845#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
846 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
847 {
848 //stop the interface before putting the chip to standby
849 netif_tx_disable(pAdapter->dev);
850 netif_carrier_off(pAdapter->dev);
851 }
852 else if (pHddCtx->cfg_ini->nEnableSuspend ==
853 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
854 {
855 //Execute deep sleep procedure
856 hdd_enter_deep_sleep(pHddCtx, pAdapter);
857 }
858#endif
859
Jeff Johnsone7245742012-09-05 17:12:55 -0700860 //Apply Dynamic Dtim For P2P
861 //Only if ignoreDynamicDtimInP2pMode is not set in ini
Jeff Johnson295189b2012-06-20 16:38:30 -0700862 if((pHddCtx->cfg_ini->enableDynamicDTIM ||
Jeff Johnsone7245742012-09-05 17:12:55 -0700863 pHddCtx->cfg_ini->enableModulatedDTIM) &&
864 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
865 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
866 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
Jeff Johnson295189b2012-06-20 16:38:30 -0700867 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
868 (eConnectionState_Associated ==
869 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
870 (pHddCtx->cfg_ini->fIsBmpsEnabled))
871 {
872 tSirSetPowerParamsReq powerRequest = { 0 };
873
874 powerRequest.uIgnoreDTIM = 1;
875
876 /*Back up the actual values from CFG */
877 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM,
878 &pHddCtx->hdd_actual_ignore_DTIM_value);
879 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL,
880 &pHddCtx->hdd_actual_LI_value);
881
882 if(pHddCtx->cfg_ini->enableModulatedDTIM)
883 {
884 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
885 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
886 }
887 else
888 {
889 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
890 }
891
892 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
893 *specified during Enter/Exit BMPS when LCD off*/
894 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
895 NULL, eANI_BOOLEAN_FALSE);
896 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
897 NULL, eANI_BOOLEAN_FALSE);
898
899 /* switch to the DTIM specified in cfg.ini */
900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
901 "Switch to DTIM%d \n", powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -0800902 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700903
904 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
905 {
906 /* put the device into full power */
907 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
908
909 /* put the device back into BMPS */
910 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
911
912 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
913 }
914 }
915
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 /*Suspend notification sent down to driver*/
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530917 hdd_conf_suspend_ind(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700918 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
919 pAdapterNode = pNext;
920 }
921 pHddCtx->hdd_wlan_suspended = TRUE;
922
923#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
924 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
925 {
926 hdd_enter_standby(pHddCtx);
927 }
928#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700929
930 return;
931}
932
933static void hdd_PowerStateChangedCB
934(
935 v_PVOID_t callbackContext,
936 tPmcState newState
937)
938{
939 hdd_context_t *pHddCtx = callbackContext;
940
941 /* if the driver was not in BMPS during early suspend,
942 * the dynamic DTIM is now updated at Riva */
943 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
944 && pHddCtx->cfg_ini->enableDynamicDTIM
945 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
946 {
947 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
948 }
949 spin_lock(&pHddCtx->filter_lock);
950 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended
951 && (pHddCtx->hdd_mcastbcast_filter_set != TRUE)) {
952 spin_unlock(&pHddCtx->filter_lock);
953 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
954#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
955 halPSAppsCpuWakeupState(vos_get_context(VOS_MODULE_ID_SME, pHddCtx->pvosContext), FALSE);
956#endif
957 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
959 }
960 else
961 spin_unlock(&pHddCtx->filter_lock);
962}
963
964
965
966void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
967{
968 v_CONTEXT_t pVosContext;
969 tHalHandle smeContext;
970
971 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
972 if (NULL == pVosContext)
973 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700974 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700975 return;
976 }
977 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
978 if (NULL == smeContext)
979 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700980 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 return;
982 }
983
984 spin_lock_init(&pHddCtx->filter_lock);
985 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
986 pHddCtx->cfg_ini->nEnableSuspend)
987 {
988 pmcRegisterDeviceStateUpdateInd(smeContext,
989 hdd_PowerStateChangedCB, pHddCtx);
990 }
991}
992
993void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
994{
995 v_CONTEXT_t pVosContext;
996 tHalHandle smeContext;
997
998 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
999 if (NULL == pVosContext)
1000 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001001 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001002 return;
1003 }
1004 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1005 if (NULL == smeContext)
1006 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001007 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 return;
1009 }
1010
1011 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1012 pHddCtx->cfg_ini->nEnableSuspend)
1013 {
1014 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1015 }
1016}
1017
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001018void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001019{
1020 hdd_context_t *pHddCtx = NULL;
1021 hdd_adapter_t *pAdapter = NULL;
1022 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1023 VOS_STATUS status;
1024 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001025
Jeff Johnson295189b2012-06-20 16:38:30 -07001026 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1027
1028 //Get the global VOSS context.
1029 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1030 if(!pVosContext) {
1031 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1032 return;
1033 }
1034
1035 //Get the HDD context.
1036 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1037
1038 if(!pHddCtx) {
1039 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1040 return;
1041 }
1042
1043 if (pHddCtx->isLogpInProgress) {
1044 hddLog(VOS_TRACE_LEVEL_INFO,
1045 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1046 return;
1047 }
1048
Jeff Johnson295189b2012-06-20 16:38:30 -07001049 pHddCtx->hdd_wlan_suspended = FALSE;
1050 /*loop through all adapters. Concurrency */
1051 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1052
1053 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1054 {
1055 pAdapter = pAdapterNode->pAdapter;
1056 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001057 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001058 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001059 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001060 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1061 pAdapterNode = pNext;
1062 continue;
1063 }
1064#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1065 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1066 {
1067 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1068 hdd_exit_deep_sleep(pAdapter);
1069 }
1070#endif
1071
1072 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1073 {
1074 /*Switch back to DTIM 1*/
1075 tSirSetPowerParamsReq powerRequest = { 0 };
1076
1077 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1078 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
1079
1080 /*Disabled ModulatedDTIM if enabled on suspend*/
1081 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1082 powerRequest.uDTIMPeriod = 0;
1083
1084 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1085 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1086 NULL, eANI_BOOLEAN_FALSE);
1087 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1088 NULL, eANI_BOOLEAN_FALSE);
1089
1090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1091 "Switch to DTIM%d \n",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001092 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001093
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301094 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1095 {
1096 /* put the device into full power */
1097 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001098
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301099 /* put the device back into BMPS */
1100 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001101
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301102 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 }
1105
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301106 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1108 pAdapterNode = pNext;
1109 }
1110
1111#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1112 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1113 {
1114 hdd_exit_standby(pHddCtx);
1115 }
1116#endif
1117
Jeff Johnson295189b2012-06-20 16:38:30 -07001118 return;
1119}
1120
Jeff Johnson295189b2012-06-20 16:38:30 -07001121VOS_STATUS hdd_wlan_reset_initialization(void)
1122{
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 v_CONTEXT_t pVosContext = NULL;
1124
1125 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1126
1127 //Get the global VOSS context.
1128 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1129 if(!pVosContext)
1130 {
1131 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1132 return VOS_STATUS_E_FAILURE;
1133 }
1134
1135 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1136
1137 // Prevent the phone from going to sleep
1138 hdd_prevent_suspend();
1139
Jeff Johnson295189b2012-06-20 16:38:30 -07001140 return VOS_STATUS_SUCCESS;
1141}
1142
1143
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001144/*
1145 * Based on the ioctl command recieved by HDD, put WLAN driver
1146 * into the quiet mode. This is the same as the early suspend
1147 * notification that driver used to listen
1148 */
1149void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001150{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001151 if (suspend)
1152 hdd_suspend_wlan();
1153 else
1154 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001155}
1156
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001157static void hdd_ssr_timer_init(void)
1158{
1159 init_timer(&ssr_timer);
1160}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001161
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001162static void hdd_ssr_timer_del(void)
1163{
1164 del_timer(&ssr_timer);
1165 ssr_timer_started = false;
1166}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001167
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001168static void hdd_ssr_timer_cb(unsigned long data)
1169{
1170 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
1171 VOS_BUG(0);
1172}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001173
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001174static void hdd_ssr_timer_start(int msec)
1175{
1176 if(ssr_timer_started)
1177 {
1178 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1179 ,__func__);
1180 }
1181 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1182 ssr_timer.function = hdd_ssr_timer_cb;
1183 add_timer(&ssr_timer);
1184 ssr_timer_started = true;
1185}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001186
Jeff Johnson295189b2012-06-20 16:38:30 -07001187/* the HDD interface to WLAN driver shutdown,
1188 * the primary shutdown function in SSR
1189 */
1190VOS_STATUS hdd_wlan_shutdown(void)
1191{
1192 VOS_STATUS vosStatus;
1193 v_CONTEXT_t pVosContext = NULL;
1194 hdd_context_t *pHddCtx = NULL;
1195 pVosSchedContext vosSchedContext = NULL;
1196
1197 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1198
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001199 /* if re-init never happens, then do SSR1 */
1200 hdd_ssr_timer_init();
1201 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1202
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 /* Get the global VOSS context. */
1204 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1205 if(!pVosContext) {
1206 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1207 return VOS_STATUS_E_FAILURE;
1208 }
1209 /* Get the HDD context. */
1210 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1211 if(!pHddCtx) {
1212 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1213 return VOS_STATUS_E_FAILURE;
1214 }
1215 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001216 /* DeRegister with platform driver as client for Suspend/Resume */
1217 vosStatus = hddDeregisterPmOps(pHddCtx);
1218 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1219 {
1220 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1221 }
1222
1223 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1224 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1225 {
1226 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1227 }
1228
1229 /* Disable IMPS/BMPS as we do not want the device to enter any power
1230 * save mode on its own during reset sequence
1231 */
1232 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1233 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1234 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1235
1236 vosSchedContext = get_vos_sched_ctxt();
1237
1238 /* Wakeup all driver threads */
1239 if(TRUE == pHddCtx->isMcThreadSuspended){
1240 complete(&vosSchedContext->ResumeMcEvent);
1241 pHddCtx->isMcThreadSuspended= FALSE;
1242 }
1243 if(TRUE == pHddCtx->isTxThreadSuspended){
1244 complete(&vosSchedContext->ResumeTxEvent);
1245 pHddCtx->isTxThreadSuspended= FALSE;
1246 }
1247 if(TRUE == pHddCtx->isRxThreadSuspended){
1248 complete(&vosSchedContext->ResumeRxEvent);
1249 pHddCtx->isRxThreadSuspended= FALSE;
1250 }
1251 /* Reset the Suspend Variable */
1252 pHddCtx->isWlanSuspended = FALSE;
1253
1254 /* Stop all the threads; we do not want any messages to be a processed,
1255 * any more and the best way to ensure that is to terminate the threads
1256 * gracefully.
1257 */
1258 /* Wait for MC to exit */
1259 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1260 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1261 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1262 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1263 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1264
1265 /* Wait for TX to exit */
1266 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1267 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1268 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1269 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1270 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1271
1272 /* Wait for RX to exit */
1273 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1274 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1275 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1276 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1277 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1278
1279#ifdef WLAN_BTAMP_FEATURE
1280 vosStatus = WLANBAP_Stop(pVosContext);
1281 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1282 {
1283 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1284 "%s: Failed to stop BAP",__func__);
1285 }
1286#endif //WLAN_BTAMP_FEATURE
1287 vosStatus = vos_wda_shutdown(pVosContext);
1288 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1289
1290 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1291 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1292 * on threads being running to process the SYS Stop
1293 */
1294 vosStatus = sme_Stop(pHddCtx->hHal, TRUE);
1295 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1296
1297 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1298 /* Stop MAC (PE and HAL) */
1299 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1300 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1301
1302 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1303 /* Stop TL */
1304 vosStatus = WLANTL_Stop(pVosContext);
1305 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1306
Jeff Johnson295189b2012-06-20 16:38:30 -07001307 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001308 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1309 /* Clean up message queues of TX and MC thread */
1310 vos_sched_flush_mc_mqs(vosSchedContext);
1311 vos_sched_flush_tx_mqs(vosSchedContext);
1312 vos_sched_flush_rx_mqs(vosSchedContext);
1313
1314 /* Deinit all the TX and MC queues */
1315 vos_sched_deinit_mqs(vosSchedContext);
1316 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1317
1318 /* shutdown VOSS */
1319 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301320
1321 /*mac context has already been released in mac_close call
1322 so setting it to NULL in hdd context*/
1323 pHddCtx->hHal = (tHalHandle)NULL;
1324
Jeff Johnson295189b2012-06-20 16:38:30 -07001325 if (free_riva_power_on_lock("wlan"))
1326 {
1327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1328 __func__);
1329 }
1330 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1331 ,__func__);
1332 return VOS_STATUS_SUCCESS;
1333}
1334
1335
1336
1337/* the HDD interface to WLAN driver re-init.
1338 * This is called to initialize/start WLAN driver after a shutdown.
1339 */
1340VOS_STATUS hdd_wlan_re_init(void)
1341{
1342 VOS_STATUS vosStatus;
1343 v_CONTEXT_t pVosContext = NULL;
1344 hdd_context_t *pHddCtx = NULL;
1345 eHalStatus halStatus;
1346#ifdef WLAN_BTAMP_FEATURE
1347 hdd_config_t *pConfig = NULL;
1348 WLANBAP_ConfigType btAmpConfig;
1349#endif
1350
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001351 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001353
1354 /* The driver should always be initialized in STA mode after SSR */
1355 hdd_set_conparam(0);
1356
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1358 vosStatus = vos_open(&pVosContext, 0);
1359 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1360 {
1361 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1362 goto err_re_init;
1363 }
1364
1365 /* Get the HDD context. */
1366 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1367 if(!pHddCtx)
1368 {
1369 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1370 goto err_vosclose;
1371 }
1372
1373 /* Save the hal context in Adapter */
1374 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1375 if ( NULL == pHddCtx->hHal )
1376 {
1377 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1378 goto err_vosclose;
1379 }
1380
1381 /* Set the SME configuration parameters. */
1382 vosStatus = hdd_set_sme_config(pHddCtx);
1383 if ( VOS_STATUS_SUCCESS != vosStatus )
1384 {
1385 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1386 goto err_vosclose;
1387 }
1388
1389 /* Initialize the WMM module */
1390 vosStatus = hdd_wmm_init(pHddCtx);
1391 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1392 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001393 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 goto err_vosclose;
1395 }
1396
1397 vosStatus = vos_preStart( pHddCtx->pvosContext );
1398 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1399 {
1400 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1401 goto err_vosclose;
1402 }
1403
1404 /* In the integrated architecture we update the configuration from
1405 the INI file and from NV before vOSS has been started so that
1406 the final contents are available to send down to the cCPU */
1407 /* Apply the cfg.ini to cfg.dat */
1408 if (FALSE == hdd_update_config_dat(pHddCtx))
1409 {
1410 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1411 goto err_vosclose;
1412 }
1413
1414 /* Set the MAC Address, currently this is used by HAL to add self sta.
1415 * Remove this once self sta is added as part of session open. */
1416 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1417 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1418 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1419 if (!HAL_STATUS_SUCCESS(halStatus))
1420 {
1421 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1422 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1423 goto err_vosclose;
1424 }
1425
1426 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1427 Note: Firmware image will be read and downloaded inside vos_start API */
1428 vosStatus = vos_start( pVosContext );
1429 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1430 {
1431 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1432 goto err_vosclose;
1433 }
1434
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001435 /* Exchange capability info between Host and FW and also get versioning info from FW */
1436 hdd_exchange_version_and_caps(pHddCtx);
1437
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 vosStatus = hdd_post_voss_start_config( pHddCtx );
1439 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1440 {
1441 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1442 __func__);
1443 goto err_vosstop;
1444 }
1445
1446#ifdef WLAN_BTAMP_FEATURE
1447 vosStatus = WLANBAP_Open(pVosContext);
1448 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1449 {
1450 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1451 "%s: Failed to open BAP",__func__);
1452 goto err_vosstop;
1453 }
1454 vosStatus = BSL_Init(pVosContext);
1455 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1456 {
1457 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1458 "%s: Failed to Init BSL",__func__);
1459 goto err_bap_close;
1460 }
1461 vosStatus = WLANBAP_Start(pVosContext);
1462 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1463 {
1464 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1465 "%s: Failed to start TL",__func__);
1466 goto err_bap_close;
1467 }
1468 pConfig = pHddCtx->cfg_ini;
1469 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1470 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1471#endif //WLAN_BTAMP_FEATURE
1472
1473 /* Restart all adapters */
1474 hdd_start_all_adapters(pHddCtx);
1475 pHddCtx->isLogpInProgress = FALSE;
1476 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001477 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001478
1479 /* Register with platform driver as client for Suspend/Resume */
1480 vosStatus = hddRegisterPmOps(pHddCtx);
1481 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1482 {
1483 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1484 goto err_bap_stop;
1485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001486 /* Allow the phone to go to sleep */
1487 hdd_allow_suspend();
1488 /* register for riva power on lock */
1489 if (req_riva_power_on_lock("wlan"))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1492 __func__);
1493 goto err_unregister_pmops;
1494 }
1495 goto success;
1496
1497err_unregister_pmops:
1498 hddDeregisterPmOps(pHddCtx);
1499
1500err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001501#ifdef CONFIG_HAS_EARLYSUSPEND
1502 hdd_unregister_mcast_bcast_filter(pHddCtx);
1503#endif
1504 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001505#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001506 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001507#endif
1508
1509#ifdef WLAN_BTAMP_FEATURE
1510err_bap_close:
1511 WLANBAP_Close(pVosContext);
1512#endif
1513
1514err_vosstop:
1515 vos_stop(pVosContext);
1516
1517err_vosclose:
1518 vos_close(pVosContext);
1519 vos_sched_close(pVosContext);
1520 if (pHddCtx)
1521 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001522 /* Unregister the Net Device Notifier */
1523 unregister_netdevice_notifier(&hdd_netdev_notifier);
1524 /* Clean up HDD Nlink Service */
1525 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1526 nl_srv_exit();
Jeff Johnson295189b2012-06-20 16:38:30 -07001527 /* Free up dynamically allocated members inside HDD Adapter */
1528 kfree(pHddCtx->cfg_ini);
1529 pHddCtx->cfg_ini= NULL;
1530
1531#ifdef CONFIG_CFG80211
1532 wiphy_unregister(pHddCtx->wiphy);
1533 wiphy_free(pHddCtx->wiphy);
1534#else
1535 vos_mem_free(pHddCtx);
1536#endif
1537 }
1538 vos_preClose(&pVosContext);
1539
1540#ifdef MEMORY_DEBUG
1541 vos_mem_exit();
1542#endif
1543
1544err_re_init:
1545 /* Allow the phone to go to sleep */
1546 hdd_allow_suspend();
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001547 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001548
1549success:
1550 /* Trigger replay of BTC events */
1551 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1552 return VOS_STATUS_SUCCESS;
1553}