blob: fa98388487b8c4372216971b8e9c556ab6b0f565 [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
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530769 //Disable NSOffload on all slots
770 for (i = 0; i<SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++)
771 {
772 offLoadRequest.nsOffloadInfo.slotIdx = i;
773 if (eHAL_STATUS_SUCCESS !=
774 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
775 pAdapter->sessionId, &offLoadRequest))
776 {
777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disable NSOflload"
778 " on slot %d"), i);
779 }
780 }
781
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530782 if (eHAL_STATUS_SUCCESS !=
783 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
784 pAdapter->sessionId, &offLoadRequest))
785 {
786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
787 "NSOffload feature"));
788 }
789 }
790 return;
791}
792#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530793
794void hdd_ipv4_notifier_work_queue(struct work_struct *work)
795{
796 hdd_adapter_t* pAdapter =
797 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
798 hdd_context_t *pHddCtx;
799 int status;
800
801 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
803 status = wlan_hdd_validate_context(pHddCtx);
804 if (0 != status)
805 {
806 hddLog(LOGE, FL("HDD context is invalid"));
807 return;
808 }
809
810 if ((eConnectionState_Associated ==
811 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
812 && (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
813 {
814 // This invocation being part of the IPv4 registration callback,
815 // we are passing second parameter as 2 to avoid registration
816 // of IPv4 notifier again.
817 hdd_conf_arp_offload(pAdapter, 2);
818 }
819}
820
821static int wlan_hdd_ipv4_changed(struct notifier_block *nb,
822 unsigned long data, void *arg)
823{
824 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
825 struct in_ifaddr **ifap = NULL;
826 struct in_device *in_dev;
827
828 struct net_device *ndev = ifa->ifa_dev->dev;
829 hdd_adapter_t *pAdapter =
830 container_of(nb, struct hdd_adapter_s, ipv4_notifier);
831
832 if (pAdapter && pAdapter->dev == ndev)
833 {
834 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
835 {
836 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
837 ifap = &ifa->ifa_next)
838 {
839 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
840 {
841 break; /* found */
842 }
843 }
844 }
845 if(ifa && ifa->ifa_local)
846 {
847 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
848 }
849 }
850
851 return NOTIFY_DONE;
852}
853
854/**----------------------------------------------------------------------------
855
856 \brief hdd_conf_arp_offload() - Configure ARP offload
857
858 Called during SUSPEND to configure the ARP offload (MC BC filter) which
859 reduces power consumption.
860
861 \param - pAdapter -Adapter context for which ARP offload is to be configured
862 \param - fenable - 0 - disable.
863 1 - enable. (with IPv4 notifier registration)
864 2 - enable. (without IPv4 notifier registration)
865
866 \return -
867 VOS_STATUS_SUCCESS - on successful operation
868 VOS_STATUS_E_FAILURE - on failure of operation
869-----------------------------------------------------------------------------*/
870VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700871{
872 struct in_ifaddr **ifap = NULL;
873 struct in_ifaddr *ifa = NULL;
874 struct in_device *in_dev;
875 int i = 0;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530876 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700877 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -0800878 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700879
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530880 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -0700881
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 if(fenable)
883 {
884 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
885 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530886 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 ifap = &ifa->ifa_next)
888 {
889 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
890 {
891 break; /* found */
892 }
893 }
894 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 if(ifa && ifa->ifa_local)
896 {
897 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
898 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
899
Arif Hussain6d2a3322013-11-17 19:50:10 -0800900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700901
Amar Singhald53568e2013-09-26 11:03:45 -0700902 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
903 pHddCtx->sus_res_mcastbcast_filter) ||
904 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
905 pHddCtx->sus_res_mcastbcast_filter)) &&
906 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -0700907 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530908 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -0700909 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
910 hddLog(VOS_TRACE_LEVEL_INFO,
911 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 }
Amar Singhald53568e2013-09-26 11:03:45 -0700913
914 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
915 offLoadRequest.enableOrDisable);
916
Jeff Johnson295189b2012-06-20 16:38:30 -0700917 //converting u32 to IPV4 address
918 for(i = 0 ; i < 4; i++)
919 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530920 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700921 (ifa->ifa_local >> (i*8) ) & 0xFF ;
922 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530923 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 offLoadRequest.params.hostIpv4Addr[0],
925 offLoadRequest.params.hostIpv4Addr[1],
926 offLoadRequest.params.hostIpv4Addr[2],
927 offLoadRequest.params.hostIpv4Addr[3]);
928
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530929 if (eHAL_STATUS_SUCCESS !=
930 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
931 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 {
933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -0800934 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 return VOS_STATUS_E_FAILURE;
936 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 }
938 else
939 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530940 hddLog(VOS_TRACE_LEVEL_INFO, FL("IP Address is not assigned\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700941 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530942
943 if (fenable == 1)
944 {
945 // Register IPv4 notifier to notify if any change in IP
946 // So that we can reconfigure the offload parameters
947 pAdapter->ipv4_notifier.notifier_call =
948 wlan_hdd_ipv4_changed;
949 ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier);
950 if (ret)
951 {
952 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
953 }
954 }
955 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700956 }
957 else
958 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530959 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
Jeff Johnson295189b2012-06-20 16:38:30 -0700960 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
961 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
962 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
963
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530964 if (eHAL_STATUS_SUCCESS !=
965 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
966 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -0700967 {
968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -0800969 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 return VOS_STATUS_E_FAILURE;
971 }
972 return VOS_STATUS_SUCCESS;
973 }
974}
975
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530976/*
977 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530978 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530979*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530980void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530981 tANI_U8 *pMcBcFilter)
982{
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530983 if (NULL == pHddCtx)
984 {
985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
986 return;
987 }
988
989 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
990 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530991 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +0530992 /* ARP offload is enabled, do not block bcast packets at RXP
993 * Will be using Bitmasking to reset the filter. As we have
994 * disable Broadcast filtering, Anding with the negation
995 * of Broadcast BIT
996 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530997 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +0530998 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530999
1000#ifdef WLAN_NS_OFFLOAD
1001 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301002 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301003 /* NS offload is enabled, do not block mcast packets at RXP
1004 * Will be using Bitmasking to reset the filter. As we have
1005 * disable Multicast filtering, Anding with the negation
1006 * of Multicast BIT
1007 */
1008 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301009 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301010#endif
1011
1012 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301013}
1014
Jeff Johnson295189b2012-06-20 16:38:30 -07001015void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1016{
1017 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1019 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1020 if(NULL == wlanRxpFilterParam)
1021 {
1022 hddLog(VOS_TRACE_LEVEL_FATAL,
1023 "%s: vos_mem_alloc failed ", __func__);
1024 return;
1025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001026 hddLog(VOS_TRACE_LEVEL_INFO,
1027 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301028 if (TRUE == setfilter)
1029 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301030 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301031 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301032 }
1033 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301034 {
1035 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301036 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301037 pHddCtx->configuredMcastBcastFilter;
1038 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301039
Jeff Johnson295189b2012-06-20 16:38:30 -07001040 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -07001042 if (eHAL_STATUS_SUCCESS != halStatus)
1043 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001044 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1045 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1046}
1047
Jeff Johnson295189b2012-06-20 16:38:30 -07001048static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1049 hdd_adapter_t *pAdapter)
1050{
1051 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1052 tpSirWlanSuspendParam wlanSuspendParam =
1053 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1054
Amar Singhald53568e2013-09-26 11:03:45 -07001055 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1056 pHddCtx->sus_res_mcastbcast_filter =
1057 pHddCtx->configuredMcastBcastFilter;
1058 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1059 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1060 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1061 pHddCtx->configuredMcastBcastFilter);
1062
1063 }
1064
Amar Singhal49fdfd52013-08-13 13:25:12 -07001065
Jeff Johnson295189b2012-06-20 16:38:30 -07001066 if(NULL == wlanSuspendParam)
1067 {
1068 hddLog(VOS_TRACE_LEVEL_FATAL,
1069 "%s: vos_mem_alloc failed ", __func__);
1070 return;
1071 }
1072
Amar Singhald53568e2013-09-26 11:03:45 -07001073 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 "%s: send wlan suspend indication", __func__);
1075
1076 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1077 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301078 //Configure supported OffLoads
1079 hdd_conf_hostoffload(pAdapter, TRUE);
1080 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001081
1082#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301083 /* During suspend, configure MC Addr list filter to the firmware
1084 * function takes care of checking necessary conditions before
1085 * configuring.
1086 */
1087 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001088#endif
1089 }
1090
1091 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1092 if(eHAL_STATUS_SUCCESS == halStatus)
1093 {
1094 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001095 } else {
1096 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 }
1098}
1099
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301100static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001101{
Chilam Ngc4244af2013-04-01 15:37:32 -07001102 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001103 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001104 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001105
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301106 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 "%s: send wlan resume indication", __func__);
1108
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301109 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1110
1111 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301113 hddLog(VOS_TRACE_LEVEL_FATAL,
1114 "%s: memory allocation failed for wlanResumeParam ", __func__);
1115 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001117
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301118 //Disable supported OffLoads
1119 hdd_conf_hostoffload(pAdapter, FALSE);
1120
1121 wlanResumeParam->configuredMcstBcstFilterSetting =
1122 pHddCtx->configuredMcastBcastFilter;
1123 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1124 if (eHAL_STATUS_SUCCESS != halStatus)
1125 {
1126 vos_mem_free(wlanResumeParam);
1127 }
1128
1129 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1130
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001131 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1132 pHddCtx->configuredMcastBcastFilter =
1133 pHddCtx->sus_res_mcastbcast_filter;
1134 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1135 }
Amar Singhald53568e2013-09-26 11:03:45 -07001136
1137 hddLog(VOS_TRACE_LEVEL_INFO,
1138 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1139 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1140 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001141
Chilam Ngc4244af2013-04-01 15:37:32 -07001142
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301143#ifdef WLAN_FEATURE_PACKET_FILTERING
1144 /* Filer was applied during suspend inditication
1145 * clear it when we resume.
1146 */
1147 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001148#endif
1149}
Jeff Johnson295189b2012-06-20 16:38:30 -07001150
Jeff Johnson295189b2012-06-20 16:38:30 -07001151//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001152void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001153{
1154 hdd_context_t *pHddCtx = NULL;
1155 v_CONTEXT_t pVosContext = NULL;
1156
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301158 hdd_adapter_t *pAdapter = NULL;
1159 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301160 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001161
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1163
1164 //Get the global VOSS context.
1165 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1166 if(!pVosContext) {
1167 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1168 return;
1169 }
1170
1171 //Get the HDD context.
1172 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1173
1174 if(!pHddCtx) {
1175 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1176 return;
1177 }
1178
1179 if (pHddCtx->isLogpInProgress) {
1180 hddLog(VOS_TRACE_LEVEL_ERROR,
1181 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1182 return;
1183 }
1184
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301185 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1187 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1188 {
1189 pAdapter = pAdapterNode->pAdapter;
1190 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001191 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1193
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001194 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001195 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1196 pAdapterNode = pNext;
1197 continue;
1198 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301199 /* Avoid multiple enter/exit BMPS in this while loop using
1200 * hdd_enter_bmps flag
1201 */
1202 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1203 {
1204 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001205
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301206 /* If device was already in BMPS, and dynamic DTIM is set,
1207 * exit(set the device to full power) and enter BMPS again
1208 * to reflect new DTIM value */
1209 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1210
1211 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1212
1213 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1214 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001215#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1216 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1217 {
1218 //stop the interface before putting the chip to standby
1219 netif_tx_disable(pAdapter->dev);
1220 netif_carrier_off(pAdapter->dev);
1221 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301222 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001223 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1224 {
1225 //Execute deep sleep procedure
1226 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1227 }
1228#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301229
1230 /*Suspend notification sent down to driver*/
1231 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1232
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301233 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1234 pAdapterNode = pNext;
1235 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301236 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301237
Jeff Johnson295189b2012-06-20 16:38:30 -07001238#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1239 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1240 {
1241 hdd_enter_standby(pHddCtx);
1242 }
1243#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001244
1245 return;
1246}
1247
1248static void hdd_PowerStateChangedCB
1249(
1250 v_PVOID_t callbackContext,
1251 tPmcState newState
1252)
1253{
1254 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001255 /* if the driver was not in BMPS during early suspend,
1256 * the dynamic DTIM is now updated at Riva */
1257 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1258 && pHddCtx->cfg_ini->enableDynamicDTIM
1259 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1260 {
1261 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1262 }
1263 spin_lock(&pHddCtx->filter_lock);
Gopichand Nakkalac1b11522013-03-25 15:25:33 +05301264 if((newState == BMPS) && pHddCtx->hdd_wlan_suspended) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 spin_unlock(&pHddCtx->filter_lock);
Amar Singhald53568e2013-09-26 11:03:45 -07001266 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1267 pHddCtx->sus_res_mcastbcast_filter =
1268 pHddCtx->configuredMcastBcastFilter;
1269 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1270
1271 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1272 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1273 pHddCtx->configuredMcastBcastFilter);
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "offload: calling hdd_conf_mcastbcast_filter");
1276
1277 }
1278
Jeff Johnson295189b2012-06-20 16:38:30 -07001279 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001280 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1282 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001283 else
Mihir Shete793209f2014-01-06 11:01:12 +05301284 {
1285 /* Android framework can send resume request when the WCN chip is
1286 * in IMPS mode. When the chip exits IMPS mode the firmware will
1287 * restore all the registers to the state they were before the chip
1288 * entered IMPS and so our hardware filter settings confgured by the
1289 * resume request will be lost. So reconfigure the filters on detecting
1290 * a change in the power state of the WCN chip.
1291 */
1292 if (IMPS != newState)
1293 {
1294 if (FALSE == pHddCtx->hdd_wlan_suspended)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_INFO,
1297 "Not in IMPS/BMPS and suspended state");
1298 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1299 }
1300 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001301 spin_unlock(&pHddCtx->filter_lock);
1302}
1303
1304
1305
1306void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1307{
1308 v_CONTEXT_t pVosContext;
1309 tHalHandle smeContext;
1310
1311 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1312 if (NULL == pVosContext)
1313 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001314 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001315 return;
1316 }
1317 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1318 if (NULL == smeContext)
1319 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001320 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001321 return;
1322 }
1323
1324 spin_lock_init(&pHddCtx->filter_lock);
1325 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1326 pHddCtx->cfg_ini->nEnableSuspend)
1327 {
1328 pmcRegisterDeviceStateUpdateInd(smeContext,
1329 hdd_PowerStateChangedCB, pHddCtx);
1330 }
1331}
1332
1333void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1334{
1335 v_CONTEXT_t pVosContext;
1336 tHalHandle smeContext;
1337
1338 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1339 if (NULL == pVosContext)
1340 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001341 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001342 return;
1343 }
1344 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1345 if (NULL == smeContext)
1346 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001347 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 return;
1349 }
1350
1351 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1352 pHddCtx->cfg_ini->nEnableSuspend)
1353 {
1354 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1355 }
1356}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301357
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301358#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301359void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301360{
1361 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301362 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301363 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1364
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301365 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301366 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301367 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1368 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1369 {
1370 vos_mem_copy(&hddGtkOffloadReqParams,
1371 &pHddStaCtx->gtkOffloadReqParams,
1372 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301373
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301374 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1375 &hddGtkOffloadReqParams, pAdapter->sessionId);
1376 if (eHAL_STATUS_SUCCESS != ret)
1377 {
1378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1379 "%s: sme_SetGTKOffload failed, returned %d",
1380 __func__, ret);
1381 return;
1382 }
1383
1384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1385 "%s: sme_SetGTKOffload successfull", __func__);
1386 }
1387
1388 }
1389 else
1390 {
1391 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1392 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1393 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1394 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1395 {
1396
1397 /* Host driver has previously offloaded GTK rekey */
1398 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301399 wlan_hdd_cfg80211_update_replayCounterCallback,
1400 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301401 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301402
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301403 {
1404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1405 "%s: sme_GetGTKOffload failed, returned %d",
1406 __func__, ret);
1407 return;
1408 }
1409 else
1410 {
1411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1412 "%s: sme_GetGTKOffload successful",
1413 __func__);
1414
1415 /* Sending GTK offload dissable */
1416 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1417 sizeof (tSirGtkOffloadParams));
1418 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1419 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301420 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301421 if (eHAL_STATUS_SUCCESS != ret)
1422 {
1423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1424 "%s: failed to dissable GTK offload, returned %d",
1425 __func__, ret);
1426 return;
1427 }
1428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1429 "%s: successfully dissabled GTK offload request to HAL",
1430 __func__);
1431 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301432 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301433 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301434 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301435}
1436#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001437
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001438void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001439{
1440 hdd_context_t *pHddCtx = NULL;
1441 hdd_adapter_t *pAdapter = NULL;
1442 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1443 VOS_STATUS status;
1444 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001445
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1447
1448 //Get the global VOSS context.
1449 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1450 if(!pVosContext) {
1451 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1452 return;
1453 }
1454
1455 //Get the HDD context.
1456 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1457
1458 if(!pHddCtx) {
1459 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1460 return;
1461 }
1462
1463 if (pHddCtx->isLogpInProgress) {
1464 hddLog(VOS_TRACE_LEVEL_INFO,
1465 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1466 return;
1467 }
1468
Jeff Johnson295189b2012-06-20 16:38:30 -07001469 pHddCtx->hdd_wlan_suspended = FALSE;
1470 /*loop through all adapters. Concurrency */
1471 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1472
1473 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1474 {
1475 pAdapter = pAdapterNode->pAdapter;
1476 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001477 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001478 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001479 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001480 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1481 pAdapterNode = pNext;
1482 continue;
1483 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301484
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301485
Jeff Johnson295189b2012-06-20 16:38:30 -07001486#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1487 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1488 {
1489 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1490 hdd_exit_deep_sleep(pAdapter);
1491 }
1492#endif
1493
1494 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1495 {
1496 /*Switch back to DTIM 1*/
1497 tSirSetPowerParamsReq powerRequest = { 0 };
1498
1499 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1500 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001501 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001502
1503 /*Disabled ModulatedDTIM if enabled on suspend*/
1504 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1505 powerRequest.uDTIMPeriod = 0;
1506
1507 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1508 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1509 NULL, eANI_BOOLEAN_FALSE);
1510 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1511 NULL, eANI_BOOLEAN_FALSE);
1512
1513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001514 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001515 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001516
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301517 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1518 {
1519 /* put the device into full power */
1520 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001521
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301522 /* put the device back into BMPS */
1523 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001524
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301525 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001527 }
1528
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301529 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001530 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1531 pAdapterNode = pNext;
1532 }
1533
1534#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1535 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1536 {
1537 hdd_exit_standby(pHddCtx);
1538 }
1539#endif
1540
Jeff Johnson295189b2012-06-20 16:38:30 -07001541 return;
1542}
1543
Jeff Johnson295189b2012-06-20 16:38:30 -07001544VOS_STATUS hdd_wlan_reset_initialization(void)
1545{
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 v_CONTEXT_t pVosContext = NULL;
1547
1548 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1549
1550 //Get the global VOSS context.
1551 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1552 if(!pVosContext)
1553 {
1554 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1555 return VOS_STATUS_E_FAILURE;
1556 }
1557
1558 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1559
1560 // Prevent the phone from going to sleep
1561 hdd_prevent_suspend();
1562
Jeff Johnson295189b2012-06-20 16:38:30 -07001563 return VOS_STATUS_SUCCESS;
1564}
1565
1566
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001567/*
1568 * Based on the ioctl command recieved by HDD, put WLAN driver
1569 * into the quiet mode. This is the same as the early suspend
1570 * notification that driver used to listen
1571 */
1572void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001573{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001574 if (suspend)
1575 hdd_suspend_wlan();
1576 else
1577 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001578}
1579
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001580static void hdd_ssr_timer_init(void)
1581{
1582 init_timer(&ssr_timer);
1583}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001584
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001585static void hdd_ssr_timer_del(void)
1586{
1587 del_timer(&ssr_timer);
1588 ssr_timer_started = false;
1589}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001590
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001591static void hdd_ssr_timer_cb(unsigned long data)
1592{
1593 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001594
1595#ifdef WCN_PRONTO
1596 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1597 wcnss_pronto_log_debug_regs();
1598#endif
1599
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001600 VOS_BUG(0);
1601}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001602
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001603static void hdd_ssr_timer_start(int msec)
1604{
1605 if(ssr_timer_started)
1606 {
1607 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1608 ,__func__);
1609 }
1610 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1611 ssr_timer.function = hdd_ssr_timer_cb;
1612 add_timer(&ssr_timer);
1613 ssr_timer_started = true;
1614}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001615
Jeff Johnson295189b2012-06-20 16:38:30 -07001616/* the HDD interface to WLAN driver shutdown,
1617 * the primary shutdown function in SSR
1618 */
1619VOS_STATUS hdd_wlan_shutdown(void)
1620{
1621 VOS_STATUS vosStatus;
1622 v_CONTEXT_t pVosContext = NULL;
1623 hdd_context_t *pHddCtx = NULL;
1624 pVosSchedContext vosSchedContext = NULL;
1625
1626 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1627
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001628 /* if re-init never happens, then do SSR1 */
1629 hdd_ssr_timer_init();
1630 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1631
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 /* Get the global VOSS context. */
1633 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1634 if(!pVosContext) {
1635 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1636 return VOS_STATUS_E_FAILURE;
1637 }
1638 /* Get the HDD context. */
1639 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1640 if(!pHddCtx) {
1641 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1642 return VOS_STATUS_E_FAILURE;
1643 }
c_hpothud662a352013-12-26 15:09:12 +05301644
1645 //Stop the traffic monitor timer
1646 if ( VOS_TIMER_STATE_RUNNING ==
1647 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1648 {
1649 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1650 }
1651
Jeff Johnson295189b2012-06-20 16:38:30 -07001652 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 /* DeRegister with platform driver as client for Suspend/Resume */
1654 vosStatus = hddDeregisterPmOps(pHddCtx);
1655 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1656 {
1657 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1658 }
1659
1660 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1661 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1662 {
1663 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1664 }
1665
1666 /* Disable IMPS/BMPS as we do not want the device to enter any power
1667 * save mode on its own during reset sequence
1668 */
1669 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1670 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1671 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1672
1673 vosSchedContext = get_vos_sched_ctxt();
1674
1675 /* Wakeup all driver threads */
1676 if(TRUE == pHddCtx->isMcThreadSuspended){
1677 complete(&vosSchedContext->ResumeMcEvent);
1678 pHddCtx->isMcThreadSuspended= FALSE;
1679 }
1680 if(TRUE == pHddCtx->isTxThreadSuspended){
1681 complete(&vosSchedContext->ResumeTxEvent);
1682 pHddCtx->isTxThreadSuspended= FALSE;
1683 }
1684 if(TRUE == pHddCtx->isRxThreadSuspended){
1685 complete(&vosSchedContext->ResumeRxEvent);
1686 pHddCtx->isRxThreadSuspended= FALSE;
1687 }
1688 /* Reset the Suspend Variable */
1689 pHddCtx->isWlanSuspended = FALSE;
1690
1691 /* Stop all the threads; we do not want any messages to be a processed,
1692 * any more and the best way to ensure that is to terminate the threads
1693 * gracefully.
1694 */
1695 /* Wait for MC to exit */
1696 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1697 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1698 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1699 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Shete165143a2013-12-19 09:06:13 +05301700 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001701
1702 /* Wait for TX to exit */
1703 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1704 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1705 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1706 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Shete165143a2013-12-19 09:06:13 +05301707 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001708
1709 /* Wait for RX to exit */
1710 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1711 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1712 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1713 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
Mihir Shete165143a2013-12-19 09:06:13 +05301714 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001715
1716#ifdef WLAN_BTAMP_FEATURE
1717 vosStatus = WLANBAP_Stop(pVosContext);
1718 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1719 {
1720 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1721 "%s: Failed to stop BAP",__func__);
1722 }
1723#endif //WLAN_BTAMP_FEATURE
1724 vosStatus = vos_wda_shutdown(pVosContext);
1725 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1726
1727 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1728 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1729 * on threads being running to process the SYS Stop
1730 */
Kiet Lama72a2322013-11-15 11:18:11 +05301731 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
Jeff Johnson295189b2012-06-20 16:38:30 -07001732 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1733
1734 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1735 /* Stop MAC (PE and HAL) */
1736 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
1737 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1738
1739 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1740 /* Stop TL */
1741 vosStatus = WLANTL_Stop(pVosContext);
1742 VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus));
1743
Jeff Johnson295189b2012-06-20 16:38:30 -07001744 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1746 /* Clean up message queues of TX and MC thread */
1747 vos_sched_flush_mc_mqs(vosSchedContext);
1748 vos_sched_flush_tx_mqs(vosSchedContext);
1749 vos_sched_flush_rx_mqs(vosSchedContext);
1750
1751 /* Deinit all the TX and MC queues */
1752 vos_sched_deinit_mqs(vosSchedContext);
1753 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1754
1755 /* shutdown VOSS */
1756 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301757
1758 /*mac context has already been released in mac_close call
1759 so setting it to NULL in hdd context*/
1760 pHddCtx->hHal = (tHalHandle)NULL;
1761
Jeff Johnson295189b2012-06-20 16:38:30 -07001762 if (free_riva_power_on_lock("wlan"))
1763 {
1764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1765 __func__);
1766 }
1767 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1768 ,__func__);
1769 return VOS_STATUS_SUCCESS;
1770}
1771
1772
1773
1774/* the HDD interface to WLAN driver re-init.
1775 * This is called to initialize/start WLAN driver after a shutdown.
1776 */
1777VOS_STATUS hdd_wlan_re_init(void)
1778{
1779 VOS_STATUS vosStatus;
1780 v_CONTEXT_t pVosContext = NULL;
1781 hdd_context_t *pHddCtx = NULL;
1782 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001783#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1784 int max_retries = 0;
1785#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001786#ifdef WLAN_BTAMP_FEATURE
1787 hdd_config_t *pConfig = NULL;
1788 WLANBAP_ConfigType btAmpConfig;
1789#endif
1790
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001791 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001793
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001794#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1795 /* wait until WCNSS driver downloads NV */
1796 while (!wcnss_device_ready() && 5 >= ++max_retries) {
1797 msleep(1000);
1798 }
1799 if (max_retries >= 5) {
1800 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
1801 goto err_re_init;
1802 }
1803#endif
1804
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001805 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
1806
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001807 /* The driver should always be initialized in STA mode after SSR */
1808 hdd_set_conparam(0);
1809
Jeff Johnson295189b2012-06-20 16:38:30 -07001810 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
1811 vosStatus = vos_open(&pVosContext, 0);
1812 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1813 {
1814 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
1815 goto err_re_init;
1816 }
1817
1818 /* Get the HDD context. */
1819 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1820 if(!pHddCtx)
1821 {
1822 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1823 goto err_vosclose;
1824 }
1825
1826 /* Save the hal context in Adapter */
1827 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
1828 if ( NULL == pHddCtx->hHal )
1829 {
1830 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
1831 goto err_vosclose;
1832 }
1833
1834 /* Set the SME configuration parameters. */
1835 vosStatus = hdd_set_sme_config(pHddCtx);
1836 if ( VOS_STATUS_SUCCESS != vosStatus )
1837 {
1838 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
1839 goto err_vosclose;
1840 }
1841
1842 /* Initialize the WMM module */
1843 vosStatus = hdd_wmm_init(pHddCtx);
1844 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
1845 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001846 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001847 goto err_vosclose;
1848 }
1849
1850 vosStatus = vos_preStart( pHddCtx->pvosContext );
1851 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1852 {
1853 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
1854 goto err_vosclose;
1855 }
1856
1857 /* In the integrated architecture we update the configuration from
1858 the INI file and from NV before vOSS has been started so that
1859 the final contents are available to send down to the cCPU */
1860 /* Apply the cfg.ini to cfg.dat */
1861 if (FALSE == hdd_update_config_dat(pHddCtx))
1862 {
1863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
1864 goto err_vosclose;
1865 }
1866
1867 /* Set the MAC Address, currently this is used by HAL to add self sta.
1868 * Remove this once self sta is added as part of session open. */
1869 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
1870 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
1871 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
1872 if (!HAL_STATUS_SUCCESS(halStatus))
1873 {
1874 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
1875 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
1876 goto err_vosclose;
1877 }
1878
1879 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
1880 Note: Firmware image will be read and downloaded inside vos_start API */
1881 vosStatus = vos_start( pVosContext );
1882 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1883 {
1884 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
1885 goto err_vosclose;
1886 }
1887
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07001888 /* Exchange capability info between Host and FW and also get versioning info from FW */
1889 hdd_exchange_version_and_caps(pHddCtx);
1890
Jeff Johnson295189b2012-06-20 16:38:30 -07001891 vosStatus = hdd_post_voss_start_config( pHddCtx );
1892 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1893 {
1894 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
1895 __func__);
1896 goto err_vosstop;
1897 }
1898
1899#ifdef WLAN_BTAMP_FEATURE
1900 vosStatus = WLANBAP_Open(pVosContext);
1901 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1902 {
1903 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1904 "%s: Failed to open BAP",__func__);
1905 goto err_vosstop;
1906 }
1907 vosStatus = BSL_Init(pVosContext);
1908 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1909 {
1910 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1911 "%s: Failed to Init BSL",__func__);
1912 goto err_bap_close;
1913 }
1914 vosStatus = WLANBAP_Start(pVosContext);
1915 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1916 {
1917 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1918 "%s: Failed to start TL",__func__);
1919 goto err_bap_close;
1920 }
1921 pConfig = pHddCtx->cfg_ini;
1922 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
1923 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
1924#endif //WLAN_BTAMP_FEATURE
1925
1926 /* Restart all adapters */
1927 hdd_start_all_adapters(pHddCtx);
1928 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07001929 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001930 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001931 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001932
1933 /* Register with platform driver as client for Suspend/Resume */
1934 vosStatus = hddRegisterPmOps(pHddCtx);
1935 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1936 {
1937 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
1938 goto err_bap_stop;
1939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001940 /* Allow the phone to go to sleep */
1941 hdd_allow_suspend();
1942 /* register for riva power on lock */
1943 if (req_riva_power_on_lock("wlan"))
1944 {
1945 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
1946 __func__);
1947 goto err_unregister_pmops;
1948 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07001949 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001950 goto success;
1951
1952err_unregister_pmops:
1953 hddDeregisterPmOps(pHddCtx);
1954
1955err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07001956#ifdef CONFIG_HAS_EARLYSUSPEND
1957 hdd_unregister_mcast_bcast_filter(pHddCtx);
1958#endif
1959 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001960#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07001961 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001962#endif
1963
1964#ifdef WLAN_BTAMP_FEATURE
1965err_bap_close:
1966 WLANBAP_Close(pVosContext);
1967#endif
1968
1969err_vosstop:
1970 vos_stop(pVosContext);
1971
1972err_vosclose:
1973 vos_close(pVosContext);
1974 vos_sched_close(pVosContext);
1975 if (pHddCtx)
1976 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 /* Unregister the Net Device Notifier */
1978 unregister_netdevice_notifier(&hdd_netdev_notifier);
1979 /* Clean up HDD Nlink Service */
1980 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07001981#ifdef WLAN_KD_READY_NOTIFIER
1982 nl_srv_exit(pHddCtx->ptt_pid);
1983#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001984 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07001985#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07001986 /* Free up dynamically allocated members inside HDD Adapter */
1987 kfree(pHddCtx->cfg_ini);
1988 pHddCtx->cfg_ini= NULL;
1989
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 wiphy_unregister(pHddCtx->wiphy);
1991 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07001992 }
1993 vos_preClose(&pVosContext);
1994
1995#ifdef MEMORY_DEBUG
1996 vos_mem_exit();
1997#endif
1998
1999err_re_init:
2000 /* Allow the phone to go to sleep */
2001 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002002 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002003 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002004 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002005
2006success:
2007 /* Trigger replay of BTC events */
2008 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2009 return VOS_STATUS_SUCCESS;
2010}