blob: 788bdcdf6391c03bae6dcad3937110959640ecd9 [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>
Jeff Johnson295189b2012-06-20 16:38:30 -070054#include <vos_sched.h>
55#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070056#include <wlan_qct_sys.h>
57#include <wlan_btc_svc.h>
58#include <wlan_nlink_common.h>
59#include <wlan_hdd_main.h>
60#include <wlan_hdd_assoc.h>
61#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070062#include <wlan_nlink_srv.h>
63#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070064#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070065
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/semaphore.h>
67#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#include "cfgApi.h"
69
70#ifdef WLAN_BTAMP_FEATURE
71#include "bapApi.h"
72#include "bap_hdd_main.h"
73#include "bap_hdd_misc.h"
74#endif
75
Jeff Johnsone7245742012-09-05 17:12:55 -070076#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070077#include <linux/inetdevice.h>
78#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053079#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053080#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070081/**-----------------------------------------------------------------------------
82* Preprocessor definitions and constants
83* ----------------------------------------------------------------------------*/
84
85/**-----------------------------------------------------------------------------
86* Type declarations
87* ----------------------------------------------------------------------------*/
88
89/**-----------------------------------------------------------------------------
90* Function and variables declarations
91* ----------------------------------------------------------------------------*/
92#include "wlan_hdd_power.h"
93#include "wlan_hdd_packet_filtering.h"
94
Sameer Thalappile5637f42013-08-07 15:46:55 -070095#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053096#define NS_DEFAULT_SLOT_INDEX 4
97#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99static eHalStatus g_full_pwr_status;
100static eHalStatus g_standby_status;
101
102extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700104
105extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700106extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700108static struct timer_list ssr_timer;
109static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111//Callback invoked by PMC to report status of standby request
112void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
113{
114 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
115 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
116 g_standby_status = status;
117
118 if(eHAL_STATUS_SUCCESS == status)
119 {
120 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
121 }
122 else
123 {
124 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
125 }
126
127 complete(&pHddCtx->standby_comp_var);
128}
129
130//Callback invoked by PMC to report status of full power request
131void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
132{
133 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
135 g_full_pwr_status = status;
136
137 if(eHAL_STATUS_SUCCESS == status)
138 {
139 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
140 }
141 else
142 {
143 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
144 }
145
146 complete(&pHddCtx->full_pwr_comp_var);
147}
148
149eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
150{
151 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530152 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700153
154 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
155 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
156
157 g_full_pwr_status = eHAL_STATUS_FAILURE;
158 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
159 eSME_FULL_PWR_NEEDED_BY_HDD);
160
161 if(status == eHAL_STATUS_PMC_PENDING)
162 {
163 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530164 ret = wait_for_completion_interruptible_timeout(
165 &pHddCtx->full_pwr_comp_var,
166 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
167 if (0 >= ret)
168 {
169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
170 __func__, ret);
171 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700172 status = g_full_pwr_status;
173 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
174 {
175 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
176 VOS_ASSERT(0);
177 goto failure;
178 }
179 }
180 else if(status != eHAL_STATUS_SUCCESS)
181 {
182 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
183 __func__, status);
184 VOS_ASSERT(0);
185 goto failure;
186 }
187 else
188 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
189
190failure:
191 //No blocking to reduce latency. No other device should be depending on WLAN
192 //to finish resume and WLAN won't be instantly on after resume
193 return status;
194}
195
196
197//Helper routine to put the chip into standby
198VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
199{
200 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
201 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530202 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700203
204 //Disable IMPS/BMPS as we do not want the device to enter any power
205 //save mode on its own during suspend sequence
206 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
207 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
208
209 //Note we do not disable queues unnecessarily. Queues should already be disabled
210 //if STA is disconnected or the queue will be disabled as and when disconnect
211 //happens because of standby procedure.
212
213 //Ensure that device is in full power first. There is scope for optimization
214 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
215 //Core s/w needs to be optimized to handle this. Until then we request full
216 //power before issuing request for standby.
217 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
218 g_full_pwr_status = eHAL_STATUS_FAILURE;
219 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
220 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
221
222 if(halStatus == eHAL_STATUS_PMC_PENDING)
223 {
224 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530225 ret = wait_for_completion_interruptible_timeout(
226 &pHddCtx->full_pwr_comp_var,
227 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
228 if (0 >= ret)
229 {
230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
231 __func__, ret);
232 }
233
Jeff Johnson295189b2012-06-20 16:38:30 -0700234 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
235 {
236 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
237 VOS_ASSERT(0);
238 vosStatus = VOS_STATUS_E_FAILURE;
239 goto failure;
240 }
241 }
242 else if(halStatus != eHAL_STATUS_SUCCESS)
243 {
244 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
245 __func__, halStatus);
246 VOS_ASSERT(0);
247 vosStatus = VOS_STATUS_E_FAILURE;
248 goto failure;
249 }
250
251 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
252 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
253 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
254 }
255
256 //Request standby. Standby will cause the STA to disassociate first. TX queues
257 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
258 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
259 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
260 //when there are concurrent sessions.
261 INIT_COMPLETION(pHddCtx->standby_comp_var);
262 g_standby_status = eHAL_STATUS_FAILURE;
263 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
264
265 if (halStatus == eHAL_STATUS_PMC_PENDING)
266 {
267 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530268 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700269 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530270 if (0 >= ret)
271 {
272 hddLog(VOS_TRACE_LEVEL_ERROR,
273 FL("wait on standby_comp_var failed %ld"), ret);
274 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
276 {
277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
278 VOS_ASSERT(0);
279 vosStatus = VOS_STATUS_E_FAILURE;
280 goto failure;
281 }
282 }
283 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
284 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
285 __func__, halStatus);
286 VOS_ASSERT(0);
287 vosStatus = VOS_STATUS_E_FAILURE;
288 goto failure;
289 }
290 else
291 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
292
293failure:
294 //Restore IMPS config
295 if(pHddCtx->cfg_ini->fIsImpsEnabled)
296 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
297
298 //Restore BMPS config
299 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
300 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
301
302 return vosStatus;
303}
304
305
306//Helper routine for Deep sleep entry
307VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
308{
309 eHalStatus halStatus;
310 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530311 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800312
Jeff Johnson295189b2012-06-20 16:38:30 -0700313 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700315 netif_tx_disable(pAdapter->dev);
316 netif_carrier_off(pAdapter->dev);
317
318 //Disable IMPS,BMPS as we do not want the device to enter any power
319 //save mode on it own during suspend sequence
320 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
321 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
322
323 //Ensure that device is in full power as we will touch H/W during vos_Stop
324 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
325 g_full_pwr_status = eHAL_STATUS_FAILURE;
326 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
327 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
328
329 if(halStatus == eHAL_STATUS_PMC_PENDING)
330 {
331 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530332 ret = wait_for_completion_interruptible_timeout(
333 &pHddCtx->full_pwr_comp_var,
334 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
335 if (0 >= ret)
336 {
337 hddLog(VOS_TRACE_LEVEL_ERROR,
338 FL("wait on full_pwr_comp_var failed %ld"), ret);
339 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700340 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
341 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
342 VOS_ASSERT(0);
343 }
344 }
345 else if(halStatus != eHAL_STATUS_SUCCESS)
346 {
347 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
348 VOS_ASSERT(0);
349 }
350
351 //Issue a disconnect. This is required to inform the supplicant that
352 //STA is getting disassociated and for GUI to be updated properly
353 INIT_COMPLETION(pAdapter->disconnect_comp_var);
354 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
355
356 //Success implies disconnect command got queued up successfully
357 if(halStatus == eHAL_STATUS_SUCCESS)
358 {
359 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530360 ret = wait_for_completion_interruptible_timeout(
361 &pAdapter->disconnect_comp_var,
362 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
363 if (0 >= ret)
364 {
365 hddLog(VOS_TRACE_LEVEL_ERROR,
366 FL("wait on disconnect_comp_var failed %ld"), ret);
367 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 }
369
370
371 //None of the steps should fail after this. Continue even in case of failure
372 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530373 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
374 {
375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
376 __func__, vosStatus);
377 VOS_ASSERT(0);
378 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700379
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
381
382 //Restore IMPS config
383 if(pHddCtx->cfg_ini->fIsImpsEnabled)
384 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
385
386 //Restore BMPS config
387 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
388 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
389
Jeff Johnson295189b2012-06-20 16:38:30 -0700390 return vosStatus;
391}
392
393VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
394{
395 VOS_STATUS vosStatus;
396 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700397
Jeff Johnson295189b2012-06-20 16:38:30 -0700398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
399 "%s: calling hdd_set_sme_config",__func__);
400 vosStatus = hdd_set_sme_config( pHddCtx );
401 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
402 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
403 {
404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
405 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700406 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700407 }
408
409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
410 "%s: calling vos_start",__func__);
411 vosStatus = vos_start( pHddCtx->pvosContext );
412 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
413 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
414 {
415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
416 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700417 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700418 }
419
420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
421 "%s: calling hdd_post_voss_start_config",__func__);
422 vosStatus = hdd_post_voss_start_config( pHddCtx );
423 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
424 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
425 {
426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
427 "%s: Failed in hdd_post_voss_start_config",__func__);
428 goto err_voss_stop;
429 }
430
431
432 //Open a SME session for future operation
433 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700434 (tANI_U8 *)&pAdapter->macAddressCurrent,
435 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700436 if ( !HAL_STATUS_SUCCESS( halStatus ) )
437 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700438 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700439 halStatus, halStatus );
440 goto err_voss_stop;
441
442 }
443
444 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
445
446 //Trigger the initial scan
447 hdd_wlan_initial_scan(pHddCtx);
448
449 return VOS_STATUS_SUCCESS;
450
451err_voss_stop:
452 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700453err_deep_sleep:
454 return VOS_STATUS_E_FAILURE;
455
456}
457
Atul Mittal37385d72014-03-27 18:15:03 +0530458void hdd_ipv6_notifier_work_queue(struct work_struct *work)
459{
460 hdd_adapter_t* pAdapter =
461 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
462 hdd_context_t *pHddCtx;
463 int status;
464
465 hddLog(LOG1, FL("Reconfiguring NS Offload"));
466
467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
468 status = wlan_hdd_validate_context(pHddCtx);
469 if (0 != status)
470 {
471 hddLog(LOGE, FL("HDD context is invalid"));
472 return;
473 }
474
475 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
476 {
477 pHddCtx->sus_res_mcastbcast_filter =
478 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530479 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
480 pHddCtx->sus_res_mcastbcast_filter);
Atul Mittal37385d72014-03-27 18:15:03 +0530481 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
482 }
483
484 if ((eConnectionState_Associated ==
485 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
486 && (pHddCtx->hdd_wlan_suspended))
487 {
488 // This invocation being part of the IPv6 registration callback,
489 // set the newly generated ip address to f/w in suspend mode.
490#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530491 if (pHddCtx->cfg_ini->fhostNSOffload)
492 {
493 hdd_conf_ns_offload(pAdapter, 1);
494 }
Atul Mittal37385d72014-03-27 18:15:03 +0530495#endif
496 }
497#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530498 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530499 * only so when new ipv6 address is generated the screen may not
500 * on so we need to call it here to update the list in f/w.
501 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530502 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530503#endif
504
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530505
Atul Mittal37385d72014-03-27 18:15:03 +0530506}
507
508
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530509int wlan_hdd_ipv6_changed(struct notifier_block *nb,
510 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530511{
512 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
513 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530514 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Atul Mittal37385d72014-03-27 18:15:03 +0530515 hdd_context_t *pHddCtx;
516 int status;
517
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530518 if (pAdapter && pAdapter->dev == ndev &&
519 (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
520 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
Atul Mittal37385d72014-03-27 18:15:03 +0530521 {
522 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
523 status = wlan_hdd_validate_context(pHddCtx);
524 if (0 != status)
525 {
526 hddLog(LOGE, FL("HDD context is invalid"));
527 return NOTIFY_DONE;
528 }
529
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530530 if (pHddCtx->cfg_ini->nEnableSuspend ==
531 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
532 {
533 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
534 }
535 else
536 {
537 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
538 pHddCtx->cfg_ini->nEnableSuspend);
539 }
Atul Mittal37385d72014-03-27 18:15:03 +0530540 }
541
542 return NOTIFY_DONE;
543}
544
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530545/*
546 * Function: hdd_conf_hostoffload
547 * Central function to configure the supported offloads,
548 * either enable or disable them.
549 */
550void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
551{
552 hdd_context_t *pHddCtx = NULL;
553 v_CONTEXT_t *pVosContext = NULL;
554 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
555
556 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
557 fenable);
558
559 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
560
561 if (NULL == pVosContext)
562 {
563 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
564 return;
565 }
566
567 //Get the HDD context.
568 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
569
570 if (NULL == pHddCtx)
571 {
572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
573 return;
574 }
575
576 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
577 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
578 {
579 if (fenable)
580 {
581 if (eConnectionState_Associated ==
582 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
583 {
584 if ((pHddCtx->cfg_ini->fhostArpOffload))
585 {
586 /*
587 * Configure the ARP Offload.
588 * Even if it fails we have to reconfigure the MC/BC
589 * filter flag as we want RIVA not to drop BroadCast
590 * Packets
591 */
592 hddLog(VOS_TRACE_LEVEL_INFO,
593 FL("Calling ARP Offload with flag: %d"), fenable);
594 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
595 pHddCtx->configuredMcastBcastFilter &=
596 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
597
598 if (!VOS_IS_STATUS_SUCCESS(vstatus))
599 {
600 hddLog(VOS_TRACE_LEVEL_ERROR,
601 "Failed to enable ARPOFfloadFeature %d",
602 vstatus);
603 }
604 }
605 //Configure GTK_OFFLOAD
606#ifdef WLAN_FEATURE_GTK_OFFLOAD
607 hdd_conf_gtk_offload(pAdapter, fenable);
608#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530609
610#ifdef WLAN_NS_OFFLOAD
611 if (pHddCtx->cfg_ini->fhostNSOffload)
612 {
613 /*
614 * Configure the NS Offload.
615 * Even if it fails we have to reconfigure the MC/BC filter flag
616 * as we want RIVA not to drop Multicast Packets
617 */
618
619 hddLog(VOS_TRACE_LEVEL_INFO,
620 FL("Calling NS Offload with flag: %d"), fenable);
621 hdd_conf_ns_offload(pAdapter, fenable);
622 pHddCtx->configuredMcastBcastFilter &=
623 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
624 }
625#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530626
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530627 }
628 }
629 else
630 {
631 //Disable ARPOFFLOAD
632 if (pHddCtx->cfg_ini->fhostArpOffload)
633 {
634 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
635 if (!VOS_IS_STATUS_SUCCESS(vstatus))
636 {
637 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530638 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530639 }
640 }
641 //Disable GTK_OFFLOAD
642#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530643 hdd_conf_gtk_offload(pAdapter, fenable);
644#endif
645
646#ifdef WLAN_NS_OFFLOAD
647 //Disable NSOFFLOAD
648 if (pHddCtx->cfg_ini->fhostNSOffload)
649 {
650 hdd_conf_ns_offload(pAdapter, fenable);
651 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530652#endif
653 }
654 }
655 return;
656}
657
Atul Mittal37385d72014-03-27 18:15:03 +0530658
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530659#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530660/**----------------------------------------------------------------------------
661
662 \brief hdd_conf_ns_offload() - Configure NS offload
663
664 Called during SUSPEND to configure the NS offload (MC BC filter) which
665 reduces power consumption.
666
667 \param - pAdapter - Adapter context for which NS offload is to be configured
668 \param - fenable - 0 - disable.
669 1 - enable. (with IPv6 notifier registration)
670 2 - enable. (without IPv6 notifier registration)
671
672 \return - void
673
674 ---------------------------------------------------------------------------*/
675void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530676{
677 struct inet6_dev *in6_dev;
678 struct inet6_ifaddr *ifp;
679 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530680 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530681 tANI_U8 **selfIPv6Addr = NULL;
682 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530683 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530684 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530685 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530686
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530687 int i = 0, slot = 0;
688 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530689 eHalStatus returnStatus;
690
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530691 ENTER();
692 hddLog(LOG1, FL(" fenable = %d"), fenable);
693
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530694 if (NULL == pAdapter)
695 {
696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
697 return;
698 }
699
700 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530701 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
702
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530703 ret = wlan_hdd_validate_context(pHddCtx);
704
705 if (0 != ret)
706 {
707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
708 FL("HDD context is not valid"));
709 return;
710 }
711
712 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
713 {
714 slot_index = NS_EXTENDED_SLOT_INDEX;
715 }
716
717 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
718
719 selfIPv6AddrValid =
720 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
721
722 if (NULL == selfIPv6AddrValid)
723 {
724 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
725 " selfIPv6AddrValid"));
726 goto end;
727 }
728
729 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
730
731 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
732
733 if (NULL == selfIPv6Addr)
734 {
735 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
736 " selfIPv6Addr"));
737 goto end;
738 }
739
740 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
741
742 for (slot = 0; slot < slot_index; slot++)
743 {
744 selfIPv6Addr[slot] =
745 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
746 if (NULL == selfIPv6Addr[slot])
747 {
748 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
749 "for selfIPv6Addr"));
750 goto end;
751 }
752 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
753 }
754
755 i = 0;
756
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530757 if (fenable)
758 {
759 in6_dev = __in6_dev_get(pAdapter->dev);
760 if (NULL != in6_dev)
761 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530762 list_for_each(p, &in6_dev->addr_list)
763 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530764 if (i >= slot_index)
765 {
766 hddLog (VOS_TRACE_LEVEL_ERROR,
767 FL("IPv6 address list is greater than IPv6"
768 "address supported by firmware"));
769 hddLog (VOS_TRACE_LEVEL_ERROR,
770 FL("FW supported IPv6 address = %d"), slot_index);
771 break;
772 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530773 ifp = list_entry(p, struct inet6_ifaddr, if_list);
774 switch(ipv6_addr_src_scope(&ifp->addr))
775 {
776 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530777 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530778 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530779 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530780 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530781 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
782 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530783 break;
784 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530785 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530786 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530787 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530788 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530789 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
790 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530791 break;
792 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530793 hddLog(VOS_TRACE_LEVEL_ERROR,
794 FL("The Scope %d is not supported"),
795 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530796 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530797 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
798 {
799 i++;
800 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530801 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530802
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530803 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530804 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530805 {
806 if (selfIPv6AddrValid[i])
807 {
808 //Filling up the request structure
809 /* Filling the selfIPv6Addr with solicited address
810 * A Solicited-Node multicast address is created by
811 * taking the last 24 bits of a unicast or anycast
812 * address and appending them to the prefix
813 *
814 * FF02:0000:0000:0000:0000:0001:FFXX:XX
815 *
816 * here XX is the unicast/anycast bits
817 */
818 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
819 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
820 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
821 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530822 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
823 selfIPv6Addr[i][13];
824 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
825 selfIPv6Addr[i][14];
826 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
827 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530828 offLoadRequest.nsOffloadInfo.slotIdx = i;
829
830 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530831 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530832 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
833 &pAdapter->macAddressCurrent.bytes,
834 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
835
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530836 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
837 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530838 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
839 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
840
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530841 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530842 FL("configuredMcastBcastFilter: %d"
843 "NSOffload Slot = %d"),
844 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530845
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530846 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700847 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
848 pHddCtx->sus_res_mcastbcast_filter) ||
849 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
850 pHddCtx->sus_res_mcastbcast_filter)) &&
851 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
852 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
853 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530854 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530855 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700856 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530857 hddLog (VOS_TRACE_LEVEL_INFO,
858 FL("Set offLoadRequest with %d"),
859 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530860 }
861
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530862 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
863 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
864 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
865
866 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530867 FL("Setting NSOffload with solicitedIp: %pI6,"
868 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530869 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
870 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
871
872 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530873 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530874 pAdapter->sessionId, &offLoadRequest);
875 if(eHAL_STATUS_SUCCESS != returnStatus)
876 {
877 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530878 FL("Failed to enable HostOffload feature with"
879 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530880 }
881 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
882 }
883 }
884 }
885 else
886 {
887 hddLog(VOS_TRACE_LEVEL_ERROR,
888 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530889 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530890 }
891 }
892 else
893 {
894 //Disable NSOffload
895 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
896 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
897 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
898
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530899 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530900 {
c_hpothu86feba52014-10-28 15:51:18 +0530901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530902 offLoadRequest.nsOffloadInfo.slotIdx = i;
903 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530904 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
905 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530906 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530907 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
908 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530909 }
910 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530911 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530912end:
913 while (slot > 0 && selfIPv6Addr[--slot])
914 {
915 vos_mem_free(selfIPv6Addr[slot]);
916 }
917 if (selfIPv6Addr)
918 {
919 vos_mem_free(selfIPv6Addr);
920 }
921 if (selfIPv6AddrValid)
922 {
923 vos_mem_free(selfIPv6AddrValid);
924 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530925 return;
926}
927#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530928
929void hdd_ipv4_notifier_work_queue(struct work_struct *work)
930{
931 hdd_adapter_t* pAdapter =
932 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
933 hdd_context_t *pHddCtx;
934 int status;
935
936 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
937 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
938 status = wlan_hdd_validate_context(pHddCtx);
939 if (0 != status)
940 {
941 hddLog(LOGE, FL("HDD context is invalid"));
942 return;
943 }
944
Deepthi Gowri5933f402014-01-23 17:48:24 +0530945 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
946 {
947 pHddCtx->sus_res_mcastbcast_filter =
948 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530949 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
950 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530951 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
952 }
953
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530954 if ((eConnectionState_Associated ==
955 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530956 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530957 {
958 // This invocation being part of the IPv4 registration callback,
959 // we are passing second parameter as 2 to avoid registration
960 // of IPv4 notifier again.
961 hdd_conf_arp_offload(pAdapter, 2);
962 }
963}
964
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530965int wlan_hdd_ipv4_changed(struct notifier_block *nb,
966 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530967{
968 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
969 struct in_ifaddr **ifap = NULL;
970 struct in_device *in_dev;
971
972 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530973 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530974 hdd_context_t *pHddCtx;
975 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530976
977 if (pAdapter && pAdapter->dev == ndev &&
978 (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
979 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530980 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530981 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
982 status = wlan_hdd_validate_context(pHddCtx);
983 if (0 != status)
984 {
985 hddLog(LOGE, FL("HDD context is invalid"));
986 return NOTIFY_DONE;
987 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530988
989 if ((pHddCtx->cfg_ini->nEnableSuspend !=
990 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
991 || (!pHddCtx->cfg_ini->fhostArpOffload))
992 {
993 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
994 pHddCtx->cfg_ini->nEnableSuspend,
995 pHddCtx->cfg_ini->fhostArpOffload);
996 return NOTIFY_DONE;
997 }
998
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530999 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1000 {
1001 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1002 ifap = &ifa->ifa_next)
1003 {
1004 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1005 {
1006 break; /* found */
1007 }
1008 }
1009 }
1010 if(ifa && ifa->ifa_local)
1011 {
1012 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
1013 }
1014 }
1015
1016 return NOTIFY_DONE;
1017}
1018
1019/**----------------------------------------------------------------------------
1020
1021 \brief hdd_conf_arp_offload() - Configure ARP offload
1022
1023 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1024 reduces power consumption.
1025
1026 \param - pAdapter -Adapter context for which ARP offload is to be configured
1027 \param - fenable - 0 - disable.
1028 1 - enable. (with IPv4 notifier registration)
1029 2 - enable. (without IPv4 notifier registration)
1030
1031 \return -
1032 VOS_STATUS_SUCCESS - on successful operation
1033 VOS_STATUS_E_FAILURE - on failure of operation
1034-----------------------------------------------------------------------------*/
1035VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001036{
1037 struct in_ifaddr **ifap = NULL;
1038 struct in_ifaddr *ifa = NULL;
1039 struct in_device *in_dev;
1040 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001042 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001043
c_hpothu86feba52014-10-28 15:51:18 +05301044 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001045
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 if(fenable)
1047 {
1048 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1049 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301050 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001051 ifap = &ifa->ifa_next)
1052 {
1053 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1054 {
1055 break; /* found */
1056 }
1057 }
1058 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001059 if(ifa && ifa->ifa_local)
1060 {
1061 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1062 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1063
Arif Hussain6d2a3322013-11-17 19:50:10 -08001064 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001065
Amar Singhald53568e2013-09-26 11:03:45 -07001066 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1067 pHddCtx->sus_res_mcastbcast_filter) ||
1068 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1069 pHddCtx->sus_res_mcastbcast_filter)) &&
1070 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001071 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301072 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001073 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1074 hddLog(VOS_TRACE_LEVEL_INFO,
1075 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001076 }
Amar Singhald53568e2013-09-26 11:03:45 -07001077
1078 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1079 offLoadRequest.enableOrDisable);
1080
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 //converting u32 to IPV4 address
1082 for(i = 0 ; i < 4; i++)
1083 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301084 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001085 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1086 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301087 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001088 offLoadRequest.params.hostIpv4Addr[0],
1089 offLoadRequest.params.hostIpv4Addr[1],
1090 offLoadRequest.params.hostIpv4Addr[2],
1091 offLoadRequest.params.hostIpv4Addr[3]);
1092
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301093 if (eHAL_STATUS_SUCCESS !=
1094 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1095 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 {
1097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001098 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001099 return VOS_STATUS_E_FAILURE;
1100 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 }
1102 else
1103 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1105 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001106 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301107
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301108 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001109 }
1110 else
1111 {
1112 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1113 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1114 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1115
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301116 if (eHAL_STATUS_SUCCESS !=
1117 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1118 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 {
1120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001121 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001122 return VOS_STATUS_E_FAILURE;
1123 }
1124 return VOS_STATUS_SUCCESS;
1125 }
1126}
1127
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301128/*
1129 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301130 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301131*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301132void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301133 tANI_U8 *pMcBcFilter)
1134{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301135 if (NULL == pHddCtx)
1136 {
1137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1138 return;
1139 }
1140
1141 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1142 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301143 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301144 /* ARP offload is enabled, do not block bcast packets at RXP
1145 * Will be using Bitmasking to reset the filter. As we have
1146 * disable Broadcast filtering, Anding with the negation
1147 * of Broadcast BIT
1148 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301149 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301150 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301151
1152#ifdef WLAN_NS_OFFLOAD
1153 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301154 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301155 /* NS offload is enabled, do not block mcast packets at RXP
1156 * Will be using Bitmasking to reset the filter. As we have
1157 * disable Multicast filtering, Anding with the negation
1158 * of Multicast BIT
1159 */
1160 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301161 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301162#endif
1163
Amar Singhald08ce752014-03-21 16:28:27 -07001164 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1165 {
1166 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1167 }
1168
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301169 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301170}
1171
Jeff Johnson295189b2012-06-20 16:38:30 -07001172void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1173{
1174 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1176 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1177 if(NULL == wlanRxpFilterParam)
1178 {
1179 hddLog(VOS_TRACE_LEVEL_FATAL,
1180 "%s: vos_mem_alloc failed ", __func__);
1181 return;
1182 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001183 hddLog(VOS_TRACE_LEVEL_INFO,
1184 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301185 if (TRUE == setfilter)
1186 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301187 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301188 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301189 }
1190 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301191 {
1192 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301193 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301194 pHddCtx->configuredMcastBcastFilter;
1195 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301196
Jeff Johnson295189b2012-06-20 16:38:30 -07001197 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -07001199 if (eHAL_STATUS_SUCCESS != halStatus)
1200 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1202 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1203}
1204
Jeff Johnson295189b2012-06-20 16:38:30 -07001205static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1206 hdd_adapter_t *pAdapter)
1207{
1208 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1209 tpSirWlanSuspendParam wlanSuspendParam =
1210 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1211
Amar Singhald53568e2013-09-26 11:03:45 -07001212 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1213 pHddCtx->sus_res_mcastbcast_filter =
1214 pHddCtx->configuredMcastBcastFilter;
1215 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1216 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1217 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1218 pHddCtx->configuredMcastBcastFilter);
1219
1220 }
1221
Amar Singhal49fdfd52013-08-13 13:25:12 -07001222
Jeff Johnson295189b2012-06-20 16:38:30 -07001223 if(NULL == wlanSuspendParam)
1224 {
1225 hddLog(VOS_TRACE_LEVEL_FATAL,
1226 "%s: vos_mem_alloc failed ", __func__);
1227 return;
1228 }
1229
Amar Singhald53568e2013-09-26 11:03:45 -07001230 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001231 "%s: send wlan suspend indication", __func__);
1232
1233 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1234 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301235 //Configure supported OffLoads
1236 hdd_conf_hostoffload(pAdapter, TRUE);
1237 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301238 hddLog(VOS_TRACE_LEVEL_INFO,
1239 FL("saving configuredMcastBcastFilterSetting = %d"),
1240 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001241#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301242 /* During suspend, configure MC Addr list filter to the firmware
1243 * function takes care of checking necessary conditions before
1244 * configuring.
1245 */
1246 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001247#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001248
1249 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1250 {
1251
1252 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1253 pHddCtx->configuredMcastBcastFilter &=
1254 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1255 }
1256
1257 wlanSuspendParam->configuredMcstBcstFilterSetting =
1258 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 }
1260
1261 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1262 if(eHAL_STATUS_SUCCESS == halStatus)
1263 {
1264 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001265 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301266 hddLog(VOS_TRACE_LEVEL_ERROR,
1267 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001268 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001269 }
1270}
1271
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301272static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001273{
Chilam Ngc4244af2013-04-01 15:37:32 -07001274 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001275 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001276 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001277
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301278 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001279 "%s: send wlan resume indication", __func__);
1280
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301281 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1282
1283 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301285 hddLog(VOS_TRACE_LEVEL_FATAL,
1286 "%s: memory allocation failed for wlanResumeParam ", __func__);
1287 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001288 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001289
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301290 //Disable supported OffLoads
1291 hdd_conf_hostoffload(pAdapter, FALSE);
1292
1293 wlanResumeParam->configuredMcstBcstFilterSetting =
1294 pHddCtx->configuredMcastBcastFilter;
1295 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1296 if (eHAL_STATUS_SUCCESS != halStatus)
1297 {
c_hpothuffdb5272013-10-02 16:42:35 +05301298 hddLog(VOS_TRACE_LEVEL_ERROR,
1299 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301300 vos_mem_free(wlanResumeParam);
1301 }
1302
1303 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1304
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001305 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1306 pHddCtx->configuredMcastBcastFilter =
1307 pHddCtx->sus_res_mcastbcast_filter;
1308 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1309 }
Amar Singhald53568e2013-09-26 11:03:45 -07001310
1311 hddLog(VOS_TRACE_LEVEL_INFO,
1312 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1313 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1314 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001315
Chilam Ngc4244af2013-04-01 15:37:32 -07001316
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301317#ifdef WLAN_FEATURE_PACKET_FILTERING
1318 /* Filer was applied during suspend inditication
1319 * clear it when we resume.
1320 */
1321 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001322#endif
1323}
Jeff Johnson295189b2012-06-20 16:38:30 -07001324
Jeff Johnson295189b2012-06-20 16:38:30 -07001325//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001326void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001327{
1328 hdd_context_t *pHddCtx = NULL;
1329 v_CONTEXT_t pVosContext = NULL;
1330
Jeff Johnson295189b2012-06-20 16:38:30 -07001331 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301332 hdd_adapter_t *pAdapter = NULL;
1333 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301334 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001335
Jeff Johnson295189b2012-06-20 16:38:30 -07001336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1337
1338 //Get the global VOSS context.
1339 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1340 if(!pVosContext) {
1341 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1342 return;
1343 }
1344
1345 //Get the HDD context.
1346 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1347
1348 if(!pHddCtx) {
1349 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1350 return;
1351 }
1352
1353 if (pHddCtx->isLogpInProgress) {
1354 hddLog(VOS_TRACE_LEVEL_ERROR,
1355 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1356 return;
1357 }
1358
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301359 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301360 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001361 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1362 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1363 {
1364 pAdapter = pAdapterNode->pAdapter;
1365 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001366 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001367 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1368
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001369 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001370 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1371 pAdapterNode = pNext;
1372 continue;
1373 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301374 /* Avoid multiple enter/exit BMPS in this while loop using
1375 * hdd_enter_bmps flag
1376 */
1377 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1378 {
1379 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001380
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301381 /* If device was already in BMPS, and dynamic DTIM is set,
1382 * exit(set the device to full power) and enter BMPS again
1383 * to reflect new DTIM value */
1384 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1385
1386 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1387
1388 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001390#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1391 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1392 {
1393 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301394 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001395 netif_tx_disable(pAdapter->dev);
1396 netif_carrier_off(pAdapter->dev);
1397 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301398 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001399 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1400 {
1401 //Execute deep sleep procedure
1402 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1403 }
1404#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301405
1406 /*Suspend notification sent down to driver*/
1407 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1408
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301409 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1410 pAdapterNode = pNext;
1411 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301412
Jeff Johnson295189b2012-06-20 16:38:30 -07001413#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1414 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1415 {
1416 hdd_enter_standby(pHddCtx);
1417 }
1418#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001419
1420 return;
1421}
1422
1423static void hdd_PowerStateChangedCB
1424(
1425 v_PVOID_t callbackContext,
1426 tPmcState newState
1427)
1428{
1429 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301430
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 /* if the driver was not in BMPS during early suspend,
1432 * the dynamic DTIM is now updated at Riva */
1433 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1434 && pHddCtx->cfg_ini->enableDynamicDTIM
1435 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1436 {
1437 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1438 }
1439 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301440 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1441 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001442 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301443 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1444 {
Amar Singhald53568e2013-09-26 11:03:45 -07001445 pHddCtx->sus_res_mcastbcast_filter =
1446 pHddCtx->configuredMcastBcastFilter;
1447 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1448
1449 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1450 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1451 pHddCtx->configuredMcastBcastFilter);
1452 hddLog(VOS_TRACE_LEVEL_INFO,
1453 "offload: calling hdd_conf_mcastbcast_filter");
1454
1455 }
1456
Jeff Johnson295189b2012-06-20 16:38:30 -07001457 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301460 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001461 else
Mihir Shete793209f2014-01-06 11:01:12 +05301462 {
1463 /* Android framework can send resume request when the WCN chip is
1464 * in IMPS mode. When the chip exits IMPS mode the firmware will
1465 * restore all the registers to the state they were before the chip
1466 * entered IMPS and so our hardware filter settings confgured by the
1467 * resume request will be lost. So reconfigure the filters on detecting
1468 * a change in the power state of the WCN chip.
1469 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301470 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301471 if (IMPS != newState)
1472 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301473 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301474 if (FALSE == pHddCtx->hdd_wlan_suspended)
1475 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301476 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301477 hddLog(VOS_TRACE_LEVEL_INFO,
1478 "Not in IMPS/BMPS and suspended state");
1479 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1480 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301481 else
1482 {
1483 spin_unlock(&pHddCtx->filter_lock);
1484 }
Mihir Shete793209f2014-01-06 11:01:12 +05301485 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301486 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001487}
1488
Jeff Johnson295189b2012-06-20 16:38:30 -07001489void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1490{
1491 v_CONTEXT_t pVosContext;
1492 tHalHandle smeContext;
1493
1494 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1495 if (NULL == pVosContext)
1496 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001497 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001498 return;
1499 }
1500 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1501 if (NULL == smeContext)
1502 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001503 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001504 return;
1505 }
1506
1507 spin_lock_init(&pHddCtx->filter_lock);
1508 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1509 pHddCtx->cfg_ini->nEnableSuspend)
1510 {
1511 pmcRegisterDeviceStateUpdateInd(smeContext,
1512 hdd_PowerStateChangedCB, pHddCtx);
1513 }
1514}
1515
1516void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1517{
1518 v_CONTEXT_t pVosContext;
1519 tHalHandle smeContext;
1520
1521 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1522 if (NULL == pVosContext)
1523 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001524 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 return;
1526 }
1527 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1528 if (NULL == smeContext)
1529 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001530 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001531 return;
1532 }
1533
1534 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1535 pHddCtx->cfg_ini->nEnableSuspend)
1536 {
1537 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1538 }
1539}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301540
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301541#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301542void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301543{
1544 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301545 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301546 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1547
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301548 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301549 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301550 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1551 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1552 {
1553 vos_mem_copy(&hddGtkOffloadReqParams,
1554 &pHddStaCtx->gtkOffloadReqParams,
1555 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301556
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301557 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1558 &hddGtkOffloadReqParams, pAdapter->sessionId);
1559 if (eHAL_STATUS_SUCCESS != ret)
1560 {
1561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1562 "%s: sme_SetGTKOffload failed, returned %d",
1563 __func__, ret);
1564 return;
1565 }
1566
1567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1568 "%s: sme_SetGTKOffload successfull", __func__);
1569 }
1570
1571 }
1572 else
1573 {
1574 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1575 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1576 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1577 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1578 {
1579
1580 /* Host driver has previously offloaded GTK rekey */
1581 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301582 wlan_hdd_cfg80211_update_replayCounterCallback,
1583 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301584 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301585
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301586 {
1587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1588 "%s: sme_GetGTKOffload failed, returned %d",
1589 __func__, ret);
1590 return;
1591 }
1592 else
1593 {
1594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1595 "%s: sme_GetGTKOffload successful",
1596 __func__);
1597
1598 /* Sending GTK offload dissable */
1599 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1600 sizeof (tSirGtkOffloadParams));
1601 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1602 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301603 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301604 if (eHAL_STATUS_SUCCESS != ret)
1605 {
1606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1607 "%s: failed to dissable GTK offload, returned %d",
1608 __func__, ret);
1609 return;
1610 }
1611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1612 "%s: successfully dissabled GTK offload request to HAL",
1613 __func__);
1614 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301615 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301616 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301617 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301618}
1619#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001620
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001621void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001622{
1623 hdd_context_t *pHddCtx = NULL;
1624 hdd_adapter_t *pAdapter = NULL;
1625 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1626 VOS_STATUS status;
1627 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001628
Jeff Johnson295189b2012-06-20 16:38:30 -07001629 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1630
1631 //Get the global VOSS context.
1632 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1633 if(!pVosContext) {
1634 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1635 return;
1636 }
1637
1638 //Get the HDD context.
1639 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1640
1641 if(!pHddCtx) {
1642 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1643 return;
1644 }
1645
Agarwal Ashish971c2882013-10-30 20:11:12 +05301646 if (pHddCtx->isLogpInProgress)
1647 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 hddLog(VOS_TRACE_LEVEL_INFO,
1649 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1650 return;
1651 }
1652
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 pHddCtx->hdd_wlan_suspended = FALSE;
1654 /*loop through all adapters. Concurrency */
1655 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1656
1657 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1658 {
1659 pAdapter = pAdapterNode->pAdapter;
1660 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001661 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001662 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001663 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001664 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1665 pAdapterNode = pNext;
1666 continue;
1667 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301668
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301669
Jeff Johnson295189b2012-06-20 16:38:30 -07001670#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1671 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1672 {
1673 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1674 hdd_exit_deep_sleep(pAdapter);
1675 }
1676#endif
1677
1678 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1679 {
1680 /*Switch back to DTIM 1*/
1681 tSirSetPowerParamsReq powerRequest = { 0 };
1682
1683 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1684 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001685 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001686
1687 /*Disabled ModulatedDTIM if enabled on suspend*/
1688 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1689 powerRequest.uDTIMPeriod = 0;
1690
1691 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1692 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1693 NULL, eANI_BOOLEAN_FALSE);
1694 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1695 NULL, eANI_BOOLEAN_FALSE);
1696
1697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001698 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001699 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001700
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301701 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1702 {
1703 /* put the device into full power */
1704 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001705
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301706 /* put the device back into BMPS */
1707 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001708
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301709 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1710 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001711 }
1712
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301713 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001714 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1715 pAdapterNode = pNext;
1716 }
1717
1718#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1719 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1720 {
1721 hdd_exit_standby(pHddCtx);
1722 }
1723#endif
1724
Jeff Johnson295189b2012-06-20 16:38:30 -07001725 return;
1726}
1727
Jeff Johnson295189b2012-06-20 16:38:30 -07001728VOS_STATUS hdd_wlan_reset_initialization(void)
1729{
Jeff Johnson295189b2012-06-20 16:38:30 -07001730 v_CONTEXT_t pVosContext = NULL;
1731
1732 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1733
1734 //Get the global VOSS context.
1735 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1736 if(!pVosContext)
1737 {
1738 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1739 return VOS_STATUS_E_FAILURE;
1740 }
1741
1742 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1743
1744 // Prevent the phone from going to sleep
1745 hdd_prevent_suspend();
1746
Jeff Johnson295189b2012-06-20 16:38:30 -07001747 return VOS_STATUS_SUCCESS;
1748}
1749
1750
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001751/*
1752 * Based on the ioctl command recieved by HDD, put WLAN driver
1753 * into the quiet mode. This is the same as the early suspend
1754 * notification that driver used to listen
1755 */
1756void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001757{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301758 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001759 if (suspend)
1760 hdd_suspend_wlan();
1761 else
1762 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301763 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001764}
1765
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001766static void hdd_ssr_timer_init(void)
1767{
1768 init_timer(&ssr_timer);
1769}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001770
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001771static void hdd_ssr_timer_del(void)
1772{
1773 del_timer(&ssr_timer);
1774 ssr_timer_started = false;
1775}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001776
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001777static void hdd_ssr_timer_cb(unsigned long data)
1778{
1779 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001780
1781#ifdef WCN_PRONTO
1782 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1783 wcnss_pronto_log_debug_regs();
1784#endif
1785
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001786 VOS_BUG(0);
1787}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001788
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001789static void hdd_ssr_timer_start(int msec)
1790{
1791 if(ssr_timer_started)
1792 {
1793 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1794 ,__func__);
1795 }
1796 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1797 ssr_timer.function = hdd_ssr_timer_cb;
1798 add_timer(&ssr_timer);
1799 ssr_timer_started = true;
1800}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001801
Jeff Johnson295189b2012-06-20 16:38:30 -07001802/* the HDD interface to WLAN driver shutdown,
1803 * the primary shutdown function in SSR
1804 */
1805VOS_STATUS hdd_wlan_shutdown(void)
1806{
1807 VOS_STATUS vosStatus;
1808 v_CONTEXT_t pVosContext = NULL;
1809 hdd_context_t *pHddCtx = NULL;
1810 pVosSchedContext vosSchedContext = NULL;
1811
1812 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1813
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001814 /* if re-init never happens, then do SSR1 */
1815 hdd_ssr_timer_init();
1816 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1817
Jeff Johnson295189b2012-06-20 16:38:30 -07001818 /* Get the global VOSS context. */
1819 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1820 if(!pVosContext) {
1821 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1822 return VOS_STATUS_E_FAILURE;
1823 }
1824 /* Get the HDD context. */
1825 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1826 if(!pHddCtx) {
1827 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1828 return VOS_STATUS_E_FAILURE;
1829 }
c_hpothud662a352013-12-26 15:09:12 +05301830
1831 //Stop the traffic monitor timer
1832 if ( VOS_TIMER_STATE_RUNNING ==
1833 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1834 {
1835 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1836 }
1837
Jeff Johnson295189b2012-06-20 16:38:30 -07001838 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 /* DeRegister with platform driver as client for Suspend/Resume */
1840 vosStatus = hddDeregisterPmOps(pHddCtx);
1841 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1842 {
1843 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1844 }
1845
1846 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1847 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1848 {
1849 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1850 }
1851
1852 /* Disable IMPS/BMPS as we do not want the device to enter any power
1853 * save mode on its own during reset sequence
1854 */
1855 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1856 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1857 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1858
1859 vosSchedContext = get_vos_sched_ctxt();
1860
1861 /* Wakeup all driver threads */
1862 if(TRUE == pHddCtx->isMcThreadSuspended){
1863 complete(&vosSchedContext->ResumeMcEvent);
1864 pHddCtx->isMcThreadSuspended= FALSE;
1865 }
1866 if(TRUE == pHddCtx->isTxThreadSuspended){
1867 complete(&vosSchedContext->ResumeTxEvent);
1868 pHddCtx->isTxThreadSuspended= FALSE;
1869 }
1870 if(TRUE == pHddCtx->isRxThreadSuspended){
1871 complete(&vosSchedContext->ResumeRxEvent);
1872 pHddCtx->isRxThreadSuspended= FALSE;
1873 }
1874 /* Reset the Suspend Variable */
1875 pHddCtx->isWlanSuspended = FALSE;
1876
1877 /* Stop all the threads; we do not want any messages to be a processed,
1878 * any more and the best way to ensure that is to terminate the threads
1879 * gracefully.
1880 */
1881 /* Wait for MC to exit */
1882 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1883 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1884 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1885 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301886 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001887
1888 /* Wait for TX to exit */
1889 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1890 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1891 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1892 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301893 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001894
1895 /* Wait for RX to exit */
1896 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1897 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1898 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1899 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301900
Mihir Sheteb5425f72013-12-19 09:06:13 +05301901 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001902
1903#ifdef WLAN_BTAMP_FEATURE
1904 vosStatus = WLANBAP_Stop(pVosContext);
1905 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1906 {
1907 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1908 "%s: Failed to stop BAP",__func__);
1909 }
1910#endif //WLAN_BTAMP_FEATURE
1911 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301912 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1913 {
1914 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1915 "%s: Failed to stop wda %d", __func__, vosStatus);
1916 VOS_ASSERT(0);
1917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001918
1919 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1920 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1921 * on threads being running to process the SYS Stop
1922 */
Kiet Lama72a2322013-11-15 11:18:11 +05301923 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301924 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1925 {
1926 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1927 "%s: Failed to stop sme %d", __func__, vosStatus);
1928 VOS_ASSERT(0);
1929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001930
1931 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1932 /* Stop MAC (PE and HAL) */
1933 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301934 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1935 {
1936 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1937 "%s: Failed to stop mac %d", __func__, vosStatus);
1938 VOS_ASSERT(0);
1939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001940
1941 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1942 /* Stop TL */
1943 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301944 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1945 {
1946 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1947 "%s: Failed to stop TL %d", __func__, vosStatus);
1948 VOS_ASSERT(0);
1949 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001950
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001952 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1953 /* Clean up message queues of TX and MC thread */
1954 vos_sched_flush_mc_mqs(vosSchedContext);
1955 vos_sched_flush_tx_mqs(vosSchedContext);
1956 vos_sched_flush_rx_mqs(vosSchedContext);
1957
1958 /* Deinit all the TX and MC queues */
1959 vos_sched_deinit_mqs(vosSchedContext);
1960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1961
1962 /* shutdown VOSS */
1963 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301964
1965 /*mac context has already been released in mac_close call
1966 so setting it to NULL in hdd context*/
1967 pHddCtx->hHal = (tHalHandle)NULL;
1968
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 if (free_riva_power_on_lock("wlan"))
1970 {
1971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1972 __func__);
1973 }
1974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1975 ,__func__);
1976 return VOS_STATUS_SUCCESS;
1977}
1978
1979
1980
1981/* the HDD interface to WLAN driver re-init.
1982 * This is called to initialize/start WLAN driver after a shutdown.
1983 */
1984VOS_STATUS hdd_wlan_re_init(void)
1985{
1986 VOS_STATUS vosStatus;
1987 v_CONTEXT_t pVosContext = NULL;
1988 hdd_context_t *pHddCtx = NULL;
1989 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001990#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1991 int max_retries = 0;
1992#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001993#ifdef WLAN_BTAMP_FEATURE
1994 hdd_config_t *pConfig = NULL;
1995 WLANBAP_ConfigType btAmpConfig;
1996#endif
1997
Katya Nigam82a93062014-06-04 15:15:36 +05301998 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001999 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002001
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002002#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2003 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002004 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002005 msleep(1000);
2006 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002007 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002008 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2009 goto err_re_init;
2010 }
2011#endif
2012
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002013 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2014
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002015 /* The driver should always be initialized in STA mode after SSR */
2016 hdd_set_conparam(0);
2017
Katya Nigam82a93062014-06-04 15:15:36 +05302018 dev = wcnss_wlan_get_device();
2019 if (NULL == dev)
2020 {
2021 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2022 goto err_re_init;
2023 }
2024
Jeff Johnson295189b2012-06-20 16:38:30 -07002025 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302026 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002027 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2028 {
2029 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2030 goto err_re_init;
2031 }
2032
2033 /* Get the HDD context. */
2034 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2035 if(!pHddCtx)
2036 {
2037 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2038 goto err_vosclose;
2039 }
2040
2041 /* Save the hal context in Adapter */
2042 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2043 if ( NULL == pHddCtx->hHal )
2044 {
2045 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2046 goto err_vosclose;
2047 }
2048
2049 /* Set the SME configuration parameters. */
2050 vosStatus = hdd_set_sme_config(pHddCtx);
2051 if ( VOS_STATUS_SUCCESS != vosStatus )
2052 {
2053 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2054 goto err_vosclose;
2055 }
2056
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 vosStatus = vos_preStart( pHddCtx->pvosContext );
2058 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2059 {
2060 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2061 goto err_vosclose;
2062 }
2063
2064 /* In the integrated architecture we update the configuration from
2065 the INI file and from NV before vOSS has been started so that
2066 the final contents are available to send down to the cCPU */
2067 /* Apply the cfg.ini to cfg.dat */
2068 if (FALSE == hdd_update_config_dat(pHddCtx))
2069 {
2070 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2071 goto err_vosclose;
2072 }
2073
2074 /* Set the MAC Address, currently this is used by HAL to add self sta.
2075 * Remove this once self sta is added as part of session open. */
2076 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2077 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2078 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2079 if (!HAL_STATUS_SUCCESS(halStatus))
2080 {
2081 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2082 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2083 goto err_vosclose;
2084 }
2085
2086 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2087 Note: Firmware image will be read and downloaded inside vos_start API */
2088 vosStatus = vos_start( pVosContext );
2089 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2090 {
2091 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2092 goto err_vosclose;
2093 }
2094
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002095 /* Exchange capability info between Host and FW and also get versioning info from FW */
2096 hdd_exchange_version_and_caps(pHddCtx);
2097
Jeff Johnson295189b2012-06-20 16:38:30 -07002098 vosStatus = hdd_post_voss_start_config( pHddCtx );
2099 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2100 {
2101 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2102 __func__);
2103 goto err_vosstop;
2104 }
2105
Mihir Shete04206452014-11-20 17:50:58 +05302106#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302107 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2108 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2109 {
2110 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2111 __func__);
2112 goto err_vosstop;
2113 }
Mihir Shete04206452014-11-20 17:50:58 +05302114#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302115
Jeff Johnson295189b2012-06-20 16:38:30 -07002116#ifdef WLAN_BTAMP_FEATURE
2117 vosStatus = WLANBAP_Open(pVosContext);
2118 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2119 {
2120 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2121 "%s: Failed to open BAP",__func__);
2122 goto err_vosstop;
2123 }
2124 vosStatus = BSL_Init(pVosContext);
2125 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2126 {
2127 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2128 "%s: Failed to Init BSL",__func__);
2129 goto err_bap_close;
2130 }
2131 vosStatus = WLANBAP_Start(pVosContext);
2132 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2133 {
2134 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2135 "%s: Failed to start TL",__func__);
2136 goto err_bap_close;
2137 }
2138 pConfig = pHddCtx->cfg_ini;
2139 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2140 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2141#endif //WLAN_BTAMP_FEATURE
2142
2143 /* Restart all adapters */
2144 hdd_start_all_adapters(pHddCtx);
2145 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002146 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302148 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002149 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302150 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002151 /* Register with platform driver as client for Suspend/Resume */
2152 vosStatus = hddRegisterPmOps(pHddCtx);
2153 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2154 {
2155 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2156 goto err_bap_stop;
2157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002158 /* Allow the phone to go to sleep */
2159 hdd_allow_suspend();
2160 /* register for riva power on lock */
2161 if (req_riva_power_on_lock("wlan"))
2162 {
2163 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2164 __func__);
2165 goto err_unregister_pmops;
2166 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002167 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302168#ifdef WLAN_FEATURE_EXTSCAN
2169 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2170 wlan_hdd_cfg80211_extscan_callback,
2171 pHddCtx);
2172#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 goto success;
2174
2175err_unregister_pmops:
2176 hddDeregisterPmOps(pHddCtx);
2177
2178err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002179#ifdef CONFIG_HAS_EARLYSUSPEND
2180 hdd_unregister_mcast_bcast_filter(pHddCtx);
2181#endif
2182 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002183#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002184 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002185#endif
2186
2187#ifdef WLAN_BTAMP_FEATURE
2188err_bap_close:
2189 WLANBAP_Close(pVosContext);
2190#endif
2191
2192err_vosstop:
2193 vos_stop(pVosContext);
2194
2195err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302196 if(!isSsrPanicOnFailure())
2197 {
2198 /* If we hit this, it means wlan driver is in bad state and needs
2199 * driver unload and load.
2200 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302201 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2202 return VOS_STATUS_E_FAILURE;
2203 }
2204
Jeff Johnson295189b2012-06-20 16:38:30 -07002205 vos_close(pVosContext);
2206 vos_sched_close(pVosContext);
2207 if (pHddCtx)
2208 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002209 /* Unregister the Net Device Notifier */
2210 unregister_netdevice_notifier(&hdd_netdev_notifier);
2211 /* Clean up HDD Nlink Service */
2212 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002213#ifdef WLAN_KD_READY_NOTIFIER
2214 nl_srv_exit(pHddCtx->ptt_pid);
2215#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002217#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 /* Free up dynamically allocated members inside HDD Adapter */
2219 kfree(pHddCtx->cfg_ini);
2220 pHddCtx->cfg_ini= NULL;
2221
Jeff Johnson295189b2012-06-20 16:38:30 -07002222 wiphy_unregister(pHddCtx->wiphy);
2223 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002224 }
2225 vos_preClose(&pVosContext);
2226
2227#ifdef MEMORY_DEBUG
2228 vos_mem_exit();
2229#endif
2230
2231err_re_init:
2232 /* Allow the phone to go to sleep */
2233 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002234 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002235 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002236 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002237
2238success:
2239 /* Trigger replay of BTC events */
2240 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2241 return VOS_STATUS_SUCCESS;
2242}