blob: 4089777d570d6468e57a5be4324a4cc89562e4bc [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharmabb94ece2014-04-04 21:22:15 +05302 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=============================================================================
29* wlan_hdd_early_suspend.c
30*
31* \brief power management functions
32*
33* Description
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 Erannaf97ef5c2014-12-26 17:47:19 +0530511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Atul Mittal37385d72014-03-27 18:15:03 +0530512 hdd_context_t *pHddCtx;
513 int status;
514
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530515 if (pAdapter && pAdapter->dev == ndev &&
516 (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
517 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
Atul Mittal37385d72014-03-27 18:15:03 +0530518 {
519 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
520 status = wlan_hdd_validate_context(pHddCtx);
521 if (0 != status)
522 {
523 hddLog(LOGE, FL("HDD context is invalid"));
524 return NOTIFY_DONE;
525 }
526
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530527 if (pHddCtx->cfg_ini->nEnableSuspend ==
528 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
529 {
530 schedule_work(&pAdapter->ipv6NotifierWorkQueue);
531 }
532 else
533 {
534 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
535 pHddCtx->cfg_ini->nEnableSuspend);
536 }
Atul Mittal37385d72014-03-27 18:15:03 +0530537 }
538
539 return NOTIFY_DONE;
540}
541
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530542/*
543 * Function: hdd_conf_hostoffload
544 * Central function to configure the supported offloads,
545 * either enable or disable them.
546 */
547void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
548{
549 hdd_context_t *pHddCtx = NULL;
550 v_CONTEXT_t *pVosContext = NULL;
551 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
552
553 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
554 fenable);
555
556 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
557
558 if (NULL == pVosContext)
559 {
560 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
561 return;
562 }
563
564 //Get the HDD context.
565 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
566
567 if (NULL == pHddCtx)
568 {
569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
570 return;
571 }
572
573 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
574 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
575 {
576 if (fenable)
577 {
578 if (eConnectionState_Associated ==
579 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
580 {
581 if ((pHddCtx->cfg_ini->fhostArpOffload))
582 {
583 /*
584 * Configure the ARP Offload.
585 * Even if it fails we have to reconfigure the MC/BC
586 * filter flag as we want RIVA not to drop BroadCast
587 * Packets
588 */
589 hddLog(VOS_TRACE_LEVEL_INFO,
590 FL("Calling ARP Offload with flag: %d"), fenable);
591 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
592 pHddCtx->configuredMcastBcastFilter &=
593 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
594
595 if (!VOS_IS_STATUS_SUCCESS(vstatus))
596 {
597 hddLog(VOS_TRACE_LEVEL_ERROR,
598 "Failed to enable ARPOFfloadFeature %d",
599 vstatus);
600 }
601 }
602 //Configure GTK_OFFLOAD
603#ifdef WLAN_FEATURE_GTK_OFFLOAD
604 hdd_conf_gtk_offload(pAdapter, fenable);
605#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530606
607#ifdef WLAN_NS_OFFLOAD
608 if (pHddCtx->cfg_ini->fhostNSOffload)
609 {
610 /*
611 * Configure the NS Offload.
612 * Even if it fails we have to reconfigure the MC/BC filter flag
613 * as we want RIVA not to drop Multicast Packets
614 */
615
616 hddLog(VOS_TRACE_LEVEL_INFO,
617 FL("Calling NS Offload with flag: %d"), fenable);
618 hdd_conf_ns_offload(pAdapter, fenable);
619 pHddCtx->configuredMcastBcastFilter &=
620 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
621 }
622#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530623
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530624 }
625 }
626 else
627 {
628 //Disable ARPOFFLOAD
629 if (pHddCtx->cfg_ini->fhostArpOffload)
630 {
631 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
632 if (!VOS_IS_STATUS_SUCCESS(vstatus))
633 {
634 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530635 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530636 }
637 }
638 //Disable GTK_OFFLOAD
639#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530640 hdd_conf_gtk_offload(pAdapter, fenable);
641#endif
642
643#ifdef WLAN_NS_OFFLOAD
644 //Disable NSOFFLOAD
645 if (pHddCtx->cfg_ini->fhostNSOffload)
646 {
647 hdd_conf_ns_offload(pAdapter, fenable);
648 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530649#endif
650 }
651 }
652 return;
653}
654
Atul Mittal37385d72014-03-27 18:15:03 +0530655
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530656#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530657/**----------------------------------------------------------------------------
658
659 \brief hdd_conf_ns_offload() - Configure NS offload
660
661 Called during SUSPEND to configure the NS offload (MC BC filter) which
662 reduces power consumption.
663
664 \param - pAdapter - Adapter context for which NS offload is to be configured
665 \param - fenable - 0 - disable.
666 1 - enable. (with IPv6 notifier registration)
667 2 - enable. (without IPv6 notifier registration)
668
669 \return - void
670
671 ---------------------------------------------------------------------------*/
672void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530673{
674 struct inet6_dev *in6_dev;
675 struct inet6_ifaddr *ifp;
676 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530677 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530678 tANI_U8 **selfIPv6Addr = NULL;
679 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530680 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530681 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530682 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530683
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530684 int i = 0, slot = 0;
685 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530686 eHalStatus returnStatus;
687
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530688 ENTER();
689 hddLog(LOG1, FL(" fenable = %d"), fenable);
690
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530691 if (NULL == pAdapter)
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
694 return;
695 }
696
697 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530698 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
699
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530700 ret = wlan_hdd_validate_context(pHddCtx);
701
702 if (0 != ret)
703 {
704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
705 FL("HDD context is not valid"));
706 return;
707 }
708
709 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
710 {
711 slot_index = NS_EXTENDED_SLOT_INDEX;
712 }
713
714 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
715
716 selfIPv6AddrValid =
717 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
718
719 if (NULL == selfIPv6AddrValid)
720 {
721 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
722 " selfIPv6AddrValid"));
723 goto end;
724 }
725
726 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
727
728 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
729
730 if (NULL == selfIPv6Addr)
731 {
732 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
733 " selfIPv6Addr"));
734 goto end;
735 }
736
737 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
738
739 for (slot = 0; slot < slot_index; slot++)
740 {
741 selfIPv6Addr[slot] =
742 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
743 if (NULL == selfIPv6Addr[slot])
744 {
745 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
746 "for selfIPv6Addr"));
747 goto end;
748 }
749 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
750 }
751
752 i = 0;
753
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530754 if (fenable)
755 {
756 in6_dev = __in6_dev_get(pAdapter->dev);
757 if (NULL != in6_dev)
758 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530759 list_for_each(p, &in6_dev->addr_list)
760 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530761 if (i >= slot_index)
762 {
763 hddLog (VOS_TRACE_LEVEL_ERROR,
764 FL("IPv6 address list is greater than IPv6"
765 "address supported by firmware"));
766 hddLog (VOS_TRACE_LEVEL_ERROR,
767 FL("FW supported IPv6 address = %d"), slot_index);
768 break;
769 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530770 ifp = list_entry(p, struct inet6_ifaddr, if_list);
771 switch(ipv6_addr_src_scope(&ifp->addr))
772 {
773 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530774 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530775 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530776 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530777 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530778 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
779 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530780 break;
781 case IPV6_ADDR_SCOPE_GLOBAL:
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_GLOBAL Address : %pI6"),
787 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530788 break;
789 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530790 hddLog(VOS_TRACE_LEVEL_ERROR,
791 FL("The Scope %d is not supported"),
792 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530793 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530794 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
795 {
796 i++;
797 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530798 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530799
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530800 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530801 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530802 {
803 if (selfIPv6AddrValid[i])
804 {
805 //Filling up the request structure
806 /* Filling the selfIPv6Addr with solicited address
807 * A Solicited-Node multicast address is created by
808 * taking the last 24 bits of a unicast or anycast
809 * address and appending them to the prefix
810 *
811 * FF02:0000:0000:0000:0000:0001:FFXX:XX
812 *
813 * here XX is the unicast/anycast bits
814 */
815 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
816 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
817 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
818 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530819 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
820 selfIPv6Addr[i][13];
821 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
822 selfIPv6Addr[i][14];
823 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
824 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530825 offLoadRequest.nsOffloadInfo.slotIdx = i;
826
827 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530828 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530829 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
830 &pAdapter->macAddressCurrent.bytes,
831 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
832
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530833 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
834 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530835 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
836 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
837
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530838 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530839 FL("configuredMcastBcastFilter: %d"
840 "NSOffload Slot = %d"),
841 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530842
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530843 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700844 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
845 pHddCtx->sus_res_mcastbcast_filter) ||
846 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
847 pHddCtx->sus_res_mcastbcast_filter)) &&
848 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
849 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
850 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530851 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530852 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700853 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530854 hddLog (VOS_TRACE_LEVEL_INFO,
855 FL("Set offLoadRequest with %d"),
856 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530857 }
858
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530859 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
860 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
861 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
862
863 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530864 FL("Setting NSOffload with solicitedIp: %pI6,"
865 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530866 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
867 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
868
869 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530870 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530871 pAdapter->sessionId, &offLoadRequest);
872 if(eHAL_STATUS_SUCCESS != returnStatus)
873 {
874 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530875 FL("Failed to enable HostOffload feature with"
876 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530877 }
878 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
879 }
880 }
881 }
882 else
883 {
884 hddLog(VOS_TRACE_LEVEL_ERROR,
885 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530886 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530887 }
888 }
889 else
890 {
891 //Disable NSOffload
892 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
893 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
894 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
895
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530896 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530897 {
c_hpothu86feba52014-10-28 15:51:18 +0530898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530899 offLoadRequest.nsOffloadInfo.slotIdx = i;
900 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530901 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
902 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530903 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
905 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530906 }
907 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530908 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530909end:
910 while (slot > 0 && selfIPv6Addr[--slot])
911 {
912 vos_mem_free(selfIPv6Addr[slot]);
913 }
914 if (selfIPv6Addr)
915 {
916 vos_mem_free(selfIPv6Addr);
917 }
918 if (selfIPv6AddrValid)
919 {
920 vos_mem_free(selfIPv6AddrValid);
921 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530922 return;
923}
924#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530925
926void hdd_ipv4_notifier_work_queue(struct work_struct *work)
927{
928 hdd_adapter_t* pAdapter =
929 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
930 hdd_context_t *pHddCtx;
931 int status;
932
933 hddLog(LOG1, FL("Reconfiguring ARP Offload"));
934 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
935 status = wlan_hdd_validate_context(pHddCtx);
936 if (0 != status)
937 {
938 hddLog(LOGE, FL("HDD context is invalid"));
939 return;
940 }
941
Deepthi Gowri5933f402014-01-23 17:48:24 +0530942 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
943 {
944 pHddCtx->sus_res_mcastbcast_filter =
945 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530946 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
947 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530948 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
949 }
950
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530951 if ((eConnectionState_Associated ==
952 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530953 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530954 {
955 // This invocation being part of the IPv4 registration callback,
956 // we are passing second parameter as 2 to avoid registration
957 // of IPv4 notifier again.
958 hdd_conf_arp_offload(pAdapter, 2);
959 }
960}
961
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530962int wlan_hdd_ipv4_changed(struct notifier_block *nb,
963 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530964{
965 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
966 struct in_ifaddr **ifap = NULL;
967 struct in_device *in_dev;
968
969 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530970 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530971 hdd_context_t *pHddCtx;
972 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +0530973
974 if (pAdapter && pAdapter->dev == ndev &&
975 (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
976 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530977 {
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530978 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
979 status = wlan_hdd_validate_context(pHddCtx);
980 if (0 != status)
981 {
982 hddLog(LOGE, FL("HDD context is invalid"));
983 return NOTIFY_DONE;
984 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530985
986 if ((pHddCtx->cfg_ini->nEnableSuspend !=
987 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
988 || (!pHddCtx->cfg_ini->fhostArpOffload))
989 {
990 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
991 pHddCtx->cfg_ini->nEnableSuspend,
992 pHddCtx->cfg_ini->fhostArpOffload);
993 return NOTIFY_DONE;
994 }
995
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530996 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
997 {
998 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
999 ifap = &ifa->ifa_next)
1000 {
1001 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1002 {
1003 break; /* found */
1004 }
1005 }
1006 }
1007 if(ifa && ifa->ifa_local)
1008 {
1009 schedule_work(&pAdapter->ipv4NotifierWorkQueue);
1010 }
1011 }
1012
1013 return NOTIFY_DONE;
1014}
1015
1016/**----------------------------------------------------------------------------
1017
1018 \brief hdd_conf_arp_offload() - Configure ARP offload
1019
1020 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1021 reduces power consumption.
1022
1023 \param - pAdapter -Adapter context for which ARP offload is to be configured
1024 \param - fenable - 0 - disable.
1025 1 - enable. (with IPv4 notifier registration)
1026 2 - enable. (without IPv4 notifier registration)
1027
1028 \return -
1029 VOS_STATUS_SUCCESS - on successful operation
1030 VOS_STATUS_E_FAILURE - on failure of operation
1031-----------------------------------------------------------------------------*/
1032VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001033{
1034 struct in_ifaddr **ifap = NULL;
1035 struct in_ifaddr *ifa = NULL;
1036 struct in_device *in_dev;
1037 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001039 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001040
c_hpothu86feba52014-10-28 15:51:18 +05301041 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001042
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 if(fenable)
1044 {
1045 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1046 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301047 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 ifap = &ifa->ifa_next)
1049 {
1050 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1051 {
1052 break; /* found */
1053 }
1054 }
1055 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001056 if(ifa && ifa->ifa_local)
1057 {
1058 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1059 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1060
Arif Hussain6d2a3322013-11-17 19:50:10 -08001061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001062
Amar Singhald53568e2013-09-26 11:03:45 -07001063 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1064 pHddCtx->sus_res_mcastbcast_filter) ||
1065 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1066 pHddCtx->sus_res_mcastbcast_filter)) &&
1067 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001068 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301069 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001070 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1071 hddLog(VOS_TRACE_LEVEL_INFO,
1072 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001073 }
Amar Singhald53568e2013-09-26 11:03:45 -07001074
1075 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1076 offLoadRequest.enableOrDisable);
1077
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 //converting u32 to IPV4 address
1079 for(i = 0 ; i < 4; i++)
1080 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301081 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1083 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301084 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001085 offLoadRequest.params.hostIpv4Addr[0],
1086 offLoadRequest.params.hostIpv4Addr[1],
1087 offLoadRequest.params.hostIpv4Addr[2],
1088 offLoadRequest.params.hostIpv4Addr[3]);
1089
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301090 if (eHAL_STATUS_SUCCESS !=
1091 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1092 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 {
1094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001095 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 return VOS_STATUS_E_FAILURE;
1097 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001098 }
1099 else
1100 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1102 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301104
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301105 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001106 }
1107 else
1108 {
1109 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1110 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1111 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1112
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301113 if (eHAL_STATUS_SUCCESS !=
1114 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1115 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 {
1117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001118 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 return VOS_STATUS_E_FAILURE;
1120 }
1121 return VOS_STATUS_SUCCESS;
1122 }
1123}
1124
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301125/*
1126 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301127 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301128*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301129void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301130 tANI_U8 *pMcBcFilter)
1131{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301132 if (NULL == pHddCtx)
1133 {
1134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1135 return;
1136 }
1137
1138 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1139 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301140 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301141 /* ARP offload is enabled, do not block bcast packets at RXP
1142 * Will be using Bitmasking to reset the filter. As we have
1143 * disable Broadcast filtering, Anding with the negation
1144 * of Broadcast BIT
1145 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301146 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301147 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301148
1149#ifdef WLAN_NS_OFFLOAD
1150 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301151 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301152 /* NS offload is enabled, do not block mcast packets at RXP
1153 * Will be using Bitmasking to reset the filter. As we have
1154 * disable Multicast filtering, Anding with the negation
1155 * of Multicast BIT
1156 */
1157 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301158 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301159#endif
1160
Amar Singhald08ce752014-03-21 16:28:27 -07001161 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1162 {
1163 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1164 }
1165
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301166 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301167}
1168
Jeff Johnson295189b2012-06-20 16:38:30 -07001169void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1170{
1171 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001172 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1173 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1174 if(NULL == wlanRxpFilterParam)
1175 {
1176 hddLog(VOS_TRACE_LEVEL_FATAL,
1177 "%s: vos_mem_alloc failed ", __func__);
1178 return;
1179 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001180 hddLog(VOS_TRACE_LEVEL_INFO,
1181 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301182 if (TRUE == setfilter)
1183 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301184 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301185 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301186 }
1187 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301188 {
1189 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301190 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301191 pHddCtx->configuredMcastBcastFilter;
1192 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301193
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001195 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301196
1197 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1198 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1199
1200 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1201 "lower mac with status %d"
1202 "configuredMcstBcstFilterSetting = %d"
1203 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1204 "Failed" : "Success", halStatus,
1205 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1206 wlanRxpFilterParam->setMcstBcstFilter);
1207
Chilam Ngc4244af2013-04-01 15:37:32 -07001208 if (eHAL_STATUS_SUCCESS != halStatus)
1209 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001210}
1211
Jeff Johnson295189b2012-06-20 16:38:30 -07001212static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1213 hdd_adapter_t *pAdapter)
1214{
1215 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1216 tpSirWlanSuspendParam wlanSuspendParam =
1217 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1218
Amar Singhald53568e2013-09-26 11:03:45 -07001219 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1220 pHddCtx->sus_res_mcastbcast_filter =
1221 pHddCtx->configuredMcastBcastFilter;
1222 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1223 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1224 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1225 pHddCtx->configuredMcastBcastFilter);
1226
1227 }
1228
Amar Singhal49fdfd52013-08-13 13:25:12 -07001229
Jeff Johnson295189b2012-06-20 16:38:30 -07001230 if(NULL == wlanSuspendParam)
1231 {
1232 hddLog(VOS_TRACE_LEVEL_FATAL,
1233 "%s: vos_mem_alloc failed ", __func__);
1234 return;
1235 }
1236
Amar Singhald53568e2013-09-26 11:03:45 -07001237 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001238 "%s: send wlan suspend indication", __func__);
1239
1240 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1241 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301242 //Configure supported OffLoads
1243 hdd_conf_hostoffload(pAdapter, TRUE);
1244 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301245 hddLog(VOS_TRACE_LEVEL_INFO,
1246 FL("saving configuredMcastBcastFilterSetting = %d"),
1247 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001248#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301249 /* During suspend, configure MC Addr list filter to the firmware
1250 * function takes care of checking necessary conditions before
1251 * configuring.
1252 */
1253 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001254#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001255
1256 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1257 {
1258
1259 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1260 pHddCtx->configuredMcastBcastFilter &=
1261 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1262 }
1263
1264 wlanSuspendParam->configuredMcstBcstFilterSetting =
1265 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001266 }
1267
1268 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1269 if(eHAL_STATUS_SUCCESS == halStatus)
1270 {
1271 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001272 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301273 hddLog(VOS_TRACE_LEVEL_ERROR,
1274 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001275 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 }
1277}
1278
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301279static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001280{
Chilam Ngc4244af2013-04-01 15:37:32 -07001281 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001282 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001283 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001284
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301285 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001286 "%s: send wlan resume indication", __func__);
1287
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301288 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1289
1290 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001291 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301292 hddLog(VOS_TRACE_LEVEL_FATAL,
1293 "%s: memory allocation failed for wlanResumeParam ", __func__);
1294 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001295 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001296
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301297 //Disable supported OffLoads
1298 hdd_conf_hostoffload(pAdapter, FALSE);
1299
1300 wlanResumeParam->configuredMcstBcstFilterSetting =
1301 pHddCtx->configuredMcastBcastFilter;
1302 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1303 if (eHAL_STATUS_SUCCESS != halStatus)
1304 {
c_hpothuffdb5272013-10-02 16:42:35 +05301305 hddLog(VOS_TRACE_LEVEL_ERROR,
1306 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301307 vos_mem_free(wlanResumeParam);
1308 }
1309
1310 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1311
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001312 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1313 pHddCtx->configuredMcastBcastFilter =
1314 pHddCtx->sus_res_mcastbcast_filter;
1315 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1316 }
Amar Singhald53568e2013-09-26 11:03:45 -07001317
1318 hddLog(VOS_TRACE_LEVEL_INFO,
1319 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1320 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1321 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001322
Chilam Ngc4244af2013-04-01 15:37:32 -07001323
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301324#ifdef WLAN_FEATURE_PACKET_FILTERING
1325 /* Filer was applied during suspend inditication
1326 * clear it when we resume.
1327 */
1328 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001329#endif
1330}
Jeff Johnson295189b2012-06-20 16:38:30 -07001331
Jeff Johnson295189b2012-06-20 16:38:30 -07001332//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001333void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001334{
1335 hdd_context_t *pHddCtx = NULL;
1336 v_CONTEXT_t pVosContext = NULL;
1337
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301339 hdd_adapter_t *pAdapter = NULL;
1340 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301341 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001342
Jeff Johnson295189b2012-06-20 16:38:30 -07001343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1344
1345 //Get the global VOSS context.
1346 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1347 if(!pVosContext) {
1348 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1349 return;
1350 }
1351
1352 //Get the HDD context.
1353 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1354
1355 if(!pHddCtx) {
1356 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1357 return;
1358 }
1359
1360 if (pHddCtx->isLogpInProgress) {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
1362 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1363 return;
1364 }
1365
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301366 if (pHddCtx->hdd_wlan_suspended)
1367 {
1368 hddLog(VOS_TRACE_LEVEL_ERROR,
1369 "%s: Ignore suspend wlan, Already suspended!", __func__);
1370 return;
1371 }
1372
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301373 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301374 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001375 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1376 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1377 {
1378 pAdapter = pAdapterNode->pAdapter;
1379 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001380 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001381 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1382
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001383 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1385 pAdapterNode = pNext;
1386 continue;
1387 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301388 /* Avoid multiple enter/exit BMPS in this while loop using
1389 * hdd_enter_bmps flag
1390 */
1391 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1392 {
1393 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001394
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301395 /* If device was already in BMPS, and dynamic DTIM is set,
1396 * exit(set the device to full power) and enter BMPS again
1397 * to reflect new DTIM value */
1398 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1399
1400 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1401
1402 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001404#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1405 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1406 {
1407 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301408 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 netif_tx_disable(pAdapter->dev);
1410 netif_carrier_off(pAdapter->dev);
1411 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301412 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001413 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1414 {
1415 //Execute deep sleep procedure
1416 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1417 }
1418#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301419
1420 /*Suspend notification sent down to driver*/
1421 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1422
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301423 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1424 pAdapterNode = pNext;
1425 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301426
Jeff Johnson295189b2012-06-20 16:38:30 -07001427#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1428 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1429 {
1430 hdd_enter_standby(pHddCtx);
1431 }
1432#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001433
1434 return;
1435}
1436
1437static void hdd_PowerStateChangedCB
1438(
1439 v_PVOID_t callbackContext,
1440 tPmcState newState
1441)
1442{
1443 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301444
Jeff Johnson295189b2012-06-20 16:38:30 -07001445 /* if the driver was not in BMPS during early suspend,
1446 * the dynamic DTIM is now updated at Riva */
1447 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1448 && pHddCtx->cfg_ini->enableDynamicDTIM
1449 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1450 {
1451 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1452 }
1453 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301454 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1455 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001456 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301457 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1458 {
Amar Singhald53568e2013-09-26 11:03:45 -07001459 pHddCtx->sus_res_mcastbcast_filter =
1460 pHddCtx->configuredMcastBcastFilter;
1461 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1462
1463 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1464 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1465 pHddCtx->configuredMcastBcastFilter);
1466 hddLog(VOS_TRACE_LEVEL_INFO,
1467 "offload: calling hdd_conf_mcastbcast_filter");
1468
1469 }
1470
Jeff Johnson295189b2012-06-20 16:38:30 -07001471 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001472 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301474 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001475 else
Mihir Shete793209f2014-01-06 11:01:12 +05301476 {
1477 /* Android framework can send resume request when the WCN chip is
1478 * in IMPS mode. When the chip exits IMPS mode the firmware will
1479 * restore all the registers to the state they were before the chip
1480 * entered IMPS and so our hardware filter settings confgured by the
1481 * resume request will be lost. So reconfigure the filters on detecting
1482 * a change in the power state of the WCN chip.
1483 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301484 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301485 if (IMPS != newState)
1486 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301487 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301488 if (FALSE == pHddCtx->hdd_wlan_suspended)
1489 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301490 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301491 hddLog(VOS_TRACE_LEVEL_INFO,
1492 "Not in IMPS/BMPS and suspended state");
1493 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1494 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301495 else
1496 {
1497 spin_unlock(&pHddCtx->filter_lock);
1498 }
Mihir Shete793209f2014-01-06 11:01:12 +05301499 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001501}
1502
Jeff Johnson295189b2012-06-20 16:38:30 -07001503void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1504{
1505 v_CONTEXT_t pVosContext;
1506 tHalHandle smeContext;
1507
1508 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1509 if (NULL == pVosContext)
1510 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001511 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001512 return;
1513 }
1514 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1515 if (NULL == smeContext)
1516 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001517 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001518 return;
1519 }
1520
1521 spin_lock_init(&pHddCtx->filter_lock);
1522 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1523 pHddCtx->cfg_ini->nEnableSuspend)
1524 {
1525 pmcRegisterDeviceStateUpdateInd(smeContext,
1526 hdd_PowerStateChangedCB, pHddCtx);
1527 }
1528}
1529
1530void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1531{
1532 v_CONTEXT_t pVosContext;
1533 tHalHandle smeContext;
1534
1535 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1536 if (NULL == pVosContext)
1537 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001538 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001539 return;
1540 }
1541 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1542 if (NULL == smeContext)
1543 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001544 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001545 return;
1546 }
1547
1548 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1549 pHddCtx->cfg_ini->nEnableSuspend)
1550 {
1551 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1552 }
1553}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301554
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301555#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301556void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301557{
1558 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301559 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301560 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1561
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301562 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301563 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301564 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1565 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1566 {
1567 vos_mem_copy(&hddGtkOffloadReqParams,
1568 &pHddStaCtx->gtkOffloadReqParams,
1569 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301570
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301571 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1572 &hddGtkOffloadReqParams, pAdapter->sessionId);
1573 if (eHAL_STATUS_SUCCESS != ret)
1574 {
1575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1576 "%s: sme_SetGTKOffload failed, returned %d",
1577 __func__, ret);
1578 return;
1579 }
1580
1581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1582 "%s: sme_SetGTKOffload successfull", __func__);
1583 }
1584
1585 }
1586 else
1587 {
1588 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1589 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1590 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1591 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1592 {
1593
1594 /* Host driver has previously offloaded GTK rekey */
1595 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301596 wlan_hdd_cfg80211_update_replayCounterCallback,
1597 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301598 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301599
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301600 {
1601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1602 "%s: sme_GetGTKOffload failed, returned %d",
1603 __func__, ret);
1604 return;
1605 }
1606 else
1607 {
1608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1609 "%s: sme_GetGTKOffload successful",
1610 __func__);
1611
1612 /* Sending GTK offload dissable */
1613 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1614 sizeof (tSirGtkOffloadParams));
1615 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1616 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301617 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301618 if (eHAL_STATUS_SUCCESS != ret)
1619 {
1620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1621 "%s: failed to dissable GTK offload, returned %d",
1622 __func__, ret);
1623 return;
1624 }
1625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1626 "%s: successfully dissabled GTK offload request to HAL",
1627 __func__);
1628 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301629 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301630 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301631 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301632}
1633#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001634
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001635void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001636{
1637 hdd_context_t *pHddCtx = NULL;
1638 hdd_adapter_t *pAdapter = NULL;
1639 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1640 VOS_STATUS status;
1641 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001642
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1644
1645 //Get the global VOSS context.
1646 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1647 if(!pVosContext) {
1648 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1649 return;
1650 }
1651
1652 //Get the HDD context.
1653 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1654
1655 if(!pHddCtx) {
1656 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1657 return;
1658 }
1659
Agarwal Ashish971c2882013-10-30 20:11:12 +05301660 if (pHddCtx->isLogpInProgress)
1661 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001662 hddLog(VOS_TRACE_LEVEL_INFO,
1663 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1664 return;
1665 }
1666
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301667 if (!pHddCtx->hdd_wlan_suspended)
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 "%s: Ignore resume wlan, Already resumed!", __func__);
1671 return;
1672 }
1673
Jeff Johnson295189b2012-06-20 16:38:30 -07001674 pHddCtx->hdd_wlan_suspended = FALSE;
1675 /*loop through all adapters. Concurrency */
1676 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1677
1678 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1679 {
1680 pAdapter = pAdapterNode->pAdapter;
1681 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001682 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001683 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001684 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001685 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1686 pAdapterNode = pNext;
1687 continue;
1688 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301689
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301690
Jeff Johnson295189b2012-06-20 16:38:30 -07001691#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1692 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1693 {
1694 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1695 hdd_exit_deep_sleep(pAdapter);
1696 }
1697#endif
1698
1699 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1700 {
1701 /*Switch back to DTIM 1*/
1702 tSirSetPowerParamsReq powerRequest = { 0 };
1703
1704 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1705 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001706 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001707
1708 /*Disabled ModulatedDTIM if enabled on suspend*/
1709 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1710 powerRequest.uDTIMPeriod = 0;
1711
1712 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1713 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1714 NULL, eANI_BOOLEAN_FALSE);
1715 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1716 NULL, eANI_BOOLEAN_FALSE);
1717
1718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001719 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001720 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001721
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301722 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1723 {
1724 /* put the device into full power */
1725 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001726
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301727 /* put the device back into BMPS */
1728 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001729
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301730 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001732 }
1733
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301734 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001735 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1736 pAdapterNode = pNext;
1737 }
1738
1739#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1740 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1741 {
1742 hdd_exit_standby(pHddCtx);
1743 }
1744#endif
1745
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 return;
1747}
1748
Jeff Johnson295189b2012-06-20 16:38:30 -07001749VOS_STATUS hdd_wlan_reset_initialization(void)
1750{
Jeff Johnson295189b2012-06-20 16:38:30 -07001751 v_CONTEXT_t pVosContext = NULL;
1752
1753 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1754
1755 //Get the global VOSS context.
1756 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1757 if(!pVosContext)
1758 {
1759 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1760 return VOS_STATUS_E_FAILURE;
1761 }
1762
1763 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1764
1765 // Prevent the phone from going to sleep
1766 hdd_prevent_suspend();
1767
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 return VOS_STATUS_SUCCESS;
1769}
1770
1771
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001772/*
1773 * Based on the ioctl command recieved by HDD, put WLAN driver
1774 * into the quiet mode. This is the same as the early suspend
1775 * notification that driver used to listen
1776 */
1777void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001778{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301779 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001780 if (suspend)
1781 hdd_suspend_wlan();
1782 else
1783 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301784 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001785}
1786
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001787static void hdd_ssr_timer_init(void)
1788{
1789 init_timer(&ssr_timer);
1790}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001791
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001792static void hdd_ssr_timer_del(void)
1793{
1794 del_timer(&ssr_timer);
1795 ssr_timer_started = false;
1796}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001797
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001798static void hdd_ssr_timer_cb(unsigned long data)
1799{
1800 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001801
1802#ifdef WCN_PRONTO
1803 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1804 wcnss_pronto_log_debug_regs();
1805#endif
1806
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001807 VOS_BUG(0);
1808}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001809
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001810static void hdd_ssr_timer_start(int msec)
1811{
1812 if(ssr_timer_started)
1813 {
1814 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1815 ,__func__);
1816 }
1817 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1818 ssr_timer.function = hdd_ssr_timer_cb;
1819 add_timer(&ssr_timer);
1820 ssr_timer_started = true;
1821}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001822
Jeff Johnson295189b2012-06-20 16:38:30 -07001823/* the HDD interface to WLAN driver shutdown,
1824 * the primary shutdown function in SSR
1825 */
1826VOS_STATUS hdd_wlan_shutdown(void)
1827{
1828 VOS_STATUS vosStatus;
1829 v_CONTEXT_t pVosContext = NULL;
1830 hdd_context_t *pHddCtx = NULL;
1831 pVosSchedContext vosSchedContext = NULL;
1832
1833 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1834
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001835 /* if re-init never happens, then do SSR1 */
1836 hdd_ssr_timer_init();
1837 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1838
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 /* Get the global VOSS context. */
1840 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1841 if(!pVosContext) {
1842 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1843 return VOS_STATUS_E_FAILURE;
1844 }
1845 /* Get the HDD context. */
1846 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1847 if(!pHddCtx) {
1848 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1849 return VOS_STATUS_E_FAILURE;
1850 }
c_hpothud662a352013-12-26 15:09:12 +05301851
1852 //Stop the traffic monitor timer
1853 if ( VOS_TIMER_STATE_RUNNING ==
1854 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1855 {
1856 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1857 }
1858
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001860 /* DeRegister with platform driver as client for Suspend/Resume */
1861 vosStatus = hddDeregisterPmOps(pHddCtx);
1862 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1863 {
1864 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1865 }
1866
1867 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1868 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1869 {
1870 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1871 }
1872
1873 /* Disable IMPS/BMPS as we do not want the device to enter any power
1874 * save mode on its own during reset sequence
1875 */
1876 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1877 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1878 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1879
1880 vosSchedContext = get_vos_sched_ctxt();
1881
1882 /* Wakeup all driver threads */
1883 if(TRUE == pHddCtx->isMcThreadSuspended){
1884 complete(&vosSchedContext->ResumeMcEvent);
1885 pHddCtx->isMcThreadSuspended= FALSE;
1886 }
1887 if(TRUE == pHddCtx->isTxThreadSuspended){
1888 complete(&vosSchedContext->ResumeTxEvent);
1889 pHddCtx->isTxThreadSuspended= FALSE;
1890 }
1891 if(TRUE == pHddCtx->isRxThreadSuspended){
1892 complete(&vosSchedContext->ResumeRxEvent);
1893 pHddCtx->isRxThreadSuspended= FALSE;
1894 }
1895 /* Reset the Suspend Variable */
1896 pHddCtx->isWlanSuspended = FALSE;
1897
1898 /* Stop all the threads; we do not want any messages to be a processed,
1899 * any more and the best way to ensure that is to terminate the threads
1900 * gracefully.
1901 */
1902 /* Wait for MC to exit */
1903 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1904 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1905 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1906 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301907 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001908
1909 /* Wait for TX to exit */
1910 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1911 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1912 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1913 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301914 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001915
1916 /* Wait for RX to exit */
1917 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1918 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1919 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1920 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301921
Mihir Sheteb5425f72013-12-19 09:06:13 +05301922 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001923
1924#ifdef WLAN_BTAMP_FEATURE
1925 vosStatus = WLANBAP_Stop(pVosContext);
1926 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1927 {
1928 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1929 "%s: Failed to stop BAP",__func__);
1930 }
1931#endif //WLAN_BTAMP_FEATURE
1932 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301933 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1934 {
1935 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1936 "%s: Failed to stop wda %d", __func__, vosStatus);
1937 VOS_ASSERT(0);
1938 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001939
1940 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1941 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1942 * on threads being running to process the SYS Stop
1943 */
Kiet Lama72a2322013-11-15 11:18:11 +05301944 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301945 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1946 {
1947 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1948 "%s: Failed to stop sme %d", __func__, vosStatus);
1949 VOS_ASSERT(0);
1950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001951
1952 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1953 /* Stop MAC (PE and HAL) */
1954 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301955 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1956 {
1957 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1958 "%s: Failed to stop mac %d", __func__, vosStatus);
1959 VOS_ASSERT(0);
1960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001961
1962 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1963 /* Stop TL */
1964 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301965 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1966 {
1967 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1968 "%s: Failed to stop TL %d", __func__, vosStatus);
1969 VOS_ASSERT(0);
1970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001971
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
1974 /* Clean up message queues of TX and MC thread */
1975 vos_sched_flush_mc_mqs(vosSchedContext);
1976 vos_sched_flush_tx_mqs(vosSchedContext);
1977 vos_sched_flush_rx_mqs(vosSchedContext);
1978
1979 /* Deinit all the TX and MC queues */
1980 vos_sched_deinit_mqs(vosSchedContext);
1981 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
1982
1983 /* shutdown VOSS */
1984 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05301985
1986 /*mac context has already been released in mac_close call
1987 so setting it to NULL in hdd context*/
1988 pHddCtx->hHal = (tHalHandle)NULL;
1989
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 if (free_riva_power_on_lock("wlan"))
1991 {
1992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
1993 __func__);
1994 }
1995 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
1996 ,__func__);
1997 return VOS_STATUS_SUCCESS;
1998}
1999
2000
2001
2002/* the HDD interface to WLAN driver re-init.
2003 * This is called to initialize/start WLAN driver after a shutdown.
2004 */
2005VOS_STATUS hdd_wlan_re_init(void)
2006{
2007 VOS_STATUS vosStatus;
2008 v_CONTEXT_t pVosContext = NULL;
2009 hdd_context_t *pHddCtx = NULL;
2010 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002011#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2012 int max_retries = 0;
2013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002014#ifdef WLAN_BTAMP_FEATURE
2015 hdd_config_t *pConfig = NULL;
2016 WLANBAP_ConfigType btAmpConfig;
2017#endif
2018
Katya Nigam82a93062014-06-04 15:15:36 +05302019 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002020 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002021 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002022
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002023#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2024 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002025 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002026 msleep(1000);
2027 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002028 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002029 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2030 goto err_re_init;
2031 }
2032#endif
2033
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002034 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2035
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002036 /* The driver should always be initialized in STA mode after SSR */
2037 hdd_set_conparam(0);
2038
Katya Nigam82a93062014-06-04 15:15:36 +05302039 dev = wcnss_wlan_get_device();
2040 if (NULL == dev)
2041 {
2042 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2043 goto err_re_init;
2044 }
2045
Jeff Johnson295189b2012-06-20 16:38:30 -07002046 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302047 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002048 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2049 {
2050 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2051 goto err_re_init;
2052 }
2053
2054 /* Get the HDD context. */
2055 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2056 if(!pHddCtx)
2057 {
2058 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2059 goto err_vosclose;
2060 }
2061
2062 /* Save the hal context in Adapter */
2063 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2064 if ( NULL == pHddCtx->hHal )
2065 {
2066 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2067 goto err_vosclose;
2068 }
2069
2070 /* Set the SME configuration parameters. */
2071 vosStatus = hdd_set_sme_config(pHddCtx);
2072 if ( VOS_STATUS_SUCCESS != vosStatus )
2073 {
2074 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2075 goto err_vosclose;
2076 }
2077
Jeff Johnson295189b2012-06-20 16:38:30 -07002078 vosStatus = vos_preStart( pHddCtx->pvosContext );
2079 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2080 {
2081 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2082 goto err_vosclose;
2083 }
2084
2085 /* In the integrated architecture we update the configuration from
2086 the INI file and from NV before vOSS has been started so that
2087 the final contents are available to send down to the cCPU */
2088 /* Apply the cfg.ini to cfg.dat */
2089 if (FALSE == hdd_update_config_dat(pHddCtx))
2090 {
2091 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2092 goto err_vosclose;
2093 }
2094
2095 /* Set the MAC Address, currently this is used by HAL to add self sta.
2096 * Remove this once self sta is added as part of session open. */
2097 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2098 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2099 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2100 if (!HAL_STATUS_SUCCESS(halStatus))
2101 {
2102 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2103 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2104 goto err_vosclose;
2105 }
2106
2107 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2108 Note: Firmware image will be read and downloaded inside vos_start API */
2109 vosStatus = vos_start( pVosContext );
2110 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2111 {
2112 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2113 goto err_vosclose;
2114 }
2115
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002116 /* Exchange capability info between Host and FW and also get versioning info from FW */
2117 hdd_exchange_version_and_caps(pHddCtx);
2118
Jeff Johnson295189b2012-06-20 16:38:30 -07002119 vosStatus = hdd_post_voss_start_config( pHddCtx );
2120 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2121 {
2122 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2123 __func__);
2124 goto err_vosstop;
2125 }
2126
Mihir Shete04206452014-11-20 17:50:58 +05302127#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302128 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2129 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2130 {
2131 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2132 __func__);
2133 goto err_vosstop;
2134 }
Mihir Shete04206452014-11-20 17:50:58 +05302135#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302136
Jeff Johnson295189b2012-06-20 16:38:30 -07002137#ifdef WLAN_BTAMP_FEATURE
2138 vosStatus = WLANBAP_Open(pVosContext);
2139 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2140 {
2141 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2142 "%s: Failed to open BAP",__func__);
2143 goto err_vosstop;
2144 }
2145 vosStatus = BSL_Init(pVosContext);
2146 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2147 {
2148 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2149 "%s: Failed to Init BSL",__func__);
2150 goto err_bap_close;
2151 }
2152 vosStatus = WLANBAP_Start(pVosContext);
2153 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2154 {
2155 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2156 "%s: Failed to start TL",__func__);
2157 goto err_bap_close;
2158 }
2159 pConfig = pHddCtx->cfg_ini;
2160 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2161 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2162#endif //WLAN_BTAMP_FEATURE
2163
2164 /* Restart all adapters */
2165 hdd_start_all_adapters(pHddCtx);
2166 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002167 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002168 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302169 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302171 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002172 /* Register with platform driver as client for Suspend/Resume */
2173 vosStatus = hddRegisterPmOps(pHddCtx);
2174 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2175 {
2176 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2177 goto err_bap_stop;
2178 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002179 /* Allow the phone to go to sleep */
2180 hdd_allow_suspend();
2181 /* register for riva power on lock */
2182 if (req_riva_power_on_lock("wlan"))
2183 {
2184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2185 __func__);
2186 goto err_unregister_pmops;
2187 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002188 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302189#ifdef WLAN_FEATURE_EXTSCAN
2190 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2191 wlan_hdd_cfg80211_extscan_callback,
2192 pHddCtx);
2193#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07002194 goto success;
2195
2196err_unregister_pmops:
2197 hddDeregisterPmOps(pHddCtx);
2198
2199err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002200#ifdef CONFIG_HAS_EARLYSUSPEND
2201 hdd_unregister_mcast_bcast_filter(pHddCtx);
2202#endif
2203 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002204#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002205 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002206#endif
2207
2208#ifdef WLAN_BTAMP_FEATURE
2209err_bap_close:
2210 WLANBAP_Close(pVosContext);
2211#endif
2212
2213err_vosstop:
2214 vos_stop(pVosContext);
2215
2216err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302217 if(!isSsrPanicOnFailure())
2218 {
2219 /* If we hit this, it means wlan driver is in bad state and needs
2220 * driver unload and load.
2221 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302222 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2223 return VOS_STATUS_E_FAILURE;
2224 }
2225
Jeff Johnson295189b2012-06-20 16:38:30 -07002226 vos_close(pVosContext);
2227 vos_sched_close(pVosContext);
2228 if (pHddCtx)
2229 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002230 /* Unregister the Net Device Notifier */
2231 unregister_netdevice_notifier(&hdd_netdev_notifier);
2232 /* Clean up HDD Nlink Service */
2233 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002234#ifdef WLAN_KD_READY_NOTIFIER
2235 nl_srv_exit(pHddCtx->ptt_pid);
2236#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002237 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002238#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 /* Free up dynamically allocated members inside HDD Adapter */
2240 kfree(pHddCtx->cfg_ini);
2241 pHddCtx->cfg_ini= NULL;
2242
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 wiphy_unregister(pHddCtx->wiphy);
2244 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002245 }
2246 vos_preClose(&pVosContext);
2247
2248#ifdef MEMORY_DEBUG
2249 vos_mem_exit();
2250#endif
2251
2252err_re_init:
2253 /* Allow the phone to go to sleep */
2254 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002255 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002256 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002257 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002258
2259success:
2260 /* Trigger replay of BTC events */
2261 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2262 return VOS_STATUS_SUCCESS;
2263}