blob: f125bf862d97cf8866c95236ee4310a3cb7370f0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -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.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=============================================================================
29* wlan_hdd_early_suspend.c
30*
31* \brief power management functions
32*
33* Description
34* Copyright 2009 (c) Qualcomm, Incorporated.
35* All Rights Reserved.
36* Qualcomm Confidential and Proprietary.
37*
38==============================================================================**/
39/* $HEADER$ */
40
41/**-----------------------------------------------------------------------------
42* Include files
43* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070044
45#include <linux/pm.h>
46#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070047#include <wlan_hdd_includes.h>
48#include <wlan_qct_driver.h>
49#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51#include "halTypes.h"
52#include "sme_Api.h"
53#include <vos_api.h>
54#include "vos_power.h"
55#include <vos_sched.h>
56#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070057#include <wlan_qct_sys.h>
58#include <wlan_btc_svc.h>
59#include <wlan_nlink_common.h>
60#include <wlan_hdd_main.h>
61#include <wlan_hdd_assoc.h>
62#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070063#include <wlan_nlink_srv.h>
64#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070065#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070066
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <linux/semaphore.h>
68#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#include "cfgApi.h"
70
71#ifdef WLAN_BTAMP_FEATURE
72#include "bapApi.h"
73#include "bap_hdd_main.h"
74#include "bap_hdd_misc.h"
75#endif
76
Jeff Johnsone7245742012-09-05 17:12:55 -070077#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070078#include <linux/inetdevice.h>
79#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053080#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053081#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082/**-----------------------------------------------------------------------------
83* Preprocessor definitions and constants
84* ----------------------------------------------------------------------------*/
85
86/**-----------------------------------------------------------------------------
87* Type declarations
88* ----------------------------------------------------------------------------*/
89
90/**-----------------------------------------------------------------------------
91* Function and variables declarations
92* ----------------------------------------------------------------------------*/
93#include "wlan_hdd_power.h"
94#include "wlan_hdd_packet_filtering.h"
95
Sameer Thalappile5637f42013-08-07 15:46:55 -070096#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053097#define NS_DEFAULT_SLOT_INDEX 4
98#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100static eHalStatus g_full_pwr_status;
101static eHalStatus g_standby_status;
102
103extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
104extern VOS_STATUS vos_chipExitDeepSleepVREGHandler(
105 vos_call_status_type* status,
106 vos_power_cb_type callback,
107 v_PVOID_t user_data);
108extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700111extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700113static struct timer_list ssr_timer;
114static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700115
116//Callback invoked by PMC to report status of standby request
117void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
118{
119 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
121 g_standby_status = status;
122
123 if(eHAL_STATUS_SUCCESS == status)
124 {
125 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
126 }
127 else
128 {
129 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
130 }
131
132 complete(&pHddCtx->standby_comp_var);
133}
134
135//Callback invoked by PMC to report status of full power request
136void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
137{
138 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
140 g_full_pwr_status = status;
141
142 if(eHAL_STATUS_SUCCESS == status)
143 {
144 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
145 }
146 else
147 {
148 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
149 }
150
151 complete(&pHddCtx->full_pwr_comp_var);
152}
153
154eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
155{
156 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530157 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
159 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
160 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
161
162 g_full_pwr_status = eHAL_STATUS_FAILURE;
163 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
164 eSME_FULL_PWR_NEEDED_BY_HDD);
165
166 if(status == eHAL_STATUS_PMC_PENDING)
167 {
168 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530169 ret = wait_for_completion_interruptible_timeout(
170 &pHddCtx->full_pwr_comp_var,
171 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
172 if (0 >= ret)
173 {
174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
175 __func__, ret);
176 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700177 status = g_full_pwr_status;
178 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
179 {
180 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
181 VOS_ASSERT(0);
182 goto failure;
183 }
184 }
185 else if(status != eHAL_STATUS_SUCCESS)
186 {
187 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
188 __func__, status);
189 VOS_ASSERT(0);
190 goto failure;
191 }
192 else
193 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
194
195failure:
196 //No blocking to reduce latency. No other device should be depending on WLAN
197 //to finish resume and WLAN won't be instantly on after resume
198 return status;
199}
200
201
202//Helper routine to put the chip into standby
203VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
204{
205 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
206 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530207 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700208
209 //Disable IMPS/BMPS as we do not want the device to enter any power
210 //save mode on its own during suspend sequence
211 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
212 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
213
214 //Note we do not disable queues unnecessarily. Queues should already be disabled
215 //if STA is disconnected or the queue will be disabled as and when disconnect
216 //happens because of standby procedure.
217
218 //Ensure that device is in full power first. There is scope for optimization
219 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
220 //Core s/w needs to be optimized to handle this. Until then we request full
221 //power before issuing request for standby.
222 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
223 g_full_pwr_status = eHAL_STATUS_FAILURE;
224 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
225 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
226
227 if(halStatus == eHAL_STATUS_PMC_PENDING)
228 {
229 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530230 ret = wait_for_completion_interruptible_timeout(
231 &pHddCtx->full_pwr_comp_var,
232 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
233 if (0 >= ret)
234 {
235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
236 __func__, ret);
237 }
238
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
240 {
241 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
242 VOS_ASSERT(0);
243 vosStatus = VOS_STATUS_E_FAILURE;
244 goto failure;
245 }
246 }
247 else if(halStatus != eHAL_STATUS_SUCCESS)
248 {
249 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
250 __func__, halStatus);
251 VOS_ASSERT(0);
252 vosStatus = VOS_STATUS_E_FAILURE;
253 goto failure;
254 }
255
256 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
257 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
258 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
259 }
260
261 //Request standby. Standby will cause the STA to disassociate first. TX queues
262 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
263 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
264 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
265 //when there are concurrent sessions.
266 INIT_COMPLETION(pHddCtx->standby_comp_var);
267 g_standby_status = eHAL_STATUS_FAILURE;
268 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
269
270 if (halStatus == eHAL_STATUS_PMC_PENDING)
271 {
272 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530273 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530275 if (0 >= ret)
276 {
277 hddLog(VOS_TRACE_LEVEL_ERROR,
278 FL("wait on standby_comp_var failed %ld"), ret);
279 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
281 {
282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
283 VOS_ASSERT(0);
284 vosStatus = VOS_STATUS_E_FAILURE;
285 goto failure;
286 }
287 }
288 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
289 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
290 __func__, halStatus);
291 VOS_ASSERT(0);
292 vosStatus = VOS_STATUS_E_FAILURE;
293 goto failure;
294 }
295 else
296 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
297
298failure:
299 //Restore IMPS config
300 if(pHddCtx->cfg_ini->fIsImpsEnabled)
301 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
302
303 //Restore BMPS config
304 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
305 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
306
307 return vosStatus;
308}
309
310
311//Helper routine for Deep sleep entry
312VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
313{
314 eHalStatus halStatus;
315 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
316 vos_call_status_type callType;
c_hpothuffdb5272013-10-02 16:42:35 +0530317 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800318
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 //Stop the Interface TX queue.
320 netif_tx_disable(pAdapter->dev);
321 netif_carrier_off(pAdapter->dev);
322
323 //Disable IMPS,BMPS as we do not want the device to enter any power
324 //save mode on it own during suspend sequence
325 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
326 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
327
328 //Ensure that device is in full power as we will touch H/W during vos_Stop
329 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
330 g_full_pwr_status = eHAL_STATUS_FAILURE;
331 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
332 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
333
334 if(halStatus == eHAL_STATUS_PMC_PENDING)
335 {
336 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530337 ret = wait_for_completion_interruptible_timeout(
338 &pHddCtx->full_pwr_comp_var,
339 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
340 if (0 >= ret)
341 {
342 hddLog(VOS_TRACE_LEVEL_ERROR,
343 FL("wait on full_pwr_comp_var failed %ld"), ret);
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
346 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
347 VOS_ASSERT(0);
348 }
349 }
350 else if(halStatus != eHAL_STATUS_SUCCESS)
351 {
352 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
353 VOS_ASSERT(0);
354 }
355
356 //Issue a disconnect. This is required to inform the supplicant that
357 //STA is getting disassociated and for GUI to be updated properly
358 INIT_COMPLETION(pAdapter->disconnect_comp_var);
359 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
360
361 //Success implies disconnect command got queued up successfully
362 if(halStatus == eHAL_STATUS_SUCCESS)
363 {
364 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530365 ret = wait_for_completion_interruptible_timeout(
366 &pAdapter->disconnect_comp_var,
367 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
368 if (0 >= ret)
369 {
370 hddLog(VOS_TRACE_LEVEL_ERROR,
371 FL("wait on disconnect_comp_var failed %ld"), ret);
372 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 }
374
375
376 //None of the steps should fail after this. Continue even in case of failure
377 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530378 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
379 {
380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
381 __func__, vosStatus);
382 VOS_ASSERT(0);
383 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700384
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 vosStatus = vos_chipAssertDeepSleep( &callType, NULL, NULL );
c_hpothuffdb5272013-10-02 16:42:35 +0530386 if( VOS_IS_STATUS_SUCCESS( vosStatus ))
387 {
388 hddLog(VOS_TRACE_LEVEL_ERROR,
389 FL("vos_chipAssertDeepSleep return failed %d"), vosStatus);
390 VOS_ASSERT(0);
391 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700392
393 //Vote off any PMIC voltage supplies
394 vosStatus = vos_chipPowerDown(NULL, NULL, NULL);
c_hpothuffdb5272013-10-02 16:42:35 +0530395 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
396 {
397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_chipPowerDown return failed %d",
398 __func__, vosStatus);
399 VOS_ASSERT(0);
400 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700401
Jeff Johnson295189b2012-06-20 16:38:30 -0700402 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
403
404 //Restore IMPS config
405 if(pHddCtx->cfg_ini->fIsImpsEnabled)
406 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
407
408 //Restore BMPS config
409 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
410 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
411
Jeff Johnson295189b2012-06-20 16:38:30 -0700412 return vosStatus;
413}
414
415VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
416{
417 VOS_STATUS vosStatus;
418 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700419
420 //Power Up Libra WLAN card first if not already powered up
421 vosStatus = vos_chipPowerUp(NULL,NULL,NULL);
422 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
423 {
c_hpothuffdb5272013-10-02 16:42:35 +0530424 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN not Powered Up."
Jeff Johnson295189b2012-06-20 16:38:30 -0700425 "exiting", __func__);
426 goto err_deep_sleep;
427 }
428
Jeff Johnson295189b2012-06-20 16:38:30 -0700429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
430 "%s: calling hdd_set_sme_config",__func__);
431 vosStatus = hdd_set_sme_config( pHddCtx );
432 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
433 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
434 {
435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
436 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700437 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700438 }
439
440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
441 "%s: calling vos_start",__func__);
442 vosStatus = vos_start( pHddCtx->pvosContext );
443 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
444 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
445 {
446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
447 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700448 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700449 }
450
451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
452 "%s: calling hdd_post_voss_start_config",__func__);
453 vosStatus = hdd_post_voss_start_config( pHddCtx );
454 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
455 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
456 {
457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
458 "%s: Failed in hdd_post_voss_start_config",__func__);
459 goto err_voss_stop;
460 }
461
462
463 //Open a SME session for future operation
464 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700465 (tANI_U8 *)&pAdapter->macAddressCurrent,
466 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700467 if ( !HAL_STATUS_SUCCESS( halStatus ) )
468 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700469 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700470 halStatus, halStatus );
471 goto err_voss_stop;
472
473 }
474
475 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
476
477 //Trigger the initial scan
478 hdd_wlan_initial_scan(pHddCtx);
479
480 return VOS_STATUS_SUCCESS;
481
482err_voss_stop:
483 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700484err_deep_sleep:
485 return VOS_STATUS_E_FAILURE;
486
487}
488
Atul Mittal37385d72014-03-27 18:15:03 +0530489void hdd_ipv6_notifier_work_queue(struct work_struct *work)
490{
491 hdd_adapter_t* pAdapter =
492 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
493 hdd_context_t *pHddCtx;
494 int status;
495
496 hddLog(LOG1, FL("Reconfiguring NS Offload"));
497
498 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
499 status = wlan_hdd_validate_context(pHddCtx);
500 if (0 != status)
501 {
502 hddLog(LOGE, FL("HDD context is invalid"));
503 return;
504 }
505
506 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
507 {
508 pHddCtx->sus_res_mcastbcast_filter =
509 pHddCtx->configuredMcastBcastFilter;
510 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
511 }
512
513 if ((eConnectionState_Associated ==
514 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
515 && (pHddCtx->hdd_wlan_suspended))
516 {
517 // This invocation being part of the IPv6 registration callback,
518 // set the newly generated ip address to f/w in suspend mode.
519#ifdef WLAN_NS_OFFLOAD
520 //Disable NSOFFLOAD
521 if (pHddCtx->cfg_ini->fhostNSOffload)
522 {
523 hdd_conf_ns_offload(pAdapter, 1);
524 }
525#endif
526 }
527#ifdef WLAN_FEATURE_PACKET_FILTERING
528 /* wlan_hdd_set_mc_addr_list() is called from the early susspend
529 * only so when new ipv6 address is generated the screen may not
530 * on so we need to call it here to update the list in f/w.
531 */
532 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
533#endif
534
535}
536
537
538static int wlan_hdd_ipv6_changed(struct notifier_block *nb,
539 unsigned long data, void *arg)
540{
541 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
542 struct net_device *ndev = ifa->idev->dev;
543 hdd_adapter_t *pAdapter =
544 container_of(nb, struct hdd_adapter_s, ipv6_notifier);
545 hdd_context_t *pHddCtx;
546 int status;
547
548 if (pAdapter && pAdapter->dev == ndev)
549 {
550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
551 status = wlan_hdd_validate_context(pHddCtx);
552 if (0 != status)
553 {
554 hddLog(LOGE, FL("HDD context is invalid"));
555 return NOTIFY_DONE;
556 }
557
558 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
559 }
560
561 return NOTIFY_DONE;
562}
563
564void hdd_ipv6_callback_register(hdd_adapter_t *pAdapter, int fenable)
565{
566
567 int ret = 0;
568
569 if (fenable)
570 {
571
572 if(!pAdapter->ipv6_notifier_registered)
573 {
574
575 // Register IPv6 notifier to notify if any change in IP
576 // So that we can reconfigure the offload parameters
577 pAdapter->ipv6_notifier.notifier_call =
578 wlan_hdd_ipv6_changed;
579 ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier);
580 if (ret)
581 {
582 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
583 }
584 else
585 {
586 hddLog(LOG1, FL("Registered IPv6 notifier"));
587 pAdapter->ipv6_notifier_registered = true;
588 }
589 }
590 }
591 else
592 {
593
594 if (pAdapter->ipv6_notifier_registered)
595 {
596 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
597 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
598 pAdapter->ipv6_notifier_registered = false;
599 }
600
601 }
602
603}
604
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530605/*
606 * Function: hdd_conf_hostoffload
607 * Central function to configure the supported offloads,
608 * either enable or disable them.
609 */
610void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
611{
612 hdd_context_t *pHddCtx = NULL;
613 v_CONTEXT_t *pVosContext = NULL;
614 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
615
616 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
617 fenable);
618
619 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
620
621 if (NULL == pVosContext)
622 {
623 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
624 return;
625 }
626
627 //Get the HDD context.
628 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
629
630 if (NULL == pHddCtx)
631 {
632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
633 return;
634 }
635
636 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
637 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
638 {
639 if (fenable)
640 {
641 if (eConnectionState_Associated ==
642 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
643 {
644 if ((pHddCtx->cfg_ini->fhostArpOffload))
645 {
646 /*
647 * Configure the ARP Offload.
648 * Even if it fails we have to reconfigure the MC/BC
649 * filter flag as we want RIVA not to drop BroadCast
650 * Packets
651 */
652 hddLog(VOS_TRACE_LEVEL_INFO,
653 FL("Calling ARP Offload with flag: %d"), fenable);
654 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
655 pHddCtx->configuredMcastBcastFilter &=
656 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
657
658 if (!VOS_IS_STATUS_SUCCESS(vstatus))
659 {
660 hddLog(VOS_TRACE_LEVEL_ERROR,
661 "Failed to enable ARPOFfloadFeature %d",
662 vstatus);
663 }
664 }
665 //Configure GTK_OFFLOAD
666#ifdef WLAN_FEATURE_GTK_OFFLOAD
667 hdd_conf_gtk_offload(pAdapter, fenable);
668#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530669
670#ifdef WLAN_NS_OFFLOAD
671 if (pHddCtx->cfg_ini->fhostNSOffload)
672 {
673 /*
674 * Configure the NS Offload.
675 * Even if it fails we have to reconfigure the MC/BC filter flag
676 * as we want RIVA not to drop Multicast Packets
677 */
678
679 hddLog(VOS_TRACE_LEVEL_INFO,
680 FL("Calling NS Offload with flag: %d"), fenable);
681 hdd_conf_ns_offload(pAdapter, fenable);
682 pHddCtx->configuredMcastBcastFilter &=
683 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
684 }
685#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530686
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530687 }
Atul Mittal37385d72014-03-27 18:15:03 +0530688 hdd_ipv6_callback_register(pAdapter, fenable);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530689 }
690 else
691 {
692 //Disable ARPOFFLOAD
693 if (pHddCtx->cfg_ini->fhostArpOffload)
694 {
695 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
696 if (!VOS_IS_STATUS_SUCCESS(vstatus))
697 {
698 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530699 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530700 }
701 }
702 //Disable GTK_OFFLOAD
703#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530704 hdd_conf_gtk_offload(pAdapter, fenable);
705#endif
706
707#ifdef WLAN_NS_OFFLOAD
708 //Disable NSOFFLOAD
709 if (pHddCtx->cfg_ini->fhostNSOffload)
710 {
711 hdd_conf_ns_offload(pAdapter, fenable);
712 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530713#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530714 hdd_ipv6_callback_register(pAdapter, fenable);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530715 }
716 }
717 return;
718}
719
Atul Mittal37385d72014-03-27 18:15:03 +0530720
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530721#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530722/**----------------------------------------------------------------------------
723
724 \brief hdd_conf_ns_offload() - Configure NS offload
725
726 Called during SUSPEND to configure the NS offload (MC BC filter) which
727 reduces power consumption.
728
729 \param - pAdapter - Adapter context for which NS offload is to be configured
730 \param - fenable - 0 - disable.
731 1 - enable. (with IPv6 notifier registration)
732 2 - enable. (without IPv6 notifier registration)
733
734 \return - void
735
736 ---------------------------------------------------------------------------*/
737void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530738{
739 struct inet6_dev *in6_dev;
740 struct inet6_ifaddr *ifp;
741 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530742 int slot_index = NS_DEFAULT_SLOT_INDEX;
743 tANI_U8 **selfIPv6Addr;
744 tANI_U8 *selfIPv6AddrValid;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530745 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530746 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530747 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530748
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530749 int i = 0, slot = 0;
750 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530751 eHalStatus returnStatus;
752
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530753 ENTER();
754 hddLog(LOG1, FL(" fenable = %d"), fenable);
755
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530756 if (NULL == pAdapter)
757 {
758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
759 return;
760 }
761
762 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530763 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
764
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530765 ret = wlan_hdd_validate_context(pHddCtx);
766
767 if (0 != ret)
768 {
769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
770 FL("HDD context is not valid"));
771 return;
772 }
773
774 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
775 {
776 slot_index = NS_EXTENDED_SLOT_INDEX;
777 }
778
779 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
780
781 selfIPv6AddrValid =
782 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
783
784 if (NULL == selfIPv6AddrValid)
785 {
786 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
787 " selfIPv6AddrValid"));
788 goto end;
789 }
790
791 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
792
793 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
794
795 if (NULL == selfIPv6Addr)
796 {
797 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
798 " selfIPv6Addr"));
799 goto end;
800 }
801
802 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
803
804 for (slot = 0; slot < slot_index; slot++)
805 {
806 selfIPv6Addr[slot] =
807 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
808 if (NULL == selfIPv6Addr[slot])
809 {
810 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
811 "for selfIPv6Addr"));
812 goto end;
813 }
814 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
815 }
816
817 i = 0;
818
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530819 if (fenable)
820 {
821 in6_dev = __in6_dev_get(pAdapter->dev);
822 if (NULL != in6_dev)
823 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530824 list_for_each(p, &in6_dev->addr_list)
825 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530826 if (i >= slot_index)
827 {
828 hddLog (VOS_TRACE_LEVEL_ERROR,
829 FL("IPv6 address list is greater than IPv6"
830 "address supported by firmware"));
831 hddLog (VOS_TRACE_LEVEL_ERROR,
832 FL("FW supported IPv6 address = %d"), slot_index);
833 break;
834 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530835 ifp = list_entry(p, struct inet6_ifaddr, if_list);
836 switch(ipv6_addr_src_scope(&ifp->addr))
837 {
838 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530839 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530840 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530841 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530842 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530843 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
844 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530845 break;
846 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530847 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530848 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530849 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530850 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530851 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
852 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530853 break;
854 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530855 hddLog(VOS_TRACE_LEVEL_ERROR,
856 FL("The Scope %d is not supported"),
857 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530858 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530859 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
860 {
861 i++;
862 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530863 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530864
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530865 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530866 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530867 {
868 if (selfIPv6AddrValid[i])
869 {
870 //Filling up the request structure
871 /* Filling the selfIPv6Addr with solicited address
872 * A Solicited-Node multicast address is created by
873 * taking the last 24 bits of a unicast or anycast
874 * address and appending them to the prefix
875 *
876 * FF02:0000:0000:0000:0000:0001:FFXX:XX
877 *
878 * here XX is the unicast/anycast bits
879 */
880 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
881 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
882 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
883 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530884 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
885 selfIPv6Addr[i][13];
886 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
887 selfIPv6Addr[i][14];
888 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
889 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530890 offLoadRequest.nsOffloadInfo.slotIdx = i;
891
892 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530893 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530894 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
895 &pAdapter->macAddressCurrent.bytes,
896 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
897
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530898 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
899 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530900 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
901 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
902
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530903 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530904 FL("configuredMcastBcastFilter: %d"
905 "NSOffload Slot = %d"),
906 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530907
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530908 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700909 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
910 pHddCtx->sus_res_mcastbcast_filter) ||
911 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
912 pHddCtx->sus_res_mcastbcast_filter)) &&
913 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
914 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
915 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530916 {
917 hddLog (VOS_TRACE_LEVEL_INFO,
Amar Singhald08ce752014-03-21 16:28:27 -0700918 FL("Set offLoadRequest with "
919 "SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE"));
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530920 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700921 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530922 }
923
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530924 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
925 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
926 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
927
928 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530929 FL("Setting NSOffload with solicitedIp: %pI6,"
930 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530931 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
932 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
933
934 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530935 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530936 pAdapter->sessionId, &offLoadRequest);
937 if(eHAL_STATUS_SUCCESS != returnStatus)
938 {
939 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530940 FL("Failed to enable HostOffload feature with"
941 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530942 }
943 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
944 }
945 }
946 }
947 else
948 {
949 hddLog(VOS_TRACE_LEVEL_ERROR,
950 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530951 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530952 }
953 }
954 else
955 {
956 //Disable NSOffload
957 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
958 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
959 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
960
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530961 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530962 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530963 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530964 offLoadRequest.nsOffloadInfo.slotIdx = i;
965 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530966 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
967 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530968 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
970 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530971 }
972 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530973 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530974end:
975 while (slot > 0 && selfIPv6Addr[--slot])
976 {
977 vos_mem_free(selfIPv6Addr[slot]);
978 }
979 if (selfIPv6Addr)
980 {
981 vos_mem_free(selfIPv6Addr);
982 }
983 if (selfIPv6AddrValid)
984 {
985 vos_mem_free(selfIPv6AddrValid);
986 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530987 return;
988}
989#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530990
991void hdd_ipv4_notifier_work_queue(struct work_struct *work)
992{
993 hdd_adapter_t* pAdapter =
994 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
995 hdd_context_t *pHddCtx;
996 int status;
997
998 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1000 status = wlan_hdd_validate_context(pHddCtx);
1001 if (0 != status)
1002 {
1003 hddLog(LOGE, FL("HDD context is invalid"));
1004 return;
1005 }
1006
Deepthi Gowri5933f402014-01-23 17:48:24 +05301007 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1008 {
1009 pHddCtx->sus_res_mcastbcast_filter =
1010 pHddCtx->configuredMcastBcastFilter;
1011 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1012 }
1013
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301014 if ((eConnectionState_Associated ==
1015 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +05301016 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301017 {
1018 // This invocation being part of the IPv4 registration callback,
1019 // we are passing second parameter as 2 to avoid registration
1020 // of IPv4 notifier again.
1021 hdd_conf_arp_offload(pAdapter, 2);
1022 }
1023}
1024
1025static int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1026 unsigned long data, void *arg)
1027{
1028 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1029 struct in_ifaddr **ifap = NULL;
1030 struct in_device *in_dev;
1031
1032 struct net_device *ndev = ifa->ifa_dev->dev;
1033 hdd_adapter_t *pAdapter =
1034 container_of(nb, struct hdd_adapter_s, ipv4_notifier);
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301035 hdd_context_t *pHddCtx;
1036 int status;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301037 if (pAdapter && pAdapter->dev == ndev)
1038 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301039 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1040 status = wlan_hdd_validate_context(pHddCtx);
1041 if (0 != status)
1042 {
1043 hddLog(LOGE, FL("HDD context is invalid"));
1044 return NOTIFY_DONE;
1045 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301046 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1047 {
1048 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1049 ifap = &ifa->ifa_next)
1050 {
1051 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1052 {
1053 break; /* found */
1054 }
1055 }
1056 }
1057 if(ifa && ifa->ifa_local)
1058 {
1059 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
1060 }
1061 }
1062
1063 return NOTIFY_DONE;
1064}
1065
1066/**----------------------------------------------------------------------------
1067
1068 \brief hdd_conf_arp_offload() - Configure ARP offload
1069
1070 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1071 reduces power consumption.
1072
1073 \param - pAdapter -Adapter context for which ARP offload is to be configured
1074 \param - fenable - 0 - disable.
1075 1 - enable. (with IPv4 notifier registration)
1076 2 - enable. (without IPv4 notifier registration)
1077
1078 \return -
1079 VOS_STATUS_SUCCESS - on successful operation
1080 VOS_STATUS_E_FAILURE - on failure of operation
1081-----------------------------------------------------------------------------*/
1082VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001083{
1084 struct in_ifaddr **ifap = NULL;
1085 struct in_ifaddr *ifa = NULL;
1086 struct in_device *in_dev;
1087 int i = 0;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301088 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001089 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001090 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001091
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301092 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001093
Jeff Johnson295189b2012-06-20 16:38:30 -07001094 if(fenable)
1095 {
1096 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1097 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301098 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001099 ifap = &ifa->ifa_next)
1100 {
1101 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1102 {
1103 break; /* found */
1104 }
1105 }
1106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 if(ifa && ifa->ifa_local)
1108 {
1109 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1110 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1111
Arif Hussain6d2a3322013-11-17 19:50:10 -08001112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001113
Amar Singhald53568e2013-09-26 11:03:45 -07001114 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1115 pHddCtx->sus_res_mcastbcast_filter) ||
1116 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1117 pHddCtx->sus_res_mcastbcast_filter)) &&
1118 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001119 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301120 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001121 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1122 hddLog(VOS_TRACE_LEVEL_INFO,
1123 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001124 }
Amar Singhald53568e2013-09-26 11:03:45 -07001125
1126 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1127 offLoadRequest.enableOrDisable);
1128
Jeff Johnson295189b2012-06-20 16:38:30 -07001129 //converting u32 to IPV4 address
1130 for(i = 0 ; i < 4; i++)
1131 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301132 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001133 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1134 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301135 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001136 offLoadRequest.params.hostIpv4Addr[0],
1137 offLoadRequest.params.hostIpv4Addr[1],
1138 offLoadRequest.params.hostIpv4Addr[2],
1139 offLoadRequest.params.hostIpv4Addr[3]);
1140
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301141 if (eHAL_STATUS_SUCCESS !=
1142 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1143 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 {
1145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001146 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001147 return VOS_STATUS_E_FAILURE;
1148 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 }
1150 else
1151 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1153 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001154 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301155
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301156 if (fenable == 1 && !pAdapter->ipv4_notifier_registered)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301157 {
1158 // Register IPv4 notifier to notify if any change in IP
1159 // So that we can reconfigure the offload parameters
1160 pAdapter->ipv4_notifier.notifier_call =
1161 wlan_hdd_ipv4_changed;
1162 ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier);
1163 if (ret)
1164 {
1165 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
1166 }
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301167 else
1168 {
1169 hddLog(LOG1, FL("Registered IPv4 notifier"));
1170 pAdapter->ipv4_notifier_registered = true;
1171 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301172 }
1173 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 }
1175 else
1176 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301177 if (pAdapter->ipv4_notifier_registered)
1178 {
1179 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
1180 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
1181 pAdapter->ipv4_notifier_registered = false;
1182 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001183 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1184 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1185 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1186
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301187 if (eHAL_STATUS_SUCCESS !=
1188 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1189 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 {
1191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001192 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 return VOS_STATUS_E_FAILURE;
1194 }
1195 return VOS_STATUS_SUCCESS;
1196 }
1197}
1198
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301199/*
1200 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301201 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301202*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301203void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301204 tANI_U8 *pMcBcFilter)
1205{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301206 if (NULL == pHddCtx)
1207 {
1208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1209 return;
1210 }
1211
1212 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1213 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301214 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301215 /* ARP offload is enabled, do not block bcast packets at RXP
1216 * Will be using Bitmasking to reset the filter. As we have
1217 * disable Broadcast filtering, Anding with the negation
1218 * of Broadcast BIT
1219 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301220 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301221 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301222
1223#ifdef WLAN_NS_OFFLOAD
1224 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301225 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301226 /* NS offload is enabled, do not block mcast packets at RXP
1227 * Will be using Bitmasking to reset the filter. As we have
1228 * disable Multicast filtering, Anding with the negation
1229 * of Multicast BIT
1230 */
1231 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301232 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301233#endif
1234
Amar Singhald08ce752014-03-21 16:28:27 -07001235 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1236 {
1237 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1238 }
1239
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301240 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301241}
1242
Jeff Johnson295189b2012-06-20 16:38:30 -07001243void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1244{
1245 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001246 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1247 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1248 if(NULL == wlanRxpFilterParam)
1249 {
1250 hddLog(VOS_TRACE_LEVEL_FATAL,
1251 "%s: vos_mem_alloc failed ", __func__);
1252 return;
1253 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001254 hddLog(VOS_TRACE_LEVEL_INFO,
1255 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301256 if (TRUE == setfilter)
1257 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301258 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301259 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301260 }
1261 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301262 {
1263 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301264 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301265 pHddCtx->configuredMcastBcastFilter;
1266 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301267
Jeff Johnson295189b2012-06-20 16:38:30 -07001268 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001269 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -07001270 if (eHAL_STATUS_SUCCESS != halStatus)
1271 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001272 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1273 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1274}
1275
Jeff Johnson295189b2012-06-20 16:38:30 -07001276static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1277 hdd_adapter_t *pAdapter)
1278{
1279 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1280 tpSirWlanSuspendParam wlanSuspendParam =
1281 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1282
Amar Singhald53568e2013-09-26 11:03:45 -07001283 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1284 pHddCtx->sus_res_mcastbcast_filter =
1285 pHddCtx->configuredMcastBcastFilter;
1286 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1287 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1288 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1289 pHddCtx->configuredMcastBcastFilter);
1290
1291 }
1292
Amar Singhal49fdfd52013-08-13 13:25:12 -07001293
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 if(NULL == wlanSuspendParam)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_FATAL,
1297 "%s: vos_mem_alloc failed ", __func__);
1298 return;
1299 }
1300
Amar Singhald53568e2013-09-26 11:03:45 -07001301 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001302 "%s: send wlan suspend indication", __func__);
1303
1304 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1305 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301306 //Configure supported OffLoads
1307 hdd_conf_hostoffload(pAdapter, TRUE);
1308 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001309
1310#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301311 /* During suspend, configure MC Addr list filter to the firmware
1312 * function takes care of checking necessary conditions before
1313 * configuring.
1314 */
1315 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001316#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001317
1318 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1319 {
1320
1321 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1322 pHddCtx->configuredMcastBcastFilter &=
1323 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1324 }
1325
1326 wlanSuspendParam->configuredMcstBcstFilterSetting =
1327 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001328 }
1329
1330 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1331 if(eHAL_STATUS_SUCCESS == halStatus)
1332 {
1333 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001334 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301335 hddLog(VOS_TRACE_LEVEL_ERROR,
1336 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001337 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 }
1339}
1340
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301341static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001342{
Chilam Ngc4244af2013-04-01 15:37:32 -07001343 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001344 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001345 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001346
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301347 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 "%s: send wlan resume indication", __func__);
1349
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301350 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1351
1352 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001353 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301354 hddLog(VOS_TRACE_LEVEL_FATAL,
1355 "%s: memory allocation failed for wlanResumeParam ", __func__);
1356 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001358
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301359 //Disable supported OffLoads
1360 hdd_conf_hostoffload(pAdapter, FALSE);
1361
1362 wlanResumeParam->configuredMcstBcstFilterSetting =
1363 pHddCtx->configuredMcastBcastFilter;
1364 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1365 if (eHAL_STATUS_SUCCESS != halStatus)
1366 {
c_hpothuffdb5272013-10-02 16:42:35 +05301367 hddLog(VOS_TRACE_LEVEL_ERROR,
1368 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301369 vos_mem_free(wlanResumeParam);
1370 }
1371
1372 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1373
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001374 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1375 pHddCtx->configuredMcastBcastFilter =
1376 pHddCtx->sus_res_mcastbcast_filter;
1377 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1378 }
Amar Singhald53568e2013-09-26 11:03:45 -07001379
1380 hddLog(VOS_TRACE_LEVEL_INFO,
1381 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1382 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1383 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001384
Chilam Ngc4244af2013-04-01 15:37:32 -07001385
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301386#ifdef WLAN_FEATURE_PACKET_FILTERING
1387 /* Filer was applied during suspend inditication
1388 * clear it when we resume.
1389 */
1390 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001391#endif
1392}
Jeff Johnson295189b2012-06-20 16:38:30 -07001393
Jeff Johnson295189b2012-06-20 16:38:30 -07001394//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001395void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001396{
1397 hdd_context_t *pHddCtx = NULL;
1398 v_CONTEXT_t pVosContext = NULL;
1399
Jeff Johnson295189b2012-06-20 16:38:30 -07001400 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301401 hdd_adapter_t *pAdapter = NULL;
1402 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301403 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001404
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1406
1407 //Get the global VOSS context.
1408 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1409 if(!pVosContext) {
1410 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1411 return;
1412 }
1413
1414 //Get the HDD context.
1415 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1416
1417 if(!pHddCtx) {
1418 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1419 return;
1420 }
1421
1422 if (pHddCtx->isLogpInProgress) {
1423 hddLog(VOS_TRACE_LEVEL_ERROR,
1424 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1425 return;
1426 }
1427
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301428 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1430 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1431 {
1432 pAdapter = pAdapterNode->pAdapter;
1433 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001434 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1436
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001437 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1439 pAdapterNode = pNext;
1440 continue;
1441 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301442 /* Avoid multiple enter/exit BMPS in this while loop using
1443 * hdd_enter_bmps flag
1444 */
1445 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1446 {
1447 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001448
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301449 /* If device was already in BMPS, and dynamic DTIM is set,
1450 * exit(set the device to full power) and enter BMPS again
1451 * to reflect new DTIM value */
1452 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1453
1454 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1455
1456 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001458#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1459 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1460 {
1461 //stop the interface before putting the chip to standby
1462 netif_tx_disable(pAdapter->dev);
1463 netif_carrier_off(pAdapter->dev);
1464 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301465 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1467 {
1468 //Execute deep sleep procedure
1469 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1470 }
1471#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301472
1473 /*Suspend notification sent down to driver*/
1474 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1475
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301476 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1477 pAdapterNode = pNext;
1478 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301479 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301480
Jeff Johnson295189b2012-06-20 16:38:30 -07001481#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1482 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1483 {
1484 hdd_enter_standby(pHddCtx);
1485 }
1486#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001487
1488 return;
1489}
1490
1491static void hdd_PowerStateChangedCB
1492(
1493 v_PVOID_t callbackContext,
1494 tPmcState newState
1495)
1496{
1497 hdd_context_t *pHddCtx = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001498 /* if the driver was not in BMPS during early suspend,
1499 * the dynamic DTIM is now updated at Riva */
1500 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1501 && pHddCtx->cfg_ini->enableDynamicDTIM
1502 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1503 {
1504 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1505 }
1506 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301507 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1508 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001509 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301510 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1511 {
Amar Singhald53568e2013-09-26 11:03:45 -07001512 pHddCtx->sus_res_mcastbcast_filter =
1513 pHddCtx->configuredMcastBcastFilter;
1514 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1515
1516 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1517 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1518 pHddCtx->configuredMcastBcastFilter);
1519 hddLog(VOS_TRACE_LEVEL_INFO,
1520 "offload: calling hdd_conf_mcastbcast_filter");
1521
1522 }
1523
Jeff Johnson295189b2012-06-20 16:38:30 -07001524 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1526 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
1527 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001528 else
Mihir Shete793209f2014-01-06 11:01:12 +05301529 {
1530 /* Android framework can send resume request when the WCN chip is
1531 * in IMPS mode. When the chip exits IMPS mode the firmware will
1532 * restore all the registers to the state they were before the chip
1533 * entered IMPS and so our hardware filter settings confgured by the
1534 * resume request will be lost. So reconfigure the filters on detecting
1535 * a change in the power state of the WCN chip.
1536 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301537 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301538 if (IMPS != newState)
1539 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301540 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301541 if (FALSE == pHddCtx->hdd_wlan_suspended)
1542 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301543 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301544 hddLog(VOS_TRACE_LEVEL_INFO,
1545 "Not in IMPS/BMPS and suspended state");
1546 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1547 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301548 else
1549 {
1550 spin_unlock(&pHddCtx->filter_lock);
1551 }
Mihir Shete793209f2014-01-06 11:01:12 +05301552 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301553 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001554}
1555
1556
1557
1558void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1559{
1560 v_CONTEXT_t pVosContext;
1561 tHalHandle smeContext;
1562
1563 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1564 if (NULL == pVosContext)
1565 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001566 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001567 return;
1568 }
1569 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1570 if (NULL == smeContext)
1571 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001572 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001573 return;
1574 }
1575
1576 spin_lock_init(&pHddCtx->filter_lock);
1577 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1578 pHddCtx->cfg_ini->nEnableSuspend)
1579 {
1580 pmcRegisterDeviceStateUpdateInd(smeContext,
1581 hdd_PowerStateChangedCB, pHddCtx);
1582 }
1583}
1584
1585void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1586{
1587 v_CONTEXT_t pVosContext;
1588 tHalHandle smeContext;
1589
1590 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1591 if (NULL == pVosContext)
1592 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001593 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001594 return;
1595 }
1596 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1597 if (NULL == smeContext)
1598 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001599 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001600 return;
1601 }
1602
1603 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1604 pHddCtx->cfg_ini->nEnableSuspend)
1605 {
1606 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1607 }
1608}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301609
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301610#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301611void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301612{
1613 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301614 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301615 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1616
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301617 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301618 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301619 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1620 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1621 {
1622 vos_mem_copy(&hddGtkOffloadReqParams,
1623 &pHddStaCtx->gtkOffloadReqParams,
1624 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301625
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301626 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1627 &hddGtkOffloadReqParams, pAdapter->sessionId);
1628 if (eHAL_STATUS_SUCCESS != ret)
1629 {
1630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1631 "%s: sme_SetGTKOffload failed, returned %d",
1632 __func__, ret);
1633 return;
1634 }
1635
1636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1637 "%s: sme_SetGTKOffload successfull", __func__);
1638 }
1639
1640 }
1641 else
1642 {
1643 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1644 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1645 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1646 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1647 {
1648
1649 /* Host driver has previously offloaded GTK rekey */
1650 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301651 wlan_hdd_cfg80211_update_replayCounterCallback,
1652 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301653 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301654
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301655 {
1656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: sme_GetGTKOffload failed, returned %d",
1658 __func__, ret);
1659 return;
1660 }
1661 else
1662 {
1663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1664 "%s: sme_GetGTKOffload successful",
1665 __func__);
1666
1667 /* Sending GTK offload dissable */
1668 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1669 sizeof (tSirGtkOffloadParams));
1670 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1671 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301672 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301673 if (eHAL_STATUS_SUCCESS != ret)
1674 {
1675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1676 "%s: failed to dissable GTK offload, returned %d",
1677 __func__, ret);
1678 return;
1679 }
1680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1681 "%s: successfully dissabled GTK offload request to HAL",
1682 __func__);
1683 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301684 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301685 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301686 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301687}
1688#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001689
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001690void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001691{
1692 hdd_context_t *pHddCtx = NULL;
1693 hdd_adapter_t *pAdapter = NULL;
1694 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1695 VOS_STATUS status;
1696 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001697
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1699
1700 //Get the global VOSS context.
1701 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1702 if(!pVosContext) {
1703 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1704 return;
1705 }
1706
1707 //Get the HDD context.
1708 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1709
1710 if(!pHddCtx) {
1711 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1712 return;
1713 }
1714
Agarwal Ashish971c2882013-10-30 20:11:12 +05301715 if (pHddCtx->isLogpInProgress)
1716 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001717 hddLog(VOS_TRACE_LEVEL_INFO,
1718 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1719 return;
1720 }
1721
Jeff Johnson295189b2012-06-20 16:38:30 -07001722 pHddCtx->hdd_wlan_suspended = FALSE;
1723 /*loop through all adapters. Concurrency */
1724 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1725
1726 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1727 {
1728 pAdapter = pAdapterNode->pAdapter;
1729 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001730 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001732 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001733 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1734 pAdapterNode = pNext;
1735 continue;
1736 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301737
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301738
Jeff Johnson295189b2012-06-20 16:38:30 -07001739#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1740 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1741 {
1742 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1743 hdd_exit_deep_sleep(pAdapter);
1744 }
1745#endif
1746
1747 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1748 {
1749 /*Switch back to DTIM 1*/
1750 tSirSetPowerParamsReq powerRequest = { 0 };
1751
1752 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1753 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001754 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001755
1756 /*Disabled ModulatedDTIM if enabled on suspend*/
1757 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1758 powerRequest.uDTIMPeriod = 0;
1759
1760 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1761 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1762 NULL, eANI_BOOLEAN_FALSE);
1763 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1764 NULL, eANI_BOOLEAN_FALSE);
1765
1766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001767 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001768 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001769
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301770 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1771 {
1772 /* put the device into full power */
1773 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001774
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301775 /* put the device back into BMPS */
1776 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001777
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301778 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1779 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001780 }
1781
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301782 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1784 pAdapterNode = pNext;
1785 }
1786
1787#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1788 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1789 {
1790 hdd_exit_standby(pHddCtx);
1791 }
1792#endif
1793
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 return;
1795}
1796
Jeff Johnson295189b2012-06-20 16:38:30 -07001797VOS_STATUS hdd_wlan_reset_initialization(void)
1798{
Jeff Johnson295189b2012-06-20 16:38:30 -07001799 v_CONTEXT_t pVosContext = NULL;
1800
1801 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1802
1803 //Get the global VOSS context.
1804 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1805 if(!pVosContext)
1806 {
1807 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1808 return VOS_STATUS_E_FAILURE;
1809 }
1810
1811 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1812
1813 // Prevent the phone from going to sleep
1814 hdd_prevent_suspend();
1815
Jeff Johnson295189b2012-06-20 16:38:30 -07001816 return VOS_STATUS_SUCCESS;
1817}
1818
1819
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001820/*
1821 * Based on the ioctl command recieved by HDD, put WLAN driver
1822 * into the quiet mode. This is the same as the early suspend
1823 * notification that driver used to listen
1824 */
1825void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001826{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001827 if (suspend)
1828 hdd_suspend_wlan();
1829 else
1830 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001831}
1832
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001833static void hdd_ssr_timer_init(void)
1834{
1835 init_timer(&ssr_timer);
1836}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001837
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001838static void hdd_ssr_timer_del(void)
1839{
1840 del_timer(&ssr_timer);
1841 ssr_timer_started = false;
1842}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001843
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001844static void hdd_ssr_timer_cb(unsigned long data)
1845{
1846 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001847
1848#ifdef WCN_PRONTO
1849 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1850 wcnss_pronto_log_debug_regs();
1851#endif
1852
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001853 VOS_BUG(0);
1854}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001855
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001856static void hdd_ssr_timer_start(int msec)
1857{
1858 if(ssr_timer_started)
1859 {
1860 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1861 ,__func__);
1862 }
1863 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1864 ssr_timer.function = hdd_ssr_timer_cb;
1865 add_timer(&ssr_timer);
1866 ssr_timer_started = true;
1867}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001868
Jeff Johnson295189b2012-06-20 16:38:30 -07001869/* the HDD interface to WLAN driver shutdown,
1870 * the primary shutdown function in SSR
1871 */
1872VOS_STATUS hdd_wlan_shutdown(void)
1873{
1874 VOS_STATUS vosStatus;
1875 v_CONTEXT_t pVosContext = NULL;
1876 hdd_context_t *pHddCtx = NULL;
1877 pVosSchedContext vosSchedContext = NULL;
c_hpothuffdb5272013-10-02 16:42:35 +05301878 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001879
1880 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1881
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001882 /* if re-init never happens, then do SSR1 */
1883 hdd_ssr_timer_init();
1884 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1885
Jeff Johnson295189b2012-06-20 16:38:30 -07001886 /* Get the global VOSS context. */
1887 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1888 if(!pVosContext) {
1889 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1890 return VOS_STATUS_E_FAILURE;
1891 }
1892 /* Get the HDD context. */
1893 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1894 if(!pHddCtx) {
1895 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1896 return VOS_STATUS_E_FAILURE;
1897 }
c_hpothud662a352013-12-26 15:09:12 +05301898
1899 //Stop the traffic monitor timer
1900 if ( VOS_TIMER_STATE_RUNNING ==
1901 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1902 {
1903 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1904 }
1905
Jeff Johnson295189b2012-06-20 16:38:30 -07001906 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 /* DeRegister with platform driver as client for Suspend/Resume */
1908 vosStatus = hddDeregisterPmOps(pHddCtx);
1909 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1910 {
1911 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1912 }
1913
1914 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1915 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1916 {
1917 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1918 }
1919
1920 /* Disable IMPS/BMPS as we do not want the device to enter any power
1921 * save mode on its own during reset sequence
1922 */
1923 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1924 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1925 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1926
1927 vosSchedContext = get_vos_sched_ctxt();
1928
1929 /* Wakeup all driver threads */
1930 if(TRUE == pHddCtx->isMcThreadSuspended){
1931 complete(&vosSchedContext->ResumeMcEvent);
1932 pHddCtx->isMcThreadSuspended= FALSE;
1933 }
1934 if(TRUE == pHddCtx->isTxThreadSuspended){
1935 complete(&vosSchedContext->ResumeTxEvent);
1936 pHddCtx->isTxThreadSuspended= FALSE;
1937 }
1938 if(TRUE == pHddCtx->isRxThreadSuspended){
1939 complete(&vosSchedContext->ResumeRxEvent);
1940 pHddCtx->isRxThreadSuspended= FALSE;
1941 }
1942 /* Reset the Suspend Variable */
1943 pHddCtx->isWlanSuspended = FALSE;
1944
1945 /* Stop all the threads; we do not want any messages to be a processed,
1946 * any more and the best way to ensure that is to terminate the threads
1947 * gracefully.
1948 */
1949 /* Wait for MC to exit */
1950 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1951 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1952 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1953 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301954 ret = wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1955 if (0 >= ret)
1956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on McShutdown failed %ld",
1958 __func__, ret);
1959 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001960
1961 /* Wait for TX to exit */
1962 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1963 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1964 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1965 wake_up_interruptible(&vosSchedContext->txWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301966 ret = wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1967 if (0 >= ret)
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on TxShutdown failed %ld",
1970 __func__, ret);
1971 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001972
1973 /* Wait for RX to exit */
1974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1975 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1976 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1977 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301978
1979 ret = wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1980 if (0 >= ret)
1981 {
1982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on RxShutdown failed %ld",
1983 __func__, ret);
1984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001985
1986#ifdef WLAN_BTAMP_FEATURE
1987 vosStatus = WLANBAP_Stop(pVosContext);
1988 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1989 {
1990 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1991 "%s: Failed to stop BAP",__func__);
1992 }
1993#endif //WLAN_BTAMP_FEATURE
1994 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301995 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1996 {
1997 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1998 "%s: Failed to stop wda %d", __func__, vosStatus);
1999 VOS_ASSERT(0);
2000 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002001
2002 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2003 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2004 * on threads being running to process the SYS Stop
2005 */
Kiet Lama72a2322013-11-15 11:18:11 +05302006 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302007 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2008 {
2009 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2010 "%s: Failed to stop sme %d", __func__, vosStatus);
2011 VOS_ASSERT(0);
2012 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002013
2014 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2015 /* Stop MAC (PE and HAL) */
2016 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302017 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2018 {
2019 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2020 "%s: Failed to stop mac %d", __func__, vosStatus);
2021 VOS_ASSERT(0);
2022 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002023
2024 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2025 /* Stop TL */
2026 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302027 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2028 {
2029 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2030 "%s: Failed to stop TL %d", __func__, vosStatus);
2031 VOS_ASSERT(0);
2032 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002033
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2036 /* Clean up message queues of TX and MC thread */
2037 vos_sched_flush_mc_mqs(vosSchedContext);
2038 vos_sched_flush_tx_mqs(vosSchedContext);
2039 vos_sched_flush_rx_mqs(vosSchedContext);
2040
2041 /* Deinit all the TX and MC queues */
2042 vos_sched_deinit_mqs(vosSchedContext);
2043 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2044
2045 /* shutdown VOSS */
2046 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302047
2048 /*mac context has already been released in mac_close call
2049 so setting it to NULL in hdd context*/
2050 pHddCtx->hHal = (tHalHandle)NULL;
2051
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 if (free_riva_power_on_lock("wlan"))
2053 {
2054 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2055 __func__);
2056 }
2057 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2058 ,__func__);
2059 return VOS_STATUS_SUCCESS;
2060}
2061
2062
2063
2064/* the HDD interface to WLAN driver re-init.
2065 * This is called to initialize/start WLAN driver after a shutdown.
2066 */
2067VOS_STATUS hdd_wlan_re_init(void)
2068{
2069 VOS_STATUS vosStatus;
2070 v_CONTEXT_t pVosContext = NULL;
2071 hdd_context_t *pHddCtx = NULL;
2072 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002073#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2074 int max_retries = 0;
2075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002076#ifdef WLAN_BTAMP_FEATURE
2077 hdd_config_t *pConfig = NULL;
2078 WLANBAP_ConfigType btAmpConfig;
2079#endif
2080
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002081 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002083
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002084#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2085 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002086 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002087 msleep(1000);
2088 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002089 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002090 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2091 goto err_re_init;
2092 }
2093#endif
2094
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002095 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2096
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002097 /* The driver should always be initialized in STA mode after SSR */
2098 hdd_set_conparam(0);
2099
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
2101 vosStatus = vos_open(&pVosContext, 0);
2102 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2103 {
2104 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2105 goto err_re_init;
2106 }
2107
2108 /* Get the HDD context. */
2109 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2110 if(!pHddCtx)
2111 {
2112 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2113 goto err_vosclose;
2114 }
2115
2116 /* Save the hal context in Adapter */
2117 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2118 if ( NULL == pHddCtx->hHal )
2119 {
2120 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2121 goto err_vosclose;
2122 }
2123
2124 /* Set the SME configuration parameters. */
2125 vosStatus = hdd_set_sme_config(pHddCtx);
2126 if ( VOS_STATUS_SUCCESS != vosStatus )
2127 {
2128 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2129 goto err_vosclose;
2130 }
2131
2132 /* Initialize the WMM module */
2133 vosStatus = hdd_wmm_init(pHddCtx);
2134 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
2135 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002136 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002137 goto err_vosclose;
2138 }
2139
2140 vosStatus = vos_preStart( pHddCtx->pvosContext );
2141 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2142 {
2143 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2144 goto err_vosclose;
2145 }
2146
2147 /* In the integrated architecture we update the configuration from
2148 the INI file and from NV before vOSS has been started so that
2149 the final contents are available to send down to the cCPU */
2150 /* Apply the cfg.ini to cfg.dat */
2151 if (FALSE == hdd_update_config_dat(pHddCtx))
2152 {
2153 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2154 goto err_vosclose;
2155 }
2156
2157 /* Set the MAC Address, currently this is used by HAL to add self sta.
2158 * Remove this once self sta is added as part of session open. */
2159 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2160 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2161 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2162 if (!HAL_STATUS_SUCCESS(halStatus))
2163 {
2164 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2165 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2166 goto err_vosclose;
2167 }
2168
2169 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2170 Note: Firmware image will be read and downloaded inside vos_start API */
2171 vosStatus = vos_start( pVosContext );
2172 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2173 {
2174 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2175 goto err_vosclose;
2176 }
2177
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002178 /* Exchange capability info between Host and FW and also get versioning info from FW */
2179 hdd_exchange_version_and_caps(pHddCtx);
2180
Jeff Johnson295189b2012-06-20 16:38:30 -07002181 vosStatus = hdd_post_voss_start_config( pHddCtx );
2182 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2183 {
2184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2185 __func__);
2186 goto err_vosstop;
2187 }
2188
2189#ifdef WLAN_BTAMP_FEATURE
2190 vosStatus = WLANBAP_Open(pVosContext);
2191 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2192 {
2193 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2194 "%s: Failed to open BAP",__func__);
2195 goto err_vosstop;
2196 }
2197 vosStatus = BSL_Init(pVosContext);
2198 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2199 {
2200 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2201 "%s: Failed to Init BSL",__func__);
2202 goto err_bap_close;
2203 }
2204 vosStatus = WLANBAP_Start(pVosContext);
2205 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2206 {
2207 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2208 "%s: Failed to start TL",__func__);
2209 goto err_bap_close;
2210 }
2211 pConfig = pHddCtx->cfg_ini;
2212 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2213 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2214#endif //WLAN_BTAMP_FEATURE
2215
2216 /* Restart all adapters */
2217 hdd_start_all_adapters(pHddCtx);
2218 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002219 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002221 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002222
2223 /* Register with platform driver as client for Suspend/Resume */
2224 vosStatus = hddRegisterPmOps(pHddCtx);
2225 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2226 {
2227 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2228 goto err_bap_stop;
2229 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002230 /* Allow the phone to go to sleep */
2231 hdd_allow_suspend();
2232 /* register for riva power on lock */
2233 if (req_riva_power_on_lock("wlan"))
2234 {
2235 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2236 __func__);
2237 goto err_unregister_pmops;
2238 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002239 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002240 goto success;
2241
2242err_unregister_pmops:
2243 hddDeregisterPmOps(pHddCtx);
2244
2245err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002246#ifdef CONFIG_HAS_EARLYSUSPEND
2247 hdd_unregister_mcast_bcast_filter(pHddCtx);
2248#endif
2249 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002250#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002251 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252#endif
2253
2254#ifdef WLAN_BTAMP_FEATURE
2255err_bap_close:
2256 WLANBAP_Close(pVosContext);
2257#endif
2258
2259err_vosstop:
2260 vos_stop(pVosContext);
2261
2262err_vosclose:
2263 vos_close(pVosContext);
2264 vos_sched_close(pVosContext);
2265 if (pHddCtx)
2266 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 /* Unregister the Net Device Notifier */
2268 unregister_netdevice_notifier(&hdd_netdev_notifier);
2269 /* Clean up HDD Nlink Service */
2270 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002271#ifdef WLAN_KD_READY_NOTIFIER
2272 nl_srv_exit(pHddCtx->ptt_pid);
2273#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002275#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002276 /* Free up dynamically allocated members inside HDD Adapter */
2277 kfree(pHddCtx->cfg_ini);
2278 pHddCtx->cfg_ini= NULL;
2279
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 wiphy_unregister(pHddCtx->wiphy);
2281 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 }
2283 vos_preClose(&pVosContext);
2284
2285#ifdef MEMORY_DEBUG
2286 vos_mem_exit();
2287#endif
2288
2289err_re_init:
2290 /* Allow the phone to go to sleep */
2291 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002292 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002293 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002294 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002295
2296success:
2297 /* Trigger replay of BTC events */
2298 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2299 return VOS_STATUS_SUCCESS;
2300}