blob: e6bc20152d59d6bd3206129ab62a86e0f017b250 [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.
314 netif_tx_disable(pAdapter->dev);
315 netif_carrier_off(pAdapter->dev);
316
317 //Disable IMPS,BMPS as we do not want the device to enter any power
318 //save mode on it own during suspend sequence
319 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
320 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
321
322 //Ensure that device is in full power as we will touch H/W during vos_Stop
323 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
324 g_full_pwr_status = eHAL_STATUS_FAILURE;
325 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
326 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
327
328 if(halStatus == eHAL_STATUS_PMC_PENDING)
329 {
330 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530331 ret = wait_for_completion_interruptible_timeout(
332 &pHddCtx->full_pwr_comp_var,
333 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
334 if (0 >= ret)
335 {
336 hddLog(VOS_TRACE_LEVEL_ERROR,
337 FL("wait on full_pwr_comp_var failed %ld"), ret);
338 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700339 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
340 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
341 VOS_ASSERT(0);
342 }
343 }
344 else if(halStatus != eHAL_STATUS_SUCCESS)
345 {
346 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
347 VOS_ASSERT(0);
348 }
349
350 //Issue a disconnect. This is required to inform the supplicant that
351 //STA is getting disassociated and for GUI to be updated properly
352 INIT_COMPLETION(pAdapter->disconnect_comp_var);
353 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
354
355 //Success implies disconnect command got queued up successfully
356 if(halStatus == eHAL_STATUS_SUCCESS)
357 {
358 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530359 ret = wait_for_completion_interruptible_timeout(
360 &pAdapter->disconnect_comp_var,
361 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
362 if (0 >= ret)
363 {
364 hddLog(VOS_TRACE_LEVEL_ERROR,
365 FL("wait on disconnect_comp_var failed %ld"), ret);
366 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700367 }
368
369
370 //None of the steps should fail after this. Continue even in case of failure
371 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530372 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
373 {
374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
375 __func__, vosStatus);
376 VOS_ASSERT(0);
377 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700378
Jeff Johnson295189b2012-06-20 16:38:30 -0700379 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
380
381 //Restore IMPS config
382 if(pHddCtx->cfg_ini->fIsImpsEnabled)
383 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
384
385 //Restore BMPS config
386 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
387 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
388
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 return vosStatus;
390}
391
392VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
393{
394 VOS_STATUS vosStatus;
395 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700396
Jeff Johnson295189b2012-06-20 16:38:30 -0700397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
398 "%s: calling hdd_set_sme_config",__func__);
399 vosStatus = hdd_set_sme_config( pHddCtx );
400 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
401 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
402 {
403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
404 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700405 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700406 }
407
408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
409 "%s: calling vos_start",__func__);
410 vosStatus = vos_start( pHddCtx->pvosContext );
411 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
412 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
413 {
414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
415 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700416 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700417 }
418
419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
420 "%s: calling hdd_post_voss_start_config",__func__);
421 vosStatus = hdd_post_voss_start_config( pHddCtx );
422 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
423 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
424 {
425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
426 "%s: Failed in hdd_post_voss_start_config",__func__);
427 goto err_voss_stop;
428 }
429
430
431 //Open a SME session for future operation
432 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700433 (tANI_U8 *)&pAdapter->macAddressCurrent,
434 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700435 if ( !HAL_STATUS_SUCCESS( halStatus ) )
436 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700437 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700438 halStatus, halStatus );
439 goto err_voss_stop;
440
441 }
442
443 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
444
445 //Trigger the initial scan
446 hdd_wlan_initial_scan(pHddCtx);
447
448 return VOS_STATUS_SUCCESS;
449
450err_voss_stop:
451 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700452err_deep_sleep:
453 return VOS_STATUS_E_FAILURE;
454
455}
456
Atul Mittal37385d72014-03-27 18:15:03 +0530457void hdd_ipv6_notifier_work_queue(struct work_struct *work)
458{
459 hdd_adapter_t* pAdapter =
460 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
461 hdd_context_t *pHddCtx;
462 int status;
463
464 hddLog(LOG1, FL("Reconfiguring NS Offload"));
465
466 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
467 status = wlan_hdd_validate_context(pHddCtx);
468 if (0 != status)
469 {
470 hddLog(LOGE, FL("HDD context is invalid"));
471 return;
472 }
473
474 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
475 {
476 pHddCtx->sus_res_mcastbcast_filter =
477 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530478 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
479 pHddCtx->sus_res_mcastbcast_filter);
Atul Mittal37385d72014-03-27 18:15:03 +0530480 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
481 }
482
483 if ((eConnectionState_Associated ==
484 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
485 && (pHddCtx->hdd_wlan_suspended))
486 {
487 // This invocation being part of the IPv6 registration callback,
488 // set the newly generated ip address to f/w in suspend mode.
489#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530490 if (pHddCtx->cfg_ini->fhostNSOffload)
491 {
492 hdd_conf_ns_offload(pAdapter, 1);
493 }
Atul Mittal37385d72014-03-27 18:15:03 +0530494#endif
495 }
496#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530497 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530498 * only so when new ipv6 address is generated the screen may not
499 * on so we need to call it here to update the list in f/w.
500 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530501 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530502#endif
503
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530504
Atul Mittal37385d72014-03-27 18:15:03 +0530505}
506
507
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530508int wlan_hdd_ipv6_changed(struct notifier_block *nb,
509 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530510{
511 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
512 struct net_device *ndev = ifa->idev->dev;
513 hdd_adapter_t *pAdapter =
514 container_of(nb, struct hdd_adapter_s, ipv6_notifier);
515 hdd_context_t *pHddCtx;
516 int status;
517
518 if (pAdapter && pAdapter->dev == ndev)
519 {
520 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
521 status = wlan_hdd_validate_context(pHddCtx);
522 if (0 != status)
523 {
524 hddLog(LOGE, FL("HDD context is invalid"));
525 return NOTIFY_DONE;
526 }
527
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530528 if (pHddCtx->cfg_ini->nEnableSuspend ==
529 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
530 {
531 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
532 }
533 else
534 {
535 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
536 pHddCtx->cfg_ini->nEnableSuspend);
537 }
Atul Mittal37385d72014-03-27 18:15:03 +0530538 }
539
540 return NOTIFY_DONE;
541}
542
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530543/*
544 * Function: hdd_conf_hostoffload
545 * Central function to configure the supported offloads,
546 * either enable or disable them.
547 */
548void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
549{
550 hdd_context_t *pHddCtx = NULL;
551 v_CONTEXT_t *pVosContext = NULL;
552 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
553
554 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
555 fenable);
556
557 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
558
559 if (NULL == pVosContext)
560 {
561 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
562 return;
563 }
564
565 //Get the HDD context.
566 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
567
568 if (NULL == pHddCtx)
569 {
570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
571 return;
572 }
573
574 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
575 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
576 {
577 if (fenable)
578 {
579 if (eConnectionState_Associated ==
580 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
581 {
582 if ((pHddCtx->cfg_ini->fhostArpOffload))
583 {
584 /*
585 * Configure the ARP Offload.
586 * Even if it fails we have to reconfigure the MC/BC
587 * filter flag as we want RIVA not to drop BroadCast
588 * Packets
589 */
590 hddLog(VOS_TRACE_LEVEL_INFO,
591 FL("Calling ARP Offload with flag: %d"), fenable);
592 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
593 pHddCtx->configuredMcastBcastFilter &=
594 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
595
596 if (!VOS_IS_STATUS_SUCCESS(vstatus))
597 {
598 hddLog(VOS_TRACE_LEVEL_ERROR,
599 "Failed to enable ARPOFfloadFeature %d",
600 vstatus);
601 }
602 }
603 //Configure GTK_OFFLOAD
604#ifdef WLAN_FEATURE_GTK_OFFLOAD
605 hdd_conf_gtk_offload(pAdapter, fenable);
606#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530607
608#ifdef WLAN_NS_OFFLOAD
609 if (pHddCtx->cfg_ini->fhostNSOffload)
610 {
611 /*
612 * Configure the NS Offload.
613 * Even if it fails we have to reconfigure the MC/BC filter flag
614 * as we want RIVA not to drop Multicast Packets
615 */
616
617 hddLog(VOS_TRACE_LEVEL_INFO,
618 FL("Calling NS Offload with flag: %d"), fenable);
619 hdd_conf_ns_offload(pAdapter, fenable);
620 pHddCtx->configuredMcastBcastFilter &=
621 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
622 }
623#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530624
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530625 }
626 }
627 else
628 {
629 //Disable ARPOFFLOAD
630 if (pHddCtx->cfg_ini->fhostArpOffload)
631 {
632 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
633 if (!VOS_IS_STATUS_SUCCESS(vstatus))
634 {
635 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530636 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530637 }
638 }
639 //Disable GTK_OFFLOAD
640#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530641 hdd_conf_gtk_offload(pAdapter, fenable);
642#endif
643
644#ifdef WLAN_NS_OFFLOAD
645 //Disable NSOFFLOAD
646 if (pHddCtx->cfg_ini->fhostNSOffload)
647 {
648 hdd_conf_ns_offload(pAdapter, fenable);
649 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530650#endif
651 }
652 }
653 return;
654}
655
Atul Mittal37385d72014-03-27 18:15:03 +0530656
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530657#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530658/**----------------------------------------------------------------------------
659
660 \brief hdd_conf_ns_offload() - Configure NS offload
661
662 Called during SUSPEND to configure the NS offload (MC BC filter) which
663 reduces power consumption.
664
665 \param - pAdapter - Adapter context for which NS offload is to be configured
666 \param - fenable - 0 - disable.
667 1 - enable. (with IPv6 notifier registration)
668 2 - enable. (without IPv6 notifier registration)
669
670 \return - void
671
672 ---------------------------------------------------------------------------*/
673void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530674{
675 struct inet6_dev *in6_dev;
676 struct inet6_ifaddr *ifp;
677 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530678 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530679 tANI_U8 **selfIPv6Addr = NULL;
680 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530681 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530682 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530683 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530684
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530685 int i = 0, slot = 0;
686 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530687 eHalStatus returnStatus;
688
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530689 ENTER();
690 hddLog(LOG1, FL(" fenable = %d"), fenable);
691
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530692 if (NULL == pAdapter)
693 {
694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
695 return;
696 }
697
698 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530699 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
700
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530701 ret = wlan_hdd_validate_context(pHddCtx);
702
703 if (0 != ret)
704 {
705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
706 FL("HDD context is not valid"));
707 return;
708 }
709
710 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
711 {
712 slot_index = NS_EXTENDED_SLOT_INDEX;
713 }
714
715 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
716
717 selfIPv6AddrValid =
718 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
719
720 if (NULL == selfIPv6AddrValid)
721 {
722 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
723 " selfIPv6AddrValid"));
724 goto end;
725 }
726
727 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
728
729 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
730
731 if (NULL == selfIPv6Addr)
732 {
733 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
734 " selfIPv6Addr"));
735 goto end;
736 }
737
738 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
739
740 for (slot = 0; slot < slot_index; slot++)
741 {
742 selfIPv6Addr[slot] =
743 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
744 if (NULL == selfIPv6Addr[slot])
745 {
746 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
747 "for selfIPv6Addr"));
748 goto end;
749 }
750 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
751 }
752
753 i = 0;
754
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530755 if (fenable)
756 {
757 in6_dev = __in6_dev_get(pAdapter->dev);
758 if (NULL != in6_dev)
759 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530760 list_for_each(p, &in6_dev->addr_list)
761 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530762 if (i >= slot_index)
763 {
764 hddLog (VOS_TRACE_LEVEL_ERROR,
765 FL("IPv6 address list is greater than IPv6"
766 "address supported by firmware"));
767 hddLog (VOS_TRACE_LEVEL_ERROR,
768 FL("FW supported IPv6 address = %d"), slot_index);
769 break;
770 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530771 ifp = list_entry(p, struct inet6_ifaddr, if_list);
772 switch(ipv6_addr_src_scope(&ifp->addr))
773 {
774 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530775 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530776 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530777 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530778 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530779 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
780 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530781 break;
782 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530783 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530784 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530785 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530786 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530787 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
788 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530789 break;
790 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530791 hddLog(VOS_TRACE_LEVEL_ERROR,
792 FL("The Scope %d is not supported"),
793 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530794 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530795 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
796 {
797 i++;
798 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530799 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530800
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530801 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530802 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530803 {
804 if (selfIPv6AddrValid[i])
805 {
806 //Filling up the request structure
807 /* Filling the selfIPv6Addr with solicited address
808 * A Solicited-Node multicast address is created by
809 * taking the last 24 bits of a unicast or anycast
810 * address and appending them to the prefix
811 *
812 * FF02:0000:0000:0000:0000:0001:FFXX:XX
813 *
814 * here XX is the unicast/anycast bits
815 */
816 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
817 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
818 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
819 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530820 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
821 selfIPv6Addr[i][13];
822 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
823 selfIPv6Addr[i][14];
824 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
825 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530826 offLoadRequest.nsOffloadInfo.slotIdx = i;
827
828 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530829 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530830 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
831 &pAdapter->macAddressCurrent.bytes,
832 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
833
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530834 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
835 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530836 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
837 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
838
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530839 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530840 FL("configuredMcastBcastFilter: %d"
841 "NSOffload Slot = %d"),
842 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530843
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530844 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700845 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
846 pHddCtx->sus_res_mcastbcast_filter) ||
847 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
848 pHddCtx->sus_res_mcastbcast_filter)) &&
849 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
850 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
851 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530852 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530853 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700854 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530855 hddLog (VOS_TRACE_LEVEL_INFO,
856 FL("Set offLoadRequest with %d"),
857 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530858 }
859
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530860 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
861 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
862 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
863
864 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530865 FL("Setting NSOffload with solicitedIp: %pI6,"
866 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530867 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
868 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
869
870 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530871 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530872 pAdapter->sessionId, &offLoadRequest);
873 if(eHAL_STATUS_SUCCESS != returnStatus)
874 {
875 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530876 FL("Failed to enable HostOffload feature with"
877 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530878 }
879 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
880 }
881 }
882 }
883 else
884 {
885 hddLog(VOS_TRACE_LEVEL_ERROR,
886 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530887 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530888 }
889 }
890 else
891 {
892 //Disable NSOffload
893 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
894 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
895 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
896
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530897 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530898 {
c_hpothu86feba52014-10-28 15:51:18 +0530899 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530900 offLoadRequest.nsOffloadInfo.slotIdx = i;
901 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530902 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
903 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530904 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
906 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530907 }
908 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530909 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530910end:
911 while (slot > 0 && selfIPv6Addr[--slot])
912 {
913 vos_mem_free(selfIPv6Addr[slot]);
914 }
915 if (selfIPv6Addr)
916 {
917 vos_mem_free(selfIPv6Addr);
918 }
919 if (selfIPv6AddrValid)
920 {
921 vos_mem_free(selfIPv6AddrValid);
922 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530923 return;
924}
925#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530926
927void hdd_ipv4_notifier_work_queue(struct work_struct *work)
928{
929 hdd_adapter_t* pAdapter =
930 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
931 hdd_context_t *pHddCtx;
932 int status;
933
934 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
935 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
936 status = wlan_hdd_validate_context(pHddCtx);
937 if (0 != status)
938 {
939 hddLog(LOGE, FL("HDD context is invalid"));
940 return;
941 }
942
Deepthi Gowri5933f402014-01-23 17:48:24 +0530943 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
944 {
945 pHddCtx->sus_res_mcastbcast_filter =
946 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530947 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
948 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530949 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
950 }
951
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530952 if ((eConnectionState_Associated ==
953 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530954 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530955 {
956 // This invocation being part of the IPv4 registration callback,
957 // we are passing second parameter as 2 to avoid registration
958 // of IPv4 notifier again.
959 hdd_conf_arp_offload(pAdapter, 2);
960 }
961}
962
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530963int wlan_hdd_ipv4_changed(struct notifier_block *nb,
964 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530965{
966 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
967 struct in_ifaddr **ifap = NULL;
968 struct in_device *in_dev;
969
970 struct net_device *ndev = ifa->ifa_dev->dev;
971 hdd_adapter_t *pAdapter =
972 container_of(nb, struct hdd_adapter_s, ipv4_notifier);
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530973 hdd_context_t *pHddCtx;
974 int status;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530975 if (pAdapter && pAdapter->dev == ndev)
976 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530977 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
978 status = wlan_hdd_validate_context(pHddCtx);
979 if (0 != status)
980 {
981 hddLog(LOGE, FL("HDD context is invalid"));
982 return NOTIFY_DONE;
983 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530984
985 if ((pHddCtx->cfg_ini->nEnableSuspend !=
986 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
987 || (!pHddCtx->cfg_ini->fhostArpOffload))
988 {
989 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
990 pHddCtx->cfg_ini->nEnableSuspend,
991 pHddCtx->cfg_ini->fhostArpOffload);
992 return NOTIFY_DONE;
993 }
994
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530995 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
996 {
997 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
998 ifap = &ifa->ifa_next)
999 {
1000 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1001 {
1002 break; /* found */
1003 }
1004 }
1005 }
1006 if(ifa && ifa->ifa_local)
1007 {
1008 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
1009 }
1010 }
1011
1012 return NOTIFY_DONE;
1013}
1014
1015/**----------------------------------------------------------------------------
1016
1017 \brief hdd_conf_arp_offload() - Configure ARP offload
1018
1019 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1020 reduces power consumption.
1021
1022 \param - pAdapter -Adapter context for which ARP offload is to be configured
1023 \param - fenable - 0 - disable.
1024 1 - enable. (with IPv4 notifier registration)
1025 2 - enable. (without IPv4 notifier registration)
1026
1027 \return -
1028 VOS_STATUS_SUCCESS - on successful operation
1029 VOS_STATUS_E_FAILURE - on failure of operation
1030-----------------------------------------------------------------------------*/
1031VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001032{
1033 struct in_ifaddr **ifap = NULL;
1034 struct in_ifaddr *ifa = NULL;
1035 struct in_device *in_dev;
1036 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001037 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001038 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001039
c_hpothu86feba52014-10-28 15:51:18 +05301040 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001041
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 if(fenable)
1043 {
1044 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1045 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301046 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001047 ifap = &ifa->ifa_next)
1048 {
1049 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1050 {
1051 break; /* found */
1052 }
1053 }
1054 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 if(ifa && ifa->ifa_local)
1056 {
1057 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1058 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1059
Arif Hussain6d2a3322013-11-17 19:50:10 -08001060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001061
Amar Singhald53568e2013-09-26 11:03:45 -07001062 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1063 pHddCtx->sus_res_mcastbcast_filter) ||
1064 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1065 pHddCtx->sus_res_mcastbcast_filter)) &&
1066 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001067 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301068 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001069 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1070 hddLog(VOS_TRACE_LEVEL_INFO,
1071 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 }
Amar Singhald53568e2013-09-26 11:03:45 -07001073
1074 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1075 offLoadRequest.enableOrDisable);
1076
Jeff Johnson295189b2012-06-20 16:38:30 -07001077 //converting u32 to IPV4 address
1078 for(i = 0 ; i < 4; i++)
1079 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301080 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1082 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301083 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 offLoadRequest.params.hostIpv4Addr[0],
1085 offLoadRequest.params.hostIpv4Addr[1],
1086 offLoadRequest.params.hostIpv4Addr[2],
1087 offLoadRequest.params.hostIpv4Addr[3]);
1088
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301089 if (eHAL_STATUS_SUCCESS !=
1090 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1091 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001092 {
1093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001094 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001095 return VOS_STATUS_E_FAILURE;
1096 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 }
1098 else
1099 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1101 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001102 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301103
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301104 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 }
1106 else
1107 {
1108 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1109 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1110 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1111
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301112 if (eHAL_STATUS_SUCCESS !=
1113 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1114 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001115 {
1116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001117 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001118 return VOS_STATUS_E_FAILURE;
1119 }
1120 return VOS_STATUS_SUCCESS;
1121 }
1122}
1123
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301124/*
1125 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301126 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301127*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301128void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301129 tANI_U8 *pMcBcFilter)
1130{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301131 if (NULL == pHddCtx)
1132 {
1133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1134 return;
1135 }
1136
1137 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1138 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301139 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301140 /* ARP offload is enabled, do not block bcast packets at RXP
1141 * Will be using Bitmasking to reset the filter. As we have
1142 * disable Broadcast filtering, Anding with the negation
1143 * of Broadcast BIT
1144 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301145 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301146 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301147
1148#ifdef WLAN_NS_OFFLOAD
1149 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301150 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301151 /* NS offload is enabled, do not block mcast packets at RXP
1152 * Will be using Bitmasking to reset the filter. As we have
1153 * disable Multicast filtering, Anding with the negation
1154 * of Multicast BIT
1155 */
1156 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301157 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301158#endif
1159
Amar Singhald08ce752014-03-21 16:28:27 -07001160 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1161 {
1162 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1163 }
1164
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301165 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301166}
1167
Jeff Johnson295189b2012-06-20 16:38:30 -07001168void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1169{
1170 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001171 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1172 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1173 if(NULL == wlanRxpFilterParam)
1174 {
1175 hddLog(VOS_TRACE_LEVEL_FATAL,
1176 "%s: vos_mem_alloc failed ", __func__);
1177 return;
1178 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001179 hddLog(VOS_TRACE_LEVEL_INFO,
1180 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301181 if (TRUE == setfilter)
1182 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301183 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301184 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301185 }
1186 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301187 {
1188 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301189 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301190 pHddCtx->configuredMcastBcastFilter;
1191 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301192
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -07001195 if (eHAL_STATUS_SUCCESS != halStatus)
1196 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001197 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1198 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1199}
1200
Jeff Johnson295189b2012-06-20 16:38:30 -07001201static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1202 hdd_adapter_t *pAdapter)
1203{
1204 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1205 tpSirWlanSuspendParam wlanSuspendParam =
1206 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1207
Amar Singhald53568e2013-09-26 11:03:45 -07001208 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1209 pHddCtx->sus_res_mcastbcast_filter =
1210 pHddCtx->configuredMcastBcastFilter;
1211 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1212 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1213 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1214 pHddCtx->configuredMcastBcastFilter);
1215
1216 }
1217
Amar Singhal49fdfd52013-08-13 13:25:12 -07001218
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 if(NULL == wlanSuspendParam)
1220 {
1221 hddLog(VOS_TRACE_LEVEL_FATAL,
1222 "%s: vos_mem_alloc failed ", __func__);
1223 return;
1224 }
1225
Amar Singhald53568e2013-09-26 11:03:45 -07001226 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 "%s: send wlan suspend indication", __func__);
1228
1229 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1230 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301231 //Configure supported OffLoads
1232 hdd_conf_hostoffload(pAdapter, TRUE);
1233 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301234 hddLog(VOS_TRACE_LEVEL_INFO,
1235 FL("saving configuredMcastBcastFilterSetting = %d"),
1236 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001237#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301238 /* During suspend, configure MC Addr list filter to the firmware
1239 * function takes care of checking necessary conditions before
1240 * configuring.
1241 */
1242 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001243#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001244
1245 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1246 {
1247
1248 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1249 pHddCtx->configuredMcastBcastFilter &=
1250 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1251 }
1252
1253 wlanSuspendParam->configuredMcstBcstFilterSetting =
1254 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001255 }
1256
1257 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1258 if(eHAL_STATUS_SUCCESS == halStatus)
1259 {
1260 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001261 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301262 hddLog(VOS_TRACE_LEVEL_ERROR,
1263 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001264 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 }
1266}
1267
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301268static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001269{
Chilam Ngc4244af2013-04-01 15:37:32 -07001270 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001271 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001272 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001273
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301274 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001275 "%s: send wlan resume indication", __func__);
1276
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301277 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1278
1279 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001280 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301281 hddLog(VOS_TRACE_LEVEL_FATAL,
1282 "%s: memory allocation failed for wlanResumeParam ", __func__);
1283 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001285
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301286 //Disable supported OffLoads
1287 hdd_conf_hostoffload(pAdapter, FALSE);
1288
1289 wlanResumeParam->configuredMcstBcstFilterSetting =
1290 pHddCtx->configuredMcastBcastFilter;
1291 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1292 if (eHAL_STATUS_SUCCESS != halStatus)
1293 {
c_hpothuffdb5272013-10-02 16:42:35 +05301294 hddLog(VOS_TRACE_LEVEL_ERROR,
1295 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301296 vos_mem_free(wlanResumeParam);
1297 }
1298
1299 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1300
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001301 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1302 pHddCtx->configuredMcastBcastFilter =
1303 pHddCtx->sus_res_mcastbcast_filter;
1304 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1305 }
Amar Singhald53568e2013-09-26 11:03:45 -07001306
1307 hddLog(VOS_TRACE_LEVEL_INFO,
1308 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1309 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1310 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001311
Chilam Ngc4244af2013-04-01 15:37:32 -07001312
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301313#ifdef WLAN_FEATURE_PACKET_FILTERING
1314 /* Filer was applied during suspend inditication
1315 * clear it when we resume.
1316 */
1317 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001318#endif
1319}
Jeff Johnson295189b2012-06-20 16:38:30 -07001320
Jeff Johnson295189b2012-06-20 16:38:30 -07001321//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001322void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001323{
1324 hdd_context_t *pHddCtx = NULL;
1325 v_CONTEXT_t pVosContext = NULL;
1326
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301328 hdd_adapter_t *pAdapter = NULL;
1329 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301330 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001331
Jeff Johnson295189b2012-06-20 16:38:30 -07001332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1333
1334 //Get the global VOSS context.
1335 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1336 if(!pVosContext) {
1337 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1338 return;
1339 }
1340
1341 //Get the HDD context.
1342 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1343
1344 if(!pHddCtx) {
1345 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1346 return;
1347 }
1348
1349 if (pHddCtx->isLogpInProgress) {
1350 hddLog(VOS_TRACE_LEVEL_ERROR,
1351 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1352 return;
1353 }
1354
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301355 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301356 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1358 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1359 {
1360 pAdapter = pAdapterNode->pAdapter;
1361 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001362 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001363 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1364
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001365 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001366 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1367 pAdapterNode = pNext;
1368 continue;
1369 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301370 /* Avoid multiple enter/exit BMPS in this while loop using
1371 * hdd_enter_bmps flag
1372 */
1373 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1374 {
1375 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001376
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301377 /* If device was already in BMPS, and dynamic DTIM is set,
1378 * exit(set the device to full power) and enter BMPS again
1379 * to reflect new DTIM value */
1380 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1381
1382 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1383
1384 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1385 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001386#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1387 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1388 {
1389 //stop the interface before putting the chip to standby
1390 netif_tx_disable(pAdapter->dev);
1391 netif_carrier_off(pAdapter->dev);
1392 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301393 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1395 {
1396 //Execute deep sleep procedure
1397 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1398 }
1399#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301400
1401 /*Suspend notification sent down to driver*/
1402 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1403
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301404 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1405 pAdapterNode = pNext;
1406 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301407
Jeff Johnson295189b2012-06-20 16:38:30 -07001408#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1409 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1410 {
1411 hdd_enter_standby(pHddCtx);
1412 }
1413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001414
1415 return;
1416}
1417
1418static void hdd_PowerStateChangedCB
1419(
1420 v_PVOID_t callbackContext,
1421 tPmcState newState
1422)
1423{
1424 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301425
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 /* if the driver was not in BMPS during early suspend,
1427 * the dynamic DTIM is now updated at Riva */
1428 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1429 && pHddCtx->cfg_ini->enableDynamicDTIM
1430 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1431 {
1432 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1433 }
1434 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301435 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1436 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301438 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1439 {
Amar Singhald53568e2013-09-26 11:03:45 -07001440 pHddCtx->sus_res_mcastbcast_filter =
1441 pHddCtx->configuredMcastBcastFilter;
1442 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1443
1444 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1445 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1446 pHddCtx->configuredMcastBcastFilter);
1447 hddLog(VOS_TRACE_LEVEL_INFO,
1448 "offload: calling hdd_conf_mcastbcast_filter");
1449
1450 }
1451
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001453 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301455 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001456 else
Mihir Shete793209f2014-01-06 11:01:12 +05301457 {
1458 /* Android framework can send resume request when the WCN chip is
1459 * in IMPS mode. When the chip exits IMPS mode the firmware will
1460 * restore all the registers to the state they were before the chip
1461 * entered IMPS and so our hardware filter settings confgured by the
1462 * resume request will be lost. So reconfigure the filters on detecting
1463 * a change in the power state of the WCN chip.
1464 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301465 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301466 if (IMPS != newState)
1467 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301468 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301469 if (FALSE == pHddCtx->hdd_wlan_suspended)
1470 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301471 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301472 hddLog(VOS_TRACE_LEVEL_INFO,
1473 "Not in IMPS/BMPS and suspended state");
1474 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1475 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301476 else
1477 {
1478 spin_unlock(&pHddCtx->filter_lock);
1479 }
Mihir Shete793209f2014-01-06 11:01:12 +05301480 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301481 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001482}
1483
Jeff Johnson295189b2012-06-20 16:38:30 -07001484void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1485{
1486 v_CONTEXT_t pVosContext;
1487 tHalHandle smeContext;
1488
1489 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1490 if (NULL == pVosContext)
1491 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001492 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001493 return;
1494 }
1495 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1496 if (NULL == smeContext)
1497 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001498 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001499 return;
1500 }
1501
1502 spin_lock_init(&pHddCtx->filter_lock);
1503 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1504 pHddCtx->cfg_ini->nEnableSuspend)
1505 {
1506 pmcRegisterDeviceStateUpdateInd(smeContext,
1507 hdd_PowerStateChangedCB, pHddCtx);
1508 }
1509}
1510
1511void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1512{
1513 v_CONTEXT_t pVosContext;
1514 tHalHandle smeContext;
1515
1516 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1517 if (NULL == pVosContext)
1518 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001519 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001520 return;
1521 }
1522 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1523 if (NULL == smeContext)
1524 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001525 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001526 return;
1527 }
1528
1529 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1530 pHddCtx->cfg_ini->nEnableSuspend)
1531 {
1532 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1533 }
1534}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301535
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301536#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301537void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301538{
1539 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301540 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301541 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1542
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301543 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301544 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301545 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1546 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1547 {
1548 vos_mem_copy(&hddGtkOffloadReqParams,
1549 &pHddStaCtx->gtkOffloadReqParams,
1550 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301551
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301552 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1553 &hddGtkOffloadReqParams, pAdapter->sessionId);
1554 if (eHAL_STATUS_SUCCESS != ret)
1555 {
1556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1557 "%s: sme_SetGTKOffload failed, returned %d",
1558 __func__, ret);
1559 return;
1560 }
1561
1562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1563 "%s: sme_SetGTKOffload successfull", __func__);
1564 }
1565
1566 }
1567 else
1568 {
1569 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1570 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1571 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1572 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1573 {
1574
1575 /* Host driver has previously offloaded GTK rekey */
1576 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301577 wlan_hdd_cfg80211_update_replayCounterCallback,
1578 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301579 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301580
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301581 {
1582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1583 "%s: sme_GetGTKOffload failed, returned %d",
1584 __func__, ret);
1585 return;
1586 }
1587 else
1588 {
1589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1590 "%s: sme_GetGTKOffload successful",
1591 __func__);
1592
1593 /* Sending GTK offload dissable */
1594 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1595 sizeof (tSirGtkOffloadParams));
1596 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1597 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301598 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301599 if (eHAL_STATUS_SUCCESS != ret)
1600 {
1601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1602 "%s: failed to dissable GTK offload, returned %d",
1603 __func__, ret);
1604 return;
1605 }
1606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1607 "%s: successfully dissabled GTK offload request to HAL",
1608 __func__);
1609 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301610 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301611 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301612 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301613}
1614#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001615
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001616void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001617{
1618 hdd_context_t *pHddCtx = NULL;
1619 hdd_adapter_t *pAdapter = NULL;
1620 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1621 VOS_STATUS status;
1622 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001623
Jeff Johnson295189b2012-06-20 16:38:30 -07001624 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1625
1626 //Get the global VOSS context.
1627 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1628 if(!pVosContext) {
1629 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1630 return;
1631 }
1632
1633 //Get the HDD context.
1634 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1635
1636 if(!pHddCtx) {
1637 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1638 return;
1639 }
1640
Agarwal Ashish971c2882013-10-30 20:11:12 +05301641 if (pHddCtx->isLogpInProgress)
1642 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 hddLog(VOS_TRACE_LEVEL_INFO,
1644 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1645 return;
1646 }
1647
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 pHddCtx->hdd_wlan_suspended = FALSE;
1649 /*loop through all adapters. Concurrency */
1650 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1651
1652 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1653 {
1654 pAdapter = pAdapterNode->pAdapter;
1655 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001656 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001657 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001658 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001659 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1660 pAdapterNode = pNext;
1661 continue;
1662 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301663
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301664
Jeff Johnson295189b2012-06-20 16:38:30 -07001665#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1666 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1667 {
1668 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1669 hdd_exit_deep_sleep(pAdapter);
1670 }
1671#endif
1672
1673 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1674 {
1675 /*Switch back to DTIM 1*/
1676 tSirSetPowerParamsReq powerRequest = { 0 };
1677
1678 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1679 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001680 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001681
1682 /*Disabled ModulatedDTIM if enabled on suspend*/
1683 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1684 powerRequest.uDTIMPeriod = 0;
1685
1686 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1687 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1688 NULL, eANI_BOOLEAN_FALSE);
1689 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1690 NULL, eANI_BOOLEAN_FALSE);
1691
1692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001693 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001694 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001695
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301696 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1697 {
1698 /* put the device into full power */
1699 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001700
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301701 /* put the device back into BMPS */
1702 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001703
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301704 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1705 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 }
1707
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301708 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001709 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1710 pAdapterNode = pNext;
1711 }
1712
1713#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1714 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1715 {
1716 hdd_exit_standby(pHddCtx);
1717 }
1718#endif
1719
Jeff Johnson295189b2012-06-20 16:38:30 -07001720 return;
1721}
1722
Jeff Johnson295189b2012-06-20 16:38:30 -07001723VOS_STATUS hdd_wlan_reset_initialization(void)
1724{
Jeff Johnson295189b2012-06-20 16:38:30 -07001725 v_CONTEXT_t pVosContext = NULL;
1726
1727 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1728
1729 //Get the global VOSS context.
1730 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1731 if(!pVosContext)
1732 {
1733 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1734 return VOS_STATUS_E_FAILURE;
1735 }
1736
1737 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1738
1739 // Prevent the phone from going to sleep
1740 hdd_prevent_suspend();
1741
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 return VOS_STATUS_SUCCESS;
1743}
1744
1745
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001746/*
1747 * Based on the ioctl command recieved by HDD, put WLAN driver
1748 * into the quiet mode. This is the same as the early suspend
1749 * notification that driver used to listen
1750 */
1751void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001752{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301753 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001754 if (suspend)
1755 hdd_suspend_wlan();
1756 else
1757 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301758 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001759}
1760
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001761static void hdd_ssr_timer_init(void)
1762{
1763 init_timer(&ssr_timer);
1764}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001765
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001766static void hdd_ssr_timer_del(void)
1767{
1768 del_timer(&ssr_timer);
1769 ssr_timer_started = false;
1770}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001771
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001772static void hdd_ssr_timer_cb(unsigned long data)
1773{
1774 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001775
1776#ifdef WCN_PRONTO
1777 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1778 wcnss_pronto_log_debug_regs();
1779#endif
1780
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001781 VOS_BUG(0);
1782}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001783
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001784static void hdd_ssr_timer_start(int msec)
1785{
1786 if(ssr_timer_started)
1787 {
1788 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1789 ,__func__);
1790 }
1791 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1792 ssr_timer.function = hdd_ssr_timer_cb;
1793 add_timer(&ssr_timer);
1794 ssr_timer_started = true;
1795}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001796
Jeff Johnson295189b2012-06-20 16:38:30 -07001797/* the HDD interface to WLAN driver shutdown,
1798 * the primary shutdown function in SSR
1799 */
1800VOS_STATUS hdd_wlan_shutdown(void)
1801{
1802 VOS_STATUS vosStatus;
1803 v_CONTEXT_t pVosContext = NULL;
1804 hdd_context_t *pHddCtx = NULL;
1805 pVosSchedContext vosSchedContext = NULL;
1806
1807 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1808
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001809 /* if re-init never happens, then do SSR1 */
1810 hdd_ssr_timer_init();
1811 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1812
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 /* Get the global VOSS context. */
1814 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1815 if(!pVosContext) {
1816 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1817 return VOS_STATUS_E_FAILURE;
1818 }
1819 /* Get the HDD context. */
1820 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1821 if(!pHddCtx) {
1822 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1823 return VOS_STATUS_E_FAILURE;
1824 }
c_hpothud662a352013-12-26 15:09:12 +05301825
1826 //Stop the traffic monitor timer
1827 if ( VOS_TIMER_STATE_RUNNING ==
1828 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1829 {
1830 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1831 }
1832
Jeff Johnson295189b2012-06-20 16:38:30 -07001833 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001834 /* DeRegister with platform driver as client for Suspend/Resume */
1835 vosStatus = hddDeregisterPmOps(pHddCtx);
1836 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1837 {
1838 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1839 }
1840
1841 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1842 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1843 {
1844 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1845 }
1846
1847 /* Disable IMPS/BMPS as we do not want the device to enter any power
1848 * save mode on its own during reset sequence
1849 */
1850 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1851 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1852 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1853
1854 vosSchedContext = get_vos_sched_ctxt();
1855
1856 /* Wakeup all driver threads */
1857 if(TRUE == pHddCtx->isMcThreadSuspended){
1858 complete(&vosSchedContext->ResumeMcEvent);
1859 pHddCtx->isMcThreadSuspended= FALSE;
1860 }
1861 if(TRUE == pHddCtx->isTxThreadSuspended){
1862 complete(&vosSchedContext->ResumeTxEvent);
1863 pHddCtx->isTxThreadSuspended= FALSE;
1864 }
1865 if(TRUE == pHddCtx->isRxThreadSuspended){
1866 complete(&vosSchedContext->ResumeRxEvent);
1867 pHddCtx->isRxThreadSuspended= FALSE;
1868 }
1869 /* Reset the Suspend Variable */
1870 pHddCtx->isWlanSuspended = FALSE;
1871
1872 /* Stop all the threads; we do not want any messages to be a processed,
1873 * any more and the best way to ensure that is to terminate the threads
1874 * gracefully.
1875 */
1876 /* Wait for MC to exit */
1877 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1878 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1879 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1880 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301881 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001882
1883 /* Wait for TX to exit */
1884 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1885 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1886 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1887 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301888 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001889
1890 /* Wait for RX to exit */
1891 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1892 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1893 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1894 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301895
Mihir Sheteb5425f72013-12-19 09:06:13 +05301896 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001897
1898#ifdef WLAN_BTAMP_FEATURE
1899 vosStatus = WLANBAP_Stop(pVosContext);
1900 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1901 {
1902 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1903 "%s: Failed to stop BAP",__func__);
1904 }
1905#endif //WLAN_BTAMP_FEATURE
1906 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301907 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1908 {
1909 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1910 "%s: Failed to stop wda %d", __func__, vosStatus);
1911 VOS_ASSERT(0);
1912 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001913
1914 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1915 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1916 * on threads being running to process the SYS Stop
1917 */
Kiet Lama72a2322013-11-15 11:18:11 +05301918 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301919 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1920 {
1921 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1922 "%s: Failed to stop sme %d", __func__, vosStatus);
1923 VOS_ASSERT(0);
1924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001925
1926 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1927 /* Stop MAC (PE and HAL) */
1928 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301929 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1930 {
1931 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1932 "%s: Failed to stop mac %d", __func__, vosStatus);
1933 VOS_ASSERT(0);
1934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001935
1936 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1937 /* Stop TL */
1938 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301939 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1940 {
1941 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1942 "%s: Failed to stop TL %d", __func__, vosStatus);
1943 VOS_ASSERT(0);
1944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001945
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1948 /* Clean up message queues of TX and MC thread */
1949 vos_sched_flush_mc_mqs(vosSchedContext);
1950 vos_sched_flush_tx_mqs(vosSchedContext);
1951 vos_sched_flush_rx_mqs(vosSchedContext);
1952
1953 /* Deinit all the TX and MC queues */
1954 vos_sched_deinit_mqs(vosSchedContext);
1955 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1956
1957 /* shutdown VOSS */
1958 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301959
1960 /*mac context has already been released in mac_close call
1961 so setting it to NULL in hdd context*/
1962 pHddCtx->hHal = (tHalHandle)NULL;
1963
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 if (free_riva_power_on_lock("wlan"))
1965 {
1966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1967 __func__);
1968 }
1969 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1970 ,__func__);
1971 return VOS_STATUS_SUCCESS;
1972}
1973
1974
1975
1976/* the HDD interface to WLAN driver re-init.
1977 * This is called to initialize/start WLAN driver after a shutdown.
1978 */
1979VOS_STATUS hdd_wlan_re_init(void)
1980{
1981 VOS_STATUS vosStatus;
1982 v_CONTEXT_t pVosContext = NULL;
1983 hdd_context_t *pHddCtx = NULL;
1984 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001985#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1986 int max_retries = 0;
1987#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001988#ifdef WLAN_BTAMP_FEATURE
1989 hdd_config_t *pConfig = NULL;
1990 WLANBAP_ConfigType btAmpConfig;
1991#endif
1992
Katya Nigam82a93062014-06-04 15:15:36 +05301993 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001994 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08001996
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07001997#ifdef HAVE_WCNSS_CAL_DOWNLOAD
1998 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08001999 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002000 msleep(1000);
2001 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002002 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002003 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2004 goto err_re_init;
2005 }
2006#endif
2007
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002008 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2009
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002010 /* The driver should always be initialized in STA mode after SSR */
2011 hdd_set_conparam(0);
2012
Katya Nigam82a93062014-06-04 15:15:36 +05302013 dev = wcnss_wlan_get_device();
2014 if (NULL == dev)
2015 {
2016 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2017 goto err_re_init;
2018 }
2019
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302021 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2023 {
2024 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2025 goto err_re_init;
2026 }
2027
2028 /* Get the HDD context. */
2029 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2030 if(!pHddCtx)
2031 {
2032 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2033 goto err_vosclose;
2034 }
2035
2036 /* Save the hal context in Adapter */
2037 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2038 if ( NULL == pHddCtx->hHal )
2039 {
2040 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2041 goto err_vosclose;
2042 }
2043
2044 /* Set the SME configuration parameters. */
2045 vosStatus = hdd_set_sme_config(pHddCtx);
2046 if ( VOS_STATUS_SUCCESS != vosStatus )
2047 {
2048 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2049 goto err_vosclose;
2050 }
2051
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 vosStatus = vos_preStart( pHddCtx->pvosContext );
2053 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2054 {
2055 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2056 goto err_vosclose;
2057 }
2058
2059 /* In the integrated architecture we update the configuration from
2060 the INI file and from NV before vOSS has been started so that
2061 the final contents are available to send down to the cCPU */
2062 /* Apply the cfg.ini to cfg.dat */
2063 if (FALSE == hdd_update_config_dat(pHddCtx))
2064 {
2065 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2066 goto err_vosclose;
2067 }
2068
2069 /* Set the MAC Address, currently this is used by HAL to add self sta.
2070 * Remove this once self sta is added as part of session open. */
2071 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2072 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2073 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2074 if (!HAL_STATUS_SUCCESS(halStatus))
2075 {
2076 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2077 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2078 goto err_vosclose;
2079 }
2080
2081 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2082 Note: Firmware image will be read and downloaded inside vos_start API */
2083 vosStatus = vos_start( pVosContext );
2084 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2085 {
2086 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2087 goto err_vosclose;
2088 }
2089
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002090 /* Exchange capability info between Host and FW and also get versioning info from FW */
2091 hdd_exchange_version_and_caps(pHddCtx);
2092
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 vosStatus = hdd_post_voss_start_config( pHddCtx );
2094 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2095 {
2096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2097 __func__);
2098 goto err_vosstop;
2099 }
2100
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302101 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2102 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2103 {
2104 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2105 __func__);
2106 goto err_vosstop;
2107 }
2108
Jeff Johnson295189b2012-06-20 16:38:30 -07002109#ifdef WLAN_BTAMP_FEATURE
2110 vosStatus = WLANBAP_Open(pVosContext);
2111 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2112 {
2113 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2114 "%s: Failed to open BAP",__func__);
2115 goto err_vosstop;
2116 }
2117 vosStatus = BSL_Init(pVosContext);
2118 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2119 {
2120 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2121 "%s: Failed to Init BSL",__func__);
2122 goto err_bap_close;
2123 }
2124 vosStatus = WLANBAP_Start(pVosContext);
2125 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2126 {
2127 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2128 "%s: Failed to start TL",__func__);
2129 goto err_bap_close;
2130 }
2131 pConfig = pHddCtx->cfg_ini;
2132 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2133 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2134#endif //WLAN_BTAMP_FEATURE
2135
2136 /* Restart all adapters */
2137 hdd_start_all_adapters(pHddCtx);
2138 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002139 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002140 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302141 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002142 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302143 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002144 /* Register with platform driver as client for Suspend/Resume */
2145 vosStatus = hddRegisterPmOps(pHddCtx);
2146 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2147 {
2148 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2149 goto err_bap_stop;
2150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002151 /* Allow the phone to go to sleep */
2152 hdd_allow_suspend();
2153 /* register for riva power on lock */
2154 if (req_riva_power_on_lock("wlan"))
2155 {
2156 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2157 __func__);
2158 goto err_unregister_pmops;
2159 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002160 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302161#ifdef WLAN_FEATURE_EXTSCAN
2162 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2163 wlan_hdd_cfg80211_extscan_callback,
2164 pHddCtx);
2165#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 goto success;
2167
2168err_unregister_pmops:
2169 hddDeregisterPmOps(pHddCtx);
2170
2171err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002172#ifdef CONFIG_HAS_EARLYSUSPEND
2173 hdd_unregister_mcast_bcast_filter(pHddCtx);
2174#endif
2175 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002176#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002177 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002178#endif
2179
2180#ifdef WLAN_BTAMP_FEATURE
2181err_bap_close:
2182 WLANBAP_Close(pVosContext);
2183#endif
2184
2185err_vosstop:
2186 vos_stop(pVosContext);
2187
2188err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302189 if(!isSsrPanicOnFailure())
2190 {
2191 /* If we hit this, it means wlan driver is in bad state and needs
2192 * driver unload and load.
2193 */
Siddharth Bhald4ad02d2014-09-15 10:31:57 +05302194 if (pHddCtx)
2195 pHddCtx->isLogpInProgress = FALSE;
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302196 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2197 return VOS_STATUS_E_FAILURE;
2198 }
2199
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 vos_close(pVosContext);
2201 vos_sched_close(pVosContext);
2202 if (pHddCtx)
2203 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 /* Unregister the Net Device Notifier */
2205 unregister_netdevice_notifier(&hdd_netdev_notifier);
2206 /* Clean up HDD Nlink Service */
2207 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002208#ifdef WLAN_KD_READY_NOTIFIER
2209 nl_srv_exit(pHddCtx->ptt_pid);
2210#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002212#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002213 /* Free up dynamically allocated members inside HDD Adapter */
2214 kfree(pHddCtx->cfg_ini);
2215 pHddCtx->cfg_ini= NULL;
2216
Jeff Johnson295189b2012-06-20 16:38:30 -07002217 wiphy_unregister(pHddCtx->wiphy);
2218 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002219 }
2220 vos_preClose(&pVosContext);
2221
2222#ifdef MEMORY_DEBUG
2223 vos_mem_exit();
2224#endif
2225
2226err_re_init:
2227 /* Allow the phone to go to sleep */
2228 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002229 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002230 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002231 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002232
2233success:
2234 /* Trigger replay of BTC events */
2235 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2236 return VOS_STATUS_SUCCESS;
2237}