blob: 3d707bc7239e0f890bfc5a919d4ae320abdd5801 [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 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700431 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700432 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
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530564void hdd_ipv6_notifier_work_queue(struct work_struct *work)
565{
566 hdd_adapter_t* pAdapter =
567 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
568 hdd_context_t *pHddCtx;
569 int status;
570
571 hddLog(LOG1, FL("Reconfiguring NS Offload"));
572 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
573 status = wlan_hdd_validate_context(pHddCtx);
574 if (0 != status)
575 {
576 hddLog(LOGE, FL("HDD context is invalid"));
577 return;
578 }
579
580 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
581 {
582 // This invocation being part of the IPv6 registration callback,
583 // we are passing second parameter as 2 to avoid registration
584 // of IPv6 notifier again.
585 hdd_conf_ns_offload(pAdapter, 2);
586 }
587}
588
589static int wlan_hdd_ipv6_changed(struct notifier_block *nb,
590 unsigned long data, void *arg)
591{
592 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
593 struct net_device *ndev = ifa->idev->dev;
594 hdd_adapter_t *pAdapter =
595 container_of(nb, struct hdd_adapter_s, ipv6_notifier);
596
597 if (pAdapter && pAdapter->dev == ndev)
598 {
599 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
600 }
601
602 return NOTIFY_DONE;
603}
604
605/**----------------------------------------------------------------------------
606
607 \brief hdd_conf_ns_offload() - Configure NS offload
608
609 Called during SUSPEND to configure the NS offload (MC BC filter) which
610 reduces power consumption.
611
612 \param - pAdapter - Adapter context for which NS offload is to be configured
613 \param - fenable - 0 - disable.
614 1 - enable. (with IPv6 notifier registration)
615 2 - enable. (without IPv6 notifier registration)
616
617 \return - void
618
619 ---------------------------------------------------------------------------*/
620void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530621{
622 struct inet6_dev *in6_dev;
623 struct inet6_ifaddr *ifp;
624 struct list_head *p;
625 tANI_U8 selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN] = {{0,}};
626 tANI_BOOLEAN selfIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0};
627 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530628 hdd_context_t *pHddCtx;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530629
630 int i =0;
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530631 int ret =0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530632 eHalStatus returnStatus;
633
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530634 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
635
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530636 ENTER();
637 if (fenable)
638 {
639 in6_dev = __in6_dev_get(pAdapter->dev);
640 if (NULL != in6_dev)
641 {
642 //read_lock_bh(&in6_dev->lock);
643 list_for_each(p, &in6_dev->addr_list)
644 {
645 ifp = list_entry(p, struct inet6_ifaddr, if_list);
646 switch(ipv6_addr_src_scope(&ifp->addr))
647 {
648 case IPV6_ADDR_SCOPE_LINKLOCAL:
649 vos_mem_copy(&selfIPv6Addr[0], &ifp->addr.s6_addr,
650 sizeof(ifp->addr.s6_addr));
651 selfIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530652 hddLog (VOS_TRACE_LEVEL_INFO,
653 "Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6",
654 selfIPv6Addr[0]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530655 break;
656 case IPV6_ADDR_SCOPE_GLOBAL:
657 vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr,
658 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530659 selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID;
660 hddLog (VOS_TRACE_LEVEL_INFO,
661 "Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6",
662 selfIPv6Addr[1]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530663 break;
664 default:
665 hddLog(LOGE, "The Scope %d is not supported",
666 ipv6_addr_src_scope(&ifp->addr));
667 }
668
669 }
670 //read_unlock_bh(&in6_dev->lock);
671 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
672 for (i =0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
673 {
674 if (selfIPv6AddrValid[i])
675 {
676 //Filling up the request structure
677 /* Filling the selfIPv6Addr with solicited address
678 * A Solicited-Node multicast address is created by
679 * taking the last 24 bits of a unicast or anycast
680 * address and appending them to the prefix
681 *
682 * FF02:0000:0000:0000:0000:0001:FFXX:XX
683 *
684 * here XX is the unicast/anycast bits
685 */
686 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
687 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
688 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
689 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
690 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = selfIPv6Addr[i][13];
691 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = selfIPv6Addr[i][14];
692 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = selfIPv6Addr[i][15];
693 offLoadRequest.nsOffloadInfo.slotIdx = i;
694
695 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
696 &selfIPv6Addr[i][0], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
697 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
698 &pAdapter->macAddressCurrent.bytes,
699 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
700
701 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID;
702 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
703 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
704
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530705 hddLog (VOS_TRACE_LEVEL_INFO,
706 "configuredMcastBcastFilter: %d",pHddCtx->configuredMcastBcastFilter);
707
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530708 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
709 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
710 pHddCtx->sus_res_mcastbcast_filter) ||
711 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
712 pHddCtx->sus_res_mcastbcast_filter)))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530713 {
714 hddLog (VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700715 "Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE \n");
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530716 offLoadRequest.enableOrDisable =
717 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
718 }
719
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530720 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
721 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
722 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
723
724 hddLog (VOS_TRACE_LEVEL_INFO,
725 "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6",
726 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
727 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
728
729 //Configure the Firmware with this
730 returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
731 pAdapter->sessionId, &offLoadRequest);
732 if(eHAL_STATUS_SUCCESS != returnStatus)
733 {
734 hddLog(VOS_TRACE_LEVEL_ERROR,
735 FL("Failed to enable HostOffload feature with status: %d"),
736 returnStatus);
737 }
738 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
739 }
740 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530741 if (fenable == 1)
742 {
743 // Register IPv6 notifier to notify if any change in IP
744 // So that we can reconfigure the offload parameters
745 pAdapter->ipv6_notifier.notifier_call =
746 wlan_hdd_ipv6_changed;
747 ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier);
748 if (ret)
749 {
750 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
751 }
752 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530753 }
754 else
755 {
756 hddLog(VOS_TRACE_LEVEL_ERROR,
757 FL("IPv6 dev does not exist. Failed to request NSOffload"));
758 return;
759 }
760 }
761 else
762 {
763 //Disable NSOffload
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530764 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530765 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
766 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
767 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
768
769 if (eHAL_STATUS_SUCCESS !=
770 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
771 pAdapter->sessionId, &offLoadRequest))
772 {
773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
774 "NSOffload feature"));
775 }
776 }
777 return;
778}
779#endif
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530780VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700781{
782 struct in_ifaddr **ifap = NULL;
783 struct in_ifaddr *ifa = NULL;
784 struct in_device *in_dev;
785 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700786 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800787 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700788
789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700790
Jeff Johnson295189b2012-06-20 16:38:30 -0700791 if(fenable)
792 {
793 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
794 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530795 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700796 ifap = &ifa->ifa_next)
797 {
798 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
799 {
800 break; /* found */
801 }
802 }
803 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700804 if(ifa && ifa->ifa_local)
805 {
806 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
807 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
808
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled \n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700810
Amar Singhald53568e2013-09-26 11:03:45 -0700811 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
812 pHddCtx->sus_res_mcastbcast_filter) ||
813 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
814 pHddCtx->sus_res_mcastbcast_filter)) &&
815 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700816 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530817 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -0700818 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
819 hddLog(VOS_TRACE_LEVEL_INFO,
820 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -0700821 }
Amar Singhald53568e2013-09-26 11:03:45 -0700822
823 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
824 offLoadRequest.enableOrDisable);
825
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 //converting u32 to IPV4 address
827 for(i = 0 ; i < 4; i++)
828 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530829 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700830 (ifa->ifa_local >> (i*8) ) & 0xFF ;
831 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530832 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700833 offLoadRequest.params.hostIpv4Addr[0],
834 offLoadRequest.params.hostIpv4Addr[1],
835 offLoadRequest.params.hostIpv4Addr[2],
836 offLoadRequest.params.hostIpv4Addr[3]);
837
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530838 if (eHAL_STATUS_SUCCESS !=
839 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
840 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
843 "feature\n", __func__);
844 return VOS_STATUS_E_FAILURE;
845 }
846 return VOS_STATUS_SUCCESS;
847 }
848 else
849 {
850 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned \n", __func__);
851 return VOS_STATUS_E_AGAIN;
852 }
853 }
854 else
855 {
856 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
857 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
858 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
859
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530860 if (eHAL_STATUS_SUCCESS !=
861 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
862 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700863 {
864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
865 "offload feature\n", __func__);
866 return VOS_STATUS_E_FAILURE;
867 }
868 return VOS_STATUS_SUCCESS;
869 }
870}
871
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530872/*
873 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530874 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530875*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530876void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530877 tANI_U8 *pMcBcFilter)
878{
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530879 if (NULL == pHddCtx)
880 {
881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
882 return;
883 }
884
885 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
886 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530887 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530888 /* ARP offload is enabled, do not block bcast packets at RXP
889 * Will be using Bitmasking to reset the filter. As we have
890 * disable Broadcast filtering, Anding with the negation
891 * of Broadcast BIT
892 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530893 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530894 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530895
896#ifdef WLAN_NS_OFFLOAD
897 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530898 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530899 /* NS offload is enabled, do not block mcast packets at RXP
900 * Will be using Bitmasking to reset the filter. As we have
901 * disable Multicast filtering, Anding with the negation
902 * of Multicast BIT
903 */
904 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530905 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530906#endif
907
908 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530909}
910
Jeff Johnson295189b2012-06-20 16:38:30 -0700911void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
912{
913 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700914 tpSirWlanSetRxpFilters wlanRxpFilterParam =
915 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
916 if(NULL == wlanRxpFilterParam)
917 {
918 hddLog(VOS_TRACE_LEVEL_FATAL,
919 "%s: vos_mem_alloc failed ", __func__);
920 return;
921 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 hddLog(VOS_TRACE_LEVEL_INFO,
923 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530924 if (TRUE == setfilter)
925 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530926 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530927 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530928 }
929 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530930 {
931 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530932 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530933 pHddCtx->configuredMcastBcastFilter;
934 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530935
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -0700938 if (eHAL_STATUS_SUCCESS != halStatus)
939 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
941 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
942}
943
Jeff Johnson295189b2012-06-20 16:38:30 -0700944static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
945 hdd_adapter_t *pAdapter)
946{
947 eHalStatus halStatus = eHAL_STATUS_FAILURE;
948 tpSirWlanSuspendParam wlanSuspendParam =
949 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
950
Amar Singhald53568e2013-09-26 11:03:45 -0700951 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
952 pHddCtx->sus_res_mcastbcast_filter =
953 pHddCtx->configuredMcastBcastFilter;
954 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
955 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
956 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
957 pHddCtx->configuredMcastBcastFilter);
958
959 }
960
Amar Singhal49fdfd52013-08-13 13:25:12 -0700961
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 if(NULL == wlanSuspendParam)
963 {
964 hddLog(VOS_TRACE_LEVEL_FATAL,
965 "%s: vos_mem_alloc failed ", __func__);
966 return;
967 }
968
Amar Singhald53568e2013-09-26 11:03:45 -0700969 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 "%s: send wlan suspend indication", __func__);
971
972 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
973 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530974 //Configure supported OffLoads
975 hdd_conf_hostoffload(pAdapter, TRUE);
976 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -0700977
978#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +0530979 /* During suspend, configure MC Addr list filter to the firmware
980 * function takes care of checking necessary conditions before
981 * configuring.
982 */
983 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700984#endif
985 }
986
987 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
988 if(eHAL_STATUS_SUCCESS == halStatus)
989 {
990 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -0700991 } else {
992 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 }
994}
995
Gopichand Nakkala0f276812013-02-24 14:45:51 +0530996static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700997{
Chilam Ngc4244af2013-04-01 15:37:32 -0700998 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -0800999 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001000 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001001
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301002 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 "%s: send wlan resume indication", __func__);
1004
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301005 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1006
1007 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301009 hddLog(VOS_TRACE_LEVEL_FATAL,
1010 "%s: memory allocation failed for wlanResumeParam ", __func__);
1011 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001013
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301014 //Disable supported OffLoads
1015 hdd_conf_hostoffload(pAdapter, FALSE);
1016
1017 wlanResumeParam->configuredMcstBcstFilterSetting =
1018 pHddCtx->configuredMcastBcastFilter;
1019 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1020 if (eHAL_STATUS_SUCCESS != halStatus)
1021 {
1022 vos_mem_free(wlanResumeParam);
1023 }
1024
1025 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1026
Amar Singhal49fdfd52013-08-13 13:25:12 -07001027 pHddCtx->configuredMcastBcastFilter =
1028 pHddCtx->sus_res_mcastbcast_filter;
Amar Singhald53568e2013-09-26 11:03:45 -07001029 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1030
1031 hddLog(VOS_TRACE_LEVEL_INFO,
1032 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1033 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1034 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001035
Chilam Ngc4244af2013-04-01 15:37:32 -07001036
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301037#ifdef WLAN_FEATURE_PACKET_FILTERING
1038 /* Filer was applied during suspend inditication
1039 * clear it when we resume.
1040 */
1041 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001042#endif
1043}
Jeff Johnson295189b2012-06-20 16:38:30 -07001044
Jeff Johnson295189b2012-06-20 16:38:30 -07001045//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001046void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001047{
1048 hdd_context_t *pHddCtx = NULL;
1049 v_CONTEXT_t pVosContext = NULL;
1050
Jeff Johnson295189b2012-06-20 16:38:30 -07001051 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301052 hdd_adapter_t *pAdapter = NULL;
1053 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301054 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001055
Jeff Johnson295189b2012-06-20 16:38:30 -07001056 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1057
1058 //Get the global VOSS context.
1059 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1060 if(!pVosContext) {
1061 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1062 return;
1063 }
1064
1065 //Get the HDD context.
1066 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1067
1068 if(!pHddCtx) {
1069 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1070 return;
1071 }
1072
1073 if (pHddCtx->isLogpInProgress) {
1074 hddLog(VOS_TRACE_LEVEL_ERROR,
1075 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1076 return;
1077 }
1078
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301079 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001080 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1081 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1082 {
1083 pAdapter = pAdapterNode->pAdapter;
1084 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001085 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1087
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001088 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001089 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1090 pAdapterNode = pNext;
1091 continue;
1092 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301093 /* Avoid multiple enter/exit BMPS in this while loop using
1094 * hdd_enter_bmps flag
1095 */
1096 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1097 {
1098 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001099
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301100 /* If device was already in BMPS, and dynamic DTIM is set,
1101 * exit(set the device to full power) and enter BMPS again
1102 * to reflect new DTIM value */
1103 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1104
1105 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1106
1107 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1108 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001109#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1110 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1111 {
1112 //stop the interface before putting the chip to standby
1113 netif_tx_disable(pAdapter->dev);
1114 netif_carrier_off(pAdapter->dev);
1115 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301116 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1118 {
1119 //Execute deep sleep procedure
1120 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1121 }
1122#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301123
1124 /*Suspend notification sent down to driver*/
1125 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1126
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301127 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1128 pAdapterNode = pNext;
1129 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301130 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301131
Jeff Johnson295189b2012-06-20 16:38:30 -07001132#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1133 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1134 {
1135 hdd_enter_standby(pHddCtx);
1136 }
1137#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001138
1139 return;
1140}
1141
1142static void hdd_PowerStateChangedCB
1143(
1144 v_PVOID_t callbackContext,
1145 tPmcState newState
1146)
1147{
1148 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 /* if the driver was not in BMPS during early suspend,
1150 * the dynamic DTIM is now updated at Riva */
1151 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1152 && pHddCtx->cfg_ini->enableDynamicDTIM
1153 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1154 {
1155 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1156 }
1157 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301158 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001159 spin_unlock(&pHddCtx->filter_lock);
Amar Singhald53568e2013-09-26 11:03:45 -07001160 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1161 pHddCtx->sus_res_mcastbcast_filter =
1162 pHddCtx->configuredMcastBcastFilter;
1163 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1164
1165 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1166 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1167 pHddCtx->configuredMcastBcastFilter);
1168 hddLog(VOS_TRACE_LEVEL_INFO,
1169 "offload: calling hdd_conf_mcastbcast_filter");
1170
1171 }
1172
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1176 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001177 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 spin_unlock(&pHddCtx->filter_lock);
1179}
1180
1181
1182
1183void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1184{
1185 v_CONTEXT_t pVosContext;
1186 tHalHandle smeContext;
1187
1188 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1189 if (NULL == pVosContext)
1190 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001191 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 return;
1193 }
1194 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1195 if (NULL == smeContext)
1196 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001197 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 return;
1199 }
1200
1201 spin_lock_init(&pHddCtx->filter_lock);
1202 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1203 pHddCtx->cfg_ini->nEnableSuspend)
1204 {
1205 pmcRegisterDeviceStateUpdateInd(smeContext,
1206 hdd_PowerStateChangedCB, pHddCtx);
1207 }
1208}
1209
1210void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1211{
1212 v_CONTEXT_t pVosContext;
1213 tHalHandle smeContext;
1214
1215 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1216 if (NULL == pVosContext)
1217 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001218 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 return;
1220 }
1221 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1222 if (NULL == smeContext)
1223 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001224 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 return;
1226 }
1227
1228 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1229 pHddCtx->cfg_ini->nEnableSuspend)
1230 {
1231 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1232 }
1233}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301234
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301235#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301236void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301237{
1238 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301239 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301240 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1241
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301242 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301243 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301244 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1245 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1246 {
1247 vos_mem_copy(&hddGtkOffloadReqParams,
1248 &pHddStaCtx->gtkOffloadReqParams,
1249 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301250
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301251 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1252 &hddGtkOffloadReqParams, pAdapter->sessionId);
1253 if (eHAL_STATUS_SUCCESS != ret)
1254 {
1255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1256 "%s: sme_SetGTKOffload failed, returned %d",
1257 __func__, ret);
1258 return;
1259 }
1260
1261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1262 "%s: sme_SetGTKOffload successfull", __func__);
1263 }
1264
1265 }
1266 else
1267 {
1268 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1269 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1270 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1271 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1272 {
1273
1274 /* Host driver has previously offloaded GTK rekey */
1275 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301276 wlan_hdd_cfg80211_update_replayCounterCallback,
1277 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301278 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301279
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301280 {
1281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1282 "%s: sme_GetGTKOffload failed, returned %d",
1283 __func__, ret);
1284 return;
1285 }
1286 else
1287 {
1288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1289 "%s: sme_GetGTKOffload successful",
1290 __func__);
1291
1292 /* Sending GTK offload dissable */
1293 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1294 sizeof (tSirGtkOffloadParams));
1295 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1296 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301297 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301298 if (eHAL_STATUS_SUCCESS != ret)
1299 {
1300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1301 "%s: failed to dissable GTK offload, returned %d",
1302 __func__, ret);
1303 return;
1304 }
1305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1306 "%s: successfully dissabled GTK offload request to HAL",
1307 __func__);
1308 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301309 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301310 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301311 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301312}
1313#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001314
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001315void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001316{
1317 hdd_context_t *pHddCtx = NULL;
1318 hdd_adapter_t *pAdapter = NULL;
1319 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1320 VOS_STATUS status;
1321 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001322
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1324
1325 //Get the global VOSS context.
1326 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1327 if(!pVosContext) {
1328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1329 return;
1330 }
1331
1332 //Get the HDD context.
1333 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1334
1335 if(!pHddCtx) {
1336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1337 return;
1338 }
1339
1340 if (pHddCtx->isLogpInProgress) {
1341 hddLog(VOS_TRACE_LEVEL_INFO,
1342 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1343 return;
1344 }
1345
Jeff Johnson295189b2012-06-20 16:38:30 -07001346 pHddCtx->hdd_wlan_suspended = FALSE;
1347 /*loop through all adapters. Concurrency */
1348 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1349
1350 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1351 {
1352 pAdapter = pAdapterNode->pAdapter;
1353 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001354 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001355 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001356 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1358 pAdapterNode = pNext;
1359 continue;
1360 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301361
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301362
Jeff Johnson295189b2012-06-20 16:38:30 -07001363#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1364 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1365 {
1366 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1367 hdd_exit_deep_sleep(pAdapter);
1368 }
1369#endif
1370
1371 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1372 {
1373 /*Switch back to DTIM 1*/
1374 tSirSetPowerParamsReq powerRequest = { 0 };
1375
1376 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1377 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001378 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001379
1380 /*Disabled ModulatedDTIM if enabled on suspend*/
1381 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1382 powerRequest.uDTIMPeriod = 0;
1383
1384 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1385 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1386 NULL, eANI_BOOLEAN_FALSE);
1387 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1388 NULL, eANI_BOOLEAN_FALSE);
1389
1390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1391 "Switch to DTIM%d \n",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001392 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001393
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301394 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1395 {
1396 /* put the device into full power */
1397 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001398
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301399 /* put the device back into BMPS */
1400 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001401
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301402 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001404 }
1405
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301406 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1408 pAdapterNode = pNext;
1409 }
1410
1411#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1412 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1413 {
1414 hdd_exit_standby(pHddCtx);
1415 }
1416#endif
1417
Jeff Johnson295189b2012-06-20 16:38:30 -07001418 return;
1419}
1420
Jeff Johnson295189b2012-06-20 16:38:30 -07001421VOS_STATUS hdd_wlan_reset_initialization(void)
1422{
Jeff Johnson295189b2012-06-20 16:38:30 -07001423 v_CONTEXT_t pVosContext = NULL;
1424
1425 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1426
1427 //Get the global VOSS context.
1428 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1429 if(!pVosContext)
1430 {
1431 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1432 return VOS_STATUS_E_FAILURE;
1433 }
1434
1435 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1436
1437 // Prevent the phone from going to sleep
1438 hdd_prevent_suspend();
1439
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 return VOS_STATUS_SUCCESS;
1441}
1442
1443
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001444/*
1445 * Based on the ioctl command recieved by HDD, put WLAN driver
1446 * into the quiet mode. This is the same as the early suspend
1447 * notification that driver used to listen
1448 */
1449void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001450{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001451 if (suspend)
1452 hdd_suspend_wlan();
1453 else
1454 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001455}
1456
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001457static void hdd_ssr_timer_init(void)
1458{
1459 init_timer(&ssr_timer);
1460}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001461
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001462static void hdd_ssr_timer_del(void)
1463{
1464 del_timer(&ssr_timer);
1465 ssr_timer_started = false;
1466}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001467
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001468static void hdd_ssr_timer_cb(unsigned long data)
1469{
1470 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001471
1472#ifdef WCN_PRONTO
1473 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1474 wcnss_pronto_log_debug_regs();
1475#endif
1476
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001477 VOS_BUG(0);
1478}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001479
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001480static void hdd_ssr_timer_start(int msec)
1481{
1482 if(ssr_timer_started)
1483 {
1484 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1485 ,__func__);
1486 }
1487 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1488 ssr_timer.function = hdd_ssr_timer_cb;
1489 add_timer(&ssr_timer);
1490 ssr_timer_started = true;
1491}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001492
Jeff Johnson295189b2012-06-20 16:38:30 -07001493/* the HDD interface to WLAN driver shutdown,
1494 * the primary shutdown function in SSR
1495 */
1496VOS_STATUS hdd_wlan_shutdown(void)
1497{
1498 VOS_STATUS vosStatus;
1499 v_CONTEXT_t pVosContext = NULL;
1500 hdd_context_t *pHddCtx = NULL;
1501 pVosSchedContext vosSchedContext = NULL;
1502
1503 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1504
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001505 /* if re-init never happens, then do SSR1 */
1506 hdd_ssr_timer_init();
1507 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1508
Jeff Johnson295189b2012-06-20 16:38:30 -07001509 /* Get the global VOSS context. */
1510 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1511 if(!pVosContext) {
1512 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1513 return VOS_STATUS_E_FAILURE;
1514 }
1515 /* Get the HDD context. */
1516 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1517 if(!pHddCtx) {
1518 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1519 return VOS_STATUS_E_FAILURE;
1520 }
1521 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001522 /* DeRegister with platform driver as client for Suspend/Resume */
1523 vosStatus = hddDeregisterPmOps(pHddCtx);
1524 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1525 {
1526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1527 }
1528
1529 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1530 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1531 {
1532 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1533 }
1534
1535 /* Disable IMPS/BMPS as we do not want the device to enter any power
1536 * save mode on its own during reset sequence
1537 */
1538 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1539 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1540 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1541
1542 vosSchedContext = get_vos_sched_ctxt();
1543
1544 /* Wakeup all driver threads */
1545 if(TRUE == pHddCtx->isMcThreadSuspended){
1546 complete(&vosSchedContext->ResumeMcEvent);
1547 pHddCtx->isMcThreadSuspended= FALSE;
1548 }
1549 if(TRUE == pHddCtx->isTxThreadSuspended){
1550 complete(&vosSchedContext->ResumeTxEvent);
1551 pHddCtx->isTxThreadSuspended= FALSE;
1552 }
1553 if(TRUE == pHddCtx->isRxThreadSuspended){
1554 complete(&vosSchedContext->ResumeRxEvent);
1555 pHddCtx->isRxThreadSuspended= FALSE;
1556 }
1557 /* Reset the Suspend Variable */
1558 pHddCtx->isWlanSuspended = FALSE;
1559
1560 /* Stop all the threads; we do not want any messages to be a processed,
1561 * any more and the best way to ensure that is to terminate the threads
1562 * gracefully.
1563 */
1564 /* Wait for MC to exit */
1565 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1566 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1567 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1568 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1569 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1570
1571 /* Wait for TX to exit */
1572 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1573 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1574 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1575 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1576 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1577
1578 /* Wait for RX to exit */
1579 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1580 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1581 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1582 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1583 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1584
1585#ifdef WLAN_BTAMP_FEATURE
1586 vosStatus = WLANBAP_Stop(pVosContext);
1587 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1588 {
1589 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1590 "%s: Failed to stop BAP",__func__);
1591 }
1592#endif //WLAN_BTAMP_FEATURE
1593 vosStatus = vos_wda_shutdown(pVosContext);
1594 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1595
1596 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1597 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1598 * on threads being running to process the SYS Stop
1599 */
Kiet Lama72a2322013-11-15 11:18:11 +05301600 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
Jeff Johnson295189b2012-06-20 16:38:30 -07001601 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1602
1603 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1604 /* Stop MAC (PE and HAL) */
1605 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1606 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1607
1608 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1609 /* Stop TL */
1610 vosStatus = WLANTL_Stop(pVosContext);
1611 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1612
Jeff Johnson295189b2012-06-20 16:38:30 -07001613 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001614 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1615 /* Clean up message queues of TX and MC thread */
1616 vos_sched_flush_mc_mqs(vosSchedContext);
1617 vos_sched_flush_tx_mqs(vosSchedContext);
1618 vos_sched_flush_rx_mqs(vosSchedContext);
1619
1620 /* Deinit all the TX and MC queues */
1621 vos_sched_deinit_mqs(vosSchedContext);
1622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1623
1624 /* shutdown VOSS */
1625 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301626
1627 /*mac context has already been released in mac_close call
1628 so setting it to NULL in hdd context*/
1629 pHddCtx->hHal = (tHalHandle)NULL;
1630
Jeff Johnson295189b2012-06-20 16:38:30 -07001631 if (free_riva_power_on_lock("wlan"))
1632 {
1633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1634 __func__);
1635 }
1636 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1637 ,__func__);
1638 return VOS_STATUS_SUCCESS;
1639}
1640
1641
1642
1643/* the HDD interface to WLAN driver re-init.
1644 * This is called to initialize/start WLAN driver after a shutdown.
1645 */
1646VOS_STATUS hdd_wlan_re_init(void)
1647{
1648 VOS_STATUS vosStatus;
1649 v_CONTEXT_t pVosContext = NULL;
1650 hdd_context_t *pHddCtx = NULL;
1651 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001652#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1653 int max_retries = 0;
1654#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001655#ifdef WLAN_BTAMP_FEATURE
1656 hdd_config_t *pConfig = NULL;
1657 WLANBAP_ConfigType btAmpConfig;
1658#endif
1659
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001660 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001661 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001662
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001663#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1664 /* wait until WCNSS driver downloads NV */
1665 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1666 msleep(1000);
1667 }
1668 if (max_retries >= 5) {
1669 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1670 goto err_re_init;
1671 }
1672#endif
1673
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001674 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
1675
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001676 /* The driver should always be initialized in STA mode after SSR */
1677 hdd_set_conparam(0);
1678
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1680 vosStatus = vos_open(&pVosContext, 0);
1681 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1682 {
1683 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1684 goto err_re_init;
1685 }
1686
1687 /* Get the HDD context. */
1688 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1689 if(!pHddCtx)
1690 {
1691 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1692 goto err_vosclose;
1693 }
1694
1695 /* Save the hal context in Adapter */
1696 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1697 if ( NULL == pHddCtx->hHal )
1698 {
1699 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1700 goto err_vosclose;
1701 }
1702
1703 /* Set the SME configuration parameters. */
1704 vosStatus = hdd_set_sme_config(pHddCtx);
1705 if ( VOS_STATUS_SUCCESS != vosStatus )
1706 {
1707 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1708 goto err_vosclose;
1709 }
1710
1711 /* Initialize the WMM module */
1712 vosStatus = hdd_wmm_init(pHddCtx);
1713 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1714 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001715 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 goto err_vosclose;
1717 }
1718
1719 vosStatus = vos_preStart( pHddCtx->pvosContext );
1720 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1721 {
1722 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1723 goto err_vosclose;
1724 }
1725
1726 /* In the integrated architecture we update the configuration from
1727 the INI file and from NV before vOSS has been started so that
1728 the final contents are available to send down to the cCPU */
1729 /* Apply the cfg.ini to cfg.dat */
1730 if (FALSE == hdd_update_config_dat(pHddCtx))
1731 {
1732 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1733 goto err_vosclose;
1734 }
1735
1736 /* Set the MAC Address, currently this is used by HAL to add self sta.
1737 * Remove this once self sta is added as part of session open. */
1738 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1739 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1740 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1741 if (!HAL_STATUS_SUCCESS(halStatus))
1742 {
1743 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1744 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1745 goto err_vosclose;
1746 }
1747
1748 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1749 Note: Firmware image will be read and downloaded inside vos_start API */
1750 vosStatus = vos_start( pVosContext );
1751 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1752 {
1753 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1754 goto err_vosclose;
1755 }
1756
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001757 /* Exchange capability info between Host and FW and also get versioning info from FW */
1758 hdd_exchange_version_and_caps(pHddCtx);
1759
Jeff Johnson295189b2012-06-20 16:38:30 -07001760 vosStatus = hdd_post_voss_start_config( pHddCtx );
1761 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1762 {
1763 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1764 __func__);
1765 goto err_vosstop;
1766 }
1767
1768#ifdef WLAN_BTAMP_FEATURE
1769 vosStatus = WLANBAP_Open(pVosContext);
1770 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1771 {
1772 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1773 "%s: Failed to open BAP",__func__);
1774 goto err_vosstop;
1775 }
1776 vosStatus = BSL_Init(pVosContext);
1777 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1778 {
1779 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1780 "%s: Failed to Init BSL",__func__);
1781 goto err_bap_close;
1782 }
1783 vosStatus = WLANBAP_Start(pVosContext);
1784 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1785 {
1786 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1787 "%s: Failed to start TL",__func__);
1788 goto err_bap_close;
1789 }
1790 pConfig = pHddCtx->cfg_ini;
1791 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1792 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1793#endif //WLAN_BTAMP_FEATURE
1794
1795 /* Restart all adapters */
1796 hdd_start_all_adapters(pHddCtx);
1797 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07001798 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001799 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001801
1802 /* Register with platform driver as client for Suspend/Resume */
1803 vosStatus = hddRegisterPmOps(pHddCtx);
1804 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1805 {
1806 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1807 goto err_bap_stop;
1808 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001809 /* Allow the phone to go to sleep */
1810 hdd_allow_suspend();
1811 /* register for riva power on lock */
1812 if (req_riva_power_on_lock("wlan"))
1813 {
1814 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1815 __func__);
1816 goto err_unregister_pmops;
1817 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001818 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001819 goto success;
1820
1821err_unregister_pmops:
1822 hddDeregisterPmOps(pHddCtx);
1823
1824err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001825#ifdef CONFIG_HAS_EARLYSUSPEND
1826 hdd_unregister_mcast_bcast_filter(pHddCtx);
1827#endif
1828 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001829#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001830 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001831#endif
1832
1833#ifdef WLAN_BTAMP_FEATURE
1834err_bap_close:
1835 WLANBAP_Close(pVosContext);
1836#endif
1837
1838err_vosstop:
1839 vos_stop(pVosContext);
1840
1841err_vosclose:
1842 vos_close(pVosContext);
1843 vos_sched_close(pVosContext);
1844 if (pHddCtx)
1845 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001846 /* Unregister the Net Device Notifier */
1847 unregister_netdevice_notifier(&hdd_netdev_notifier);
1848 /* Clean up HDD Nlink Service */
1849 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07001850#ifdef WLAN_KD_READY_NOTIFIER
1851 nl_srv_exit(pHddCtx->ptt_pid);
1852#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001853 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07001854#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07001855 /* Free up dynamically allocated members inside HDD Adapter */
1856 kfree(pHddCtx->cfg_ini);
1857 pHddCtx->cfg_ini= NULL;
1858
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 wiphy_unregister(pHddCtx->wiphy);
1860 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 }
1862 vos_preClose(&pVosContext);
1863
1864#ifdef MEMORY_DEBUG
1865 vos_mem_exit();
1866#endif
1867
1868err_re_init:
1869 /* Allow the phone to go to sleep */
1870 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001871 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07001872 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001873 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001874
1875success:
1876 /* Trigger replay of BTC events */
1877 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1878 return VOS_STATUS_SUCCESS;
1879}