blob: 8098473162912169f27a29df8749708492c8d0da [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05302 * Copyright (c) 2012-2015 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
Jeff Johnson295189b2012-06-20 16:38:30 -070034*
35==============================================================================**/
36/* $HEADER$ */
37
38/**-----------------------------------------------------------------------------
39* Include files
40* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42#include <linux/pm.h>
43#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070044#include <wlan_hdd_includes.h>
45#include <wlan_qct_driver.h>
46#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48#include "halTypes.h"
49#include "sme_Api.h"
50#include <vos_api.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070051#include <vos_sched.h>
52#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <wlan_qct_sys.h>
54#include <wlan_btc_svc.h>
55#include <wlan_nlink_common.h>
56#include <wlan_hdd_main.h>
57#include <wlan_hdd_assoc.h>
58#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070059#include <wlan_nlink_srv.h>
60#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070061#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062
Jeff Johnson295189b2012-06-20 16:38:30 -070063#include <linux/semaphore.h>
64#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include "cfgApi.h"
66
67#ifdef WLAN_BTAMP_FEATURE
68#include "bapApi.h"
69#include "bap_hdd_main.h"
70#include "bap_hdd_misc.h"
71#endif
72
Jeff Johnsone7245742012-09-05 17:12:55 -070073#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070074#include <linux/inetdevice.h>
75#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053076#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053077#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070078/**-----------------------------------------------------------------------------
79* Preprocessor definitions and constants
80* ----------------------------------------------------------------------------*/
81
82/**-----------------------------------------------------------------------------
83* Type declarations
84* ----------------------------------------------------------------------------*/
85
86/**-----------------------------------------------------------------------------
87* Function and variables declarations
88* ----------------------------------------------------------------------------*/
89#include "wlan_hdd_power.h"
90#include "wlan_hdd_packet_filtering.h"
91
Sameer Thalappile5637f42013-08-07 15:46:55 -070092#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053093#define NS_DEFAULT_SLOT_INDEX 4
94#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070095
96static eHalStatus g_full_pwr_status;
97static eHalStatus g_standby_status;
98
99extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700103extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700104
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700105static struct timer_list ssr_timer;
106static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108//Callback invoked by PMC to report status of standby request
109void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
110{
111 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
113 g_standby_status = status;
114
115 if(eHAL_STATUS_SUCCESS == status)
116 {
117 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
118 }
119 else
120 {
121 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
122 }
123
124 complete(&pHddCtx->standby_comp_var);
125}
126
127//Callback invoked by PMC to report status of full power request
128void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
129{
130 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
131 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
132 g_full_pwr_status = status;
133
134 if(eHAL_STATUS_SUCCESS == status)
135 {
136 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
137 }
138 else
139 {
140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
141 }
142
143 complete(&pHddCtx->full_pwr_comp_var);
144}
145
146eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
147{
148 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530149 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700150
151 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
152 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
153
154 g_full_pwr_status = eHAL_STATUS_FAILURE;
155 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
156 eSME_FULL_PWR_NEEDED_BY_HDD);
157
158 if(status == eHAL_STATUS_PMC_PENDING)
159 {
160 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530161 ret = wait_for_completion_interruptible_timeout(
162 &pHddCtx->full_pwr_comp_var,
163 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
164 if (0 >= ret)
165 {
166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
167 __func__, ret);
168 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700169 status = g_full_pwr_status;
170 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
171 {
172 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
173 VOS_ASSERT(0);
174 goto failure;
175 }
176 }
177 else if(status != eHAL_STATUS_SUCCESS)
178 {
179 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
180 __func__, status);
181 VOS_ASSERT(0);
182 goto failure;
183 }
184 else
185 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
186
187failure:
188 //No blocking to reduce latency. No other device should be depending on WLAN
189 //to finish resume and WLAN won't be instantly on after resume
190 return status;
191}
192
193
194//Helper routine to put the chip into standby
195VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
196{
197 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
198 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530199 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700200
201 //Disable IMPS/BMPS as we do not want the device to enter any power
202 //save mode on its own during suspend sequence
203 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
204 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
205
206 //Note we do not disable queues unnecessarily. Queues should already be disabled
207 //if STA is disconnected or the queue will be disabled as and when disconnect
208 //happens because of standby procedure.
209
210 //Ensure that device is in full power first. There is scope for optimization
211 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
212 //Core s/w needs to be optimized to handle this. Until then we request full
213 //power before issuing request for standby.
214 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
215 g_full_pwr_status = eHAL_STATUS_FAILURE;
216 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
217 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
218
219 if(halStatus == eHAL_STATUS_PMC_PENDING)
220 {
221 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530222 ret = wait_for_completion_interruptible_timeout(
223 &pHddCtx->full_pwr_comp_var,
224 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
225 if (0 >= ret)
226 {
227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
228 __func__, ret);
229 }
230
Jeff Johnson295189b2012-06-20 16:38:30 -0700231 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
232 {
233 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
234 VOS_ASSERT(0);
235 vosStatus = VOS_STATUS_E_FAILURE;
236 goto failure;
237 }
238 }
239 else if(halStatus != eHAL_STATUS_SUCCESS)
240 {
241 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
242 __func__, halStatus);
243 VOS_ASSERT(0);
244 vosStatus = VOS_STATUS_E_FAILURE;
245 goto failure;
246 }
247
248 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
249 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
250 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
251 }
252
253 //Request standby. Standby will cause the STA to disassociate first. TX queues
254 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
255 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
256 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
257 //when there are concurrent sessions.
258 INIT_COMPLETION(pHddCtx->standby_comp_var);
259 g_standby_status = eHAL_STATUS_FAILURE;
260 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
261
262 if (halStatus == eHAL_STATUS_PMC_PENDING)
263 {
264 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530265 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530267 if (0 >= ret)
268 {
269 hddLog(VOS_TRACE_LEVEL_ERROR,
270 FL("wait on standby_comp_var failed %ld"), ret);
271 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
273 {
274 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
275 VOS_ASSERT(0);
276 vosStatus = VOS_STATUS_E_FAILURE;
277 goto failure;
278 }
279 }
280 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
281 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
282 __func__, halStatus);
283 VOS_ASSERT(0);
284 vosStatus = VOS_STATUS_E_FAILURE;
285 goto failure;
286 }
287 else
288 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
289
290failure:
291 //Restore IMPS config
292 if(pHddCtx->cfg_ini->fIsImpsEnabled)
293 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
294
295 //Restore BMPS config
296 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
297 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
298
299 return vosStatus;
300}
301
302
303//Helper routine for Deep sleep entry
304VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
305{
306 eHalStatus halStatus;
307 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530308 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800309
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 netif_tx_disable(pAdapter->dev);
313 netif_carrier_off(pAdapter->dev);
314
315 //Disable IMPS,BMPS as we do not want the device to enter any power
316 //save mode on it own during suspend sequence
317 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
318 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
319
320 //Ensure that device is in full power as we will touch H/W during vos_Stop
321 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
322 g_full_pwr_status = eHAL_STATUS_FAILURE;
323 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
324 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
325
326 if(halStatus == eHAL_STATUS_PMC_PENDING)
327 {
328 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530329 ret = wait_for_completion_interruptible_timeout(
330 &pHddCtx->full_pwr_comp_var,
331 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
332 if (0 >= ret)
333 {
334 hddLog(VOS_TRACE_LEVEL_ERROR,
335 FL("wait on full_pwr_comp_var failed %ld"), ret);
336 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
338 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
339 VOS_ASSERT(0);
340 }
341 }
342 else if(halStatus != eHAL_STATUS_SUCCESS)
343 {
344 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
345 VOS_ASSERT(0);
346 }
347
348 //Issue a disconnect. This is required to inform the supplicant that
349 //STA is getting disassociated and for GUI to be updated properly
350 INIT_COMPLETION(pAdapter->disconnect_comp_var);
351 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
352
353 //Success implies disconnect command got queued up successfully
354 if(halStatus == eHAL_STATUS_SUCCESS)
355 {
356 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530357 ret = wait_for_completion_interruptible_timeout(
358 &pAdapter->disconnect_comp_var,
359 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
360 if (0 >= ret)
361 {
362 hddLog(VOS_TRACE_LEVEL_ERROR,
363 FL("wait on disconnect_comp_var failed %ld"), ret);
364 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 }
366
367
368 //None of the steps should fail after this. Continue even in case of failure
369 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530370 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
371 {
372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
373 __func__, vosStatus);
374 VOS_ASSERT(0);
375 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700376
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
378
379 //Restore IMPS config
380 if(pHddCtx->cfg_ini->fIsImpsEnabled)
381 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
382
383 //Restore BMPS config
384 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
385 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
386
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 return vosStatus;
388}
389
390VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
391{
392 VOS_STATUS vosStatus;
393 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700394
Jeff Johnson295189b2012-06-20 16:38:30 -0700395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
396 "%s: calling hdd_set_sme_config",__func__);
397 vosStatus = hdd_set_sme_config( pHddCtx );
398 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
399 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
400 {
401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
402 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700403 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700404 }
405
406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
407 "%s: calling vos_start",__func__);
408 vosStatus = vos_start( pHddCtx->pvosContext );
409 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
410 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
411 {
412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
413 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700414 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700415 }
416
417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
418 "%s: calling hdd_post_voss_start_config",__func__);
419 vosStatus = hdd_post_voss_start_config( pHddCtx );
420 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
421 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
422 {
423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
424 "%s: Failed in hdd_post_voss_start_config",__func__);
425 goto err_voss_stop;
426 }
427
428
429 //Open a SME session for future operation
430 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700431 (tANI_U8 *)&pAdapter->macAddressCurrent,
432 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700433 if ( !HAL_STATUS_SUCCESS( halStatus ) )
434 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700435 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700436 halStatus, halStatus );
437 goto err_voss_stop;
438
439 }
440
441 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
442
443 //Trigger the initial scan
444 hdd_wlan_initial_scan(pHddCtx);
445
446 return VOS_STATUS_SUCCESS;
447
448err_voss_stop:
449 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700450err_deep_sleep:
451 return VOS_STATUS_E_FAILURE;
452
453}
454
Atul Mittal37385d72014-03-27 18:15:03 +0530455void hdd_ipv6_notifier_work_queue(struct work_struct *work)
456{
457 hdd_adapter_t* pAdapter =
458 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
459 hdd_context_t *pHddCtx;
460 int status;
461
462 hddLog(LOG1, FL("Reconfiguring NS Offload"));
463
464 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
465 status = wlan_hdd_validate_context(pHddCtx);
466 if (0 != status)
467 {
468 hddLog(LOGE, FL("HDD context is invalid"));
469 return;
470 }
471
472 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
473 {
474 pHddCtx->sus_res_mcastbcast_filter =
475 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530476 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
477 pHddCtx->sus_res_mcastbcast_filter);
Atul Mittal37385d72014-03-27 18:15:03 +0530478 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
479 }
480
481 if ((eConnectionState_Associated ==
482 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
483 && (pHddCtx->hdd_wlan_suspended))
484 {
485 // This invocation being part of the IPv6 registration callback,
486 // set the newly generated ip address to f/w in suspend mode.
487#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530488 if (pHddCtx->cfg_ini->fhostNSOffload)
489 {
490 hdd_conf_ns_offload(pAdapter, 1);
491 }
Atul Mittal37385d72014-03-27 18:15:03 +0530492#endif
493 }
494#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530495 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530496 * only so when new ipv6 address is generated the screen may not
497 * on so we need to call it here to update the list in f/w.
498 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530499 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530500#endif
501
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530502
Atul Mittal37385d72014-03-27 18:15:03 +0530503}
504
505
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530506int wlan_hdd_ipv6_changed(struct notifier_block *nb,
507 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530508{
509 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
510 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530511 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530512 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530513 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530514 int status;
515
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530516 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
517 status = wlan_hdd_validate_context(pHddCtx);
518 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530519 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530520 hddLog(LOGE, FL("HDD context is invalid"));
521 return NOTIFY_DONE;
522 }
Atul Mittal37385d72014-03-27 18:15:03 +0530523
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530524 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
525 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
526 {
527 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
528 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
529 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
530 {
531 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530532 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530533 {
534 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
535 }
536 else
537 {
538 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
539 pHddCtx->cfg_ini->nEnableSuspend);
540 }
541 break;
542 }
543 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
544 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530545 }
546
547 return NOTIFY_DONE;
548}
549
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530550/*
551 * Function: hdd_conf_hostoffload
552 * Central function to configure the supported offloads,
553 * either enable or disable them.
554 */
555void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
556{
557 hdd_context_t *pHddCtx = NULL;
558 v_CONTEXT_t *pVosContext = NULL;
559 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
560
561 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
562 fenable);
563
564 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
565
566 if (NULL == pVosContext)
567 {
568 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
569 return;
570 }
571
572 //Get the HDD context.
573 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
574
575 if (NULL == pHddCtx)
576 {
577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
578 return;
579 }
580
581 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
582 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
583 {
584 if (fenable)
585 {
586 if (eConnectionState_Associated ==
587 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
588 {
589 if ((pHddCtx->cfg_ini->fhostArpOffload))
590 {
591 /*
592 * Configure the ARP Offload.
593 * Even if it fails we have to reconfigure the MC/BC
594 * filter flag as we want RIVA not to drop BroadCast
595 * Packets
596 */
597 hddLog(VOS_TRACE_LEVEL_INFO,
598 FL("Calling ARP Offload with flag: %d"), fenable);
599 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
600 pHddCtx->configuredMcastBcastFilter &=
601 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
602
603 if (!VOS_IS_STATUS_SUCCESS(vstatus))
604 {
605 hddLog(VOS_TRACE_LEVEL_ERROR,
606 "Failed to enable ARPOFfloadFeature %d",
607 vstatus);
608 }
609 }
610 //Configure GTK_OFFLOAD
611#ifdef WLAN_FEATURE_GTK_OFFLOAD
612 hdd_conf_gtk_offload(pAdapter, fenable);
613#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530614
615#ifdef WLAN_NS_OFFLOAD
616 if (pHddCtx->cfg_ini->fhostNSOffload)
617 {
618 /*
619 * Configure the NS Offload.
620 * Even if it fails we have to reconfigure the MC/BC filter flag
621 * as we want RIVA not to drop Multicast Packets
622 */
623
624 hddLog(VOS_TRACE_LEVEL_INFO,
625 FL("Calling NS Offload with flag: %d"), fenable);
626 hdd_conf_ns_offload(pAdapter, fenable);
627 pHddCtx->configuredMcastBcastFilter &=
628 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
629 }
630#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530631
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530632 }
633 }
634 else
635 {
636 //Disable ARPOFFLOAD
637 if (pHddCtx->cfg_ini->fhostArpOffload)
638 {
639 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
640 if (!VOS_IS_STATUS_SUCCESS(vstatus))
641 {
642 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530643 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530644 }
645 }
646 //Disable GTK_OFFLOAD
647#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530648 hdd_conf_gtk_offload(pAdapter, fenable);
649#endif
650
651#ifdef WLAN_NS_OFFLOAD
652 //Disable NSOFFLOAD
653 if (pHddCtx->cfg_ini->fhostNSOffload)
654 {
655 hdd_conf_ns_offload(pAdapter, fenable);
656 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530657#endif
658 }
659 }
660 return;
661}
662
Atul Mittal37385d72014-03-27 18:15:03 +0530663
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530664#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530665/**----------------------------------------------------------------------------
666
667 \brief hdd_conf_ns_offload() - Configure NS offload
668
669 Called during SUSPEND to configure the NS offload (MC BC filter) which
670 reduces power consumption.
671
672 \param - pAdapter - Adapter context for which NS offload is to be configured
673 \param - fenable - 0 - disable.
674 1 - enable. (with IPv6 notifier registration)
675 2 - enable. (without IPv6 notifier registration)
676
677 \return - void
678
679 ---------------------------------------------------------------------------*/
680void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530681{
682 struct inet6_dev *in6_dev;
683 struct inet6_ifaddr *ifp;
684 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530685 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530686 tANI_U8 **selfIPv6Addr = NULL;
687 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530688 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530689 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530690 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530691
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530692 int i = 0, slot = 0;
693 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530694 eHalStatus returnStatus;
695
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530696 ENTER();
697 hddLog(LOG1, FL(" fenable = %d"), fenable);
698
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530699 if (NULL == pAdapter)
700 {
701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
702 return;
703 }
704
705 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530706 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
707
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530708 ret = wlan_hdd_validate_context(pHddCtx);
709
710 if (0 != ret)
711 {
712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
713 FL("HDD context is not valid"));
714 return;
715 }
716
717 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
718 {
719 slot_index = NS_EXTENDED_SLOT_INDEX;
720 }
721
722 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
723
724 selfIPv6AddrValid =
725 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
726
727 if (NULL == selfIPv6AddrValid)
728 {
729 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
730 " selfIPv6AddrValid"));
731 goto end;
732 }
733
734 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
735
736 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
737
738 if (NULL == selfIPv6Addr)
739 {
740 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
741 " selfIPv6Addr"));
742 goto end;
743 }
744
745 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
746
747 for (slot = 0; slot < slot_index; slot++)
748 {
749 selfIPv6Addr[slot] =
750 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
751 if (NULL == selfIPv6Addr[slot])
752 {
753 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
754 "for selfIPv6Addr"));
755 goto end;
756 }
757 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
758 }
759
760 i = 0;
761
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530762 if (fenable)
763 {
764 in6_dev = __in6_dev_get(pAdapter->dev);
765 if (NULL != in6_dev)
766 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530767 list_for_each(p, &in6_dev->addr_list)
768 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530769 if (i >= slot_index)
770 {
771 hddLog (VOS_TRACE_LEVEL_ERROR,
772 FL("IPv6 address list is greater than IPv6"
773 "address supported by firmware"));
774 hddLog (VOS_TRACE_LEVEL_ERROR,
775 FL("FW supported IPv6 address = %d"), slot_index);
776 break;
777 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530778 ifp = list_entry(p, struct inet6_ifaddr, if_list);
779 switch(ipv6_addr_src_scope(&ifp->addr))
780 {
781 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530782 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530783 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530784 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530785 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530786 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
787 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530788 break;
789 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530790 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530791 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530792 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530793 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530794 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
795 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530796 break;
797 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530798 hddLog(VOS_TRACE_LEVEL_ERROR,
799 FL("The Scope %d is not supported"),
800 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530801 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530802 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
803 {
804 i++;
805 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530806 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530807
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530808 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530809 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530810 {
811 if (selfIPv6AddrValid[i])
812 {
813 //Filling up the request structure
814 /* Filling the selfIPv6Addr with solicited address
815 * A Solicited-Node multicast address is created by
816 * taking the last 24 bits of a unicast or anycast
817 * address and appending them to the prefix
818 *
819 * FF02:0000:0000:0000:0000:0001:FFXX:XX
820 *
821 * here XX is the unicast/anycast bits
822 */
823 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
824 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
825 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
826 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530827 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
828 selfIPv6Addr[i][13];
829 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
830 selfIPv6Addr[i][14];
831 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
832 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530833 offLoadRequest.nsOffloadInfo.slotIdx = i;
834
835 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530836 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530837 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
838 &pAdapter->macAddressCurrent.bytes,
839 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
840
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530841 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
842 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530843 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
844 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
845
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530846 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530847 FL("configuredMcastBcastFilter: %d"
848 "NSOffload Slot = %d"),
849 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530850
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530851 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700852 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
853 pHddCtx->sus_res_mcastbcast_filter) ||
854 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
855 pHddCtx->sus_res_mcastbcast_filter)) &&
856 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
857 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
858 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530859 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530860 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700861 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530862 hddLog (VOS_TRACE_LEVEL_INFO,
863 FL("Set offLoadRequest with %d"),
864 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530865 }
866
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530867 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
868 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
869 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
870
871 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530872 FL("Setting NSOffload with solicitedIp: %pI6,"
873 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530874 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
875 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
876
877 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530878 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530879 pAdapter->sessionId, &offLoadRequest);
880 if(eHAL_STATUS_SUCCESS != returnStatus)
881 {
882 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530883 FL("Failed to enable HostOffload feature with"
884 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530885 }
886 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
887 }
888 }
889 }
890 else
891 {
892 hddLog(VOS_TRACE_LEVEL_ERROR,
893 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530894 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530895 }
896 }
897 else
898 {
899 //Disable NSOffload
900 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
901 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
902 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
903
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530904 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530905 {
c_hpothu86feba52014-10-28 15:51:18 +0530906 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530907 offLoadRequest.nsOffloadInfo.slotIdx = i;
908 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530909 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
910 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530911 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
913 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530914 }
915 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530916 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530917end:
918 while (slot > 0 && selfIPv6Addr[--slot])
919 {
920 vos_mem_free(selfIPv6Addr[slot]);
921 }
922 if (selfIPv6Addr)
923 {
924 vos_mem_free(selfIPv6Addr);
925 }
926 if (selfIPv6AddrValid)
927 {
928 vos_mem_free(selfIPv6AddrValid);
929 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530930 return;
931}
932#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530933
934void hdd_ipv4_notifier_work_queue(struct work_struct *work)
935{
936 hdd_adapter_t* pAdapter =
937 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
938 hdd_context_t *pHddCtx;
939 int status;
940
941 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
942 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
943 status = wlan_hdd_validate_context(pHddCtx);
944 if (0 != status)
945 {
946 hddLog(LOGE, FL("HDD context is invalid"));
947 return;
948 }
949
Deepthi Gowri5933f402014-01-23 17:48:24 +0530950 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
951 {
952 pHddCtx->sus_res_mcastbcast_filter =
953 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530954 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
955 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530956 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
957 }
958
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530959 if ((eConnectionState_Associated ==
960 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530961 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530962 {
963 // This invocation being part of the IPv4 registration callback,
964 // we are passing second parameter as 2 to avoid registration
965 // of IPv4 notifier again.
966 hdd_conf_arp_offload(pAdapter, 2);
967 }
968}
969
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530970int wlan_hdd_ipv4_changed(struct notifier_block *nb,
971 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530972{
973 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
974 struct in_ifaddr **ifap = NULL;
975 struct in_device *in_dev;
976
977 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530978 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530979 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530980 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530981 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530982
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530983 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
984 status = wlan_hdd_validate_context(pHddCtx);
985 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530986 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530987 hddLog(LOGE, FL("HDD context is invalid"));
988 return NOTIFY_DONE;
989 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530990
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530991 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
992 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
993 {
994 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
995 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
996 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
997 {
998 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530999 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301000 || (!pHddCtx->cfg_ini->fhostArpOffload))
1001 {
1002 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1003 pHddCtx->cfg_ini->nEnableSuspend,
1004 pHddCtx->cfg_ini->fhostArpOffload);
1005 return NOTIFY_DONE;
1006 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301007
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301008 if ((in_dev =
1009 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1010 {
1011 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1012 ifap = &ifa->ifa_next)
1013 {
1014 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1015 ifa->ifa_label))
1016 {
1017 break; /* found */
1018 }
1019 }
1020 }
1021 if(ifa && ifa->ifa_local)
1022 {
1023 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1024 }
1025 break;
1026 }
1027 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1028 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301029 }
1030
1031 return NOTIFY_DONE;
1032}
1033
1034/**----------------------------------------------------------------------------
1035
1036 \brief hdd_conf_arp_offload() - Configure ARP offload
1037
1038 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1039 reduces power consumption.
1040
1041 \param - pAdapter -Adapter context for which ARP offload is to be configured
1042 \param - fenable - 0 - disable.
1043 1 - enable. (with IPv4 notifier registration)
1044 2 - enable. (without IPv4 notifier registration)
1045
1046 \return -
1047 VOS_STATUS_SUCCESS - on successful operation
1048 VOS_STATUS_E_FAILURE - on failure of operation
1049-----------------------------------------------------------------------------*/
1050VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001051{
1052 struct in_ifaddr **ifap = NULL;
1053 struct in_ifaddr *ifa = NULL;
1054 struct in_device *in_dev;
1055 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001056 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001057 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001058
c_hpothu86feba52014-10-28 15:51:18 +05301059 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001060
Jeff Johnson295189b2012-06-20 16:38:30 -07001061 if(fenable)
1062 {
1063 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1064 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301065 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001066 ifap = &ifa->ifa_next)
1067 {
1068 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1069 {
1070 break; /* found */
1071 }
1072 }
1073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 if(ifa && ifa->ifa_local)
1075 {
1076 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1077 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1078
Arif Hussain6d2a3322013-11-17 19:50:10 -08001079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001080
Amar Singhald53568e2013-09-26 11:03:45 -07001081 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1082 pHddCtx->sus_res_mcastbcast_filter) ||
1083 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1084 pHddCtx->sus_res_mcastbcast_filter)) &&
1085 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001086 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301087 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001088 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1089 hddLog(VOS_TRACE_LEVEL_INFO,
1090 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001091 }
Amar Singhald53568e2013-09-26 11:03:45 -07001092
1093 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1094 offLoadRequest.enableOrDisable);
1095
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 //converting u32 to IPV4 address
1097 for(i = 0 ; i < 4; i++)
1098 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301099 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1101 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301102 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 offLoadRequest.params.hostIpv4Addr[0],
1104 offLoadRequest.params.hostIpv4Addr[1],
1105 offLoadRequest.params.hostIpv4Addr[2],
1106 offLoadRequest.params.hostIpv4Addr[3]);
1107
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301108 if (eHAL_STATUS_SUCCESS !=
1109 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1110 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001111 {
1112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001113 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 return VOS_STATUS_E_FAILURE;
1115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 }
1117 else
1118 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1120 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001121 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301122
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301123 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001124 }
1125 else
1126 {
1127 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1128 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1129 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1130
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301131 if (eHAL_STATUS_SUCCESS !=
1132 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1133 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 {
1135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001136 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 return VOS_STATUS_E_FAILURE;
1138 }
1139 return VOS_STATUS_SUCCESS;
1140 }
1141}
1142
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301143/*
1144 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301145 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301146*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301147void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301148 tANI_U8 *pMcBcFilter)
1149{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301150 if (NULL == pHddCtx)
1151 {
1152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1153 return;
1154 }
1155
1156 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1157 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301158 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301159 /* ARP offload is enabled, do not block bcast packets at RXP
1160 * Will be using Bitmasking to reset the filter. As we have
1161 * disable Broadcast filtering, Anding with the negation
1162 * of Broadcast BIT
1163 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301164 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301165 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301166
1167#ifdef WLAN_NS_OFFLOAD
1168 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301169 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301170 /* NS offload is enabled, do not block mcast packets at RXP
1171 * Will be using Bitmasking to reset the filter. As we have
1172 * disable Multicast filtering, Anding with the negation
1173 * of Multicast BIT
1174 */
1175 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301176 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301177#endif
1178
Amar Singhald08ce752014-03-21 16:28:27 -07001179 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1180 {
1181 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1182 }
1183
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301184 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301185}
1186
Jeff Johnson295189b2012-06-20 16:38:30 -07001187void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1188{
1189 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1191 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1192 if(NULL == wlanRxpFilterParam)
1193 {
1194 hddLog(VOS_TRACE_LEVEL_FATAL,
1195 "%s: vos_mem_alloc failed ", __func__);
1196 return;
1197 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 hddLog(VOS_TRACE_LEVEL_INFO,
1199 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301200 if (TRUE == setfilter)
1201 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301202 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301203 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301204 }
1205 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301206 {
1207 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301208 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301209 pHddCtx->configuredMcastBcastFilter;
1210 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301211
Jeff Johnson295189b2012-06-20 16:38:30 -07001212 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001213 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301214
1215 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1216 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1217
1218 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1219 "lower mac with status %d"
1220 "configuredMcstBcstFilterSetting = %d"
1221 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1222 "Failed" : "Success", halStatus,
1223 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1224 wlanRxpFilterParam->setMcstBcstFilter);
1225
Chilam Ngc4244af2013-04-01 15:37:32 -07001226 if (eHAL_STATUS_SUCCESS != halStatus)
1227 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001228}
1229
Jeff Johnson295189b2012-06-20 16:38:30 -07001230static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1231 hdd_adapter_t *pAdapter)
1232{
1233 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1234 tpSirWlanSuspendParam wlanSuspendParam =
1235 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1236
Amar Singhald53568e2013-09-26 11:03:45 -07001237 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1238 pHddCtx->sus_res_mcastbcast_filter =
1239 pHddCtx->configuredMcastBcastFilter;
1240 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1241 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1242 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1243 pHddCtx->configuredMcastBcastFilter);
1244
1245 }
1246
Amar Singhal49fdfd52013-08-13 13:25:12 -07001247
Jeff Johnson295189b2012-06-20 16:38:30 -07001248 if(NULL == wlanSuspendParam)
1249 {
1250 hddLog(VOS_TRACE_LEVEL_FATAL,
1251 "%s: vos_mem_alloc failed ", __func__);
1252 return;
1253 }
1254
Amar Singhald53568e2013-09-26 11:03:45 -07001255 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001256 "%s: send wlan suspend indication", __func__);
1257
1258 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1259 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301260 //Configure supported OffLoads
1261 hdd_conf_hostoffload(pAdapter, TRUE);
1262 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301263 hddLog(VOS_TRACE_LEVEL_INFO,
1264 FL("saving configuredMcastBcastFilterSetting = %d"),
1265 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001266#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301267 /* During suspend, configure MC Addr list filter to the firmware
1268 * function takes care of checking necessary conditions before
1269 * configuring.
1270 */
1271 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001272#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001273
1274 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1275 {
1276
1277 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1278 pHddCtx->configuredMcastBcastFilter &=
1279 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1280 }
1281
1282 wlanSuspendParam->configuredMcstBcstFilterSetting =
1283 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 }
1285
1286 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1287 if(eHAL_STATUS_SUCCESS == halStatus)
1288 {
1289 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001290 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301291 hddLog(VOS_TRACE_LEVEL_ERROR,
1292 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001293 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 }
1295}
1296
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301297static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001298{
Chilam Ngc4244af2013-04-01 15:37:32 -07001299 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001300 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001301 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001302
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301303 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001304 "%s: send wlan resume indication", __func__);
1305
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301306 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1307
1308 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001309 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301310 hddLog(VOS_TRACE_LEVEL_FATAL,
1311 "%s: memory allocation failed for wlanResumeParam ", __func__);
1312 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001313 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001314
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301315 //Disable supported OffLoads
1316 hdd_conf_hostoffload(pAdapter, FALSE);
1317
1318 wlanResumeParam->configuredMcstBcstFilterSetting =
1319 pHddCtx->configuredMcastBcastFilter;
1320 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1321 if (eHAL_STATUS_SUCCESS != halStatus)
1322 {
c_hpothuffdb5272013-10-02 16:42:35 +05301323 hddLog(VOS_TRACE_LEVEL_ERROR,
1324 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301325 vos_mem_free(wlanResumeParam);
1326 }
1327
1328 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1329
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001330 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1331 pHddCtx->configuredMcastBcastFilter =
1332 pHddCtx->sus_res_mcastbcast_filter;
1333 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1334 }
Amar Singhald53568e2013-09-26 11:03:45 -07001335
1336 hddLog(VOS_TRACE_LEVEL_INFO,
1337 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1338 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1339 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001340
Chilam Ngc4244af2013-04-01 15:37:32 -07001341
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301342#ifdef WLAN_FEATURE_PACKET_FILTERING
1343 /* Filer was applied during suspend inditication
1344 * clear it when we resume.
1345 */
1346 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001347#endif
1348}
Jeff Johnson295189b2012-06-20 16:38:30 -07001349
Jeff Johnson295189b2012-06-20 16:38:30 -07001350//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001351void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001352{
1353 hdd_context_t *pHddCtx = NULL;
1354 v_CONTEXT_t pVosContext = NULL;
1355
Jeff Johnson295189b2012-06-20 16:38:30 -07001356 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301357 hdd_adapter_t *pAdapter = NULL;
1358 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301359 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001360
Jeff Johnson295189b2012-06-20 16:38:30 -07001361 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1362
1363 //Get the global VOSS context.
1364 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1365 if(!pVosContext) {
1366 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1367 return;
1368 }
1369
1370 //Get the HDD context.
1371 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1372
1373 if(!pHddCtx) {
1374 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1375 return;
1376 }
1377
1378 if (pHddCtx->isLogpInProgress) {
1379 hddLog(VOS_TRACE_LEVEL_ERROR,
1380 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1381 return;
1382 }
1383
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301384 if (pHddCtx->hdd_wlan_suspended)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
1387 "%s: Ignore suspend wlan, Already suspended!", __func__);
1388 return;
1389 }
1390
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301391 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301392 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001393 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1394 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1395 {
1396 pAdapter = pAdapterNode->pAdapter;
1397 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001398 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001399 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1400
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001401 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1403 pAdapterNode = pNext;
1404 continue;
1405 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301406 /* Avoid multiple enter/exit BMPS in this while loop using
1407 * hdd_enter_bmps flag
1408 */
1409 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1410 {
1411 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001412
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301413 /* If device was already in BMPS, and dynamic DTIM is set,
1414 * exit(set the device to full power) and enter BMPS again
1415 * to reflect new DTIM value */
1416 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1417
1418 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1419
1420 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001422#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1423 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1424 {
1425 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301426 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001427 netif_tx_disable(pAdapter->dev);
1428 netif_carrier_off(pAdapter->dev);
1429 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301430 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1432 {
1433 //Execute deep sleep procedure
1434 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1435 }
1436#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301437
1438 /*Suspend notification sent down to driver*/
1439 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1440
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301441 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1442 pAdapterNode = pNext;
1443 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301444
Jeff Johnson295189b2012-06-20 16:38:30 -07001445#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1446 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1447 {
1448 hdd_enter_standby(pHddCtx);
1449 }
1450#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001451
1452 return;
1453}
1454
1455static void hdd_PowerStateChangedCB
1456(
1457 v_PVOID_t callbackContext,
1458 tPmcState newState
1459)
1460{
1461 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301462
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 /* if the driver was not in BMPS during early suspend,
1464 * the dynamic DTIM is now updated at Riva */
1465 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1466 && pHddCtx->cfg_ini->enableDynamicDTIM
1467 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1468 {
1469 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1470 }
1471 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301472 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1473 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001474 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301475 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1476 {
Amar Singhald53568e2013-09-26 11:03:45 -07001477 pHddCtx->sus_res_mcastbcast_filter =
1478 pHddCtx->configuredMcastBcastFilter;
1479 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1480
1481 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1482 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1483 pHddCtx->configuredMcastBcastFilter);
1484 hddLog(VOS_TRACE_LEVEL_INFO,
1485 "offload: calling hdd_conf_mcastbcast_filter");
1486
1487 }
1488
Jeff Johnson295189b2012-06-20 16:38:30 -07001489 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001490 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301492 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001493 else
Mihir Shete793209f2014-01-06 11:01:12 +05301494 {
1495 /* Android framework can send resume request when the WCN chip is
1496 * in IMPS mode. When the chip exits IMPS mode the firmware will
1497 * restore all the registers to the state they were before the chip
1498 * entered IMPS and so our hardware filter settings confgured by the
1499 * resume request will be lost. So reconfigure the filters on detecting
1500 * a change in the power state of the WCN chip.
1501 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301502 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301503 if (IMPS != newState)
1504 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301505 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301506 if (FALSE == pHddCtx->hdd_wlan_suspended)
1507 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301508 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301509 hddLog(VOS_TRACE_LEVEL_INFO,
1510 "Not in IMPS/BMPS and suspended state");
1511 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1512 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301513 else
1514 {
1515 spin_unlock(&pHddCtx->filter_lock);
1516 }
Mihir Shete793209f2014-01-06 11:01:12 +05301517 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301518 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001519}
1520
Jeff Johnson295189b2012-06-20 16:38:30 -07001521void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1522{
1523 v_CONTEXT_t pVosContext;
1524 tHalHandle smeContext;
1525
1526 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1527 if (NULL == pVosContext)
1528 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001529 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001530 return;
1531 }
1532 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1533 if (NULL == smeContext)
1534 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001535 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001536 return;
1537 }
1538
1539 spin_lock_init(&pHddCtx->filter_lock);
1540 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1541 pHddCtx->cfg_ini->nEnableSuspend)
1542 {
1543 pmcRegisterDeviceStateUpdateInd(smeContext,
1544 hdd_PowerStateChangedCB, pHddCtx);
1545 }
1546}
1547
1548void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1549{
1550 v_CONTEXT_t pVosContext;
1551 tHalHandle smeContext;
1552
1553 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1554 if (NULL == pVosContext)
1555 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001556 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001557 return;
1558 }
1559 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1560 if (NULL == smeContext)
1561 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001562 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001563 return;
1564 }
1565
1566 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1567 pHddCtx->cfg_ini->nEnableSuspend)
1568 {
1569 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1570 }
1571}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301572
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301573#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301574void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301575{
1576 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301577 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301578 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1579
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301580 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301581 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301582 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1583 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1584 {
1585 vos_mem_copy(&hddGtkOffloadReqParams,
1586 &pHddStaCtx->gtkOffloadReqParams,
1587 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301588
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301589 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1590 &hddGtkOffloadReqParams, pAdapter->sessionId);
1591 if (eHAL_STATUS_SUCCESS != ret)
1592 {
1593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1594 "%s: sme_SetGTKOffload failed, returned %d",
1595 __func__, ret);
1596 return;
1597 }
1598
1599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1600 "%s: sme_SetGTKOffload successfull", __func__);
1601 }
1602
1603 }
1604 else
1605 {
1606 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1607 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1608 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1609 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1610 {
1611
1612 /* Host driver has previously offloaded GTK rekey */
1613 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301614 wlan_hdd_cfg80211_update_replayCounterCallback,
1615 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301616 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301617
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301618 {
1619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1620 "%s: sme_GetGTKOffload failed, returned %d",
1621 __func__, ret);
1622 return;
1623 }
1624 else
1625 {
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1627 "%s: sme_GetGTKOffload successful",
1628 __func__);
1629
1630 /* Sending GTK offload dissable */
1631 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1632 sizeof (tSirGtkOffloadParams));
1633 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1634 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301635 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301636 if (eHAL_STATUS_SUCCESS != ret)
1637 {
1638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1639 "%s: failed to dissable GTK offload, returned %d",
1640 __func__, ret);
1641 return;
1642 }
1643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1644 "%s: successfully dissabled GTK offload request to HAL",
1645 __func__);
1646 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301647 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301648 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301649 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301650}
1651#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001652
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001653void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001654{
1655 hdd_context_t *pHddCtx = NULL;
1656 hdd_adapter_t *pAdapter = NULL;
1657 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1658 VOS_STATUS status;
1659 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001660
Jeff Johnson295189b2012-06-20 16:38:30 -07001661 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1662
1663 //Get the global VOSS context.
1664 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1665 if(!pVosContext) {
1666 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1667 return;
1668 }
1669
1670 //Get the HDD context.
1671 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1672
1673 if(!pHddCtx) {
1674 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1675 return;
1676 }
1677
Agarwal Ashish971c2882013-10-30 20:11:12 +05301678 if (pHddCtx->isLogpInProgress)
1679 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 hddLog(VOS_TRACE_LEVEL_INFO,
1681 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1682 return;
1683 }
1684
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301685 if (!pHddCtx->hdd_wlan_suspended)
1686 {
1687 hddLog(VOS_TRACE_LEVEL_ERROR,
1688 "%s: Ignore resume wlan, Already resumed!", __func__);
1689 return;
1690 }
1691
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 pHddCtx->hdd_wlan_suspended = FALSE;
1693 /*loop through all adapters. Concurrency */
1694 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1695
1696 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1697 {
1698 pAdapter = pAdapterNode->pAdapter;
1699 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001700 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001701 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001702 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001703 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1704 pAdapterNode = pNext;
1705 continue;
1706 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301707
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301708
Jeff Johnson295189b2012-06-20 16:38:30 -07001709#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1710 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1711 {
1712 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1713 hdd_exit_deep_sleep(pAdapter);
1714 }
1715#endif
1716
1717 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1718 {
1719 /*Switch back to DTIM 1*/
1720 tSirSetPowerParamsReq powerRequest = { 0 };
1721
1722 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1723 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001724 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001725
1726 /*Disabled ModulatedDTIM if enabled on suspend*/
1727 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1728 powerRequest.uDTIMPeriod = 0;
1729
1730 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1731 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1732 NULL, eANI_BOOLEAN_FALSE);
1733 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1734 NULL, eANI_BOOLEAN_FALSE);
1735
1736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001737 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001738 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001739
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301740 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1741 {
1742 /* put the device into full power */
1743 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001744
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301745 /* put the device back into BMPS */
1746 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001747
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301748 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1749 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001750 }
1751
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301752 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1754 pAdapterNode = pNext;
1755 }
1756
1757#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1758 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1759 {
1760 hdd_exit_standby(pHddCtx);
1761 }
1762#endif
1763
Jeff Johnson295189b2012-06-20 16:38:30 -07001764 return;
1765}
1766
Jeff Johnson295189b2012-06-20 16:38:30 -07001767VOS_STATUS hdd_wlan_reset_initialization(void)
1768{
Jeff Johnson295189b2012-06-20 16:38:30 -07001769 v_CONTEXT_t pVosContext = NULL;
1770
1771 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1772
1773 //Get the global VOSS context.
1774 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1775 if(!pVosContext)
1776 {
1777 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1778 return VOS_STATUS_E_FAILURE;
1779 }
1780
1781 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1782
1783 // Prevent the phone from going to sleep
1784 hdd_prevent_suspend();
1785
Jeff Johnson295189b2012-06-20 16:38:30 -07001786 return VOS_STATUS_SUCCESS;
1787}
1788
1789
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001790/*
1791 * Based on the ioctl command recieved by HDD, put WLAN driver
1792 * into the quiet mode. This is the same as the early suspend
1793 * notification that driver used to listen
1794 */
1795void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001796{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301797 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001798 if (suspend)
1799 hdd_suspend_wlan();
1800 else
1801 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301802 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001803}
1804
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001805static void hdd_ssr_timer_init(void)
1806{
1807 init_timer(&ssr_timer);
1808}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001809
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001810static void hdd_ssr_timer_del(void)
1811{
1812 del_timer(&ssr_timer);
1813 ssr_timer_started = false;
1814}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001815
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001816static void hdd_ssr_timer_cb(unsigned long data)
1817{
1818 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001819
1820#ifdef WCN_PRONTO
1821 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1822 wcnss_pronto_log_debug_regs();
1823#endif
1824
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001825 VOS_BUG(0);
1826}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001827
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001828static void hdd_ssr_timer_start(int msec)
1829{
1830 if(ssr_timer_started)
1831 {
1832 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1833 ,__func__);
1834 }
1835 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1836 ssr_timer.function = hdd_ssr_timer_cb;
1837 add_timer(&ssr_timer);
1838 ssr_timer_started = true;
1839}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001840
Jeff Johnson295189b2012-06-20 16:38:30 -07001841/* the HDD interface to WLAN driver shutdown,
1842 * the primary shutdown function in SSR
1843 */
1844VOS_STATUS hdd_wlan_shutdown(void)
1845{
1846 VOS_STATUS vosStatus;
1847 v_CONTEXT_t pVosContext = NULL;
1848 hdd_context_t *pHddCtx = NULL;
1849 pVosSchedContext vosSchedContext = NULL;
1850
1851 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1852
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001853 /* if re-init never happens, then do SSR1 */
1854 hdd_ssr_timer_init();
1855 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1856
Jeff Johnson295189b2012-06-20 16:38:30 -07001857 /* Get the global VOSS context. */
1858 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1859 if(!pVosContext) {
1860 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1861 return VOS_STATUS_E_FAILURE;
1862 }
1863 /* Get the HDD context. */
1864 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1865 if(!pHddCtx) {
1866 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1867 return VOS_STATUS_E_FAILURE;
1868 }
c_hpothud662a352013-12-26 15:09:12 +05301869
1870 //Stop the traffic monitor timer
1871 if ( VOS_TIMER_STATE_RUNNING ==
1872 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1873 {
1874 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1875 }
1876
Jeff Johnson295189b2012-06-20 16:38:30 -07001877 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 /* DeRegister with platform driver as client for Suspend/Resume */
1879 vosStatus = hddDeregisterPmOps(pHddCtx);
1880 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1881 {
1882 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1883 }
1884
1885 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1886 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1887 {
1888 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1889 }
1890
1891 /* Disable IMPS/BMPS as we do not want the device to enter any power
1892 * save mode on its own during reset sequence
1893 */
1894 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1895 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1896 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1897
1898 vosSchedContext = get_vos_sched_ctxt();
1899
1900 /* Wakeup all driver threads */
1901 if(TRUE == pHddCtx->isMcThreadSuspended){
1902 complete(&vosSchedContext->ResumeMcEvent);
1903 pHddCtx->isMcThreadSuspended= FALSE;
1904 }
1905 if(TRUE == pHddCtx->isTxThreadSuspended){
1906 complete(&vosSchedContext->ResumeTxEvent);
1907 pHddCtx->isTxThreadSuspended= FALSE;
1908 }
1909 if(TRUE == pHddCtx->isRxThreadSuspended){
1910 complete(&vosSchedContext->ResumeRxEvent);
1911 pHddCtx->isRxThreadSuspended= FALSE;
1912 }
1913 /* Reset the Suspend Variable */
1914 pHddCtx->isWlanSuspended = FALSE;
1915
1916 /* Stop all the threads; we do not want any messages to be a processed,
1917 * any more and the best way to ensure that is to terminate the threads
1918 * gracefully.
1919 */
1920 /* Wait for MC to exit */
1921 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1922 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1923 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1924 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301925 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001926
1927 /* Wait for TX to exit */
1928 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1929 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1930 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1931 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301932 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001933
1934 /* Wait for RX to exit */
1935 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1936 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1937 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1938 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301939
Mihir Sheteb5425f72013-12-19 09:06:13 +05301940 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001941
1942#ifdef WLAN_BTAMP_FEATURE
1943 vosStatus = WLANBAP_Stop(pVosContext);
1944 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1945 {
1946 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1947 "%s: Failed to stop BAP",__func__);
1948 }
1949#endif //WLAN_BTAMP_FEATURE
1950 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301951 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1952 {
1953 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1954 "%s: Failed to stop wda %d", __func__, vosStatus);
1955 VOS_ASSERT(0);
1956 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001957
1958 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1959 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1960 * on threads being running to process the SYS Stop
1961 */
Kiet Lama72a2322013-11-15 11:18:11 +05301962 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301963 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1964 {
1965 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1966 "%s: Failed to stop sme %d", __func__, vosStatus);
1967 VOS_ASSERT(0);
1968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001969
1970 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1971 /* Stop MAC (PE and HAL) */
1972 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301973 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1974 {
1975 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1976 "%s: Failed to stop mac %d", __func__, vosStatus);
1977 VOS_ASSERT(0);
1978 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001979
1980 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1981 /* Stop TL */
1982 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301983 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1984 {
1985 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1986 "%s: Failed to stop TL %d", __func__, vosStatus);
1987 VOS_ASSERT(0);
1988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001989
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1992 /* Clean up message queues of TX and MC thread */
1993 vos_sched_flush_mc_mqs(vosSchedContext);
1994 vos_sched_flush_tx_mqs(vosSchedContext);
1995 vos_sched_flush_rx_mqs(vosSchedContext);
1996
1997 /* Deinit all the TX and MC queues */
1998 vos_sched_deinit_mqs(vosSchedContext);
1999 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2000
2001 /* shutdown VOSS */
2002 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302003
2004 /*mac context has already been released in mac_close call
2005 so setting it to NULL in hdd context*/
2006 pHddCtx->hHal = (tHalHandle)NULL;
2007
Jeff Johnson295189b2012-06-20 16:38:30 -07002008 if (free_riva_power_on_lock("wlan"))
2009 {
2010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2011 __func__);
2012 }
2013 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2014 ,__func__);
2015 return VOS_STATUS_SUCCESS;
2016}
2017
2018
2019
2020/* the HDD interface to WLAN driver re-init.
2021 * This is called to initialize/start WLAN driver after a shutdown.
2022 */
2023VOS_STATUS hdd_wlan_re_init(void)
2024{
2025 VOS_STATUS vosStatus;
2026 v_CONTEXT_t pVosContext = NULL;
2027 hdd_context_t *pHddCtx = NULL;
2028 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002029#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2030 int max_retries = 0;
2031#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002032#ifdef WLAN_BTAMP_FEATURE
2033 hdd_config_t *pConfig = NULL;
2034 WLANBAP_ConfigType btAmpConfig;
2035#endif
2036
Katya Nigam82a93062014-06-04 15:15:36 +05302037 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002038 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002039 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002040
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002041#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2042 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002043 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002044 msleep(1000);
2045 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002046 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002047 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2048 goto err_re_init;
2049 }
2050#endif
2051
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002052 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2053
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002054 /* The driver should always be initialized in STA mode after SSR */
2055 hdd_set_conparam(0);
2056
Katya Nigam82a93062014-06-04 15:15:36 +05302057 dev = wcnss_wlan_get_device();
2058 if (NULL == dev)
2059 {
2060 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2061 goto err_re_init;
2062 }
2063
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302065 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2067 {
2068 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2069 goto err_re_init;
2070 }
2071
2072 /* Get the HDD context. */
2073 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2074 if(!pHddCtx)
2075 {
2076 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2077 goto err_vosclose;
2078 }
2079
2080 /* Save the hal context in Adapter */
2081 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2082 if ( NULL == pHddCtx->hHal )
2083 {
2084 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2085 goto err_vosclose;
2086 }
2087
2088 /* Set the SME configuration parameters. */
2089 vosStatus = hdd_set_sme_config(pHddCtx);
2090 if ( VOS_STATUS_SUCCESS != vosStatus )
2091 {
2092 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2093 goto err_vosclose;
2094 }
2095
Jeff Johnson295189b2012-06-20 16:38:30 -07002096 vosStatus = vos_preStart( pHddCtx->pvosContext );
2097 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2098 {
2099 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2100 goto err_vosclose;
2101 }
2102
2103 /* In the integrated architecture we update the configuration from
2104 the INI file and from NV before vOSS has been started so that
2105 the final contents are available to send down to the cCPU */
2106 /* Apply the cfg.ini to cfg.dat */
2107 if (FALSE == hdd_update_config_dat(pHddCtx))
2108 {
2109 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2110 goto err_vosclose;
2111 }
2112
2113 /* Set the MAC Address, currently this is used by HAL to add self sta.
2114 * Remove this once self sta is added as part of session open. */
2115 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2116 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2117 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2118 if (!HAL_STATUS_SUCCESS(halStatus))
2119 {
2120 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2121 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2122 goto err_vosclose;
2123 }
2124
2125 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2126 Note: Firmware image will be read and downloaded inside vos_start API */
2127 vosStatus = vos_start( pVosContext );
2128 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2129 {
2130 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2131 goto err_vosclose;
2132 }
2133
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002134 /* Exchange capability info between Host and FW and also get versioning info from FW */
2135 hdd_exchange_version_and_caps(pHddCtx);
2136
Jeff Johnson295189b2012-06-20 16:38:30 -07002137 vosStatus = hdd_post_voss_start_config( pHddCtx );
2138 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2139 {
2140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2141 __func__);
2142 goto err_vosstop;
2143 }
2144
Mihir Shete04206452014-11-20 17:50:58 +05302145#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302146 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2147 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2148 {
2149 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2150 __func__);
2151 goto err_vosstop;
2152 }
Mihir Shete04206452014-11-20 17:50:58 +05302153#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302154
Jeff Johnson295189b2012-06-20 16:38:30 -07002155#ifdef WLAN_BTAMP_FEATURE
2156 vosStatus = WLANBAP_Open(pVosContext);
2157 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2158 {
2159 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2160 "%s: Failed to open BAP",__func__);
2161 goto err_vosstop;
2162 }
2163 vosStatus = BSL_Init(pVosContext);
2164 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2165 {
2166 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2167 "%s: Failed to Init BSL",__func__);
2168 goto err_bap_close;
2169 }
2170 vosStatus = WLANBAP_Start(pVosContext);
2171 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2172 {
2173 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2174 "%s: Failed to start TL",__func__);
2175 goto err_bap_close;
2176 }
2177 pConfig = pHddCtx->cfg_ini;
2178 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2179 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2180#endif //WLAN_BTAMP_FEATURE
2181
2182 /* Restart all adapters */
2183 hdd_start_all_adapters(pHddCtx);
2184 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002185 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002186 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302187 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002188 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302189 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 /* Register with platform driver as client for Suspend/Resume */
2191 vosStatus = hddRegisterPmOps(pHddCtx);
2192 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2193 {
2194 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2195 goto err_bap_stop;
2196 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002197 /* Allow the phone to go to sleep */
2198 hdd_allow_suspend();
2199 /* register for riva power on lock */
2200 if (req_riva_power_on_lock("wlan"))
2201 {
2202 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2203 __func__);
2204 goto err_unregister_pmops;
2205 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002206 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302207#ifdef WLAN_FEATURE_EXTSCAN
2208 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2209 wlan_hdd_cfg80211_extscan_callback,
2210 pHddCtx);
2211#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 goto success;
2213
2214err_unregister_pmops:
2215 hddDeregisterPmOps(pHddCtx);
2216
2217err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002218#ifdef CONFIG_HAS_EARLYSUSPEND
2219 hdd_unregister_mcast_bcast_filter(pHddCtx);
2220#endif
2221 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002222#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002223 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002224#endif
2225
2226#ifdef WLAN_BTAMP_FEATURE
2227err_bap_close:
2228 WLANBAP_Close(pVosContext);
2229#endif
2230
2231err_vosstop:
2232 vos_stop(pVosContext);
2233
2234err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302235 if(!isSsrPanicOnFailure())
2236 {
2237 /* If we hit this, it means wlan driver is in bad state and needs
2238 * driver unload and load.
2239 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302240 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2241 return VOS_STATUS_E_FAILURE;
2242 }
2243
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 vos_close(pVosContext);
2245 vos_sched_close(pVosContext);
2246 if (pHddCtx)
2247 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 /* Unregister the Net Device Notifier */
2249 unregister_netdevice_notifier(&hdd_netdev_notifier);
2250 /* Clean up HDD Nlink Service */
2251 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002252#ifdef WLAN_KD_READY_NOTIFIER
2253 nl_srv_exit(pHddCtx->ptt_pid);
2254#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002256#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002257 /* Free up dynamically allocated members inside HDD Adapter */
2258 kfree(pHddCtx->cfg_ini);
2259 pHddCtx->cfg_ini= NULL;
2260
Jeff Johnson295189b2012-06-20 16:38:30 -07002261 wiphy_unregister(pHddCtx->wiphy);
2262 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 }
2264 vos_preClose(&pVosContext);
2265
2266#ifdef MEMORY_DEBUG
2267 vos_mem_exit();
2268#endif
2269
2270err_re_init:
2271 /* Allow the phone to go to sleep */
2272 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002273 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002274 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002275 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002276
2277success:
2278 /* Trigger replay of BTC events */
2279 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2280 return VOS_STATUS_SUCCESS;
2281}