blob: d7fe538ca481eb8aa0a331b372002be2feff25f3 [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,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800715 "Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE");
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
Arif Hussain6d2a3322013-11-17 19:50:10 -0800789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:", __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
Arif Hussain6d2a3322013-11-17 19:50:10 -0800809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __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 "
Arif Hussain6d2a3322013-11-17 19:50:10 -0800843 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 return VOS_STATUS_E_FAILURE;
845 }
846 return VOS_STATUS_SUCCESS;
847 }
848 else
849 {
Arif Hussain6d2a3322013-11-17 19:50:10 -0800850 hddLog(VOS_TRACE_LEVEL_INFO, "%s:IP Address is not assigned", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700851 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 "
Arif Hussain6d2a3322013-11-17 19:50:10 -0800865 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 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 Singhalf8ba2b82013-12-02 12:54:38 -08001027 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1028 pHddCtx->configuredMcastBcastFilter =
1029 pHddCtx->sus_res_mcastbcast_filter;
1030 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1031 }
Amar Singhald53568e2013-09-26 11:03:45 -07001032
1033 hddLog(VOS_TRACE_LEVEL_INFO,
1034 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1035 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1036 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001037
Chilam Ngc4244af2013-04-01 15:37:32 -07001038
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301039#ifdef WLAN_FEATURE_PACKET_FILTERING
1040 /* Filer was applied during suspend inditication
1041 * clear it when we resume.
1042 */
1043 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001044#endif
1045}
Jeff Johnson295189b2012-06-20 16:38:30 -07001046
Jeff Johnson295189b2012-06-20 16:38:30 -07001047//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001048void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001049{
1050 hdd_context_t *pHddCtx = NULL;
1051 v_CONTEXT_t pVosContext = NULL;
1052
Jeff Johnson295189b2012-06-20 16:38:30 -07001053 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301054 hdd_adapter_t *pAdapter = NULL;
1055 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301056 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001057
Jeff Johnson295189b2012-06-20 16:38:30 -07001058 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1059
1060 //Get the global VOSS context.
1061 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1062 if(!pVosContext) {
1063 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1064 return;
1065 }
1066
1067 //Get the HDD context.
1068 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1069
1070 if(!pHddCtx) {
1071 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1072 return;
1073 }
1074
1075 if (pHddCtx->isLogpInProgress) {
1076 hddLog(VOS_TRACE_LEVEL_ERROR,
1077 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1078 return;
1079 }
1080
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301081 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1083 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1084 {
1085 pAdapter = pAdapterNode->pAdapter;
1086 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001087 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001088 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1089
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001090 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001091 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1092 pAdapterNode = pNext;
1093 continue;
1094 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301095 /* Avoid multiple enter/exit BMPS in this while loop using
1096 * hdd_enter_bmps flag
1097 */
1098 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1099 {
1100 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001101
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301102 /* If device was already in BMPS, and dynamic DTIM is set,
1103 * exit(set the device to full power) and enter BMPS again
1104 * to reflect new DTIM value */
1105 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1106
1107 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1108
1109 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1110 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001111#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1112 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1113 {
1114 //stop the interface before putting the chip to standby
1115 netif_tx_disable(pAdapter->dev);
1116 netif_carrier_off(pAdapter->dev);
1117 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301118 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1120 {
1121 //Execute deep sleep procedure
1122 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1123 }
1124#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301125
1126 /*Suspend notification sent down to driver*/
1127 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1128
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301129 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1130 pAdapterNode = pNext;
1131 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301132 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301133
Jeff Johnson295189b2012-06-20 16:38:30 -07001134#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1135 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1136 {
1137 hdd_enter_standby(pHddCtx);
1138 }
1139#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001140
1141 return;
1142}
1143
1144static void hdd_PowerStateChangedCB
1145(
1146 v_PVOID_t callbackContext,
1147 tPmcState newState
1148)
1149{
1150 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001151 /* if the driver was not in BMPS during early suspend,
1152 * the dynamic DTIM is now updated at Riva */
1153 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1154 && pHddCtx->cfg_ini->enableDynamicDTIM
1155 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1156 {
1157 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1158 }
1159 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301160 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001161 spin_unlock(&pHddCtx->filter_lock);
Amar Singhald53568e2013-09-26 11:03:45 -07001162 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1163 pHddCtx->sus_res_mcastbcast_filter =
1164 pHddCtx->configuredMcastBcastFilter;
1165 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1166
1167 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1168 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1169 pHddCtx->configuredMcastBcastFilter);
1170 hddLog(VOS_TRACE_LEVEL_INFO,
1171 "offload: calling hdd_conf_mcastbcast_filter");
1172
1173 }
1174
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001176 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1178 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001179 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001180 spin_unlock(&pHddCtx->filter_lock);
1181}
1182
1183
1184
1185void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1186{
1187 v_CONTEXT_t pVosContext;
1188 tHalHandle smeContext;
1189
1190 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1191 if (NULL == pVosContext)
1192 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001193 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 return;
1195 }
1196 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1197 if (NULL == smeContext)
1198 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001199 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 return;
1201 }
1202
1203 spin_lock_init(&pHddCtx->filter_lock);
1204 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1205 pHddCtx->cfg_ini->nEnableSuspend)
1206 {
1207 pmcRegisterDeviceStateUpdateInd(smeContext,
1208 hdd_PowerStateChangedCB, pHddCtx);
1209 }
1210}
1211
1212void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1213{
1214 v_CONTEXT_t pVosContext;
1215 tHalHandle smeContext;
1216
1217 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1218 if (NULL == pVosContext)
1219 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001220 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 return;
1222 }
1223 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1224 if (NULL == smeContext)
1225 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001226 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 return;
1228 }
1229
1230 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1231 pHddCtx->cfg_ini->nEnableSuspend)
1232 {
1233 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1234 }
1235}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301236
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301237#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301238void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301239{
1240 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301241 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301242 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1243
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301244 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301245 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301246 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1247 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1248 {
1249 vos_mem_copy(&hddGtkOffloadReqParams,
1250 &pHddStaCtx->gtkOffloadReqParams,
1251 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301252
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301253 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1254 &hddGtkOffloadReqParams, pAdapter->sessionId);
1255 if (eHAL_STATUS_SUCCESS != ret)
1256 {
1257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1258 "%s: sme_SetGTKOffload failed, returned %d",
1259 __func__, ret);
1260 return;
1261 }
1262
1263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1264 "%s: sme_SetGTKOffload successfull", __func__);
1265 }
1266
1267 }
1268 else
1269 {
1270 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1271 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1272 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1273 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1274 {
1275
1276 /* Host driver has previously offloaded GTK rekey */
1277 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301278 wlan_hdd_cfg80211_update_replayCounterCallback,
1279 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301280 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301281
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301282 {
1283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1284 "%s: sme_GetGTKOffload failed, returned %d",
1285 __func__, ret);
1286 return;
1287 }
1288 else
1289 {
1290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1291 "%s: sme_GetGTKOffload successful",
1292 __func__);
1293
1294 /* Sending GTK offload dissable */
1295 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1296 sizeof (tSirGtkOffloadParams));
1297 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1298 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301299 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301300 if (eHAL_STATUS_SUCCESS != ret)
1301 {
1302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1303 "%s: failed to dissable GTK offload, returned %d",
1304 __func__, ret);
1305 return;
1306 }
1307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1308 "%s: successfully dissabled GTK offload request to HAL",
1309 __func__);
1310 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301311 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301312 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301313 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301314}
1315#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001316
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001317void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001318{
1319 hdd_context_t *pHddCtx = NULL;
1320 hdd_adapter_t *pAdapter = NULL;
1321 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1322 VOS_STATUS status;
1323 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001324
Jeff Johnson295189b2012-06-20 16:38:30 -07001325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1326
1327 //Get the global VOSS context.
1328 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1329 if(!pVosContext) {
1330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1331 return;
1332 }
1333
1334 //Get the HDD context.
1335 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1336
1337 if(!pHddCtx) {
1338 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1339 return;
1340 }
1341
1342 if (pHddCtx->isLogpInProgress) {
1343 hddLog(VOS_TRACE_LEVEL_INFO,
1344 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1345 return;
1346 }
1347
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 pHddCtx->hdd_wlan_suspended = FALSE;
1349 /*loop through all adapters. Concurrency */
1350 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1351
1352 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1353 {
1354 pAdapter = pAdapterNode->pAdapter;
1355 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001356 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001358 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1360 pAdapterNode = pNext;
1361 continue;
1362 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301363
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301364
Jeff Johnson295189b2012-06-20 16:38:30 -07001365#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1366 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1367 {
1368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1369 hdd_exit_deep_sleep(pAdapter);
1370 }
1371#endif
1372
1373 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1374 {
1375 /*Switch back to DTIM 1*/
1376 tSirSetPowerParamsReq powerRequest = { 0 };
1377
1378 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1379 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001380 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001381
1382 /*Disabled ModulatedDTIM if enabled on suspend*/
1383 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1384 powerRequest.uDTIMPeriod = 0;
1385
1386 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1387 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1388 NULL, eANI_BOOLEAN_FALSE);
1389 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1390 NULL, eANI_BOOLEAN_FALSE);
1391
1392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001393 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001394 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001395
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301396 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1397 {
1398 /* put the device into full power */
1399 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001400
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301401 /* put the device back into BMPS */
1402 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001403
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301404 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1405 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001406 }
1407
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301408 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1410 pAdapterNode = pNext;
1411 }
1412
1413#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1414 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1415 {
1416 hdd_exit_standby(pHddCtx);
1417 }
1418#endif
1419
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 return;
1421}
1422
Jeff Johnson295189b2012-06-20 16:38:30 -07001423VOS_STATUS hdd_wlan_reset_initialization(void)
1424{
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 v_CONTEXT_t pVosContext = NULL;
1426
1427 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1428
1429 //Get the global VOSS context.
1430 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1431 if(!pVosContext)
1432 {
1433 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1434 return VOS_STATUS_E_FAILURE;
1435 }
1436
1437 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1438
1439 // Prevent the phone from going to sleep
1440 hdd_prevent_suspend();
1441
Jeff Johnson295189b2012-06-20 16:38:30 -07001442 return VOS_STATUS_SUCCESS;
1443}
1444
1445
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001446/*
1447 * Based on the ioctl command recieved by HDD, put WLAN driver
1448 * into the quiet mode. This is the same as the early suspend
1449 * notification that driver used to listen
1450 */
1451void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001452{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001453 if (suspend)
1454 hdd_suspend_wlan();
1455 else
1456 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001457}
1458
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001459static void hdd_ssr_timer_init(void)
1460{
1461 init_timer(&ssr_timer);
1462}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001463
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001464static void hdd_ssr_timer_del(void)
1465{
1466 del_timer(&ssr_timer);
1467 ssr_timer_started = false;
1468}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001469
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001470static void hdd_ssr_timer_cb(unsigned long data)
1471{
1472 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001473
1474#ifdef WCN_PRONTO
1475 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1476 wcnss_pronto_log_debug_regs();
1477#endif
1478
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001479 VOS_BUG(0);
1480}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001481
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001482static void hdd_ssr_timer_start(int msec)
1483{
1484 if(ssr_timer_started)
1485 {
1486 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1487 ,__func__);
1488 }
1489 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1490 ssr_timer.function = hdd_ssr_timer_cb;
1491 add_timer(&ssr_timer);
1492 ssr_timer_started = true;
1493}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001494
Jeff Johnson295189b2012-06-20 16:38:30 -07001495/* the HDD interface to WLAN driver shutdown,
1496 * the primary shutdown function in SSR
1497 */
1498VOS_STATUS hdd_wlan_shutdown(void)
1499{
1500 VOS_STATUS vosStatus;
1501 v_CONTEXT_t pVosContext = NULL;
1502 hdd_context_t *pHddCtx = NULL;
1503 pVosSchedContext vosSchedContext = NULL;
1504
1505 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1506
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001507 /* if re-init never happens, then do SSR1 */
1508 hdd_ssr_timer_init();
1509 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1510
Jeff Johnson295189b2012-06-20 16:38:30 -07001511 /* Get the global VOSS context. */
1512 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1513 if(!pVosContext) {
1514 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1515 return VOS_STATUS_E_FAILURE;
1516 }
1517 /* Get the HDD context. */
1518 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1519 if(!pHddCtx) {
1520 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1521 return VOS_STATUS_E_FAILURE;
1522 }
1523 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001524 /* DeRegister with platform driver as client for Suspend/Resume */
1525 vosStatus = hddDeregisterPmOps(pHddCtx);
1526 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1527 {
1528 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1529 }
1530
1531 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1532 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1533 {
1534 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1535 }
1536
1537 /* Disable IMPS/BMPS as we do not want the device to enter any power
1538 * save mode on its own during reset sequence
1539 */
1540 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1541 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1542 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1543
1544 vosSchedContext = get_vos_sched_ctxt();
1545
1546 /* Wakeup all driver threads */
1547 if(TRUE == pHddCtx->isMcThreadSuspended){
1548 complete(&vosSchedContext->ResumeMcEvent);
1549 pHddCtx->isMcThreadSuspended= FALSE;
1550 }
1551 if(TRUE == pHddCtx->isTxThreadSuspended){
1552 complete(&vosSchedContext->ResumeTxEvent);
1553 pHddCtx->isTxThreadSuspended= FALSE;
1554 }
1555 if(TRUE == pHddCtx->isRxThreadSuspended){
1556 complete(&vosSchedContext->ResumeRxEvent);
1557 pHddCtx->isRxThreadSuspended= FALSE;
1558 }
1559 /* Reset the Suspend Variable */
1560 pHddCtx->isWlanSuspended = FALSE;
1561
1562 /* Stop all the threads; we do not want any messages to be a processed,
1563 * any more and the best way to ensure that is to terminate the threads
1564 * gracefully.
1565 */
1566 /* Wait for MC to exit */
1567 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1568 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1569 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1570 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
1571 wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1572
1573 /* Wait for TX to exit */
1574 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1575 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1576 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1577 wake_up_interruptible(&vosSchedContext->txWaitQueue);
1578 wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1579
1580 /* Wait for RX to exit */
1581 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1582 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1583 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1584 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
1585 wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1586
1587#ifdef WLAN_BTAMP_FEATURE
1588 vosStatus = WLANBAP_Stop(pVosContext);
1589 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1590 {
1591 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1592 "%s: Failed to stop BAP",__func__);
1593 }
1594#endif //WLAN_BTAMP_FEATURE
1595 vosStatus = vos_wda_shutdown(pVosContext);
1596 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1597
1598 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1599 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1600 * on threads being running to process the SYS Stop
1601 */
Kiet Lama72a2322013-11-15 11:18:11 +05301602 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
Jeff Johnson295189b2012-06-20 16:38:30 -07001603 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1604
1605 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1606 /* Stop MAC (PE and HAL) */
1607 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1608 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1609
1610 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1611 /* Stop TL */
1612 vosStatus = WLANTL_Stop(pVosContext);
1613 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1614
Jeff Johnson295189b2012-06-20 16:38:30 -07001615 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001616 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1617 /* Clean up message queues of TX and MC thread */
1618 vos_sched_flush_mc_mqs(vosSchedContext);
1619 vos_sched_flush_tx_mqs(vosSchedContext);
1620 vos_sched_flush_rx_mqs(vosSchedContext);
1621
1622 /* Deinit all the TX and MC queues */
1623 vos_sched_deinit_mqs(vosSchedContext);
1624 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1625
1626 /* shutdown VOSS */
1627 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301628
1629 /*mac context has already been released in mac_close call
1630 so setting it to NULL in hdd context*/
1631 pHddCtx->hHal = (tHalHandle)NULL;
1632
Jeff Johnson295189b2012-06-20 16:38:30 -07001633 if (free_riva_power_on_lock("wlan"))
1634 {
1635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1636 __func__);
1637 }
1638 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1639 ,__func__);
1640 return VOS_STATUS_SUCCESS;
1641}
1642
1643
1644
1645/* the HDD interface to WLAN driver re-init.
1646 * This is called to initialize/start WLAN driver after a shutdown.
1647 */
1648VOS_STATUS hdd_wlan_re_init(void)
1649{
1650 VOS_STATUS vosStatus;
1651 v_CONTEXT_t pVosContext = NULL;
1652 hdd_context_t *pHddCtx = NULL;
1653 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001654#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1655 int max_retries = 0;
1656#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001657#ifdef WLAN_BTAMP_FEATURE
1658 hdd_config_t *pConfig = NULL;
1659 WLANBAP_ConfigType btAmpConfig;
1660#endif
1661
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001662 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001664
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001665#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1666 /* wait until WCNSS driver downloads NV */
1667 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1668 msleep(1000);
1669 }
1670 if (max_retries >= 5) {
1671 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1672 goto err_re_init;
1673 }
1674#endif
1675
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001676 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
1677
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001678 /* The driver should always be initialized in STA mode after SSR */
1679 hdd_set_conparam(0);
1680
Jeff Johnson295189b2012-06-20 16:38:30 -07001681 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1682 vosStatus = vos_open(&pVosContext, 0);
1683 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1684 {
1685 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1686 goto err_re_init;
1687 }
1688
1689 /* Get the HDD context. */
1690 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1691 if(!pHddCtx)
1692 {
1693 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1694 goto err_vosclose;
1695 }
1696
1697 /* Save the hal context in Adapter */
1698 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1699 if ( NULL == pHddCtx->hHal )
1700 {
1701 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1702 goto err_vosclose;
1703 }
1704
1705 /* Set the SME configuration parameters. */
1706 vosStatus = hdd_set_sme_config(pHddCtx);
1707 if ( VOS_STATUS_SUCCESS != vosStatus )
1708 {
1709 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1710 goto err_vosclose;
1711 }
1712
1713 /* Initialize the WMM module */
1714 vosStatus = hdd_wmm_init(pHddCtx);
1715 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1716 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001717 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001718 goto err_vosclose;
1719 }
1720
1721 vosStatus = vos_preStart( pHddCtx->pvosContext );
1722 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1723 {
1724 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1725 goto err_vosclose;
1726 }
1727
1728 /* In the integrated architecture we update the configuration from
1729 the INI file and from NV before vOSS has been started so that
1730 the final contents are available to send down to the cCPU */
1731 /* Apply the cfg.ini to cfg.dat */
1732 if (FALSE == hdd_update_config_dat(pHddCtx))
1733 {
1734 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1735 goto err_vosclose;
1736 }
1737
1738 /* Set the MAC Address, currently this is used by HAL to add self sta.
1739 * Remove this once self sta is added as part of session open. */
1740 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1741 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1742 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1743 if (!HAL_STATUS_SUCCESS(halStatus))
1744 {
1745 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1746 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1747 goto err_vosclose;
1748 }
1749
1750 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1751 Note: Firmware image will be read and downloaded inside vos_start API */
1752 vosStatus = vos_start( pVosContext );
1753 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1754 {
1755 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1756 goto err_vosclose;
1757 }
1758
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001759 /* Exchange capability info between Host and FW and also get versioning info from FW */
1760 hdd_exchange_version_and_caps(pHddCtx);
1761
Jeff Johnson295189b2012-06-20 16:38:30 -07001762 vosStatus = hdd_post_voss_start_config( pHddCtx );
1763 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1764 {
1765 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1766 __func__);
1767 goto err_vosstop;
1768 }
1769
1770#ifdef WLAN_BTAMP_FEATURE
1771 vosStatus = WLANBAP_Open(pVosContext);
1772 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1773 {
1774 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1775 "%s: Failed to open BAP",__func__);
1776 goto err_vosstop;
1777 }
1778 vosStatus = BSL_Init(pVosContext);
1779 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1780 {
1781 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1782 "%s: Failed to Init BSL",__func__);
1783 goto err_bap_close;
1784 }
1785 vosStatus = WLANBAP_Start(pVosContext);
1786 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1787 {
1788 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1789 "%s: Failed to start TL",__func__);
1790 goto err_bap_close;
1791 }
1792 pConfig = pHddCtx->cfg_ini;
1793 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1794 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1795#endif //WLAN_BTAMP_FEATURE
1796
1797 /* Restart all adapters */
1798 hdd_start_all_adapters(pHddCtx);
1799 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07001800 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001801 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001803
1804 /* Register with platform driver as client for Suspend/Resume */
1805 vosStatus = hddRegisterPmOps(pHddCtx);
1806 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1807 {
1808 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1809 goto err_bap_stop;
1810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 /* Allow the phone to go to sleep */
1812 hdd_allow_suspend();
1813 /* register for riva power on lock */
1814 if (req_riva_power_on_lock("wlan"))
1815 {
1816 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1817 __func__);
1818 goto err_unregister_pmops;
1819 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001820 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001821 goto success;
1822
1823err_unregister_pmops:
1824 hddDeregisterPmOps(pHddCtx);
1825
1826err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001827#ifdef CONFIG_HAS_EARLYSUSPEND
1828 hdd_unregister_mcast_bcast_filter(pHddCtx);
1829#endif
1830 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001831#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001832 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001833#endif
1834
1835#ifdef WLAN_BTAMP_FEATURE
1836err_bap_close:
1837 WLANBAP_Close(pVosContext);
1838#endif
1839
1840err_vosstop:
1841 vos_stop(pVosContext);
1842
1843err_vosclose:
1844 vos_close(pVosContext);
1845 vos_sched_close(pVosContext);
1846 if (pHddCtx)
1847 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001848 /* Unregister the Net Device Notifier */
1849 unregister_netdevice_notifier(&hdd_netdev_notifier);
1850 /* Clean up HDD Nlink Service */
1851 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07001852#ifdef WLAN_KD_READY_NOTIFIER
1853 nl_srv_exit(pHddCtx->ptt_pid);
1854#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001855 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07001856#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07001857 /* Free up dynamically allocated members inside HDD Adapter */
1858 kfree(pHddCtx->cfg_ini);
1859 pHddCtx->cfg_ini= NULL;
1860
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 wiphy_unregister(pHddCtx->wiphy);
1862 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 }
1864 vos_preClose(&pVosContext);
1865
1866#ifdef MEMORY_DEBUG
1867 vos_mem_exit();
1868#endif
1869
1870err_re_init:
1871 /* Allow the phone to go to sleep */
1872 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001873 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07001874 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001875 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001876
1877success:
1878 /* Trigger replay of BTC events */
1879 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
1880 return VOS_STATUS_SUCCESS;
1881}