blob: 8b8064e67ddc4c55b51a43f84a7088fdff61f9e6 [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 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
1499 hdd_adapter_t *pAdapter;
1500 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1501
Jeff Johnson295189b2012-06-20 16:38:30 -07001502 /* if the driver was not in BMPS during early suspend,
1503 * the dynamic DTIM is now updated at Riva */
1504 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1505 && pHddCtx->cfg_ini->enableDynamicDTIM
1506 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1507 {
1508 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1509 }
1510 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301511 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1512 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001513 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301514 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1515 {
Amar Singhald53568e2013-09-26 11:03:45 -07001516 pHddCtx->sus_res_mcastbcast_filter =
1517 pHddCtx->configuredMcastBcastFilter;
1518 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1519
1520 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1521 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1522 pHddCtx->configuredMcastBcastFilter);
1523 hddLog(VOS_TRACE_LEVEL_INFO,
1524 "offload: calling hdd_conf_mcastbcast_filter");
1525
1526 }
1527
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301531
1532 vstatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1533 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vstatus )
1534 {
1535 pAdapter = pAdapterNode->pAdapter;
1536 if( pAdapter &&
1537 (( pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)))
1538 {
1539 if (pHddCtx->cfg_ini->fhostArpOffload)
1540 {
1541 //Configure ARPOFFLOAD
1542 vstatus = hdd_conf_arp_offload(pAdapter, 1);
1543 if (!VOS_IS_STATUS_SUCCESS(vstatus))
1544 {
1545 hddLog(VOS_TRACE_LEVEL_ERROR,
1546 "Failed to disable ARPOffload Feature %d", vstatus);
1547 }
1548 }
1549#ifdef WLAN_NS_OFFLOAD
1550 //Enable NSOFFLOAD
1551 if (pHddCtx->cfg_ini->fhostNSOffload)
1552 {
1553 hdd_conf_ns_offload(pAdapter, 1);
1554 }
1555#endif
1556 }
1557 vstatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1558 pAdapterNode = pNext;
1559 }
1560 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001561 else
Mihir Shete793209f2014-01-06 11:01:12 +05301562 {
1563 /* Android framework can send resume request when the WCN chip is
1564 * in IMPS mode. When the chip exits IMPS mode the firmware will
1565 * restore all the registers to the state they were before the chip
1566 * entered IMPS and so our hardware filter settings confgured by the
1567 * resume request will be lost. So reconfigure the filters on detecting
1568 * a change in the power state of the WCN chip.
1569 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301570 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301571 if (IMPS != newState)
1572 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301573 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301574 if (FALSE == pHddCtx->hdd_wlan_suspended)
1575 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301576 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301577 hddLog(VOS_TRACE_LEVEL_INFO,
1578 "Not in IMPS/BMPS and suspended state");
1579 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1580 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301581 else
1582 {
1583 spin_unlock(&pHddCtx->filter_lock);
1584 }
Mihir Shete793209f2014-01-06 11:01:12 +05301585 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301586 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001587}
1588
Jeff Johnson295189b2012-06-20 16:38:30 -07001589void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1590{
1591 v_CONTEXT_t pVosContext;
1592 tHalHandle smeContext;
1593
1594 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1595 if (NULL == pVosContext)
1596 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001597 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001598 return;
1599 }
1600 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1601 if (NULL == smeContext)
1602 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001603 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001604 return;
1605 }
1606
1607 spin_lock_init(&pHddCtx->filter_lock);
1608 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1609 pHddCtx->cfg_ini->nEnableSuspend)
1610 {
1611 pmcRegisterDeviceStateUpdateInd(smeContext,
1612 hdd_PowerStateChangedCB, pHddCtx);
1613 }
1614}
1615
1616void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1617{
1618 v_CONTEXT_t pVosContext;
1619 tHalHandle smeContext;
1620
1621 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1622 if (NULL == pVosContext)
1623 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001624 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001625 return;
1626 }
1627 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1628 if (NULL == smeContext)
1629 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001630 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001631 return;
1632 }
1633
1634 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1635 pHddCtx->cfg_ini->nEnableSuspend)
1636 {
1637 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1638 }
1639}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301640
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301641#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301642void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301643{
1644 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301645 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301646 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1647
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301648 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301649 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301650 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1651 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1652 {
1653 vos_mem_copy(&hddGtkOffloadReqParams,
1654 &pHddStaCtx->gtkOffloadReqParams,
1655 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301656
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301657 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1658 &hddGtkOffloadReqParams, pAdapter->sessionId);
1659 if (eHAL_STATUS_SUCCESS != ret)
1660 {
1661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1662 "%s: sme_SetGTKOffload failed, returned %d",
1663 __func__, ret);
1664 return;
1665 }
1666
1667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1668 "%s: sme_SetGTKOffload successfull", __func__);
1669 }
1670
1671 }
1672 else
1673 {
1674 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1675 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1676 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1677 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1678 {
1679
1680 /* Host driver has previously offloaded GTK rekey */
1681 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301682 wlan_hdd_cfg80211_update_replayCounterCallback,
1683 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301684 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301685
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301686 {
1687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1688 "%s: sme_GetGTKOffload failed, returned %d",
1689 __func__, ret);
1690 return;
1691 }
1692 else
1693 {
1694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1695 "%s: sme_GetGTKOffload successful",
1696 __func__);
1697
1698 /* Sending GTK offload dissable */
1699 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1700 sizeof (tSirGtkOffloadParams));
1701 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1702 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301703 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301704 if (eHAL_STATUS_SUCCESS != ret)
1705 {
1706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1707 "%s: failed to dissable GTK offload, returned %d",
1708 __func__, ret);
1709 return;
1710 }
1711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1712 "%s: successfully dissabled GTK offload request to HAL",
1713 __func__);
1714 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301715 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301716 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301717 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301718}
1719#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001720
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001721void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001722{
1723 hdd_context_t *pHddCtx = NULL;
1724 hdd_adapter_t *pAdapter = NULL;
1725 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1726 VOS_STATUS status;
1727 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001728
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1730
1731 //Get the global VOSS context.
1732 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1733 if(!pVosContext) {
1734 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1735 return;
1736 }
1737
1738 //Get the HDD context.
1739 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1740
1741 if(!pHddCtx) {
1742 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1743 return;
1744 }
1745
Agarwal Ashish971c2882013-10-30 20:11:12 +05301746 if (pHddCtx->isLogpInProgress)
1747 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 hddLog(VOS_TRACE_LEVEL_INFO,
1749 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1750 return;
1751 }
1752
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 pHddCtx->hdd_wlan_suspended = FALSE;
1754 /*loop through all adapters. Concurrency */
1755 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1756
1757 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1758 {
1759 pAdapter = pAdapterNode->pAdapter;
1760 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001761 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001762 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001763 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001764 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1765 pAdapterNode = pNext;
1766 continue;
1767 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301768
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301769
Jeff Johnson295189b2012-06-20 16:38:30 -07001770#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1771 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1772 {
1773 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1774 hdd_exit_deep_sleep(pAdapter);
1775 }
1776#endif
1777
1778 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1779 {
1780 /*Switch back to DTIM 1*/
1781 tSirSetPowerParamsReq powerRequest = { 0 };
1782
1783 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1784 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001785 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001786
1787 /*Disabled ModulatedDTIM if enabled on suspend*/
1788 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1789 powerRequest.uDTIMPeriod = 0;
1790
1791 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1792 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1793 NULL, eANI_BOOLEAN_FALSE);
1794 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1795 NULL, eANI_BOOLEAN_FALSE);
1796
1797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001798 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001799 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001800
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301801 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1802 {
1803 /* put the device into full power */
1804 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001805
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301806 /* put the device back into BMPS */
1807 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001808
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301809 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 }
1812
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301813 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001814 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1815 pAdapterNode = pNext;
1816 }
1817
1818#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1819 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1820 {
1821 hdd_exit_standby(pHddCtx);
1822 }
1823#endif
1824
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 return;
1826}
1827
Jeff Johnson295189b2012-06-20 16:38:30 -07001828VOS_STATUS hdd_wlan_reset_initialization(void)
1829{
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 v_CONTEXT_t pVosContext = NULL;
1831
1832 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1833
1834 //Get the global VOSS context.
1835 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1836 if(!pVosContext)
1837 {
1838 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1839 return VOS_STATUS_E_FAILURE;
1840 }
1841
1842 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1843
1844 // Prevent the phone from going to sleep
1845 hdd_prevent_suspend();
1846
Jeff Johnson295189b2012-06-20 16:38:30 -07001847 return VOS_STATUS_SUCCESS;
1848}
1849
1850
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001851/*
1852 * Based on the ioctl command recieved by HDD, put WLAN driver
1853 * into the quiet mode. This is the same as the early suspend
1854 * notification that driver used to listen
1855 */
1856void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001857{
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001858 if (suspend)
1859 hdd_suspend_wlan();
1860 else
1861 hdd_resume_wlan();
Jeff Johnson295189b2012-06-20 16:38:30 -07001862}
1863
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001864static void hdd_ssr_timer_init(void)
1865{
1866 init_timer(&ssr_timer);
1867}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001868
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001869static void hdd_ssr_timer_del(void)
1870{
1871 del_timer(&ssr_timer);
1872 ssr_timer_started = false;
1873}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001874
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001875static void hdd_ssr_timer_cb(unsigned long data)
1876{
1877 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001878
1879#ifdef WCN_PRONTO
1880 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1881 wcnss_pronto_log_debug_regs();
1882#endif
1883
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001884 VOS_BUG(0);
1885}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001886
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001887static void hdd_ssr_timer_start(int msec)
1888{
1889 if(ssr_timer_started)
1890 {
1891 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1892 ,__func__);
1893 }
1894 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1895 ssr_timer.function = hdd_ssr_timer_cb;
1896 add_timer(&ssr_timer);
1897 ssr_timer_started = true;
1898}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001899
Jeff Johnson295189b2012-06-20 16:38:30 -07001900/* the HDD interface to WLAN driver shutdown,
1901 * the primary shutdown function in SSR
1902 */
1903VOS_STATUS hdd_wlan_shutdown(void)
1904{
1905 VOS_STATUS vosStatus;
1906 v_CONTEXT_t pVosContext = NULL;
1907 hdd_context_t *pHddCtx = NULL;
1908 pVosSchedContext vosSchedContext = NULL;
c_hpothuffdb5272013-10-02 16:42:35 +05301909 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001910
1911 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1912
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001913 /* if re-init never happens, then do SSR1 */
1914 hdd_ssr_timer_init();
1915 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1916
Jeff Johnson295189b2012-06-20 16:38:30 -07001917 /* Get the global VOSS context. */
1918 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1919 if(!pVosContext) {
1920 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1921 return VOS_STATUS_E_FAILURE;
1922 }
1923 /* Get the HDD context. */
1924 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1925 if(!pHddCtx) {
1926 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1927 return VOS_STATUS_E_FAILURE;
1928 }
c_hpothud662a352013-12-26 15:09:12 +05301929
1930 //Stop the traffic monitor timer
1931 if ( VOS_TIMER_STATE_RUNNING ==
1932 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1933 {
1934 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1935 }
1936
Jeff Johnson295189b2012-06-20 16:38:30 -07001937 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001938 /* DeRegister with platform driver as client for Suspend/Resume */
1939 vosStatus = hddDeregisterPmOps(pHddCtx);
1940 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1941 {
1942 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1943 }
1944
1945 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1946 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1947 {
1948 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1949 }
1950
1951 /* Disable IMPS/BMPS as we do not want the device to enter any power
1952 * save mode on its own during reset sequence
1953 */
1954 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1955 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1956 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1957
1958 vosSchedContext = get_vos_sched_ctxt();
1959
1960 /* Wakeup all driver threads */
1961 if(TRUE == pHddCtx->isMcThreadSuspended){
1962 complete(&vosSchedContext->ResumeMcEvent);
1963 pHddCtx->isMcThreadSuspended= FALSE;
1964 }
1965 if(TRUE == pHddCtx->isTxThreadSuspended){
1966 complete(&vosSchedContext->ResumeTxEvent);
1967 pHddCtx->isTxThreadSuspended= FALSE;
1968 }
1969 if(TRUE == pHddCtx->isRxThreadSuspended){
1970 complete(&vosSchedContext->ResumeRxEvent);
1971 pHddCtx->isRxThreadSuspended= FALSE;
1972 }
1973 /* Reset the Suspend Variable */
1974 pHddCtx->isWlanSuspended = FALSE;
1975
1976 /* Stop all the threads; we do not want any messages to be a processed,
1977 * any more and the best way to ensure that is to terminate the threads
1978 * gracefully.
1979 */
1980 /* Wait for MC to exit */
1981 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1982 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1983 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1984 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301985 ret = wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1986 if (0 >= ret)
1987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on McShutdown failed %ld",
1989 __func__, ret);
1990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001991
1992 /* Wait for TX to exit */
1993 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1994 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1995 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1996 wake_up_interruptible(&vosSchedContext->txWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301997 ret = wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1998 if (0 >= ret)
1999 {
2000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on TxShutdown failed %ld",
2001 __func__, ret);
2002 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002003
2004 /* Wait for RX to exit */
2005 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
2006 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
2007 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
2008 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05302009
2010 ret = wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
2011 if (0 >= ret)
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on RxShutdown failed %ld",
2014 __func__, ret);
2015 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002016
2017#ifdef WLAN_BTAMP_FEATURE
2018 vosStatus = WLANBAP_Stop(pVosContext);
2019 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2020 {
2021 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2022 "%s: Failed to stop BAP",__func__);
2023 }
2024#endif //WLAN_BTAMP_FEATURE
2025 vosStatus = vos_wda_shutdown(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 wda %d", __func__, vosStatus);
2030 VOS_ASSERT(0);
2031 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002032
2033 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2034 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2035 * on threads being running to process the SYS Stop
2036 */
Kiet Lama72a2322013-11-15 11:18:11 +05302037 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302038 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2039 {
2040 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2041 "%s: Failed to stop sme %d", __func__, vosStatus);
2042 VOS_ASSERT(0);
2043 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002044
2045 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2046 /* Stop MAC (PE and HAL) */
2047 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302048 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2049 {
2050 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2051 "%s: Failed to stop mac %d", __func__, vosStatus);
2052 VOS_ASSERT(0);
2053 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002054
2055 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2056 /* Stop TL */
2057 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302058 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2059 {
2060 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2061 "%s: Failed to stop TL %d", __func__, vosStatus);
2062 VOS_ASSERT(0);
2063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002064
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2067 /* Clean up message queues of TX and MC thread */
2068 vos_sched_flush_mc_mqs(vosSchedContext);
2069 vos_sched_flush_tx_mqs(vosSchedContext);
2070 vos_sched_flush_rx_mqs(vosSchedContext);
2071
2072 /* Deinit all the TX and MC queues */
2073 vos_sched_deinit_mqs(vosSchedContext);
2074 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2075
2076 /* shutdown VOSS */
2077 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302078
2079 /*mac context has already been released in mac_close call
2080 so setting it to NULL in hdd context*/
2081 pHddCtx->hHal = (tHalHandle)NULL;
2082
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 if (free_riva_power_on_lock("wlan"))
2084 {
2085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2086 __func__);
2087 }
2088 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2089 ,__func__);
2090 return VOS_STATUS_SUCCESS;
2091}
2092
2093
2094
2095/* the HDD interface to WLAN driver re-init.
2096 * This is called to initialize/start WLAN driver after a shutdown.
2097 */
2098VOS_STATUS hdd_wlan_re_init(void)
2099{
2100 VOS_STATUS vosStatus;
2101 v_CONTEXT_t pVosContext = NULL;
2102 hdd_context_t *pHddCtx = NULL;
2103 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002104#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2105 int max_retries = 0;
2106#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002107#ifdef WLAN_BTAMP_FEATURE
2108 hdd_config_t *pConfig = NULL;
2109 WLANBAP_ConfigType btAmpConfig;
2110#endif
2111
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002112 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002114
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002115#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2116 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002117 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002118 msleep(1000);
2119 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002120 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002121 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2122 goto err_re_init;
2123 }
2124#endif
2125
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002126 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2127
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002128 /* The driver should always be initialized in STA mode after SSR */
2129 hdd_set_conparam(0);
2130
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
2132 vosStatus = vos_open(&pVosContext, 0);
2133 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2134 {
2135 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2136 goto err_re_init;
2137 }
2138
2139 /* Get the HDD context. */
2140 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2141 if(!pHddCtx)
2142 {
2143 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2144 goto err_vosclose;
2145 }
2146
2147 /* Save the hal context in Adapter */
2148 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2149 if ( NULL == pHddCtx->hHal )
2150 {
2151 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2152 goto err_vosclose;
2153 }
2154
2155 /* Set the SME configuration parameters. */
2156 vosStatus = hdd_set_sme_config(pHddCtx);
2157 if ( VOS_STATUS_SUCCESS != vosStatus )
2158 {
2159 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2160 goto err_vosclose;
2161 }
2162
2163 /* Initialize the WMM module */
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002164 vosStatus = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
2165 vosStatus = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ))
2167 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002168 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002169 goto err_vosclose;
2170 }
2171
2172 vosStatus = vos_preStart( pHddCtx->pvosContext );
2173 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2174 {
2175 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2176 goto err_vosclose;
2177 }
2178
2179 /* In the integrated architecture we update the configuration from
2180 the INI file and from NV before vOSS has been started so that
2181 the final contents are available to send down to the cCPU */
2182 /* Apply the cfg.ini to cfg.dat */
2183 if (FALSE == hdd_update_config_dat(pHddCtx))
2184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2186 goto err_vosclose;
2187 }
2188
2189 /* Set the MAC Address, currently this is used by HAL to add self sta.
2190 * Remove this once self sta is added as part of session open. */
2191 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2192 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2193 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2194 if (!HAL_STATUS_SUCCESS(halStatus))
2195 {
2196 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2197 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2198 goto err_vosclose;
2199 }
2200
2201 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2202 Note: Firmware image will be read and downloaded inside vos_start API */
2203 vosStatus = vos_start( pVosContext );
2204 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2205 {
2206 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2207 goto err_vosclose;
2208 }
2209
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002210 /* Exchange capability info between Host and FW and also get versioning info from FW */
2211 hdd_exchange_version_and_caps(pHddCtx);
2212
Jeff Johnson295189b2012-06-20 16:38:30 -07002213 vosStatus = hdd_post_voss_start_config( pHddCtx );
2214 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2215 {
2216 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2217 __func__);
2218 goto err_vosstop;
2219 }
2220
2221#ifdef WLAN_BTAMP_FEATURE
2222 vosStatus = WLANBAP_Open(pVosContext);
2223 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2224 {
2225 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2226 "%s: Failed to open BAP",__func__);
2227 goto err_vosstop;
2228 }
2229 vosStatus = BSL_Init(pVosContext);
2230 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2231 {
2232 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2233 "%s: Failed to Init BSL",__func__);
2234 goto err_bap_close;
2235 }
2236 vosStatus = WLANBAP_Start(pVosContext);
2237 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2238 {
2239 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2240 "%s: Failed to start TL",__func__);
2241 goto err_bap_close;
2242 }
2243 pConfig = pHddCtx->cfg_ini;
2244 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2245 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2246#endif //WLAN_BTAMP_FEATURE
2247
2248 /* Restart all adapters */
2249 hdd_start_all_adapters(pHddCtx);
2250 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002251 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002254
2255 /* Register with platform driver as client for Suspend/Resume */
2256 vosStatus = hddRegisterPmOps(pHddCtx);
2257 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2258 {
2259 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2260 goto err_bap_stop;
2261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 /* Allow the phone to go to sleep */
2263 hdd_allow_suspend();
2264 /* register for riva power on lock */
2265 if (req_riva_power_on_lock("wlan"))
2266 {
2267 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2268 __func__);
2269 goto err_unregister_pmops;
2270 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002271 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002272 goto success;
2273
2274err_unregister_pmops:
2275 hddDeregisterPmOps(pHddCtx);
2276
2277err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002278#ifdef CONFIG_HAS_EARLYSUSPEND
2279 hdd_unregister_mcast_bcast_filter(pHddCtx);
2280#endif
2281 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002282#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002283 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002284#endif
2285
2286#ifdef WLAN_BTAMP_FEATURE
2287err_bap_close:
2288 WLANBAP_Close(pVosContext);
2289#endif
2290
2291err_vosstop:
2292 vos_stop(pVosContext);
2293
2294err_vosclose:
2295 vos_close(pVosContext);
2296 vos_sched_close(pVosContext);
2297 if (pHddCtx)
2298 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002299 /* Unregister the Net Device Notifier */
2300 unregister_netdevice_notifier(&hdd_netdev_notifier);
2301 /* Clean up HDD Nlink Service */
2302 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002303#ifdef WLAN_KD_READY_NOTIFIER
2304 nl_srv_exit(pHddCtx->ptt_pid);
2305#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002306 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002307#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002308 /* Free up dynamically allocated members inside HDD Adapter */
2309 kfree(pHddCtx->cfg_ini);
2310 pHddCtx->cfg_ini= NULL;
2311
Jeff Johnson295189b2012-06-20 16:38:30 -07002312 wiphy_unregister(pHddCtx->wiphy);
2313 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 }
2315 vos_preClose(&pVosContext);
2316
2317#ifdef MEMORY_DEBUG
2318 vos_mem_exit();
2319#endif
2320
2321err_re_init:
2322 /* Allow the phone to go to sleep */
2323 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002324 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002325 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002326 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002327
2328success:
2329 /* Trigger replay of BTC events */
2330 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2331 return VOS_STATUS_SUCCESS;
2332}