blob: 9c5590afd13b435ceaceda3583137713329934a3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharmabb94ece2014-04-04 21:22:15 +05302 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301498
Jeff Johnson295189b2012-06-20 16:38:30 -07001499 /* if the driver was not in BMPS during early suspend,
1500 * the dynamic DTIM is now updated at Riva */
1501 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1502 && pHddCtx->cfg_ini->enableDynamicDTIM
1503 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1504 {
1505 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1506 }
1507 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301508 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1509 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001510 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301511 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1512 {
Amar Singhald53568e2013-09-26 11:03:45 -07001513 pHddCtx->sus_res_mcastbcast_filter =
1514 pHddCtx->configuredMcastBcastFilter;
1515 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1516
1517 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1518 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1519 pHddCtx->configuredMcastBcastFilter);
1520 hddLog(VOS_TRACE_LEVEL_INFO,
1521 "offload: calling hdd_conf_mcastbcast_filter");
1522
1523 }
1524
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001526 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301528 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001529 else
Mihir Shete793209f2014-01-06 11:01:12 +05301530 {
1531 /* Android framework can send resume request when the WCN chip is
1532 * in IMPS mode. When the chip exits IMPS mode the firmware will
1533 * restore all the registers to the state they were before the chip
1534 * entered IMPS and so our hardware filter settings confgured by the
1535 * resume request will be lost. So reconfigure the filters on detecting
1536 * a change in the power state of the WCN chip.
1537 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301538 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301539 if (IMPS != newState)
1540 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301541 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301542 if (FALSE == pHddCtx->hdd_wlan_suspended)
1543 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301544 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301545 hddLog(VOS_TRACE_LEVEL_INFO,
1546 "Not in IMPS/BMPS and suspended state");
1547 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1548 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301549 else
1550 {
1551 spin_unlock(&pHddCtx->filter_lock);
1552 }
Mihir Shete793209f2014-01-06 11:01:12 +05301553 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001555}
1556
Jeff Johnson295189b2012-06-20 16:38:30 -07001557void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1558{
1559 v_CONTEXT_t pVosContext;
1560 tHalHandle smeContext;
1561
1562 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1563 if (NULL == pVosContext)
1564 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001565 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001566 return;
1567 }
1568 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1569 if (NULL == smeContext)
1570 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001571 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 return;
1573 }
1574
1575 spin_lock_init(&pHddCtx->filter_lock);
1576 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1577 pHddCtx->cfg_ini->nEnableSuspend)
1578 {
1579 pmcRegisterDeviceStateUpdateInd(smeContext,
1580 hdd_PowerStateChangedCB, pHddCtx);
1581 }
1582}
1583
1584void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1585{
1586 v_CONTEXT_t pVosContext;
1587 tHalHandle smeContext;
1588
1589 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1590 if (NULL == pVosContext)
1591 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001592 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001593 return;
1594 }
1595 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1596 if (NULL == smeContext)
1597 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001598 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 return;
1600 }
1601
1602 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1603 pHddCtx->cfg_ini->nEnableSuspend)
1604 {
1605 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1606 }
1607}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301608
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301609#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301610void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301611{
1612 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301613 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301614 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1615
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301616 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301617 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301618 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1619 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1620 {
1621 vos_mem_copy(&hddGtkOffloadReqParams,
1622 &pHddStaCtx->gtkOffloadReqParams,
1623 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301624
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301625 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1626 &hddGtkOffloadReqParams, pAdapter->sessionId);
1627 if (eHAL_STATUS_SUCCESS != ret)
1628 {
1629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1630 "%s: sme_SetGTKOffload failed, returned %d",
1631 __func__, ret);
1632 return;
1633 }
1634
1635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1636 "%s: sme_SetGTKOffload successfull", __func__);
1637 }
1638
1639 }
1640 else
1641 {
1642 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1643 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1644 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1645 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1646 {
1647
1648 /* Host driver has previously offloaded GTK rekey */
1649 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301650 wlan_hdd_cfg80211_update_replayCounterCallback,
1651 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301652 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301653
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301654 {
1655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1656 "%s: sme_GetGTKOffload failed, returned %d",
1657 __func__, ret);
1658 return;
1659 }
1660 else
1661 {
1662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1663 "%s: sme_GetGTKOffload successful",
1664 __func__);
1665
1666 /* Sending GTK offload dissable */
1667 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1668 sizeof (tSirGtkOffloadParams));
1669 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1670 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301671 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301672 if (eHAL_STATUS_SUCCESS != ret)
1673 {
1674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1675 "%s: failed to dissable GTK offload, returned %d",
1676 __func__, ret);
1677 return;
1678 }
1679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1680 "%s: successfully dissabled GTK offload request to HAL",
1681 __func__);
1682 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301683 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301684 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301685 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301686}
1687#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001688
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001689void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001690{
1691 hdd_context_t *pHddCtx = NULL;
1692 hdd_adapter_t *pAdapter = NULL;
1693 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1694 VOS_STATUS status;
1695 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001696
Jeff Johnson295189b2012-06-20 16:38:30 -07001697 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1698
1699 //Get the global VOSS context.
1700 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1701 if(!pVosContext) {
1702 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1703 return;
1704 }
1705
1706 //Get the HDD context.
1707 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1708
1709 if(!pHddCtx) {
1710 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1711 return;
1712 }
1713
Agarwal Ashish971c2882013-10-30 20:11:12 +05301714 if (pHddCtx->isLogpInProgress)
1715 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 hddLog(VOS_TRACE_LEVEL_INFO,
1717 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1718 return;
1719 }
1720
Jeff Johnson295189b2012-06-20 16:38:30 -07001721 pHddCtx->hdd_wlan_suspended = FALSE;
1722 /*loop through all adapters. Concurrency */
1723 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1724
1725 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1726 {
1727 pAdapter = pAdapterNode->pAdapter;
1728 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001729 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001730 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001731 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001732 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1733 pAdapterNode = pNext;
1734 continue;
1735 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301736
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301737
Jeff Johnson295189b2012-06-20 16:38:30 -07001738#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1739 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1740 {
1741 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1742 hdd_exit_deep_sleep(pAdapter);
1743 }
1744#endif
1745
1746 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1747 {
1748 /*Switch back to DTIM 1*/
1749 tSirSetPowerParamsReq powerRequest = { 0 };
1750
1751 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1752 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001753 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001754
1755 /*Disabled ModulatedDTIM if enabled on suspend*/
1756 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1757 powerRequest.uDTIMPeriod = 0;
1758
1759 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1760 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1761 NULL, eANI_BOOLEAN_FALSE);
1762 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1763 NULL, eANI_BOOLEAN_FALSE);
1764
1765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001766 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001767 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001768
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301769 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1770 {
1771 /* put the device into full power */
1772 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001773
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301774 /* put the device back into BMPS */
1775 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001776
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301777 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1778 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 }
1780
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301781 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1783 pAdapterNode = pNext;
1784 }
1785
1786#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1787 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1788 {
1789 hdd_exit_standby(pHddCtx);
1790 }
1791#endif
1792
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 return;
1794}
1795
Jeff Johnson295189b2012-06-20 16:38:30 -07001796VOS_STATUS hdd_wlan_reset_initialization(void)
1797{
Jeff Johnson295189b2012-06-20 16:38:30 -07001798 v_CONTEXT_t pVosContext = NULL;
1799
1800 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1801
1802 //Get the global VOSS context.
1803 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1804 if(!pVosContext)
1805 {
1806 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1807 return VOS_STATUS_E_FAILURE;
1808 }
1809
1810 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1811
1812 // Prevent the phone from going to sleep
1813 hdd_prevent_suspend();
1814
Jeff Johnson295189b2012-06-20 16:38:30 -07001815 return VOS_STATUS_SUCCESS;
1816}
1817
1818
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001819/*
1820 * Based on the ioctl command recieved by HDD, put WLAN driver
1821 * into the quiet mode. This is the same as the early suspend
1822 * notification that driver used to listen
1823 */
1824void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001825{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001826 if (suspend)
1827 hdd_suspend_wlan();
1828 else
1829 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001830}
1831
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001832static void hdd_ssr_timer_init(void)
1833{
1834 init_timer(&ssr_timer);
1835}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001836
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001837static void hdd_ssr_timer_del(void)
1838{
1839 del_timer(&ssr_timer);
1840 ssr_timer_started = false;
1841}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001842
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001843static void hdd_ssr_timer_cb(unsigned long data)
1844{
1845 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001846
1847#ifdef WCN_PRONTO
1848 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1849 wcnss_pronto_log_debug_regs();
1850#endif
1851
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001852 VOS_BUG(0);
1853}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001854
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001855static void hdd_ssr_timer_start(int msec)
1856{
1857 if(ssr_timer_started)
1858 {
1859 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1860 ,__func__);
1861 }
1862 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1863 ssr_timer.function = hdd_ssr_timer_cb;
1864 add_timer(&ssr_timer);
1865 ssr_timer_started = true;
1866}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001867
Jeff Johnson295189b2012-06-20 16:38:30 -07001868/* the HDD interface to WLAN driver shutdown,
1869 * the primary shutdown function in SSR
1870 */
1871VOS_STATUS hdd_wlan_shutdown(void)
1872{
1873 VOS_STATUS vosStatus;
1874 v_CONTEXT_t pVosContext = NULL;
1875 hdd_context_t *pHddCtx = NULL;
1876 pVosSchedContext vosSchedContext = NULL;
c_hpothuffdb5272013-10-02 16:42:35 +05301877 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001878
1879 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1880
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001881 /* if re-init never happens, then do SSR1 */
1882 hdd_ssr_timer_init();
1883 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1884
Jeff Johnson295189b2012-06-20 16:38:30 -07001885 /* Get the global VOSS context. */
1886 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1887 if(!pVosContext) {
1888 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1889 return VOS_STATUS_E_FAILURE;
1890 }
1891 /* Get the HDD context. */
1892 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1893 if(!pHddCtx) {
1894 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1895 return VOS_STATUS_E_FAILURE;
1896 }
c_hpothud662a352013-12-26 15:09:12 +05301897
1898 //Stop the traffic monitor timer
1899 if ( VOS_TIMER_STATE_RUNNING ==
1900 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1901 {
1902 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1903 }
1904
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001906 /* DeRegister with platform driver as client for Suspend/Resume */
1907 vosStatus = hddDeregisterPmOps(pHddCtx);
1908 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1909 {
1910 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1911 }
1912
1913 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1914 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1915 {
1916 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1917 }
1918
1919 /* Disable IMPS/BMPS as we do not want the device to enter any power
1920 * save mode on its own during reset sequence
1921 */
1922 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1923 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1924 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1925
1926 vosSchedContext = get_vos_sched_ctxt();
1927
1928 /* Wakeup all driver threads */
1929 if(TRUE == pHddCtx->isMcThreadSuspended){
1930 complete(&vosSchedContext->ResumeMcEvent);
1931 pHddCtx->isMcThreadSuspended= FALSE;
1932 }
1933 if(TRUE == pHddCtx->isTxThreadSuspended){
1934 complete(&vosSchedContext->ResumeTxEvent);
1935 pHddCtx->isTxThreadSuspended= FALSE;
1936 }
1937 if(TRUE == pHddCtx->isRxThreadSuspended){
1938 complete(&vosSchedContext->ResumeRxEvent);
1939 pHddCtx->isRxThreadSuspended= FALSE;
1940 }
1941 /* Reset the Suspend Variable */
1942 pHddCtx->isWlanSuspended = FALSE;
1943
1944 /* Stop all the threads; we do not want any messages to be a processed,
1945 * any more and the best way to ensure that is to terminate the threads
1946 * gracefully.
1947 */
1948 /* Wait for MC to exit */
1949 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1950 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1951 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1952 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301953 ret = wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1954 if (0 >= ret)
1955 {
1956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on McShutdown failed %ld",
1957 __func__, ret);
1958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001959
1960 /* Wait for TX to exit */
1961 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1962 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1963 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1964 wake_up_interruptible(&vosSchedContext->txWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301965 ret = wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1966 if (0 >= ret)
1967 {
1968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on TxShutdown failed %ld",
1969 __func__, ret);
1970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001971
1972 /* Wait for RX to exit */
1973 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1974 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1975 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1976 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301977
1978 ret = wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1979 if (0 >= ret)
1980 {
1981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on RxShutdown failed %ld",
1982 __func__, ret);
1983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001984
1985#ifdef WLAN_BTAMP_FEATURE
1986 vosStatus = WLANBAP_Stop(pVosContext);
1987 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1988 {
1989 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1990 "%s: Failed to stop BAP",__func__);
1991 }
1992#endif //WLAN_BTAMP_FEATURE
1993 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301994 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1995 {
1996 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1997 "%s: Failed to stop wda %d", __func__, vosStatus);
1998 VOS_ASSERT(0);
1999 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002000
2001 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2002 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2003 * on threads being running to process the SYS Stop
2004 */
Kiet Lama72a2322013-11-15 11:18:11 +05302005 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302006 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2007 {
2008 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2009 "%s: Failed to stop sme %d", __func__, vosStatus);
2010 VOS_ASSERT(0);
2011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002012
2013 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2014 /* Stop MAC (PE and HAL) */
2015 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302016 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2017 {
2018 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2019 "%s: Failed to stop mac %d", __func__, vosStatus);
2020 VOS_ASSERT(0);
2021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002022
2023 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2024 /* Stop TL */
2025 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302026 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2027 {
2028 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2029 "%s: Failed to stop TL %d", __func__, vosStatus);
2030 VOS_ASSERT(0);
2031 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002032
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2035 /* Clean up message queues of TX and MC thread */
2036 vos_sched_flush_mc_mqs(vosSchedContext);
2037 vos_sched_flush_tx_mqs(vosSchedContext);
2038 vos_sched_flush_rx_mqs(vosSchedContext);
2039
2040 /* Deinit all the TX and MC queues */
2041 vos_sched_deinit_mqs(vosSchedContext);
2042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2043
2044 /* shutdown VOSS */
2045 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302046
2047 /*mac context has already been released in mac_close call
2048 so setting it to NULL in hdd context*/
2049 pHddCtx->hHal = (tHalHandle)NULL;
2050
Jeff Johnson295189b2012-06-20 16:38:30 -07002051 if (free_riva_power_on_lock("wlan"))
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2054 __func__);
2055 }
2056 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2057 ,__func__);
2058 return VOS_STATUS_SUCCESS;
2059}
2060
2061
2062
2063/* the HDD interface to WLAN driver re-init.
2064 * This is called to initialize/start WLAN driver after a shutdown.
2065 */
2066VOS_STATUS hdd_wlan_re_init(void)
2067{
2068 VOS_STATUS vosStatus;
2069 v_CONTEXT_t pVosContext = NULL;
2070 hdd_context_t *pHddCtx = NULL;
2071 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002072#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2073 int max_retries = 0;
2074#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002075#ifdef WLAN_BTAMP_FEATURE
2076 hdd_config_t *pConfig = NULL;
2077 WLANBAP_ConfigType btAmpConfig;
2078#endif
2079
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002080 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002082
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002083#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2084 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002085 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002086 msleep(1000);
2087 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002088 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002089 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2090 goto err_re_init;
2091 }
2092#endif
2093
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002094 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2095
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002096 /* The driver should always be initialized in STA mode after SSR */
2097 hdd_set_conparam(0);
2098
Jeff Johnson295189b2012-06-20 16:38:30 -07002099 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
2100 vosStatus = vos_open(&pVosContext, 0);
2101 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2102 {
2103 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2104 goto err_re_init;
2105 }
2106
2107 /* Get the HDD context. */
2108 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2109 if(!pHddCtx)
2110 {
2111 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2112 goto err_vosclose;
2113 }
2114
2115 /* Save the hal context in Adapter */
2116 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2117 if ( NULL == pHddCtx->hHal )
2118 {
2119 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2120 goto err_vosclose;
2121 }
2122
2123 /* Set the SME configuration parameters. */
2124 vosStatus = hdd_set_sme_config(pHddCtx);
2125 if ( VOS_STATUS_SUCCESS != vosStatus )
2126 {
2127 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2128 goto err_vosclose;
2129 }
2130
2131 /* Initialize the WMM module */
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002132 vosStatus = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
2133 vosStatus = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07002134 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}