blob: bbde0045cd672f6150f5c6b42a581c512eb8c7bd [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=============================================================================
29* wlan_hdd_early_suspend.c
30*
31* \brief power management functions
32*
33* Description
Jeff Johnson295189b2012-06-20 16:38:30 -070034*
35==============================================================================**/
36/* $HEADER$ */
37
38/**-----------------------------------------------------------------------------
39* Include files
40* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42#include <linux/pm.h>
43#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070044#include <wlan_hdd_includes.h>
45#include <wlan_qct_driver.h>
46#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48#include "halTypes.h"
49#include "sme_Api.h"
50#include <vos_api.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070051#include <vos_sched.h>
52#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <wlan_qct_sys.h>
54#include <wlan_btc_svc.h>
55#include <wlan_nlink_common.h>
56#include <wlan_hdd_main.h>
57#include <wlan_hdd_assoc.h>
58#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070059#include <wlan_nlink_srv.h>
60#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070061#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062
Jeff Johnson295189b2012-06-20 16:38:30 -070063#include <linux/semaphore.h>
64#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include "cfgApi.h"
66
67#ifdef WLAN_BTAMP_FEATURE
68#include "bapApi.h"
69#include "bap_hdd_main.h"
70#include "bap_hdd_misc.h"
71#endif
72
Jeff Johnsone7245742012-09-05 17:12:55 -070073#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070074#include <linux/inetdevice.h>
75#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053076#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053077#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070078/**-----------------------------------------------------------------------------
79* Preprocessor definitions and constants
80* ----------------------------------------------------------------------------*/
81
82/**-----------------------------------------------------------------------------
83* Type declarations
84* ----------------------------------------------------------------------------*/
85
86/**-----------------------------------------------------------------------------
87* Function and variables declarations
88* ----------------------------------------------------------------------------*/
89#include "wlan_hdd_power.h"
90#include "wlan_hdd_packet_filtering.h"
91
Sameer Thalappile5637f42013-08-07 15:46:55 -070092#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053093#define NS_DEFAULT_SLOT_INDEX 4
94#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070095
96static eHalStatus g_full_pwr_status;
97static eHalStatus g_standby_status;
98
99extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700103extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700104
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700105static struct timer_list ssr_timer;
106static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108//Callback invoked by PMC to report status of standby request
109void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
110{
111 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
113 g_standby_status = status;
114
115 if(eHAL_STATUS_SUCCESS == status)
116 {
117 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
118 }
119 else
120 {
121 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
122 }
123
124 complete(&pHddCtx->standby_comp_var);
125}
126
127//Callback invoked by PMC to report status of full power request
128void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
129{
130 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
131 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
132 g_full_pwr_status = status;
133
134 if(eHAL_STATUS_SUCCESS == status)
135 {
136 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
137 }
138 else
139 {
140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
141 }
142
143 complete(&pHddCtx->full_pwr_comp_var);
144}
145
146eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
147{
148 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530149 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700150
151 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
152 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
153
154 g_full_pwr_status = eHAL_STATUS_FAILURE;
155 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
156 eSME_FULL_PWR_NEEDED_BY_HDD);
157
158 if(status == eHAL_STATUS_PMC_PENDING)
159 {
160 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530161 ret = wait_for_completion_interruptible_timeout(
162 &pHddCtx->full_pwr_comp_var,
163 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
164 if (0 >= ret)
165 {
166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
167 __func__, ret);
168 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700169 status = g_full_pwr_status;
170 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
171 {
172 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
173 VOS_ASSERT(0);
174 goto failure;
175 }
176 }
177 else if(status != eHAL_STATUS_SUCCESS)
178 {
179 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
180 __func__, status);
181 VOS_ASSERT(0);
182 goto failure;
183 }
184 else
185 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
186
187failure:
188 //No blocking to reduce latency. No other device should be depending on WLAN
189 //to finish resume and WLAN won't be instantly on after resume
190 return status;
191}
192
193
194//Helper routine to put the chip into standby
195VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
196{
197 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
198 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530199 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700200
201 //Disable IMPS/BMPS as we do not want the device to enter any power
202 //save mode on its own during suspend sequence
203 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
204 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
205
206 //Note we do not disable queues unnecessarily. Queues should already be disabled
207 //if STA is disconnected or the queue will be disabled as and when disconnect
208 //happens because of standby procedure.
209
210 //Ensure that device is in full power first. There is scope for optimization
211 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
212 //Core s/w needs to be optimized to handle this. Until then we request full
213 //power before issuing request for standby.
214 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
215 g_full_pwr_status = eHAL_STATUS_FAILURE;
216 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
217 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
218
219 if(halStatus == eHAL_STATUS_PMC_PENDING)
220 {
221 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530222 ret = wait_for_completion_interruptible_timeout(
223 &pHddCtx->full_pwr_comp_var,
224 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
225 if (0 >= ret)
226 {
227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
228 __func__, ret);
229 }
230
Jeff Johnson295189b2012-06-20 16:38:30 -0700231 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
232 {
233 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
234 VOS_ASSERT(0);
235 vosStatus = VOS_STATUS_E_FAILURE;
236 goto failure;
237 }
238 }
239 else if(halStatus != eHAL_STATUS_SUCCESS)
240 {
241 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
242 __func__, halStatus);
243 VOS_ASSERT(0);
244 vosStatus = VOS_STATUS_E_FAILURE;
245 goto failure;
246 }
247
248 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
249 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
250 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
251 }
252
253 //Request standby. Standby will cause the STA to disassociate first. TX queues
254 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
255 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
256 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
257 //when there are concurrent sessions.
258 INIT_COMPLETION(pHddCtx->standby_comp_var);
259 g_standby_status = eHAL_STATUS_FAILURE;
260 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
261
262 if (halStatus == eHAL_STATUS_PMC_PENDING)
263 {
264 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530265 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530267 if (0 >= ret)
268 {
269 hddLog(VOS_TRACE_LEVEL_ERROR,
270 FL("wait on standby_comp_var failed %ld"), ret);
271 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
273 {
274 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
275 VOS_ASSERT(0);
276 vosStatus = VOS_STATUS_E_FAILURE;
277 goto failure;
278 }
279 }
280 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
281 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
282 __func__, halStatus);
283 VOS_ASSERT(0);
284 vosStatus = VOS_STATUS_E_FAILURE;
285 goto failure;
286 }
287 else
288 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
289
290failure:
291 //Restore IMPS config
292 if(pHddCtx->cfg_ini->fIsImpsEnabled)
293 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
294
295 //Restore BMPS config
296 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
297 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
298
299 return vosStatus;
300}
301
302
303//Helper routine for Deep sleep entry
304VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
305{
306 eHalStatus halStatus;
307 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530308 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800309
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 netif_tx_disable(pAdapter->dev);
313 netif_carrier_off(pAdapter->dev);
314
315 //Disable IMPS,BMPS as we do not want the device to enter any power
316 //save mode on it own during suspend sequence
317 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
318 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
319
320 //Ensure that device is in full power as we will touch H/W during vos_Stop
321 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
322 g_full_pwr_status = eHAL_STATUS_FAILURE;
323 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
324 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
325
326 if(halStatus == eHAL_STATUS_PMC_PENDING)
327 {
328 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530329 ret = wait_for_completion_interruptible_timeout(
330 &pHddCtx->full_pwr_comp_var,
331 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
332 if (0 >= ret)
333 {
334 hddLog(VOS_TRACE_LEVEL_ERROR,
335 FL("wait on full_pwr_comp_var failed %ld"), ret);
336 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
338 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
339 VOS_ASSERT(0);
340 }
341 }
342 else if(halStatus != eHAL_STATUS_SUCCESS)
343 {
344 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
345 VOS_ASSERT(0);
346 }
347
348 //Issue a disconnect. This is required to inform the supplicant that
349 //STA is getting disassociated and for GUI to be updated properly
350 INIT_COMPLETION(pAdapter->disconnect_comp_var);
351 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
352
353 //Success implies disconnect command got queued up successfully
354 if(halStatus == eHAL_STATUS_SUCCESS)
355 {
356 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530357 ret = wait_for_completion_interruptible_timeout(
358 &pAdapter->disconnect_comp_var,
359 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
360 if (0 >= ret)
361 {
362 hddLog(VOS_TRACE_LEVEL_ERROR,
363 FL("wait on disconnect_comp_var failed %ld"), ret);
364 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 }
366
367
368 //None of the steps should fail after this. Continue even in case of failure
369 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530370 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
371 {
372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
373 __func__, vosStatus);
374 VOS_ASSERT(0);
375 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700376
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
378
379 //Restore IMPS config
380 if(pHddCtx->cfg_ini->fIsImpsEnabled)
381 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
382
383 //Restore BMPS config
384 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
385 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
386
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 return vosStatus;
388}
389
390VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
391{
392 VOS_STATUS vosStatus;
393 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700394
Jeff Johnson295189b2012-06-20 16:38:30 -0700395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
396 "%s: calling hdd_set_sme_config",__func__);
397 vosStatus = hdd_set_sme_config( pHddCtx );
398 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
399 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
400 {
401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
402 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700403 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700404 }
405
406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
407 "%s: calling vos_start",__func__);
408 vosStatus = vos_start( pHddCtx->pvosContext );
409 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
410 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
411 {
412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
413 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700414 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700415 }
416
417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
418 "%s: calling hdd_post_voss_start_config",__func__);
419 vosStatus = hdd_post_voss_start_config( pHddCtx );
420 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
421 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
422 {
423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
424 "%s: Failed in hdd_post_voss_start_config",__func__);
425 goto err_voss_stop;
426 }
427
428
429 //Open a SME session for future operation
430 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700431 (tANI_U8 *)&pAdapter->macAddressCurrent,
432 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700433 if ( !HAL_STATUS_SUCCESS( halStatus ) )
434 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700435 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700436 halStatus, halStatus );
437 goto err_voss_stop;
438
439 }
440
441 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
442
443 //Trigger the initial scan
444 hdd_wlan_initial_scan(pHddCtx);
445
446 return VOS_STATUS_SUCCESS;
447
448err_voss_stop:
449 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700450err_deep_sleep:
451 return VOS_STATUS_E_FAILURE;
452
453}
454
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530455void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
Atul Mittal37385d72014-03-27 18:15:03 +0530456{
457 hdd_adapter_t* pAdapter =
458 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
459 hdd_context_t *pHddCtx;
460 int status;
461
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530462 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530463 if (NULL == pAdapter)
464 {
465 hddLog(LOGE, FL("Adapter is invalid"));
466 return;
467 }
Atul Mittal37385d72014-03-27 18:15:03 +0530468
469 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
470 status = wlan_hdd_validate_context(pHddCtx);
471 if (0 != status)
472 {
Atul Mittal37385d72014-03-27 18:15:03 +0530473 return;
474 }
475
476 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
477 {
478 pHddCtx->sus_res_mcastbcast_filter =
479 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530480 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
481 pHddCtx->sus_res_mcastbcast_filter);
Atul Mittal37385d72014-03-27 18:15:03 +0530482 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
483 }
484
485 if ((eConnectionState_Associated ==
486 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
487 && (pHddCtx->hdd_wlan_suspended))
488 {
489 // This invocation being part of the IPv6 registration callback,
490 // set the newly generated ip address to f/w in suspend mode.
491#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530492 if (pHddCtx->cfg_ini->fhostNSOffload)
493 {
494 hdd_conf_ns_offload(pAdapter, 1);
495 }
Atul Mittal37385d72014-03-27 18:15:03 +0530496#endif
497 }
498#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530499 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530500 * only so when new ipv6 address is generated the screen may not
501 * on so we need to call it here to update the list in f/w.
502 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530503 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530504#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530505 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530506}
507
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530508void hdd_ipv6_notifier_work_queue(struct work_struct *work)
509{
510 vos_ssr_protect(__func__);
511 __hdd_ipv6_notifier_work_queue(work);
512 vos_ssr_unprotect(__func__);
513}
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530514int wlan_hdd_ipv6_changed(struct notifier_block *nb,
515 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530516{
517 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
518 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530519 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530520 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530521 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530522 int status;
523
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530524 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530525 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
526 status = wlan_hdd_validate_context(pHddCtx);
527 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530528 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530529 return NOTIFY_DONE;
530 }
Atul Mittal37385d72014-03-27 18:15:03 +0530531
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530532 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
533 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
534 {
535 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
536 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
537 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
538 {
539 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530540 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530541 {
542 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
543 }
544 else
545 {
546 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
547 pHddCtx->cfg_ini->nEnableSuspend);
548 }
549 break;
550 }
551 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
552 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530553 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530554 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530555 return NOTIFY_DONE;
556}
557
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530558/*
559 * Function: hdd_conf_hostoffload
560 * Central function to configure the supported offloads,
561 * either enable or disable them.
562 */
563void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
564{
565 hdd_context_t *pHddCtx = NULL;
566 v_CONTEXT_t *pVosContext = NULL;
567 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
568
569 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
570 fenable);
571
572 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
573
574 if (NULL == pVosContext)
575 {
576 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
577 return;
578 }
579
580 //Get the HDD context.
581 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
582
583 if (NULL == pHddCtx)
584 {
585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
586 return;
587 }
588
589 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
590 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
591 {
592 if (fenable)
593 {
594 if (eConnectionState_Associated ==
595 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
596 {
597 if ((pHddCtx->cfg_ini->fhostArpOffload))
598 {
599 /*
600 * Configure the ARP Offload.
601 * Even if it fails we have to reconfigure the MC/BC
602 * filter flag as we want RIVA not to drop BroadCast
603 * Packets
604 */
605 hddLog(VOS_TRACE_LEVEL_INFO,
606 FL("Calling ARP Offload with flag: %d"), fenable);
607 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
608 pHddCtx->configuredMcastBcastFilter &=
609 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
610
611 if (!VOS_IS_STATUS_SUCCESS(vstatus))
612 {
613 hddLog(VOS_TRACE_LEVEL_ERROR,
614 "Failed to enable ARPOFfloadFeature %d",
615 vstatus);
616 }
617 }
618 //Configure GTK_OFFLOAD
619#ifdef WLAN_FEATURE_GTK_OFFLOAD
620 hdd_conf_gtk_offload(pAdapter, fenable);
621#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530622
623#ifdef WLAN_NS_OFFLOAD
624 if (pHddCtx->cfg_ini->fhostNSOffload)
625 {
626 /*
627 * Configure the NS Offload.
628 * Even if it fails we have to reconfigure the MC/BC filter flag
629 * as we want RIVA not to drop Multicast Packets
630 */
631
632 hddLog(VOS_TRACE_LEVEL_INFO,
633 FL("Calling NS Offload with flag: %d"), fenable);
634 hdd_conf_ns_offload(pAdapter, fenable);
635 pHddCtx->configuredMcastBcastFilter &=
636 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
637 }
638#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530639
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530640 }
641 }
642 else
643 {
644 //Disable ARPOFFLOAD
645 if (pHddCtx->cfg_ini->fhostArpOffload)
646 {
647 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
648 if (!VOS_IS_STATUS_SUCCESS(vstatus))
649 {
650 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530651 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530652 }
653 }
654 //Disable GTK_OFFLOAD
655#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530656 hdd_conf_gtk_offload(pAdapter, fenable);
657#endif
658
659#ifdef WLAN_NS_OFFLOAD
660 //Disable NSOFFLOAD
661 if (pHddCtx->cfg_ini->fhostNSOffload)
662 {
663 hdd_conf_ns_offload(pAdapter, fenable);
664 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530665#endif
666 }
667 }
668 return;
669}
670
Atul Mittal37385d72014-03-27 18:15:03 +0530671
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530672#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530673/**----------------------------------------------------------------------------
674
675 \brief hdd_conf_ns_offload() - Configure NS offload
676
677 Called during SUSPEND to configure the NS offload (MC BC filter) which
678 reduces power consumption.
679
680 \param - pAdapter - Adapter context for which NS offload is to be configured
681 \param - fenable - 0 - disable.
682 1 - enable. (with IPv6 notifier registration)
683 2 - enable. (without IPv6 notifier registration)
684
685 \return - void
686
687 ---------------------------------------------------------------------------*/
688void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530689{
690 struct inet6_dev *in6_dev;
691 struct inet6_ifaddr *ifp;
692 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530693 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530694 tANI_U8 **selfIPv6Addr = NULL;
695 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530696 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530697 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530698 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530699
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530700 int i = 0, slot = 0;
701 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530702 eHalStatus returnStatus;
703
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530704 ENTER();
705 hddLog(LOG1, FL(" fenable = %d"), fenable);
706
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530707 if (NULL == pAdapter)
708 {
709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
710 return;
711 }
712
713 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530714 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
715
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530716 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530717 if (0 != ret)
718 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530719 return;
720 }
721
722 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
723 {
724 slot_index = NS_EXTENDED_SLOT_INDEX;
725 }
726
727 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
728
729 selfIPv6AddrValid =
730 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
731
732 if (NULL == selfIPv6AddrValid)
733 {
734 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
735 " selfIPv6AddrValid"));
736 goto end;
737 }
738
739 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
740
741 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
742
743 if (NULL == selfIPv6Addr)
744 {
745 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
746 " selfIPv6Addr"));
747 goto end;
748 }
749
750 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
751
752 for (slot = 0; slot < slot_index; slot++)
753 {
754 selfIPv6Addr[slot] =
755 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
756 if (NULL == selfIPv6Addr[slot])
757 {
758 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
759 "for selfIPv6Addr"));
760 goto end;
761 }
762 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
763 }
764
765 i = 0;
766
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530767 if (fenable)
768 {
769 in6_dev = __in6_dev_get(pAdapter->dev);
770 if (NULL != in6_dev)
771 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530772 list_for_each(p, &in6_dev->addr_list)
773 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530774 if (i >= slot_index)
775 {
776 hddLog (VOS_TRACE_LEVEL_ERROR,
777 FL("IPv6 address list is greater than IPv6"
778 "address supported by firmware"));
779 hddLog (VOS_TRACE_LEVEL_ERROR,
780 FL("FW supported IPv6 address = %d"), slot_index);
781 break;
782 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530783 ifp = list_entry(p, struct inet6_ifaddr, if_list);
784 switch(ipv6_addr_src_scope(&ifp->addr))
785 {
786 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530787 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530788 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530789 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530790 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530791 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
792 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530793 break;
794 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530795 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530796 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530797 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530798 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530799 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
800 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530801 break;
802 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530803 hddLog(VOS_TRACE_LEVEL_ERROR,
804 FL("The Scope %d is not supported"),
805 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530806 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530807 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
808 {
809 i++;
810 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530811 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530812
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530813 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530814 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530815 {
816 if (selfIPv6AddrValid[i])
817 {
818 //Filling up the request structure
819 /* Filling the selfIPv6Addr with solicited address
820 * A Solicited-Node multicast address is created by
821 * taking the last 24 bits of a unicast or anycast
822 * address and appending them to the prefix
823 *
824 * FF02:0000:0000:0000:0000:0001:FFXX:XX
825 *
826 * here XX is the unicast/anycast bits
827 */
828 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
829 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
830 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
831 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530832 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
833 selfIPv6Addr[i][13];
834 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
835 selfIPv6Addr[i][14];
836 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
837 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530838 offLoadRequest.nsOffloadInfo.slotIdx = i;
839
840 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530841 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530842 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
843 &pAdapter->macAddressCurrent.bytes,
844 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
845
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530846 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
847 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530848 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
849 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
850
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530851 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530852 FL("configuredMcastBcastFilter: %d"
853 "NSOffload Slot = %d"),
854 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530855
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530856 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700857 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
858 pHddCtx->sus_res_mcastbcast_filter) ||
859 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
860 pHddCtx->sus_res_mcastbcast_filter)) &&
861 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
862 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
863 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530864 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530865 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700866 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530867 hddLog (VOS_TRACE_LEVEL_INFO,
868 FL("Set offLoadRequest with %d"),
869 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530870 }
871
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530872 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
873 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
874 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
875
876 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530877 FL("Setting NSOffload with solicitedIp: %pI6,"
878 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530879 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
880 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
881
882 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530883 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530884 pAdapter->sessionId, &offLoadRequest);
885 if(eHAL_STATUS_SUCCESS != returnStatus)
886 {
887 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530888 FL("Failed to enable HostOffload feature with"
889 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530890 }
891 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
892 }
893 }
894 }
895 else
896 {
897 hddLog(VOS_TRACE_LEVEL_ERROR,
898 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530899 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530900 }
901 }
902 else
903 {
904 //Disable NSOffload
905 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
906 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
907 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
908
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530909 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530910 {
c_hpothu86feba52014-10-28 15:51:18 +0530911 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530912 offLoadRequest.nsOffloadInfo.slotIdx = i;
913 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530914 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
915 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530916 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
918 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530919 }
920 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530921 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530922end:
923 while (slot > 0 && selfIPv6Addr[--slot])
924 {
925 vos_mem_free(selfIPv6Addr[slot]);
926 }
927 if (selfIPv6Addr)
928 {
929 vos_mem_free(selfIPv6Addr);
930 }
931 if (selfIPv6AddrValid)
932 {
933 vos_mem_free(selfIPv6AddrValid);
934 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530935 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530936 return;
937}
938#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530939
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530940void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530941{
942 hdd_adapter_t* pAdapter =
943 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
944 hdd_context_t *pHddCtx;
945 int status;
946
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530947 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530948 if (NULL == pAdapter)
949 {
950 hddLog(LOGE, FL("Adapter is invalid"));
951 return;
952 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530953 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
954 status = wlan_hdd_validate_context(pHddCtx);
955 if (0 != status)
956 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530957 return;
958 }
959
Deepthi Gowri5933f402014-01-23 17:48:24 +0530960 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
961 {
962 pHddCtx->sus_res_mcastbcast_filter =
963 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530964 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
965 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530966 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
967 }
968
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530969 if ((eConnectionState_Associated ==
970 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530971 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530972 {
973 // This invocation being part of the IPv4 registration callback,
974 // we are passing second parameter as 2 to avoid registration
975 // of IPv4 notifier again.
976 hdd_conf_arp_offload(pAdapter, 2);
977 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530978 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530979}
980
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530981void hdd_ipv4_notifier_work_queue(struct work_struct *work)
982{
983 vos_ssr_protect(__func__);
984 __hdd_ipv4_notifier_work_queue(work);
985 vos_ssr_unprotect(__func__);
986}
987
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530988int wlan_hdd_ipv4_changed(struct notifier_block *nb,
989 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530990{
991 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
992 struct in_ifaddr **ifap = NULL;
993 struct in_device *in_dev;
994
995 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530996 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530997 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530998 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530999 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301000
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301001 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301002 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1003 status = wlan_hdd_validate_context(pHddCtx);
1004 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301005 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301006 return NOTIFY_DONE;
1007 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301008
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301009 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1010 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1011 {
1012 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1013 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1014 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1015 {
1016 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301017 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301018 || (!pHddCtx->cfg_ini->fhostArpOffload))
1019 {
1020 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1021 pHddCtx->cfg_ini->nEnableSuspend,
1022 pHddCtx->cfg_ini->fhostArpOffload);
1023 return NOTIFY_DONE;
1024 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301025
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301026 if ((in_dev =
1027 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1028 {
1029 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1030 ifap = &ifa->ifa_next)
1031 {
1032 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1033 ifa->ifa_label))
1034 {
1035 break; /* found */
1036 }
1037 }
1038 }
1039 if(ifa && ifa->ifa_local)
1040 {
1041 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1042 }
1043 break;
1044 }
1045 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1046 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301047 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301048 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301049 return NOTIFY_DONE;
1050}
1051
1052/**----------------------------------------------------------------------------
1053
1054 \brief hdd_conf_arp_offload() - Configure ARP offload
1055
1056 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1057 reduces power consumption.
1058
1059 \param - pAdapter -Adapter context for which ARP offload is to be configured
1060 \param - fenable - 0 - disable.
1061 1 - enable. (with IPv4 notifier registration)
1062 2 - enable. (without IPv4 notifier registration)
1063
1064 \return -
1065 VOS_STATUS_SUCCESS - on successful operation
1066 VOS_STATUS_E_FAILURE - on failure of operation
1067-----------------------------------------------------------------------------*/
1068VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001069{
1070 struct in_ifaddr **ifap = NULL;
1071 struct in_ifaddr *ifa = NULL;
1072 struct in_device *in_dev;
1073 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001075 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001076
c_hpothu86feba52014-10-28 15:51:18 +05301077 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001078
Jeff Johnson295189b2012-06-20 16:38:30 -07001079 if(fenable)
1080 {
1081 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1082 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301083 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 ifap = &ifa->ifa_next)
1085 {
1086 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1087 {
1088 break; /* found */
1089 }
1090 }
1091 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001092 if(ifa && ifa->ifa_local)
1093 {
1094 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1095 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1096
Arif Hussain6d2a3322013-11-17 19:50:10 -08001097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001098
Amar Singhald53568e2013-09-26 11:03:45 -07001099 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1100 pHddCtx->sus_res_mcastbcast_filter) ||
1101 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1102 pHddCtx->sus_res_mcastbcast_filter)) &&
1103 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001104 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301105 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001106 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1107 hddLog(VOS_TRACE_LEVEL_INFO,
1108 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001109 }
Amar Singhald53568e2013-09-26 11:03:45 -07001110
1111 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1112 offLoadRequest.enableOrDisable);
1113
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 //converting u32 to IPV4 address
1115 for(i = 0 ; i < 4; i++)
1116 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301117 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001118 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1119 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301120 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001121 offLoadRequest.params.hostIpv4Addr[0],
1122 offLoadRequest.params.hostIpv4Addr[1],
1123 offLoadRequest.params.hostIpv4Addr[2],
1124 offLoadRequest.params.hostIpv4Addr[3]);
1125
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301126 if (eHAL_STATUS_SUCCESS !=
1127 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1128 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001129 {
1130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001131 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 return VOS_STATUS_E_FAILURE;
1133 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 }
1135 else
1136 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1138 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001139 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301140
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301141 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 }
1143 else
1144 {
1145 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1146 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1147 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1148
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301149 if (eHAL_STATUS_SUCCESS !=
1150 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1151 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 {
1153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001154 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 return VOS_STATUS_E_FAILURE;
1156 }
1157 return VOS_STATUS_SUCCESS;
1158 }
1159}
1160
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301161/*
1162 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301163 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301164*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301165void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301166 tANI_U8 *pMcBcFilter)
1167{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301168 if (NULL == pHddCtx)
1169 {
1170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1171 return;
1172 }
1173
1174 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1175 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301176 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301177 /* ARP offload is enabled, do not block bcast packets at RXP
1178 * Will be using Bitmasking to reset the filter. As we have
1179 * disable Broadcast filtering, Anding with the negation
1180 * of Broadcast BIT
1181 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301182 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301183 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301184
1185#ifdef WLAN_NS_OFFLOAD
1186 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301187 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301188 /* NS offload is enabled, do not block mcast packets at RXP
1189 * Will be using Bitmasking to reset the filter. As we have
1190 * disable Multicast filtering, Anding with the negation
1191 * of Multicast BIT
1192 */
1193 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301194 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301195#endif
1196
Amar Singhald08ce752014-03-21 16:28:27 -07001197 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1198 {
1199 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1200 }
1201
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301202 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301203}
1204
Jeff Johnson295189b2012-06-20 16:38:30 -07001205void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1206{
1207 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001208 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1209 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1210 if(NULL == wlanRxpFilterParam)
1211 {
1212 hddLog(VOS_TRACE_LEVEL_FATAL,
1213 "%s: vos_mem_alloc failed ", __func__);
1214 return;
1215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001216 hddLog(VOS_TRACE_LEVEL_INFO,
1217 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301218 if (TRUE == setfilter)
1219 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301220 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301221 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301222 }
1223 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301224 {
1225 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301226 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301227 pHddCtx->configuredMcastBcastFilter;
1228 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301229
Jeff Johnson295189b2012-06-20 16:38:30 -07001230 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001231 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301232
1233 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1234 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1235
1236 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1237 "lower mac with status %d"
1238 "configuredMcstBcstFilterSetting = %d"
1239 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1240 "Failed" : "Success", halStatus,
1241 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1242 wlanRxpFilterParam->setMcstBcstFilter);
1243
Chilam Ngc4244af2013-04-01 15:37:32 -07001244 if (eHAL_STATUS_SUCCESS != halStatus)
1245 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001246}
1247
Jeff Johnson295189b2012-06-20 16:38:30 -07001248static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1249 hdd_adapter_t *pAdapter)
1250{
1251 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1252 tpSirWlanSuspendParam wlanSuspendParam =
1253 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1254
Amar Singhald53568e2013-09-26 11:03:45 -07001255 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1256 pHddCtx->sus_res_mcastbcast_filter =
1257 pHddCtx->configuredMcastBcastFilter;
1258 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1259 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1260 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1261 pHddCtx->configuredMcastBcastFilter);
1262
1263 }
1264
Amar Singhal49fdfd52013-08-13 13:25:12 -07001265
Jeff Johnson295189b2012-06-20 16:38:30 -07001266 if(NULL == wlanSuspendParam)
1267 {
1268 hddLog(VOS_TRACE_LEVEL_FATAL,
1269 "%s: vos_mem_alloc failed ", __func__);
1270 return;
1271 }
1272
Amar Singhald53568e2013-09-26 11:03:45 -07001273 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001274 "%s: send wlan suspend indication", __func__);
1275
1276 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1277 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301278 //Configure supported OffLoads
1279 hdd_conf_hostoffload(pAdapter, TRUE);
1280 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301281 hddLog(VOS_TRACE_LEVEL_INFO,
1282 FL("saving configuredMcastBcastFilterSetting = %d"),
1283 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001284#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301285 /* During suspend, configure MC Addr list filter to the firmware
1286 * function takes care of checking necessary conditions before
1287 * configuring.
1288 */
1289 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001290#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001291
1292 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1293 {
1294
1295 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1296 pHddCtx->configuredMcastBcastFilter &=
1297 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1298 }
1299
1300 wlanSuspendParam->configuredMcstBcstFilterSetting =
1301 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001302 }
1303
1304 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1305 if(eHAL_STATUS_SUCCESS == halStatus)
1306 {
1307 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001308 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301309 hddLog(VOS_TRACE_LEVEL_ERROR,
1310 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001311 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001312 }
1313}
1314
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301315static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001316{
Chilam Ngc4244af2013-04-01 15:37:32 -07001317 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001318 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001319 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001320
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301321 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 "%s: send wlan resume indication", __func__);
1323
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301324 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1325
1326 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301328 hddLog(VOS_TRACE_LEVEL_FATAL,
1329 "%s: memory allocation failed for wlanResumeParam ", __func__);
1330 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001331 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001332
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301333 //Disable supported OffLoads
1334 hdd_conf_hostoffload(pAdapter, FALSE);
1335
1336 wlanResumeParam->configuredMcstBcstFilterSetting =
1337 pHddCtx->configuredMcastBcastFilter;
1338 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1339 if (eHAL_STATUS_SUCCESS != halStatus)
1340 {
c_hpothuffdb5272013-10-02 16:42:35 +05301341 hddLog(VOS_TRACE_LEVEL_ERROR,
1342 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301343 vos_mem_free(wlanResumeParam);
1344 }
1345
1346 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1347
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001348 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1349 pHddCtx->configuredMcastBcastFilter =
1350 pHddCtx->sus_res_mcastbcast_filter;
1351 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1352 }
Amar Singhald53568e2013-09-26 11:03:45 -07001353
1354 hddLog(VOS_TRACE_LEVEL_INFO,
1355 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1356 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1357 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001358
Chilam Ngc4244af2013-04-01 15:37:32 -07001359
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301360#ifdef WLAN_FEATURE_PACKET_FILTERING
1361 /* Filer was applied during suspend inditication
1362 * clear it when we resume.
1363 */
1364 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001365#endif
1366}
Jeff Johnson295189b2012-06-20 16:38:30 -07001367
Jeff Johnson295189b2012-06-20 16:38:30 -07001368//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001369void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001370{
1371 hdd_context_t *pHddCtx = NULL;
1372 v_CONTEXT_t pVosContext = NULL;
1373
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301375 hdd_adapter_t *pAdapter = NULL;
1376 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301377 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001378
Jeff Johnson295189b2012-06-20 16:38:30 -07001379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1380
1381 //Get the global VOSS context.
1382 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1383 if(!pVosContext) {
1384 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1385 return;
1386 }
1387
1388 //Get the HDD context.
1389 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1390
1391 if(!pHddCtx) {
1392 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1393 return;
1394 }
1395
1396 if (pHddCtx->isLogpInProgress) {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1399 return;
1400 }
1401
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301402 if (pHddCtx->hdd_wlan_suspended)
1403 {
1404 hddLog(VOS_TRACE_LEVEL_ERROR,
1405 "%s: Ignore suspend wlan, Already suspended!", __func__);
1406 return;
1407 }
1408
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301409 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301410 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001411 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1412 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1413 {
1414 pAdapter = pAdapterNode->pAdapter;
1415 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001416 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001417 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1418
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001419 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1421 pAdapterNode = pNext;
1422 continue;
1423 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301424 /* Avoid multiple enter/exit BMPS in this while loop using
1425 * hdd_enter_bmps flag
1426 */
1427 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1428 {
1429 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001430
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301431 /* If device was already in BMPS, and dynamic DTIM is set,
1432 * exit(set the device to full power) and enter BMPS again
1433 * to reflect new DTIM value */
1434 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1435
1436 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1437
1438 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001440#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1441 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1442 {
1443 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301444 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001445 netif_tx_disable(pAdapter->dev);
1446 netif_carrier_off(pAdapter->dev);
1447 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301448 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1450 {
1451 //Execute deep sleep procedure
1452 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1453 }
1454#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301455
1456 /*Suspend notification sent down to driver*/
1457 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1458
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301459 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1460 pAdapterNode = pNext;
1461 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301462
Jeff Johnson295189b2012-06-20 16:38:30 -07001463#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1464 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1465 {
1466 hdd_enter_standby(pHddCtx);
1467 }
1468#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001469
1470 return;
1471}
1472
1473static void hdd_PowerStateChangedCB
1474(
1475 v_PVOID_t callbackContext,
1476 tPmcState newState
1477)
1478{
1479 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301480
Jeff Johnson295189b2012-06-20 16:38:30 -07001481 /* if the driver was not in BMPS during early suspend,
1482 * the dynamic DTIM is now updated at Riva */
1483 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1484 && pHddCtx->cfg_ini->enableDynamicDTIM
1485 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1486 {
1487 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1488 }
1489 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301490 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1491 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301493 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1494 {
Amar Singhald53568e2013-09-26 11:03:45 -07001495 pHddCtx->sus_res_mcastbcast_filter =
1496 pHddCtx->configuredMcastBcastFilter;
1497 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1498
1499 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1500 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1501 pHddCtx->configuredMcastBcastFilter);
1502 hddLog(VOS_TRACE_LEVEL_INFO,
1503 "offload: calling hdd_conf_mcastbcast_filter");
1504
1505 }
1506
Jeff Johnson295189b2012-06-20 16:38:30 -07001507 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301510 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001511 else
Mihir Shete793209f2014-01-06 11:01:12 +05301512 {
1513 /* Android framework can send resume request when the WCN chip is
1514 * in IMPS mode. When the chip exits IMPS mode the firmware will
1515 * restore all the registers to the state they were before the chip
1516 * entered IMPS and so our hardware filter settings confgured by the
1517 * resume request will be lost. So reconfigure the filters on detecting
1518 * a change in the power state of the WCN chip.
1519 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301520 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301521 if (IMPS != newState)
1522 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301523 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301524 if (FALSE == pHddCtx->hdd_wlan_suspended)
1525 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301526 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301527 hddLog(VOS_TRACE_LEVEL_INFO,
1528 "Not in IMPS/BMPS and suspended state");
1529 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1530 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301531 else
1532 {
1533 spin_unlock(&pHddCtx->filter_lock);
1534 }
Mihir Shete793209f2014-01-06 11:01:12 +05301535 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001537}
1538
Jeff Johnson295189b2012-06-20 16:38:30 -07001539void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1540{
1541 v_CONTEXT_t pVosContext;
1542 tHalHandle smeContext;
1543
1544 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1545 if (NULL == pVosContext)
1546 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001547 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 return;
1549 }
1550 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1551 if (NULL == smeContext)
1552 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001553 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001554 return;
1555 }
1556
1557 spin_lock_init(&pHddCtx->filter_lock);
1558 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1559 pHddCtx->cfg_ini->nEnableSuspend)
1560 {
1561 pmcRegisterDeviceStateUpdateInd(smeContext,
1562 hdd_PowerStateChangedCB, pHddCtx);
1563 }
1564}
1565
1566void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1567{
1568 v_CONTEXT_t pVosContext;
1569 tHalHandle smeContext;
1570
1571 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1572 if (NULL == pVosContext)
1573 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001574 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 return;
1576 }
1577 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1578 if (NULL == smeContext)
1579 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001580 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 return;
1582 }
1583
1584 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1585 pHddCtx->cfg_ini->nEnableSuspend)
1586 {
1587 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1588 }
1589}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301590
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301591#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301592void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301593{
1594 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301595 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301596 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1597
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301598 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301599 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301600 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1601 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1602 {
1603 vos_mem_copy(&hddGtkOffloadReqParams,
1604 &pHddStaCtx->gtkOffloadReqParams,
1605 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301606
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301607 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1608 &hddGtkOffloadReqParams, pAdapter->sessionId);
1609 if (eHAL_STATUS_SUCCESS != ret)
1610 {
1611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1612 "%s: sme_SetGTKOffload failed, returned %d",
1613 __func__, ret);
1614 return;
1615 }
1616
1617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1618 "%s: sme_SetGTKOffload successfull", __func__);
1619 }
1620
1621 }
1622 else
1623 {
1624 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1625 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1626 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1627 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1628 {
1629
1630 /* Host driver has previously offloaded GTK rekey */
1631 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301632 wlan_hdd_cfg80211_update_replayCounterCallback,
1633 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301634 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301635
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301636 {
1637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1638 "%s: sme_GetGTKOffload failed, returned %d",
1639 __func__, ret);
1640 return;
1641 }
1642 else
1643 {
1644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1645 "%s: sme_GetGTKOffload successful",
1646 __func__);
1647
1648 /* Sending GTK offload dissable */
1649 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1650 sizeof (tSirGtkOffloadParams));
1651 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1652 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301653 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301654 if (eHAL_STATUS_SUCCESS != ret)
1655 {
1656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: failed to dissable GTK offload, returned %d",
1658 __func__, ret);
1659 return;
1660 }
1661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1662 "%s: successfully dissabled GTK offload request to HAL",
1663 __func__);
1664 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301665 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301666 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301667 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301668}
1669#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001670
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001671void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001672{
1673 hdd_context_t *pHddCtx = NULL;
1674 hdd_adapter_t *pAdapter = NULL;
1675 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1676 VOS_STATUS status;
1677 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001678
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1680
1681 //Get the global VOSS context.
1682 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1683 if(!pVosContext) {
1684 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1685 return;
1686 }
1687
1688 //Get the HDD context.
1689 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1690
1691 if(!pHddCtx) {
1692 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1693 return;
1694 }
1695
Agarwal Ashish971c2882013-10-30 20:11:12 +05301696 if (pHddCtx->isLogpInProgress)
1697 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 hddLog(VOS_TRACE_LEVEL_INFO,
1699 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1700 return;
1701 }
1702
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301703 if (!pHddCtx->hdd_wlan_suspended)
1704 {
1705 hddLog(VOS_TRACE_LEVEL_ERROR,
1706 "%s: Ignore resume wlan, Already resumed!", __func__);
1707 return;
1708 }
1709
Jeff Johnson295189b2012-06-20 16:38:30 -07001710 pHddCtx->hdd_wlan_suspended = FALSE;
1711 /*loop through all adapters. Concurrency */
1712 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1713
1714 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1715 {
1716 pAdapter = pAdapterNode->pAdapter;
1717 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001718 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001719 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001720 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001721 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1722 pAdapterNode = pNext;
1723 continue;
1724 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301725
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301726
Jeff Johnson295189b2012-06-20 16:38:30 -07001727#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1728 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1729 {
1730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1731 hdd_exit_deep_sleep(pAdapter);
1732 }
1733#endif
1734
1735 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1736 {
1737 /*Switch back to DTIM 1*/
1738 tSirSetPowerParamsReq powerRequest = { 0 };
1739
1740 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1741 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001742 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001743
1744 /*Disabled ModulatedDTIM if enabled on suspend*/
1745 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1746 powerRequest.uDTIMPeriod = 0;
1747
1748 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1749 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1750 NULL, eANI_BOOLEAN_FALSE);
1751 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1752 NULL, eANI_BOOLEAN_FALSE);
1753
1754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001755 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001756 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001757
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301758 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1759 {
1760 /* put the device into full power */
1761 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001762
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301763 /* put the device back into BMPS */
1764 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001765
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301766 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1767 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 }
1769
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301770 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001771 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1772 pAdapterNode = pNext;
1773 }
1774
1775#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1776 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1777 {
1778 hdd_exit_standby(pHddCtx);
1779 }
1780#endif
1781
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 return;
1783}
1784
Jeff Johnson295189b2012-06-20 16:38:30 -07001785VOS_STATUS hdd_wlan_reset_initialization(void)
1786{
Jeff Johnson295189b2012-06-20 16:38:30 -07001787 v_CONTEXT_t pVosContext = NULL;
1788
1789 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1790
1791 //Get the global VOSS context.
1792 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1793 if(!pVosContext)
1794 {
1795 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1796 return VOS_STATUS_E_FAILURE;
1797 }
1798
1799 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1800
1801 // Prevent the phone from going to sleep
1802 hdd_prevent_suspend();
1803
Jeff Johnson295189b2012-06-20 16:38:30 -07001804 return VOS_STATUS_SUCCESS;
1805}
1806
1807
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001808/*
1809 * Based on the ioctl command recieved by HDD, put WLAN driver
1810 * into the quiet mode. This is the same as the early suspend
1811 * notification that driver used to listen
1812 */
1813void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001814{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301815 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001816 if (suspend)
1817 hdd_suspend_wlan();
1818 else
1819 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301820 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001821}
1822
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001823static void hdd_ssr_timer_init(void)
1824{
1825 init_timer(&ssr_timer);
1826}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001827
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001828static void hdd_ssr_timer_del(void)
1829{
1830 del_timer(&ssr_timer);
1831 ssr_timer_started = false;
1832}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001833
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001834static void hdd_ssr_timer_cb(unsigned long data)
1835{
1836 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001837
1838#ifdef WCN_PRONTO
1839 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1840 wcnss_pronto_log_debug_regs();
1841#endif
1842
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001843 VOS_BUG(0);
1844}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001845
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001846static void hdd_ssr_timer_start(int msec)
1847{
1848 if(ssr_timer_started)
1849 {
1850 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1851 ,__func__);
1852 }
1853 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1854 ssr_timer.function = hdd_ssr_timer_cb;
1855 add_timer(&ssr_timer);
1856 ssr_timer_started = true;
1857}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001858
Jeff Johnson295189b2012-06-20 16:38:30 -07001859/* the HDD interface to WLAN driver shutdown,
1860 * the primary shutdown function in SSR
1861 */
1862VOS_STATUS hdd_wlan_shutdown(void)
1863{
1864 VOS_STATUS vosStatus;
1865 v_CONTEXT_t pVosContext = NULL;
1866 hdd_context_t *pHddCtx = NULL;
1867 pVosSchedContext vosSchedContext = NULL;
1868
1869 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1870
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001871 /* if re-init never happens, then do SSR1 */
1872 hdd_ssr_timer_init();
1873 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1874
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 /* Get the global VOSS context. */
1876 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1877 if(!pVosContext) {
1878 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1879 return VOS_STATUS_E_FAILURE;
1880 }
1881 /* Get the HDD context. */
1882 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1883 if(!pHddCtx) {
1884 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1885 return VOS_STATUS_E_FAILURE;
1886 }
c_hpothud662a352013-12-26 15:09:12 +05301887
1888 //Stop the traffic monitor timer
1889 if ( VOS_TIMER_STATE_RUNNING ==
1890 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1891 {
1892 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1893 }
1894
Jeff Johnson295189b2012-06-20 16:38:30 -07001895 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 /* DeRegister with platform driver as client for Suspend/Resume */
1897 vosStatus = hddDeregisterPmOps(pHddCtx);
1898 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1899 {
1900 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1901 }
1902
1903 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1904 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1905 {
1906 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1907 }
1908
1909 /* Disable IMPS/BMPS as we do not want the device to enter any power
1910 * save mode on its own during reset sequence
1911 */
1912 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1913 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1914 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1915
1916 vosSchedContext = get_vos_sched_ctxt();
1917
1918 /* Wakeup all driver threads */
1919 if(TRUE == pHddCtx->isMcThreadSuspended){
1920 complete(&vosSchedContext->ResumeMcEvent);
1921 pHddCtx->isMcThreadSuspended= FALSE;
1922 }
1923 if(TRUE == pHddCtx->isTxThreadSuspended){
1924 complete(&vosSchedContext->ResumeTxEvent);
1925 pHddCtx->isTxThreadSuspended= FALSE;
1926 }
1927 if(TRUE == pHddCtx->isRxThreadSuspended){
1928 complete(&vosSchedContext->ResumeRxEvent);
1929 pHddCtx->isRxThreadSuspended= FALSE;
1930 }
1931 /* Reset the Suspend Variable */
1932 pHddCtx->isWlanSuspended = FALSE;
1933
1934 /* Stop all the threads; we do not want any messages to be a processed,
1935 * any more and the best way to ensure that is to terminate the threads
1936 * gracefully.
1937 */
1938 /* Wait for MC to exit */
1939 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1940 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1941 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1942 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301943 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001944
1945 /* Wait for TX to exit */
1946 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1947 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1948 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1949 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301950 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001951
1952 /* Wait for RX to exit */
1953 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1954 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1955 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1956 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301957
Mihir Sheteb5425f72013-12-19 09:06:13 +05301958 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001959
1960#ifdef WLAN_BTAMP_FEATURE
1961 vosStatus = WLANBAP_Stop(pVosContext);
1962 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1963 {
1964 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1965 "%s: Failed to stop BAP",__func__);
1966 }
1967#endif //WLAN_BTAMP_FEATURE
1968 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301969 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1970 {
1971 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1972 "%s: Failed to stop wda %d", __func__, vosStatus);
1973 VOS_ASSERT(0);
1974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001975
1976 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1977 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1978 * on threads being running to process the SYS Stop
1979 */
Kiet Lama72a2322013-11-15 11:18:11 +05301980 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301981 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1982 {
1983 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1984 "%s: Failed to stop sme %d", __func__, vosStatus);
1985 VOS_ASSERT(0);
1986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001987
1988 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
1989 /* Stop MAC (PE and HAL) */
1990 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05301991 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1992 {
1993 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1994 "%s: Failed to stop mac %d", __func__, vosStatus);
1995 VOS_ASSERT(0);
1996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001997
1998 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
1999 /* Stop TL */
2000 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302001 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2002 {
2003 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2004 "%s: Failed to stop TL %d", __func__, vosStatus);
2005 VOS_ASSERT(0);
2006 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002007
Jeff Johnson295189b2012-06-20 16:38:30 -07002008 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2010 /* Clean up message queues of TX and MC thread */
2011 vos_sched_flush_mc_mqs(vosSchedContext);
2012 vos_sched_flush_tx_mqs(vosSchedContext);
2013 vos_sched_flush_rx_mqs(vosSchedContext);
2014
2015 /* Deinit all the TX and MC queues */
2016 vos_sched_deinit_mqs(vosSchedContext);
2017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2018
2019 /* shutdown VOSS */
2020 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302021
2022 /*mac context has already been released in mac_close call
2023 so setting it to NULL in hdd context*/
2024 pHddCtx->hHal = (tHalHandle)NULL;
2025
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 if (free_riva_power_on_lock("wlan"))
2027 {
2028 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2029 __func__);
2030 }
2031 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2032 ,__func__);
2033 return VOS_STATUS_SUCCESS;
2034}
2035
2036
2037
2038/* the HDD interface to WLAN driver re-init.
2039 * This is called to initialize/start WLAN driver after a shutdown.
2040 */
2041VOS_STATUS hdd_wlan_re_init(void)
2042{
2043 VOS_STATUS vosStatus;
2044 v_CONTEXT_t pVosContext = NULL;
2045 hdd_context_t *pHddCtx = NULL;
2046 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002047#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2048 int max_retries = 0;
2049#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302050#ifdef HAVE_CBC_DONE
2051 int max_cbc_retries = 0;
2052#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002053#ifdef WLAN_BTAMP_FEATURE
2054 hdd_config_t *pConfig = NULL;
2055 WLANBAP_ConfigType btAmpConfig;
2056#endif
2057
Katya Nigam82a93062014-06-04 15:15:36 +05302058 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002059 hdd_ssr_timer_del();
Jeff Johnson295189b2012-06-20 16:38:30 -07002060 hdd_prevent_suspend();
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002061
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002062#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2063 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002064 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002065 msleep(1000);
2066 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002067 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002068 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2069 goto err_re_init;
2070 }
2071#endif
2072
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302073#ifdef HAVE_CBC_DONE
2074 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2075 msleep(1000);
2076 }
2077 if (max_cbc_retries >= 20) {
2078 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2079 }
2080#endif
2081
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002082 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2083
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002084 /* The driver should always be initialized in STA mode after SSR */
2085 hdd_set_conparam(0);
2086
Katya Nigam82a93062014-06-04 15:15:36 +05302087 dev = wcnss_wlan_get_device();
2088 if (NULL == dev)
2089 {
2090 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2091 goto err_re_init;
2092 }
2093
Jeff Johnson295189b2012-06-20 16:38:30 -07002094 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302095 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002096 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2097 {
2098 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2099 goto err_re_init;
2100 }
2101
2102 /* Get the HDD context. */
2103 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2104 if(!pHddCtx)
2105 {
2106 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2107 goto err_vosclose;
2108 }
2109
2110 /* Save the hal context in Adapter */
2111 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2112 if ( NULL == pHddCtx->hHal )
2113 {
2114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2115 goto err_vosclose;
2116 }
2117
2118 /* Set the SME configuration parameters. */
2119 vosStatus = hdd_set_sme_config(pHddCtx);
2120 if ( VOS_STATUS_SUCCESS != vosStatus )
2121 {
2122 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2123 goto err_vosclose;
2124 }
2125
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 vosStatus = vos_preStart( pHddCtx->pvosContext );
2127 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2128 {
2129 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2130 goto err_vosclose;
2131 }
2132
2133 /* In the integrated architecture we update the configuration from
2134 the INI file and from NV before vOSS has been started so that
2135 the final contents are available to send down to the cCPU */
2136 /* Apply the cfg.ini to cfg.dat */
2137 if (FALSE == hdd_update_config_dat(pHddCtx))
2138 {
2139 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2140 goto err_vosclose;
2141 }
2142
2143 /* Set the MAC Address, currently this is used by HAL to add self sta.
2144 * Remove this once self sta is added as part of session open. */
2145 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2146 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2147 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2148 if (!HAL_STATUS_SUCCESS(halStatus))
2149 {
2150 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2151 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2152 goto err_vosclose;
2153 }
2154
2155 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2156 Note: Firmware image will be read and downloaded inside vos_start API */
2157 vosStatus = vos_start( pVosContext );
2158 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2159 {
2160 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2161 goto err_vosclose;
2162 }
2163
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002164 /* Exchange capability info between Host and FW and also get versioning info from FW */
2165 hdd_exchange_version_and_caps(pHddCtx);
2166
Jeff Johnson295189b2012-06-20 16:38:30 -07002167 vosStatus = hdd_post_voss_start_config( pHddCtx );
2168 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2169 {
2170 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2171 __func__);
2172 goto err_vosstop;
2173 }
2174
Mihir Shete04206452014-11-20 17:50:58 +05302175#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302176 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2177 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2178 {
2179 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2180 __func__);
2181 goto err_vosstop;
2182 }
Mihir Shete04206452014-11-20 17:50:58 +05302183#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302184
Jeff Johnson295189b2012-06-20 16:38:30 -07002185#ifdef WLAN_BTAMP_FEATURE
2186 vosStatus = WLANBAP_Open(pVosContext);
2187 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2188 {
2189 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2190 "%s: Failed to open BAP",__func__);
2191 goto err_vosstop;
2192 }
2193 vosStatus = BSL_Init(pVosContext);
2194 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2195 {
2196 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2197 "%s: Failed to Init BSL",__func__);
2198 goto err_bap_close;
2199 }
2200 vosStatus = WLANBAP_Start(pVosContext);
2201 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2202 {
2203 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2204 "%s: Failed to start TL",__func__);
2205 goto err_bap_close;
2206 }
2207 pConfig = pHddCtx->cfg_ini;
2208 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2209 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2210#endif //WLAN_BTAMP_FEATURE
2211
2212 /* Restart all adapters */
2213 hdd_start_all_adapters(pHddCtx);
2214 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002215 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302217 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302219 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 /* Register with platform driver as client for Suspend/Resume */
2221 vosStatus = hddRegisterPmOps(pHddCtx);
2222 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2223 {
2224 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2225 goto err_bap_stop;
2226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 /* Allow the phone to go to sleep */
2228 hdd_allow_suspend();
2229 /* register for riva power on lock */
2230 if (req_riva_power_on_lock("wlan"))
2231 {
2232 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2233 __func__);
2234 goto err_unregister_pmops;
2235 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002236 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302237#ifdef WLAN_FEATURE_EXTSCAN
2238 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2239 wlan_hdd_cfg80211_extscan_callback,
2240 pHddCtx);
2241#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07002242 goto success;
2243
2244err_unregister_pmops:
2245 hddDeregisterPmOps(pHddCtx);
2246
2247err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002248#ifdef CONFIG_HAS_EARLYSUSPEND
2249 hdd_unregister_mcast_bcast_filter(pHddCtx);
2250#endif
2251 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002253 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002254#endif
2255
2256#ifdef WLAN_BTAMP_FEATURE
2257err_bap_close:
2258 WLANBAP_Close(pVosContext);
2259#endif
2260
2261err_vosstop:
2262 vos_stop(pVosContext);
2263
2264err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302265 if(!isSsrPanicOnFailure())
2266 {
2267 /* If we hit this, it means wlan driver is in bad state and needs
2268 * driver unload and load.
2269 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302270 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2271 return VOS_STATUS_E_FAILURE;
2272 }
2273
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 vos_close(pVosContext);
2275 vos_sched_close(pVosContext);
2276 if (pHddCtx)
2277 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002278 /* Unregister the Net Device Notifier */
2279 unregister_netdevice_notifier(&hdd_netdev_notifier);
2280 /* Clean up HDD Nlink Service */
2281 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002282#ifdef WLAN_KD_READY_NOTIFIER
2283 nl_srv_exit(pHddCtx->ptt_pid);
2284#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002285 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002286#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002287 /* Free up dynamically allocated members inside HDD Adapter */
2288 kfree(pHddCtx->cfg_ini);
2289 pHddCtx->cfg_ini= NULL;
2290
Jeff Johnson295189b2012-06-20 16:38:30 -07002291 wiphy_unregister(pHddCtx->wiphy);
2292 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002293 }
2294 vos_preClose(&pVosContext);
2295
2296#ifdef MEMORY_DEBUG
2297 vos_mem_exit();
2298#endif
2299
2300err_re_init:
2301 /* Allow the phone to go to sleep */
2302 hdd_allow_suspend();
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002303 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002304 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002305 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002306
2307success:
2308 /* Trigger replay of BTC events */
2309 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2310 return VOS_STATUS_SUCCESS;
2311}