blob: 3a424a473caf85baf6d2a9bce79be092933a6a1c [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
490 //Disable NSOFFLOAD
491 if (pHddCtx->cfg_ini->fhostNSOffload)
492 {
493 hdd_conf_ns_offload(pAdapter, 1);
494 }
495#endif
496 }
497#ifdef WLAN_FEATURE_PACKET_FILTERING
498 /* wlan_hdd_set_mc_addr_list() is called from the early susspend
499 * only so when new ipv6 address is generated the screen may not
500 * on so we need to call it here to update the list in f/w.
501 */
502 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
503#endif
504
505}
506
507
508static int wlan_hdd_ipv6_changed(struct notifier_block *nb,
509 unsigned long data, void *arg)
510{
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
528 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
529 }
530
531 return NOTIFY_DONE;
532}
533
534void hdd_ipv6_callback_register(hdd_adapter_t *pAdapter, int fenable)
535{
536
537 int ret = 0;
538
539 if (fenable)
540 {
541
542 if(!pAdapter->ipv6_notifier_registered)
543 {
544
545 // Register IPv6 notifier to notify if any change in IP
546 // So that we can reconfigure the offload parameters
547 pAdapter->ipv6_notifier.notifier_call =
548 wlan_hdd_ipv6_changed;
549 ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier);
550 if (ret)
551 {
552 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
553 }
554 else
555 {
556 hddLog(LOG1, FL("Registered IPv6 notifier"));
557 pAdapter->ipv6_notifier_registered = true;
558 }
559 }
560 }
561 else
562 {
563
564 if (pAdapter->ipv6_notifier_registered)
565 {
566 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
567 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
568 pAdapter->ipv6_notifier_registered = false;
569 }
570
571 }
572
573}
574
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530575/*
576 * Function: hdd_conf_hostoffload
577 * Central function to configure the supported offloads,
578 * either enable or disable them.
579 */
580void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
581{
582 hdd_context_t *pHddCtx = NULL;
583 v_CONTEXT_t *pVosContext = NULL;
584 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
585
586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
587 fenable);
588
589 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
590
591 if (NULL == pVosContext)
592 {
593 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
594 return;
595 }
596
597 //Get the HDD context.
598 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
599
600 if (NULL == pHddCtx)
601 {
602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
603 return;
604 }
605
606 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
607 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
608 {
609 if (fenable)
610 {
611 if (eConnectionState_Associated ==
612 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
613 {
614 if ((pHddCtx->cfg_ini->fhostArpOffload))
615 {
616 /*
617 * Configure the ARP Offload.
618 * Even if it fails we have to reconfigure the MC/BC
619 * filter flag as we want RIVA not to drop BroadCast
620 * Packets
621 */
622 hddLog(VOS_TRACE_LEVEL_INFO,
623 FL("Calling ARP Offload with flag: %d"), fenable);
624 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
625 pHddCtx->configuredMcastBcastFilter &=
626 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
627
628 if (!VOS_IS_STATUS_SUCCESS(vstatus))
629 {
630 hddLog(VOS_TRACE_LEVEL_ERROR,
631 "Failed to enable ARPOFfloadFeature %d",
632 vstatus);
633 }
634 }
635 //Configure GTK_OFFLOAD
636#ifdef WLAN_FEATURE_GTK_OFFLOAD
637 hdd_conf_gtk_offload(pAdapter, fenable);
638#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530639
640#ifdef WLAN_NS_OFFLOAD
641 if (pHddCtx->cfg_ini->fhostNSOffload)
642 {
643 /*
644 * Configure the NS Offload.
645 * Even if it fails we have to reconfigure the MC/BC filter flag
646 * as we want RIVA not to drop Multicast Packets
647 */
648
649 hddLog(VOS_TRACE_LEVEL_INFO,
650 FL("Calling NS Offload with flag: %d"), fenable);
651 hdd_conf_ns_offload(pAdapter, fenable);
652 pHddCtx->configuredMcastBcastFilter &=
653 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
654 }
655#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530656
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530657 }
Atul Mittal37385d72014-03-27 18:15:03 +0530658 hdd_ipv6_callback_register(pAdapter, fenable);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530659 }
660 else
661 {
662 //Disable ARPOFFLOAD
663 if (pHddCtx->cfg_ini->fhostArpOffload)
664 {
665 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
666 if (!VOS_IS_STATUS_SUCCESS(vstatus))
667 {
668 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530669 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530670 }
671 }
672 //Disable GTK_OFFLOAD
673#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530674 hdd_conf_gtk_offload(pAdapter, fenable);
675#endif
676
677#ifdef WLAN_NS_OFFLOAD
678 //Disable NSOFFLOAD
679 if (pHddCtx->cfg_ini->fhostNSOffload)
680 {
681 hdd_conf_ns_offload(pAdapter, fenable);
682 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530683#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530684 hdd_ipv6_callback_register(pAdapter, fenable);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530685 }
686 }
687 return;
688}
689
Atul Mittal37385d72014-03-27 18:15:03 +0530690
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530691#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530692/**----------------------------------------------------------------------------
693
694 \brief hdd_conf_ns_offload() - Configure NS offload
695
696 Called during SUSPEND to configure the NS offload (MC BC filter) which
697 reduces power consumption.
698
699 \param - pAdapter - Adapter context for which NS offload is to be configured
700 \param - fenable - 0 - disable.
701 1 - enable. (with IPv6 notifier registration)
702 2 - enable. (without IPv6 notifier registration)
703
704 \return - void
705
706 ---------------------------------------------------------------------------*/
707void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530708{
709 struct inet6_dev *in6_dev;
710 struct inet6_ifaddr *ifp;
711 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530712 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530713 tANI_U8 **selfIPv6Addr = NULL;
714 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530715 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530716 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530717 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530718
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530719 int i = 0, slot = 0;
720 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530721 eHalStatus returnStatus;
722
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530723 ENTER();
724 hddLog(LOG1, FL(" fenable = %d"), fenable);
725
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530726 if (NULL == pAdapter)
727 {
728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
729 return;
730 }
731
732 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
734
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530735 ret = wlan_hdd_validate_context(pHddCtx);
736
737 if (0 != ret)
738 {
739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
740 FL("HDD context is not valid"));
741 return;
742 }
743
744 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
745 {
746 slot_index = NS_EXTENDED_SLOT_INDEX;
747 }
748
749 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
750
751 selfIPv6AddrValid =
752 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
753
754 if (NULL == selfIPv6AddrValid)
755 {
756 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
757 " selfIPv6AddrValid"));
758 goto end;
759 }
760
761 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
762
763 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
764
765 if (NULL == selfIPv6Addr)
766 {
767 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
768 " selfIPv6Addr"));
769 goto end;
770 }
771
772 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
773
774 for (slot = 0; slot < slot_index; slot++)
775 {
776 selfIPv6Addr[slot] =
777 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
778 if (NULL == selfIPv6Addr[slot])
779 {
780 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
781 "for selfIPv6Addr"));
782 goto end;
783 }
784 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
785 }
786
787 i = 0;
788
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530789 if (fenable)
790 {
791 in6_dev = __in6_dev_get(pAdapter->dev);
792 if (NULL != in6_dev)
793 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530794 list_for_each(p, &in6_dev->addr_list)
795 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530796 if (i >= slot_index)
797 {
798 hddLog (VOS_TRACE_LEVEL_ERROR,
799 FL("IPv6 address list is greater than IPv6"
800 "address supported by firmware"));
801 hddLog (VOS_TRACE_LEVEL_ERROR,
802 FL("FW supported IPv6 address = %d"), slot_index);
803 break;
804 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530805 ifp = list_entry(p, struct inet6_ifaddr, if_list);
806 switch(ipv6_addr_src_scope(&ifp->addr))
807 {
808 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530809 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530810 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530811 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530812 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530813 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
814 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530815 break;
816 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530817 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530818 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530819 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530820 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530821 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
822 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530823 break;
824 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530825 hddLog(VOS_TRACE_LEVEL_ERROR,
826 FL("The Scope %d is not supported"),
827 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530828 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530829 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
830 {
831 i++;
832 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530833 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530834
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530835 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530836 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530837 {
838 if (selfIPv6AddrValid[i])
839 {
840 //Filling up the request structure
841 /* Filling the selfIPv6Addr with solicited address
842 * A Solicited-Node multicast address is created by
843 * taking the last 24 bits of a unicast or anycast
844 * address and appending them to the prefix
845 *
846 * FF02:0000:0000:0000:0000:0001:FFXX:XX
847 *
848 * here XX is the unicast/anycast bits
849 */
850 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
851 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
852 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
853 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530854 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
855 selfIPv6Addr[i][13];
856 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
857 selfIPv6Addr[i][14];
858 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
859 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530860 offLoadRequest.nsOffloadInfo.slotIdx = i;
861
862 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530863 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530864 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
865 &pAdapter->macAddressCurrent.bytes,
866 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
867
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530868 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
869 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530870 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
871 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
872
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530873 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530874 FL("configuredMcastBcastFilter: %d"
875 "NSOffload Slot = %d"),
876 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530877
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530878 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700879 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
880 pHddCtx->sus_res_mcastbcast_filter) ||
881 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
882 pHddCtx->sus_res_mcastbcast_filter)) &&
883 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
884 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
885 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530886 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530887 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700888 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530889 hddLog (VOS_TRACE_LEVEL_INFO,
890 FL("Set offLoadRequest with %d"),
891 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530892 }
893
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530894 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
895 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
896 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
897
898 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530899 FL("Setting NSOffload with solicitedIp: %pI6,"
900 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530901 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
902 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
903
904 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530905 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530906 pAdapter->sessionId, &offLoadRequest);
907 if(eHAL_STATUS_SUCCESS != returnStatus)
908 {
909 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530910 FL("Failed to enable HostOffload feature with"
911 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530912 }
913 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
914 }
915 }
916 }
917 else
918 {
919 hddLog(VOS_TRACE_LEVEL_ERROR,
920 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530921 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530922 }
923 }
924 else
925 {
926 //Disable NSOffload
927 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
928 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
929 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
930
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530931 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530932 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530934 offLoadRequest.nsOffloadInfo.slotIdx = i;
935 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530936 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
937 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530938 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
940 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530941 }
942 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530943 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530944end:
945 while (slot > 0 && selfIPv6Addr[--slot])
946 {
947 vos_mem_free(selfIPv6Addr[slot]);
948 }
949 if (selfIPv6Addr)
950 {
951 vos_mem_free(selfIPv6Addr);
952 }
953 if (selfIPv6AddrValid)
954 {
955 vos_mem_free(selfIPv6AddrValid);
956 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530957 return;
958}
959#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530960
961void hdd_ipv4_notifier_work_queue(struct work_struct *work)
962{
963 hdd_adapter_t* pAdapter =
964 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
965 hdd_context_t *pHddCtx;
966 int status;
967
968 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
969 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
970 status = wlan_hdd_validate_context(pHddCtx);
971 if (0 != status)
972 {
973 hddLog(LOGE, FL("HDD context is invalid"));
974 return;
975 }
976
Deepthi Gowri5933f402014-01-23 17:48:24 +0530977 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
978 {
979 pHddCtx->sus_res_mcastbcast_filter =
980 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530981 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
982 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530983 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
984 }
985
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530986 if ((eConnectionState_Associated ==
987 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530988 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530989 {
990 // This invocation being part of the IPv4 registration callback,
991 // we are passing second parameter as 2 to avoid registration
992 // of IPv4 notifier again.
993 hdd_conf_arp_offload(pAdapter, 2);
994 }
995}
996
997static int wlan_hdd_ipv4_changed(struct notifier_block *nb,
998 unsigned long data, void *arg)
999{
1000 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1001 struct in_ifaddr **ifap = NULL;
1002 struct in_device *in_dev;
1003
1004 struct net_device *ndev = ifa->ifa_dev->dev;
1005 hdd_adapter_t *pAdapter =
1006 container_of(nb, struct hdd_adapter_s, ipv4_notifier);
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301007 hdd_context_t *pHddCtx;
1008 int status;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301009 if (pAdapter && pAdapter->dev == ndev)
1010 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301011 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1012 status = wlan_hdd_validate_context(pHddCtx);
1013 if (0 != status)
1014 {
1015 hddLog(LOGE, FL("HDD context is invalid"));
1016 return NOTIFY_DONE;
1017 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301018 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1019 {
1020 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1021 ifap = &ifa->ifa_next)
1022 {
1023 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1024 {
1025 break; /* found */
1026 }
1027 }
1028 }
1029 if(ifa && ifa->ifa_local)
1030 {
1031 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
1032 }
1033 }
1034
1035 return NOTIFY_DONE;
1036}
1037
1038/**----------------------------------------------------------------------------
1039
1040 \brief hdd_conf_arp_offload() - Configure ARP offload
1041
1042 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1043 reduces power consumption.
1044
1045 \param - pAdapter -Adapter context for which ARP offload is to be configured
1046 \param - fenable - 0 - disable.
1047 1 - enable. (with IPv4 notifier registration)
1048 2 - enable. (without IPv4 notifier registration)
1049
1050 \return -
1051 VOS_STATUS_SUCCESS - on successful operation
1052 VOS_STATUS_E_FAILURE - on failure of operation
1053-----------------------------------------------------------------------------*/
1054VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001055{
1056 struct in_ifaddr **ifap = NULL;
1057 struct in_ifaddr *ifa = NULL;
1058 struct in_device *in_dev;
1059 int i = 0;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301060 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001061 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001062 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001063
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301064 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001065
Jeff Johnson295189b2012-06-20 16:38:30 -07001066 if(fenable)
1067 {
1068 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1069 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301070 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001071 ifap = &ifa->ifa_next)
1072 {
1073 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1074 {
1075 break; /* found */
1076 }
1077 }
1078 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001079 if(ifa && ifa->ifa_local)
1080 {
1081 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1082 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1083
Arif Hussain6d2a3322013-11-17 19:50:10 -08001084 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001085
Amar Singhald53568e2013-09-26 11:03:45 -07001086 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1087 pHddCtx->sus_res_mcastbcast_filter) ||
1088 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1089 pHddCtx->sus_res_mcastbcast_filter)) &&
1090 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001091 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301092 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001093 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1094 hddLog(VOS_TRACE_LEVEL_INFO,
1095 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 }
Amar Singhald53568e2013-09-26 11:03:45 -07001097
1098 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1099 offLoadRequest.enableOrDisable);
1100
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 //converting u32 to IPV4 address
1102 for(i = 0 ; i < 4; i++)
1103 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301104 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1106 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301107 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 offLoadRequest.params.hostIpv4Addr[0],
1109 offLoadRequest.params.hostIpv4Addr[1],
1110 offLoadRequest.params.hostIpv4Addr[2],
1111 offLoadRequest.params.hostIpv4Addr[3]);
1112
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301113 if (eHAL_STATUS_SUCCESS !=
1114 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1115 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 {
1117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001118 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 return VOS_STATUS_E_FAILURE;
1120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001121 }
1122 else
1123 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1125 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301127
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301128 if (fenable == 1 && !pAdapter->ipv4_notifier_registered)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301129 {
1130 // Register IPv4 notifier to notify if any change in IP
1131 // So that we can reconfigure the offload parameters
1132 pAdapter->ipv4_notifier.notifier_call =
1133 wlan_hdd_ipv4_changed;
1134 ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier);
1135 if (ret)
1136 {
1137 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
1138 }
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301139 else
1140 {
1141 hddLog(LOG1, FL("Registered IPv4 notifier"));
1142 pAdapter->ipv4_notifier_registered = true;
1143 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301144 }
1145 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001146 }
1147 else
1148 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301149 if (pAdapter->ipv4_notifier_registered)
1150 {
1151 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
1152 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
1153 pAdapter->ipv4_notifier_registered = false;
1154 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1156 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1157 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1158
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301159 if (eHAL_STATUS_SUCCESS !=
1160 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1161 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 {
1163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001164 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001165 return VOS_STATUS_E_FAILURE;
1166 }
1167 return VOS_STATUS_SUCCESS;
1168 }
1169}
1170
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301171/*
1172 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301173 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301174*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301175void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301176 tANI_U8 *pMcBcFilter)
1177{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301178 if (NULL == pHddCtx)
1179 {
1180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1181 return;
1182 }
1183
1184 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1185 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301186 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301187 /* ARP offload is enabled, do not block bcast packets at RXP
1188 * Will be using Bitmasking to reset the filter. As we have
1189 * disable Broadcast filtering, Anding with the negation
1190 * of Broadcast BIT
1191 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301192 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301193 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301194
1195#ifdef WLAN_NS_OFFLOAD
1196 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301197 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301198 /* NS offload is enabled, do not block mcast packets at RXP
1199 * Will be using Bitmasking to reset the filter. As we have
1200 * disable Multicast filtering, Anding with the negation
1201 * of Multicast BIT
1202 */
1203 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301204 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301205#endif
1206
Amar Singhald08ce752014-03-21 16:28:27 -07001207 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1208 {
1209 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1210 }
1211
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301212 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301213}
1214
Jeff Johnson295189b2012-06-20 16:38:30 -07001215void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1216{
1217 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1219 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1220 if(NULL == wlanRxpFilterParam)
1221 {
1222 hddLog(VOS_TRACE_LEVEL_FATAL,
1223 "%s: vos_mem_alloc failed ", __func__);
1224 return;
1225 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001226 hddLog(VOS_TRACE_LEVEL_INFO,
1227 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301228 if (TRUE == setfilter)
1229 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301230 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301231 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301232 }
1233 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301234 {
1235 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301236 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301237 pHddCtx->configuredMcastBcastFilter;
1238 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301239
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Chilam Ngc4244af2013-04-01 15:37:32 -07001242 if (eHAL_STATUS_SUCCESS != halStatus)
1243 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001244 if(setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1245 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1246}
1247
Jeff Johnson295189b2012-06-20 16:38:30 -07001248static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1249 hdd_adapter_t *pAdapter)
1250{
1251 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1252 tpSirWlanSuspendParam wlanSuspendParam =
1253 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1254
Amar Singhald53568e2013-09-26 11:03:45 -07001255 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1256 pHddCtx->sus_res_mcastbcast_filter =
1257 pHddCtx->configuredMcastBcastFilter;
1258 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1259 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1260 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1261 pHddCtx->configuredMcastBcastFilter);
1262
1263 }
1264
Amar Singhal49fdfd52013-08-13 13:25:12 -07001265
Jeff Johnson295189b2012-06-20 16:38:30 -07001266 if(NULL == wlanSuspendParam)
1267 {
1268 hddLog(VOS_TRACE_LEVEL_FATAL,
1269 "%s: vos_mem_alloc failed ", __func__);
1270 return;
1271 }
1272
Amar Singhald53568e2013-09-26 11:03:45 -07001273 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001274 "%s: send wlan suspend indication", __func__);
1275
1276 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1277 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301278 //Configure supported OffLoads
1279 hdd_conf_hostoffload(pAdapter, TRUE);
1280 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301281 hddLog(VOS_TRACE_LEVEL_INFO,
1282 FL("saving configuredMcastBcastFilterSetting = %d"),
1283 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001284#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301285 /* During suspend, configure MC Addr list filter to the firmware
1286 * function takes care of checking necessary conditions before
1287 * configuring.
1288 */
1289 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001290#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001291
1292 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1293 {
1294
1295 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1296 pHddCtx->configuredMcastBcastFilter &=
1297 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1298 }
1299
1300 wlanSuspendParam->configuredMcstBcstFilterSetting =
1301 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001302 }
1303
1304 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1305 if(eHAL_STATUS_SUCCESS == halStatus)
1306 {
1307 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001308 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301309 hddLog(VOS_TRACE_LEVEL_ERROR,
1310 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001311 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001312 }
1313}
1314
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301315static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001316{
Chilam Ngc4244af2013-04-01 15:37:32 -07001317 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001318 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001319 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001320
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301321 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 "%s: send wlan resume indication", __func__);
1323
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301324 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1325
1326 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301328 hddLog(VOS_TRACE_LEVEL_FATAL,
1329 "%s: memory allocation failed for wlanResumeParam ", __func__);
1330 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001331 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001332
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301333 //Disable supported OffLoads
1334 hdd_conf_hostoffload(pAdapter, FALSE);
1335
1336 wlanResumeParam->configuredMcstBcstFilterSetting =
1337 pHddCtx->configuredMcastBcastFilter;
1338 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1339 if (eHAL_STATUS_SUCCESS != halStatus)
1340 {
c_hpothuffdb5272013-10-02 16:42:35 +05301341 hddLog(VOS_TRACE_LEVEL_ERROR,
1342 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301343 vos_mem_free(wlanResumeParam);
1344 }
1345
1346 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1347
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001348 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1349 pHddCtx->configuredMcastBcastFilter =
1350 pHddCtx->sus_res_mcastbcast_filter;
1351 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1352 }
Amar Singhald53568e2013-09-26 11:03:45 -07001353
1354 hddLog(VOS_TRACE_LEVEL_INFO,
1355 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1356 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1357 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001358
Chilam Ngc4244af2013-04-01 15:37:32 -07001359
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301360#ifdef WLAN_FEATURE_PACKET_FILTERING
1361 /* Filer was applied during suspend inditication
1362 * clear it when we resume.
1363 */
1364 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001365#endif
1366}
Jeff Johnson295189b2012-06-20 16:38:30 -07001367
Jeff Johnson295189b2012-06-20 16:38:30 -07001368//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001369void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001370{
1371 hdd_context_t *pHddCtx = NULL;
1372 v_CONTEXT_t pVosContext = NULL;
1373
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301375 hdd_adapter_t *pAdapter = NULL;
1376 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301377 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001378
Jeff Johnson295189b2012-06-20 16:38:30 -07001379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1380
1381 //Get the global VOSS context.
1382 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1383 if(!pVosContext) {
1384 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1385 return;
1386 }
1387
1388 //Get the HDD context.
1389 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1390
1391 if(!pHddCtx) {
1392 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1393 return;
1394 }
1395
1396 if (pHddCtx->isLogpInProgress) {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1399 return;
1400 }
1401
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301402 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001403 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1404 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1405 {
1406 pAdapter = pAdapterNode->pAdapter;
1407 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001408 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1410
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001411 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1413 pAdapterNode = pNext;
1414 continue;
1415 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301416 /* Avoid multiple enter/exit BMPS in this while loop using
1417 * hdd_enter_bmps flag
1418 */
1419 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1420 {
1421 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001422
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301423 /* If device was already in BMPS, and dynamic DTIM is set,
1424 * exit(set the device to full power) and enter BMPS again
1425 * to reflect new DTIM value */
1426 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1427
1428 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1429
1430 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001432#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1433 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1434 {
1435 //stop the interface before putting the chip to standby
1436 netif_tx_disable(pAdapter->dev);
1437 netif_carrier_off(pAdapter->dev);
1438 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301439 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1441 {
1442 //Execute deep sleep procedure
1443 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1444 }
1445#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301446
1447 /*Suspend notification sent down to driver*/
1448 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1449
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301450 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1451 pAdapterNode = pNext;
1452 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301453 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301454
Jeff Johnson295189b2012-06-20 16:38:30 -07001455#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1456 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1457 {
1458 hdd_enter_standby(pHddCtx);
1459 }
1460#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001461
1462 return;
1463}
1464
1465static void hdd_PowerStateChangedCB
1466(
1467 v_PVOID_t callbackContext,
1468 tPmcState newState
1469)
1470{
1471 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301472
Jeff Johnson295189b2012-06-20 16:38:30 -07001473 /* if the driver was not in BMPS during early suspend,
1474 * the dynamic DTIM is now updated at Riva */
1475 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1476 && pHddCtx->cfg_ini->enableDynamicDTIM
1477 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1478 {
1479 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1480 }
1481 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301482 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1483 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301485 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1486 {
Amar Singhald53568e2013-09-26 11:03:45 -07001487 pHddCtx->sus_res_mcastbcast_filter =
1488 pHddCtx->configuredMcastBcastFilter;
1489 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1490
1491 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1492 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1493 pHddCtx->configuredMcastBcastFilter);
1494 hddLog(VOS_TRACE_LEVEL_INFO,
1495 "offload: calling hdd_conf_mcastbcast_filter");
1496
1497 }
1498
Jeff Johnson295189b2012-06-20 16:38:30 -07001499 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001500 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301502 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001503 else
Mihir Shete793209f2014-01-06 11:01:12 +05301504 {
1505 /* Android framework can send resume request when the WCN chip is
1506 * in IMPS mode. When the chip exits IMPS mode the firmware will
1507 * restore all the registers to the state they were before the chip
1508 * entered IMPS and so our hardware filter settings confgured by the
1509 * resume request will be lost. So reconfigure the filters on detecting
1510 * a change in the power state of the WCN chip.
1511 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301512 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301513 if (IMPS != newState)
1514 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301515 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301516 if (FALSE == pHddCtx->hdd_wlan_suspended)
1517 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301518 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301519 hddLog(VOS_TRACE_LEVEL_INFO,
1520 "Not in IMPS/BMPS and suspended state");
1521 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1522 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301523 else
1524 {
1525 spin_unlock(&pHddCtx->filter_lock);
1526 }
Mihir Shete793209f2014-01-06 11:01:12 +05301527 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001529}
1530
Jeff Johnson295189b2012-06-20 16:38:30 -07001531void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1532{
1533 v_CONTEXT_t pVosContext;
1534 tHalHandle smeContext;
1535
1536 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1537 if (NULL == pVosContext)
1538 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001539 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001540 return;
1541 }
1542 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1543 if (NULL == smeContext)
1544 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001545 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 return;
1547 }
1548
1549 spin_lock_init(&pHddCtx->filter_lock);
1550 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1551 pHddCtx->cfg_ini->nEnableSuspend)
1552 {
1553 pmcRegisterDeviceStateUpdateInd(smeContext,
1554 hdd_PowerStateChangedCB, pHddCtx);
1555 }
1556}
1557
1558void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1559{
1560 v_CONTEXT_t pVosContext;
1561 tHalHandle smeContext;
1562
1563 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1564 if (NULL == pVosContext)
1565 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001566 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001567 return;
1568 }
1569 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1570 if (NULL == smeContext)
1571 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001572 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001573 return;
1574 }
1575
1576 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1577 pHddCtx->cfg_ini->nEnableSuspend)
1578 {
1579 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1580 }
1581}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301582
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301583#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301584void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301585{
1586 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301587 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301588 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1589
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301590 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301591 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301592 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1593 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1594 {
1595 vos_mem_copy(&hddGtkOffloadReqParams,
1596 &pHddStaCtx->gtkOffloadReqParams,
1597 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301598
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301599 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1600 &hddGtkOffloadReqParams, pAdapter->sessionId);
1601 if (eHAL_STATUS_SUCCESS != ret)
1602 {
1603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1604 "%s: sme_SetGTKOffload failed, returned %d",
1605 __func__, ret);
1606 return;
1607 }
1608
1609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1610 "%s: sme_SetGTKOffload successfull", __func__);
1611 }
1612
1613 }
1614 else
1615 {
1616 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1617 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1618 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1619 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1620 {
1621
1622 /* Host driver has previously offloaded GTK rekey */
1623 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301624 wlan_hdd_cfg80211_update_replayCounterCallback,
1625 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301626 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301627
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301628 {
1629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1630 "%s: sme_GetGTKOffload failed, returned %d",
1631 __func__, ret);
1632 return;
1633 }
1634 else
1635 {
1636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1637 "%s: sme_GetGTKOffload successful",
1638 __func__);
1639
1640 /* Sending GTK offload dissable */
1641 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1642 sizeof (tSirGtkOffloadParams));
1643 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1644 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301645 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301646 if (eHAL_STATUS_SUCCESS != ret)
1647 {
1648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1649 "%s: failed to dissable GTK offload, returned %d",
1650 __func__, ret);
1651 return;
1652 }
1653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1654 "%s: successfully dissabled GTK offload request to HAL",
1655 __func__);
1656 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301657 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301658 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301659 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301660}
1661#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001662
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001663void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001664{
1665 hdd_context_t *pHddCtx = NULL;
1666 hdd_adapter_t *pAdapter = NULL;
1667 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1668 VOS_STATUS status;
1669 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001670
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1672
1673 //Get the global VOSS context.
1674 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1675 if(!pVosContext) {
1676 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1677 return;
1678 }
1679
1680 //Get the HDD context.
1681 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1682
1683 if(!pHddCtx) {
1684 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1685 return;
1686 }
1687
Agarwal Ashish971c2882013-10-30 20:11:12 +05301688 if (pHddCtx->isLogpInProgress)
1689 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001690 hddLog(VOS_TRACE_LEVEL_INFO,
1691 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1692 return;
1693 }
1694
Jeff Johnson295189b2012-06-20 16:38:30 -07001695 pHddCtx->hdd_wlan_suspended = FALSE;
1696 /*loop through all adapters. Concurrency */
1697 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1698
1699 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1700 {
1701 pAdapter = pAdapterNode->pAdapter;
1702 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001703 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001704 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001705 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1707 pAdapterNode = pNext;
1708 continue;
1709 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301710
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301711
Jeff Johnson295189b2012-06-20 16:38:30 -07001712#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1713 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1714 {
1715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1716 hdd_exit_deep_sleep(pAdapter);
1717 }
1718#endif
1719
1720 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1721 {
1722 /*Switch back to DTIM 1*/
1723 tSirSetPowerParamsReq powerRequest = { 0 };
1724
1725 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1726 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001727 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001728
1729 /*Disabled ModulatedDTIM if enabled on suspend*/
1730 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1731 powerRequest.uDTIMPeriod = 0;
1732
1733 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1734 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1735 NULL, eANI_BOOLEAN_FALSE);
1736 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1737 NULL, eANI_BOOLEAN_FALSE);
1738
1739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001740 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001741 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001742
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301743 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1744 {
1745 /* put the device into full power */
1746 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001747
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301748 /* put the device back into BMPS */
1749 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001750
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301751 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1752 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 }
1754
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301755 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001756 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1757 pAdapterNode = pNext;
1758 }
1759
1760#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1761 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1762 {
1763 hdd_exit_standby(pHddCtx);
1764 }
1765#endif
1766
Jeff Johnson295189b2012-06-20 16:38:30 -07001767 return;
1768}
1769
Jeff Johnson295189b2012-06-20 16:38:30 -07001770VOS_STATUS hdd_wlan_reset_initialization(void)
1771{
Jeff Johnson295189b2012-06-20 16:38:30 -07001772 v_CONTEXT_t pVosContext = NULL;
1773
1774 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1775
1776 //Get the global VOSS context.
1777 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1778 if(!pVosContext)
1779 {
1780 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1781 return VOS_STATUS_E_FAILURE;
1782 }
1783
1784 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1785
1786 // Prevent the phone from going to sleep
1787 hdd_prevent_suspend();
1788
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 return VOS_STATUS_SUCCESS;
1790}
1791
1792
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001793/*
1794 * Based on the ioctl command recieved by HDD, put WLAN driver
1795 * into the quiet mode. This is the same as the early suspend
1796 * notification that driver used to listen
1797 */
1798void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001799{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301800 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001801 if (suspend)
1802 hdd_suspend_wlan();
1803 else
1804 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301805 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001806}
1807
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001808static void hdd_ssr_timer_init(void)
1809{
1810 init_timer(&ssr_timer);
1811}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001812
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001813static void hdd_ssr_timer_del(void)
1814{
1815 del_timer(&ssr_timer);
1816 ssr_timer_started = false;
1817}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001818
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001819static void hdd_ssr_timer_cb(unsigned long data)
1820{
1821 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001822
1823#ifdef WCN_PRONTO
1824 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1825 wcnss_pronto_log_debug_regs();
1826#endif
1827
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001828 VOS_BUG(0);
1829}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001830
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001831static void hdd_ssr_timer_start(int msec)
1832{
1833 if(ssr_timer_started)
1834 {
1835 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1836 ,__func__);
1837 }
1838 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1839 ssr_timer.function = hdd_ssr_timer_cb;
1840 add_timer(&ssr_timer);
1841 ssr_timer_started = true;
1842}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001843
Jeff Johnson295189b2012-06-20 16:38:30 -07001844/* the HDD interface to WLAN driver shutdown,
1845 * the primary shutdown function in SSR
1846 */
1847VOS_STATUS hdd_wlan_shutdown(void)
1848{
1849 VOS_STATUS vosStatus;
1850 v_CONTEXT_t pVosContext = NULL;
1851 hdd_context_t *pHddCtx = NULL;
1852 pVosSchedContext vosSchedContext = NULL;
c_hpothuffdb5272013-10-02 16:42:35 +05301853 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001854
1855 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1856
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001857 /* if re-init never happens, then do SSR1 */
1858 hdd_ssr_timer_init();
1859 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1860
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 /* Get the global VOSS context. */
1862 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1863 if(!pVosContext) {
1864 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1865 return VOS_STATUS_E_FAILURE;
1866 }
1867 /* Get the HDD context. */
1868 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1869 if(!pHddCtx) {
1870 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1871 return VOS_STATUS_E_FAILURE;
1872 }
c_hpothud662a352013-12-26 15:09:12 +05301873
1874 //Stop the traffic monitor timer
1875 if ( VOS_TIMER_STATE_RUNNING ==
1876 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1877 {
1878 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1879 }
1880
Jeff Johnson295189b2012-06-20 16:38:30 -07001881 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 /* DeRegister with platform driver as client for Suspend/Resume */
1883 vosStatus = hddDeregisterPmOps(pHddCtx);
1884 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1885 {
1886 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1887 }
1888
1889 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1890 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1891 {
1892 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1893 }
1894
1895 /* Disable IMPS/BMPS as we do not want the device to enter any power
1896 * save mode on its own during reset sequence
1897 */
1898 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1899 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1900 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1901
1902 vosSchedContext = get_vos_sched_ctxt();
1903
1904 /* Wakeup all driver threads */
1905 if(TRUE == pHddCtx->isMcThreadSuspended){
1906 complete(&vosSchedContext->ResumeMcEvent);
1907 pHddCtx->isMcThreadSuspended= FALSE;
1908 }
1909 if(TRUE == pHddCtx->isTxThreadSuspended){
1910 complete(&vosSchedContext->ResumeTxEvent);
1911 pHddCtx->isTxThreadSuspended= FALSE;
1912 }
1913 if(TRUE == pHddCtx->isRxThreadSuspended){
1914 complete(&vosSchedContext->ResumeRxEvent);
1915 pHddCtx->isRxThreadSuspended= FALSE;
1916 }
1917 /* Reset the Suspend Variable */
1918 pHddCtx->isWlanSuspended = FALSE;
1919
1920 /* Stop all the threads; we do not want any messages to be a processed,
1921 * any more and the best way to ensure that is to terminate the threads
1922 * gracefully.
1923 */
1924 /* Wait for MC to exit */
1925 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1926 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1927 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1928 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301929 ret = wait_for_completion_interruptible(&vosSchedContext->McShutdown);
1930 if (0 >= ret)
1931 {
1932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on McShutdown failed %ld",
1933 __func__, ret);
1934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001935
1936 /* Wait for TX to exit */
1937 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1938 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1939 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1940 wake_up_interruptible(&vosSchedContext->txWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301941 ret = wait_for_completion_interruptible(&vosSchedContext->TxShutdown);
1942 if (0 >= ret)
1943 {
1944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on TxShutdown failed %ld",
1945 __func__, ret);
1946 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001947
1948 /* Wait for RX to exit */
1949 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1950 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1951 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1952 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301953
1954 ret = wait_for_completion_interruptible(&vosSchedContext->RxShutdown);
1955 if (0 >= ret)
1956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on RxShutdown failed %ld",
1958 __func__, ret);
1959 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001960
1961#ifdef WLAN_BTAMP_FEATURE
1962 vosStatus = WLANBAP_Stop(pVosContext);
1963 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1964 {
1965 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1966 "%s: Failed to stop BAP",__func__);
1967 }
1968#endif //WLAN_BTAMP_FEATURE
1969 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301970 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1971 {
1972 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1973 "%s: Failed to stop wda %d", __func__, vosStatus);
1974 VOS_ASSERT(0);
1975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001976
1977 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1978 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1979 * on threads being running to process the SYS Stop
1980 */
Kiet Lama72a2322013-11-15 11:18:11 +05301981 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301982 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1983 {
1984 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1985 "%s: Failed to stop sme %d", __func__, vosStatus);
1986 VOS_ASSERT(0);
1987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001988
1989 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1990 /* Stop MAC (PE and HAL) */
1991 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301992 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1993 {
1994 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1995 "%s: Failed to stop mac %d", __func__, vosStatus);
1996 VOS_ASSERT(0);
1997 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001998
1999 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2000 /* Stop TL */
2001 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302002 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2003 {
2004 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2005 "%s: Failed to stop TL %d", __func__, vosStatus);
2006 VOS_ASSERT(0);
2007 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002008
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002010 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2011 /* Clean up message queues of TX and MC thread */
2012 vos_sched_flush_mc_mqs(vosSchedContext);
2013 vos_sched_flush_tx_mqs(vosSchedContext);
2014 vos_sched_flush_rx_mqs(vosSchedContext);
2015
2016 /* Deinit all the TX and MC queues */
2017 vos_sched_deinit_mqs(vosSchedContext);
2018 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2019
2020 /* shutdown VOSS */
2021 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302022
2023 /*mac context has already been released in mac_close call
2024 so setting it to NULL in hdd context*/
2025 pHddCtx->hHal = (tHalHandle)NULL;
2026
Jeff Johnson295189b2012-06-20 16:38:30 -07002027 if (free_riva_power_on_lock("wlan"))
2028 {
2029 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2030 __func__);
2031 }
2032 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2033 ,__func__);
2034 return VOS_STATUS_SUCCESS;
2035}
2036
2037
2038
2039/* the HDD interface to WLAN driver re-init.
2040 * This is called to initialize/start WLAN driver after a shutdown.
2041 */
2042VOS_STATUS hdd_wlan_re_init(void)
2043{
2044 VOS_STATUS vosStatus;
2045 v_CONTEXT_t pVosContext = NULL;
2046 hdd_context_t *pHddCtx = NULL;
2047 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002048#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2049 int max_retries = 0;
2050#endif
Anand N Sunkad337f2fd2014-10-10 22:37:38 +05302051#ifdef HAVE_CBC_DONE
2052 int max_cbc_retries = 0;
2053#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002054#ifdef WLAN_BTAMP_FEATURE
2055 hdd_config_t *pConfig = NULL;
2056 WLANBAP_ConfigType btAmpConfig;
2057#endif
2058
Katya Nigam82a93062014-06-04 15:15:36 +05302059 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002060 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002061 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002062
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002063#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2064 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002065 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002066 msleep(1000);
2067 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002068 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002069 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2070 goto err_re_init;
2071 }
2072#endif
2073
Anand N Sunkad337f2fd2014-10-10 22:37:38 +05302074#ifdef HAVE_CBC_DONE
2075 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2076 msleep(1000);
2077 }
2078 if (max_cbc_retries >= 20) {
2079 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2080 }
2081#endif
2082
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002083 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2084
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002085 /* The driver should always be initialized in STA mode after SSR */
2086 hdd_set_conparam(0);
2087
Katya Nigam82a93062014-06-04 15:15:36 +05302088 dev = wcnss_wlan_get_device();
2089 if (NULL == dev)
2090 {
2091 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2092 goto err_re_init;
2093 }
2094
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302096 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2098 {
2099 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2100 goto err_re_init;
2101 }
2102
2103 /* Get the HDD context. */
2104 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2105 if(!pHddCtx)
2106 {
2107 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2108 goto err_vosclose;
2109 }
2110
2111 /* Save the hal context in Adapter */
2112 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2113 if ( NULL == pHddCtx->hHal )
2114 {
2115 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2116 goto err_vosclose;
2117 }
2118
2119 /* Set the SME configuration parameters. */
2120 vosStatus = hdd_set_sme_config(pHddCtx);
2121 if ( VOS_STATUS_SUCCESS != vosStatus )
2122 {
2123 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2124 goto err_vosclose;
2125 }
2126
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 vosStatus = vos_preStart( pHddCtx->pvosContext );
2128 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2129 {
2130 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2131 goto err_vosclose;
2132 }
2133
2134 /* In the integrated architecture we update the configuration from
2135 the INI file and from NV before vOSS has been started so that
2136 the final contents are available to send down to the cCPU */
2137 /* Apply the cfg.ini to cfg.dat */
2138 if (FALSE == hdd_update_config_dat(pHddCtx))
2139 {
2140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2141 goto err_vosclose;
2142 }
2143
2144 /* Set the MAC Address, currently this is used by HAL to add self sta.
2145 * Remove this once self sta is added as part of session open. */
2146 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2147 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2148 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2149 if (!HAL_STATUS_SUCCESS(halStatus))
2150 {
2151 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2152 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2153 goto err_vosclose;
2154 }
2155
2156 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2157 Note: Firmware image will be read and downloaded inside vos_start API */
2158 vosStatus = vos_start( pVosContext );
2159 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2160 {
2161 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2162 goto err_vosclose;
2163 }
2164
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002165 /* Exchange capability info between Host and FW and also get versioning info from FW */
2166 hdd_exchange_version_and_caps(pHddCtx);
2167
Jeff Johnson295189b2012-06-20 16:38:30 -07002168 vosStatus = hdd_post_voss_start_config( pHddCtx );
2169 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2170 {
2171 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2172 __func__);
2173 goto err_vosstop;
2174 }
2175
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302176 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2177 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2178 {
2179 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2180 __func__);
2181 goto err_vosstop;
2182 }
2183
Jeff Johnson295189b2012-06-20 16:38:30 -07002184#ifdef WLAN_BTAMP_FEATURE
2185 vosStatus = WLANBAP_Open(pVosContext);
2186 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2187 {
2188 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2189 "%s: Failed to open BAP",__func__);
2190 goto err_vosstop;
2191 }
2192 vosStatus = BSL_Init(pVosContext);
2193 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2194 {
2195 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2196 "%s: Failed to Init BSL",__func__);
2197 goto err_bap_close;
2198 }
2199 vosStatus = WLANBAP_Start(pVosContext);
2200 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2201 {
2202 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2203 "%s: Failed to start TL",__func__);
2204 goto err_bap_close;
2205 }
2206 pConfig = pHddCtx->cfg_ini;
2207 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2208 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2209#endif //WLAN_BTAMP_FEATURE
2210
2211 /* Restart all adapters */
2212 hdd_start_all_adapters(pHddCtx);
2213 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002214 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302216 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002217 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302218 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002219 /* Register with platform driver as client for Suspend/Resume */
2220 vosStatus = hddRegisterPmOps(pHddCtx);
2221 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2222 {
2223 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2224 goto err_bap_stop;
2225 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002226 /* Allow the phone to go to sleep */
2227 hdd_allow_suspend();
2228 /* register for riva power on lock */
2229 if (req_riva_power_on_lock("wlan"))
2230 {
2231 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2232 __func__);
2233 goto err_unregister_pmops;
2234 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002235 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302236#ifdef WLAN_FEATURE_EXTSCAN
2237 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2238 wlan_hdd_cfg80211_extscan_callback,
2239 pHddCtx);
2240#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 goto success;
2242
2243err_unregister_pmops:
2244 hddDeregisterPmOps(pHddCtx);
2245
2246err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002247#ifdef CONFIG_HAS_EARLYSUSPEND
2248 hdd_unregister_mcast_bcast_filter(pHddCtx);
2249#endif
2250 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002251#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002252 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002253#endif
2254
2255#ifdef WLAN_BTAMP_FEATURE
2256err_bap_close:
2257 WLANBAP_Close(pVosContext);
2258#endif
2259
2260err_vosstop:
2261 vos_stop(pVosContext);
2262
2263err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302264 if(!isSsrPanicOnFailure())
2265 {
2266 /* If we hit this, it means wlan driver is in bad state and needs
2267 * driver unload and load.
2268 */
Siddharth Bhald4ad02d2014-09-15 10:31:57 +05302269 if (pHddCtx)
2270 pHddCtx->isLogpInProgress = FALSE;
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302271 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2272 return VOS_STATUS_E_FAILURE;
2273 }
2274
Jeff Johnson295189b2012-06-20 16:38:30 -07002275 vos_close(pVosContext);
2276 vos_sched_close(pVosContext);
2277 if (pHddCtx)
2278 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002279 /* Unregister the Net Device Notifier */
2280 unregister_netdevice_notifier(&hdd_netdev_notifier);
2281 /* Clean up HDD Nlink Service */
2282 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002283#ifdef WLAN_KD_READY_NOTIFIER
2284 nl_srv_exit(pHddCtx->ptt_pid);
2285#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002286 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002287#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002288 /* Free up dynamically allocated members inside HDD Adapter */
2289 kfree(pHddCtx->cfg_ini);
2290 pHddCtx->cfg_ini= NULL;
2291
Jeff Johnson295189b2012-06-20 16:38:30 -07002292 wiphy_unregister(pHddCtx->wiphy);
2293 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002294 }
2295 vos_preClose(&pVosContext);
2296
2297#ifdef MEMORY_DEBUG
2298 vos_mem_exit();
2299#endif
2300
2301err_re_init:
2302 /* Allow the phone to go to sleep */
2303 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002304 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002305 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002306 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002307
2308success:
2309 /* Trigger replay of BTC events */
2310 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2311 return VOS_STATUS_SUCCESS;
2312}