blob: 524d193ac9acc3c9539c0f5d57ab58eaf0f1b23e [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"
Siddharth Bhal7bd19932015-03-03 16:54:36 +053066#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067
68#ifdef WLAN_BTAMP_FEATURE
69#include "bapApi.h"
70#include "bap_hdd_main.h"
71#include "bap_hdd_misc.h"
72#endif
73
Jeff Johnsone7245742012-09-05 17:12:55 -070074#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070075#include <linux/inetdevice.h>
76#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053077#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053078#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070079/**-----------------------------------------------------------------------------
80* Preprocessor definitions and constants
81* ----------------------------------------------------------------------------*/
82
83/**-----------------------------------------------------------------------------
84* Type declarations
85* ----------------------------------------------------------------------------*/
86
87/**-----------------------------------------------------------------------------
88* Function and variables declarations
89* ----------------------------------------------------------------------------*/
90#include "wlan_hdd_power.h"
91#include "wlan_hdd_packet_filtering.h"
92
Sameer Thalappile5637f42013-08-07 15:46:55 -070093#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053094#define NS_DEFAULT_SLOT_INDEX 4
95#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070096
97static eHalStatus g_full_pwr_status;
98static eHalStatus g_standby_status;
99
100extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700104extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700106static struct timer_list ssr_timer;
107static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109//Callback invoked by PMC to report status of standby request
110void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
111{
112 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
114 g_standby_status = status;
115
116 if(eHAL_STATUS_SUCCESS == status)
117 {
118 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
119 }
120 else
121 {
122 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
123 }
124
125 complete(&pHddCtx->standby_comp_var);
126}
127
128//Callback invoked by PMC to report status of full power request
129void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
130{
131 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
133 g_full_pwr_status = status;
134
135 if(eHAL_STATUS_SUCCESS == status)
136 {
137 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
138 }
139 else
140 {
141 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
142 }
143
144 complete(&pHddCtx->full_pwr_comp_var);
145}
146
147eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
148{
149 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530150 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700151
152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
153 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
154
155 g_full_pwr_status = eHAL_STATUS_FAILURE;
156 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
157 eSME_FULL_PWR_NEEDED_BY_HDD);
158
159 if(status == eHAL_STATUS_PMC_PENDING)
160 {
161 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530162 ret = wait_for_completion_interruptible_timeout(
163 &pHddCtx->full_pwr_comp_var,
164 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
165 if (0 >= ret)
166 {
167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
168 __func__, ret);
169 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700170 status = g_full_pwr_status;
171 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
172 {
173 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
174 VOS_ASSERT(0);
175 goto failure;
176 }
177 }
178 else if(status != eHAL_STATUS_SUCCESS)
179 {
180 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
181 __func__, status);
182 VOS_ASSERT(0);
183 goto failure;
184 }
185 else
186 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
187
188failure:
189 //No blocking to reduce latency. No other device should be depending on WLAN
190 //to finish resume and WLAN won't be instantly on after resume
191 return status;
192}
193
194
195//Helper routine to put the chip into standby
196VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
197{
198 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
199 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530200 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202 //Disable IMPS/BMPS as we do not want the device to enter any power
203 //save mode on its own during suspend sequence
204 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
205 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
206
207 //Note we do not disable queues unnecessarily. Queues should already be disabled
208 //if STA is disconnected or the queue will be disabled as and when disconnect
209 //happens because of standby procedure.
210
211 //Ensure that device is in full power first. There is scope for optimization
212 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
213 //Core s/w needs to be optimized to handle this. Until then we request full
214 //power before issuing request for standby.
215 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
216 g_full_pwr_status = eHAL_STATUS_FAILURE;
217 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
218 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
219
220 if(halStatus == eHAL_STATUS_PMC_PENDING)
221 {
222 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530223 ret = wait_for_completion_interruptible_timeout(
224 &pHddCtx->full_pwr_comp_var,
225 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
226 if (0 >= ret)
227 {
228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
229 __func__, ret);
230 }
231
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
233 {
234 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
235 VOS_ASSERT(0);
236 vosStatus = VOS_STATUS_E_FAILURE;
237 goto failure;
238 }
239 }
240 else if(halStatus != eHAL_STATUS_SUCCESS)
241 {
242 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
243 __func__, halStatus);
244 VOS_ASSERT(0);
245 vosStatus = VOS_STATUS_E_FAILURE;
246 goto failure;
247 }
248
249 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
250 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
251 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
252 }
253
254 //Request standby. Standby will cause the STA to disassociate first. TX queues
255 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
256 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
257 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
258 //when there are concurrent sessions.
259 INIT_COMPLETION(pHddCtx->standby_comp_var);
260 g_standby_status = eHAL_STATUS_FAILURE;
261 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
262
263 if (halStatus == eHAL_STATUS_PMC_PENDING)
264 {
265 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530266 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530268 if (0 >= ret)
269 {
270 hddLog(VOS_TRACE_LEVEL_ERROR,
271 FL("wait on standby_comp_var failed %ld"), ret);
272 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
274 {
275 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
276 VOS_ASSERT(0);
277 vosStatus = VOS_STATUS_E_FAILURE;
278 goto failure;
279 }
280 }
281 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
283 __func__, halStatus);
284 VOS_ASSERT(0);
285 vosStatus = VOS_STATUS_E_FAILURE;
286 goto failure;
287 }
288 else
289 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
290
291failure:
292 //Restore IMPS config
293 if(pHddCtx->cfg_ini->fIsImpsEnabled)
294 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
295
296 //Restore BMPS config
297 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
298 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
299
300 return vosStatus;
301}
302
303
304//Helper routine for Deep sleep entry
305VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
306{
307 eHalStatus halStatus;
308 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530309 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800310
Jeff Johnson295189b2012-06-20 16:38:30 -0700311 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530312 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700313 netif_tx_disable(pAdapter->dev);
314 netif_carrier_off(pAdapter->dev);
315
316 //Disable IMPS,BMPS as we do not want the device to enter any power
317 //save mode on it own during suspend sequence
318 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
319 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
320
321 //Ensure that device is in full power as we will touch H/W during vos_Stop
322 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
323 g_full_pwr_status = eHAL_STATUS_FAILURE;
324 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
325 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
326
327 if(halStatus == eHAL_STATUS_PMC_PENDING)
328 {
329 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530330 ret = wait_for_completion_interruptible_timeout(
331 &pHddCtx->full_pwr_comp_var,
332 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
333 if (0 >= ret)
334 {
335 hddLog(VOS_TRACE_LEVEL_ERROR,
336 FL("wait on full_pwr_comp_var failed %ld"), ret);
337 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
339 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
340 VOS_ASSERT(0);
341 }
342 }
343 else if(halStatus != eHAL_STATUS_SUCCESS)
344 {
345 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
346 VOS_ASSERT(0);
347 }
348
349 //Issue a disconnect. This is required to inform the supplicant that
350 //STA is getting disassociated and for GUI to be updated properly
351 INIT_COMPLETION(pAdapter->disconnect_comp_var);
352 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
353
354 //Success implies disconnect command got queued up successfully
355 if(halStatus == eHAL_STATUS_SUCCESS)
356 {
357 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530358 ret = wait_for_completion_interruptible_timeout(
359 &pAdapter->disconnect_comp_var,
360 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
361 if (0 >= ret)
362 {
363 hddLog(VOS_TRACE_LEVEL_ERROR,
364 FL("wait on disconnect_comp_var failed %ld"), ret);
365 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700366 }
367
368
369 //None of the steps should fail after this. Continue even in case of failure
370 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530371 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
372 {
373 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
374 __func__, vosStatus);
375 VOS_ASSERT(0);
376 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700377
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
379
380 //Restore IMPS config
381 if(pHddCtx->cfg_ini->fIsImpsEnabled)
382 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
383
384 //Restore BMPS config
385 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
386 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
387
Jeff Johnson295189b2012-06-20 16:38:30 -0700388 return vosStatus;
389}
390
391VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
392{
393 VOS_STATUS vosStatus;
394 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700395
Jeff Johnson295189b2012-06-20 16:38:30 -0700396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
397 "%s: calling hdd_set_sme_config",__func__);
398 vosStatus = hdd_set_sme_config( pHddCtx );
399 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
400 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
401 {
402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
403 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700404 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700405 }
406
407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
408 "%s: calling vos_start",__func__);
409 vosStatus = vos_start( pHddCtx->pvosContext );
410 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
411 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
412 {
413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
414 "%s: Failed in vos_start",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700415 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700416 }
417
418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
419 "%s: calling hdd_post_voss_start_config",__func__);
420 vosStatus = hdd_post_voss_start_config( pHddCtx );
421 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
422 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
423 {
424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
425 "%s: Failed in hdd_post_voss_start_config",__func__);
426 goto err_voss_stop;
427 }
428
429
430 //Open a SME session for future operation
431 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700432 (tANI_U8 *)&pAdapter->macAddressCurrent,
433 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700434 if ( !HAL_STATUS_SUCCESS( halStatus ) )
435 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700436 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700437 halStatus, halStatus );
438 goto err_voss_stop;
439
440 }
441
442 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
443
444 //Trigger the initial scan
445 hdd_wlan_initial_scan(pHddCtx);
446
447 return VOS_STATUS_SUCCESS;
448
449err_voss_stop:
450 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700451err_deep_sleep:
452 return VOS_STATUS_E_FAILURE;
453
454}
455
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530456void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
Atul Mittal37385d72014-03-27 18:15:03 +0530457{
458 hdd_adapter_t* pAdapter =
459 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
460 hdd_context_t *pHddCtx;
461 int status;
462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530463 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530464 if (NULL == pAdapter)
465 {
466 hddLog(LOGE, FL("Adapter is invalid"));
467 return;
468 }
Atul Mittal37385d72014-03-27 18:15:03 +0530469
470 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
471 status = wlan_hdd_validate_context(pHddCtx);
472 if (0 != status)
473 {
Atul Mittal37385d72014-03-27 18:15:03 +0530474 return;
475 }
476
477 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
478 {
479 pHddCtx->sus_res_mcastbcast_filter =
480 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530481 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
482 pHddCtx->sus_res_mcastbcast_filter);
Atul Mittal37385d72014-03-27 18:15:03 +0530483 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
484 }
485
486 if ((eConnectionState_Associated ==
487 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
488 && (pHddCtx->hdd_wlan_suspended))
489 {
490 // This invocation being part of the IPv6 registration callback,
491 // set the newly generated ip address to f/w in suspend mode.
492#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530493 if (pHddCtx->cfg_ini->fhostNSOffload)
494 {
495 hdd_conf_ns_offload(pAdapter, 1);
496 }
Atul Mittal37385d72014-03-27 18:15:03 +0530497#endif
498 }
499#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530500 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530501 * only so when new ipv6 address is generated the screen may not
502 * on so we need to call it here to update the list in f/w.
503 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530504 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530505#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530506 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530507}
508
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530509void hdd_ipv6_notifier_work_queue(struct work_struct *work)
510{
511 vos_ssr_protect(__func__);
512 __hdd_ipv6_notifier_work_queue(work);
513 vos_ssr_unprotect(__func__);
514}
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530515int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530516 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530517{
518 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
519 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530520 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530521 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530522 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530523 int status;
524
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530525 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530526 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
527 status = wlan_hdd_validate_context(pHddCtx);
528 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530529 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530530 return NOTIFY_DONE;
531 }
Atul Mittal37385d72014-03-27 18:15:03 +0530532
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530533 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
534 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
535 {
536 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
537 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
538 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
539 {
540 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530541 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530542 {
543 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
544 }
545 else
546 {
547 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
548 pHddCtx->cfg_ini->nEnableSuspend);
549 }
550 break;
551 }
552 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
553 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530554 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530555 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530556 return NOTIFY_DONE;
557}
558
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530559int wlan_hdd_ipv6_changed(struct notifier_block *nb,
560 unsigned long data, void *arg)
561{
562 int ret;
563 vos_ssr_protect(__func__);
564 ret = __wlan_hdd_ipv6_changed( nb, data, arg);
565 vos_ssr_unprotect(__func__);
566 return ret;
567}
568
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530569/*
570 * Function: hdd_conf_hostoffload
571 * Central function to configure the supported offloads,
572 * either enable or disable them.
573 */
574void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
575{
576 hdd_context_t *pHddCtx = NULL;
577 v_CONTEXT_t *pVosContext = NULL;
578 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
579
580 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
581 fenable);
582
583 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
584
585 if (NULL == pVosContext)
586 {
587 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
588 return;
589 }
590
591 //Get the HDD context.
592 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
593
594 if (NULL == pHddCtx)
595 {
596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
597 return;
598 }
599
600 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
601 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
602 {
603 if (fenable)
604 {
605 if (eConnectionState_Associated ==
606 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
607 {
608 if ((pHddCtx->cfg_ini->fhostArpOffload))
609 {
610 /*
611 * Configure the ARP Offload.
612 * Even if it fails we have to reconfigure the MC/BC
613 * filter flag as we want RIVA not to drop BroadCast
614 * Packets
615 */
616 hddLog(VOS_TRACE_LEVEL_INFO,
617 FL("Calling ARP Offload with flag: %d"), fenable);
618 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
619 pHddCtx->configuredMcastBcastFilter &=
620 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
621
622 if (!VOS_IS_STATUS_SUCCESS(vstatus))
623 {
624 hddLog(VOS_TRACE_LEVEL_ERROR,
625 "Failed to enable ARPOFfloadFeature %d",
626 vstatus);
627 }
628 }
629 //Configure GTK_OFFLOAD
630#ifdef WLAN_FEATURE_GTK_OFFLOAD
631 hdd_conf_gtk_offload(pAdapter, fenable);
632#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530633
634#ifdef WLAN_NS_OFFLOAD
635 if (pHddCtx->cfg_ini->fhostNSOffload)
636 {
637 /*
638 * Configure the NS Offload.
639 * Even if it fails we have to reconfigure the MC/BC filter flag
640 * as we want RIVA not to drop Multicast Packets
641 */
642
643 hddLog(VOS_TRACE_LEVEL_INFO,
644 FL("Calling NS Offload with flag: %d"), fenable);
645 hdd_conf_ns_offload(pAdapter, fenable);
646 pHddCtx->configuredMcastBcastFilter &=
647 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
648 }
649#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530650
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530651 }
652 }
653 else
654 {
655 //Disable ARPOFFLOAD
656 if (pHddCtx->cfg_ini->fhostArpOffload)
657 {
658 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
659 if (!VOS_IS_STATUS_SUCCESS(vstatus))
660 {
661 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530662 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530663 }
664 }
665 //Disable GTK_OFFLOAD
666#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530667 hdd_conf_gtk_offload(pAdapter, fenable);
668#endif
669
670#ifdef WLAN_NS_OFFLOAD
671 //Disable NSOFFLOAD
672 if (pHddCtx->cfg_ini->fhostNSOffload)
673 {
674 hdd_conf_ns_offload(pAdapter, fenable);
675 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530676#endif
677 }
678 }
679 return;
680}
681
Atul Mittal37385d72014-03-27 18:15:03 +0530682
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530683#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530684/**----------------------------------------------------------------------------
685
686 \brief hdd_conf_ns_offload() - Configure NS offload
687
688 Called during SUSPEND to configure the NS offload (MC BC filter) which
689 reduces power consumption.
690
691 \param - pAdapter - Adapter context for which NS offload is to be configured
692 \param - fenable - 0 - disable.
693 1 - enable. (with IPv6 notifier registration)
694 2 - enable. (without IPv6 notifier registration)
695
696 \return - void
697
698 ---------------------------------------------------------------------------*/
699void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530700{
701 struct inet6_dev *in6_dev;
702 struct inet6_ifaddr *ifp;
703 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530704 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530705 tANI_U8 **selfIPv6Addr = NULL;
706 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530707 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530708 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530709 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530710
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530711 int i = 0, slot = 0;
712 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530713 eHalStatus returnStatus;
714
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530715 ENTER();
716 hddLog(LOG1, FL(" fenable = %d"), fenable);
717
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530718 if (NULL == pAdapter)
719 {
720 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
721 return;
722 }
723
724 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530725 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
726
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530727 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530728 if (0 != ret)
729 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530730 return;
731 }
732
733 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
734 {
735 slot_index = NS_EXTENDED_SLOT_INDEX;
736 }
737
738 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
739
740 selfIPv6AddrValid =
741 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
742
743 if (NULL == selfIPv6AddrValid)
744 {
745 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
746 " selfIPv6AddrValid"));
747 goto end;
748 }
749
750 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
751
752 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
753
754 if (NULL == selfIPv6Addr)
755 {
756 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
757 " selfIPv6Addr"));
758 goto end;
759 }
760
761 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
762
763 for (slot = 0; slot < slot_index; slot++)
764 {
765 selfIPv6Addr[slot] =
766 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
767 if (NULL == selfIPv6Addr[slot])
768 {
769 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
770 "for selfIPv6Addr"));
771 goto end;
772 }
773 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
774 }
775
776 i = 0;
777
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530778 if (fenable)
779 {
780 in6_dev = __in6_dev_get(pAdapter->dev);
781 if (NULL != in6_dev)
782 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530783 list_for_each(p, &in6_dev->addr_list)
784 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530785 if (i >= slot_index)
786 {
787 hddLog (VOS_TRACE_LEVEL_ERROR,
788 FL("IPv6 address list is greater than IPv6"
789 "address supported by firmware"));
790 hddLog (VOS_TRACE_LEVEL_ERROR,
791 FL("FW supported IPv6 address = %d"), slot_index);
792 break;
793 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530794 ifp = list_entry(p, struct inet6_ifaddr, if_list);
795 switch(ipv6_addr_src_scope(&ifp->addr))
796 {
797 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530798 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530799 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530800 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530801 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530802 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
803 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530804 break;
805 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530806 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530807 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530808 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530809 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530810 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
811 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530812 break;
813 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530814 hddLog(VOS_TRACE_LEVEL_ERROR,
815 FL("The Scope %d is not supported"),
816 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530817 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530818 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
819 {
820 i++;
821 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530822 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530823
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530824 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530825 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530826 {
827 if (selfIPv6AddrValid[i])
828 {
829 //Filling up the request structure
830 /* Filling the selfIPv6Addr with solicited address
831 * A Solicited-Node multicast address is created by
832 * taking the last 24 bits of a unicast or anycast
833 * address and appending them to the prefix
834 *
835 * FF02:0000:0000:0000:0000:0001:FFXX:XX
836 *
837 * here XX is the unicast/anycast bits
838 */
839 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
840 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
841 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
842 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530843 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
844 selfIPv6Addr[i][13];
845 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
846 selfIPv6Addr[i][14];
847 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
848 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530849 offLoadRequest.nsOffloadInfo.slotIdx = i;
850
851 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530852 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530853 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
854 &pAdapter->macAddressCurrent.bytes,
855 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
856
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530857 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
858 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530859 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
860 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
861
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530862 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530863 FL("configuredMcastBcastFilter: %d"
864 "NSOffload Slot = %d"),
865 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530866
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530867 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700868 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
869 pHddCtx->sus_res_mcastbcast_filter) ||
870 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
871 pHddCtx->sus_res_mcastbcast_filter)) &&
872 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
873 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
874 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530875 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530876 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700877 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530878 hddLog (VOS_TRACE_LEVEL_INFO,
879 FL("Set offLoadRequest with %d"),
880 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530881 }
882
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530883 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
884 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
885 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
886
887 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530888 FL("Setting NSOffload with solicitedIp: %pI6,"
889 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530890 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
891 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
892
893 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530894 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530895 pAdapter->sessionId, &offLoadRequest);
896 if(eHAL_STATUS_SUCCESS != returnStatus)
897 {
898 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530899 FL("Failed to enable HostOffload feature with"
900 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530901 }
902 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
903 }
904 }
905 }
906 else
907 {
908 hddLog(VOS_TRACE_LEVEL_ERROR,
909 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530910 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530911 }
912 }
913 else
914 {
915 //Disable NSOffload
916 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
917 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
918 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
919
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530920 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530921 {
c_hpothu86feba52014-10-28 15:51:18 +0530922 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530923 offLoadRequest.nsOffloadInfo.slotIdx = i;
924 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530925 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
926 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530927 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
929 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530930 }
931 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530932 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530933end:
934 while (slot > 0 && selfIPv6Addr[--slot])
935 {
936 vos_mem_free(selfIPv6Addr[slot]);
937 }
938 if (selfIPv6Addr)
939 {
940 vos_mem_free(selfIPv6Addr);
941 }
942 if (selfIPv6AddrValid)
943 {
944 vos_mem_free(selfIPv6AddrValid);
945 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530946 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530947 return;
948}
949#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530950
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530951void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530952{
953 hdd_adapter_t* pAdapter =
954 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
955 hdd_context_t *pHddCtx;
956 int status;
957
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530958 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530959 if (NULL == pAdapter)
960 {
961 hddLog(LOGE, FL("Adapter is invalid"));
962 return;
963 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530964 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
965 status = wlan_hdd_validate_context(pHddCtx);
966 if (0 != status)
967 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530968 return;
969 }
970
Deepthi Gowri5933f402014-01-23 17:48:24 +0530971 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
972 {
973 pHddCtx->sus_res_mcastbcast_filter =
974 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530975 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
976 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530977 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
978 }
979
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530980 if ((eConnectionState_Associated ==
981 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530982 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530983 {
984 // This invocation being part of the IPv4 registration callback,
985 // we are passing second parameter as 2 to avoid registration
986 // of IPv4 notifier again.
987 hdd_conf_arp_offload(pAdapter, 2);
988 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530989 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530990}
991
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530992void hdd_ipv4_notifier_work_queue(struct work_struct *work)
993{
994 vos_ssr_protect(__func__);
995 __hdd_ipv4_notifier_work_queue(work);
996 vos_ssr_unprotect(__func__);
997}
998
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530999int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301000 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301001{
1002 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1003 struct in_ifaddr **ifap = NULL;
1004 struct in_device *in_dev;
1005
1006 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301007 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301008 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301009 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301010 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301011
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301012 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301013 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1014 status = wlan_hdd_validate_context(pHddCtx);
1015 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301016 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301017 return NOTIFY_DONE;
1018 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301019
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301020 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1021 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1022 {
1023 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1024 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1025 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1026 {
1027 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301028 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301029 || (!pHddCtx->cfg_ini->fhostArpOffload))
1030 {
1031 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1032 pHddCtx->cfg_ini->nEnableSuspend,
1033 pHddCtx->cfg_ini->fhostArpOffload);
1034 return NOTIFY_DONE;
1035 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301036
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301037 if ((in_dev =
1038 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1039 {
1040 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1041 ifap = &ifa->ifa_next)
1042 {
1043 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1044 ifa->ifa_label))
1045 {
1046 break; /* found */
1047 }
1048 }
1049 }
1050 if(ifa && ifa->ifa_local)
1051 {
1052 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1053 }
1054 break;
1055 }
1056 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1057 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301058 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301059 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301060 return NOTIFY_DONE;
1061}
1062
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301063int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1064 unsigned long data, void *arg)
1065{
1066 int ret;
1067 vos_ssr_protect(__func__);
1068 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1069 vos_ssr_unprotect(__func__);
1070 return ret;
1071}
1072
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301073/**----------------------------------------------------------------------------
1074
1075 \brief hdd_conf_arp_offload() - Configure ARP offload
1076
1077 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1078 reduces power consumption.
1079
1080 \param - pAdapter -Adapter context for which ARP offload is to be configured
1081 \param - fenable - 0 - disable.
1082 1 - enable. (with IPv4 notifier registration)
1083 2 - enable. (without IPv4 notifier registration)
1084
1085 \return -
1086 VOS_STATUS_SUCCESS - on successful operation
1087 VOS_STATUS_E_FAILURE - on failure of operation
1088-----------------------------------------------------------------------------*/
1089VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001090{
1091 struct in_ifaddr **ifap = NULL;
1092 struct in_ifaddr *ifa = NULL;
1093 struct in_device *in_dev;
1094 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001095 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001096 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001097
c_hpothu86feba52014-10-28 15:51:18 +05301098 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d \n"), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001099
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 if(fenable)
1101 {
1102 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1103 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301104 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 ifap = &ifa->ifa_next)
1106 {
1107 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1108 {
1109 break; /* found */
1110 }
1111 }
1112 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001113 if(ifa && ifa->ifa_local)
1114 {
1115 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1116 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1117
Arif Hussain6d2a3322013-11-17 19:50:10 -08001118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001119
Amar Singhald53568e2013-09-26 11:03:45 -07001120 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1121 pHddCtx->sus_res_mcastbcast_filter) ||
1122 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1123 pHddCtx->sus_res_mcastbcast_filter)) &&
1124 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001125 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301126 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001127 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1128 hddLog(VOS_TRACE_LEVEL_INFO,
1129 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001130 }
Amar Singhald53568e2013-09-26 11:03:45 -07001131
1132 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1133 offLoadRequest.enableOrDisable);
1134
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 //converting u32 to IPV4 address
1136 for(i = 0 ; i < 4; i++)
1137 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301138 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001139 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1140 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301141 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 offLoadRequest.params.hostIpv4Addr[0],
1143 offLoadRequest.params.hostIpv4Addr[1],
1144 offLoadRequest.params.hostIpv4Addr[2],
1145 offLoadRequest.params.hostIpv4Addr[3]);
1146
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301147 if (eHAL_STATUS_SUCCESS !=
1148 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1149 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 {
1151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001152 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 return VOS_STATUS_E_FAILURE;
1154 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 }
1156 else
1157 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1159 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001160 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301161
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301162 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 }
1164 else
1165 {
1166 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1167 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1168 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1169
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301170 if (eHAL_STATUS_SUCCESS !=
1171 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1172 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 {
1174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001175 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001176 return VOS_STATUS_E_FAILURE;
1177 }
1178 return VOS_STATUS_SUCCESS;
1179 }
1180}
1181
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301182/*
1183 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301184 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301185*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301186void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301187 tANI_U8 *pMcBcFilter)
1188{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301189 if (NULL == pHddCtx)
1190 {
1191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1192 return;
1193 }
1194
1195 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1196 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301197 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301198 /* ARP offload is enabled, do not block bcast packets at RXP
1199 * Will be using Bitmasking to reset the filter. As we have
1200 * disable Broadcast filtering, Anding with the negation
1201 * of Broadcast BIT
1202 */
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301203 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301204 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301205
1206#ifdef WLAN_NS_OFFLOAD
1207 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301208 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301209 /* NS offload is enabled, do not block mcast packets at RXP
1210 * Will be using Bitmasking to reset the filter. As we have
1211 * disable Multicast filtering, Anding with the negation
1212 * of Multicast BIT
1213 */
1214 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301215 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301216#endif
1217
Amar Singhald08ce752014-03-21 16:28:27 -07001218 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1219 {
1220 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1221 }
1222
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301223 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301224}
1225
Jeff Johnson295189b2012-06-20 16:38:30 -07001226void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1227{
1228 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1230 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
1231 if(NULL == wlanRxpFilterParam)
1232 {
1233 hddLog(VOS_TRACE_LEVEL_FATAL,
1234 "%s: vos_mem_alloc failed ", __func__);
1235 return;
1236 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001237 hddLog(VOS_TRACE_LEVEL_INFO,
1238 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301239 if (TRUE == setfilter)
1240 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301241 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301242 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301243 }
1244 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301245 {
1246 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301247 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301248 pHddCtx->configuredMcastBcastFilter;
1249 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301250
Jeff Johnson295189b2012-06-20 16:38:30 -07001251 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001252 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301253
1254 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
1255 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
1256
1257 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1258 "lower mac with status %d"
1259 "configuredMcstBcstFilterSetting = %d"
1260 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1261 "Failed" : "Success", halStatus,
1262 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1263 wlanRxpFilterParam->setMcstBcstFilter);
1264
Chilam Ngc4244af2013-04-01 15:37:32 -07001265 if (eHAL_STATUS_SUCCESS != halStatus)
1266 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001267}
1268
Jeff Johnson295189b2012-06-20 16:38:30 -07001269static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1270 hdd_adapter_t *pAdapter)
1271{
1272 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1273 tpSirWlanSuspendParam wlanSuspendParam =
1274 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1275
Amar Singhald53568e2013-09-26 11:03:45 -07001276 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1277 pHddCtx->sus_res_mcastbcast_filter =
1278 pHddCtx->configuredMcastBcastFilter;
1279 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1280 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1281 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1282 pHddCtx->configuredMcastBcastFilter);
1283
1284 }
1285
Amar Singhal49fdfd52013-08-13 13:25:12 -07001286
Jeff Johnson295189b2012-06-20 16:38:30 -07001287 if(NULL == wlanSuspendParam)
1288 {
1289 hddLog(VOS_TRACE_LEVEL_FATAL,
1290 "%s: vos_mem_alloc failed ", __func__);
1291 return;
1292 }
1293
Amar Singhald53568e2013-09-26 11:03:45 -07001294 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001295 "%s: send wlan suspend indication", __func__);
1296
1297 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1298 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301299 //Configure supported OffLoads
1300 hdd_conf_hostoffload(pAdapter, TRUE);
1301 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301302 hddLog(VOS_TRACE_LEVEL_INFO,
1303 FL("saving configuredMcastBcastFilterSetting = %d"),
1304 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001305#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301306 /* During suspend, configure MC Addr list filter to the firmware
1307 * function takes care of checking necessary conditions before
1308 * configuring.
1309 */
1310 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001311#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001312
1313 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1314 {
1315
1316 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1317 pHddCtx->configuredMcastBcastFilter &=
1318 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1319 }
1320
1321 wlanSuspendParam->configuredMcstBcstFilterSetting =
1322 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 }
1324
1325 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1326 if(eHAL_STATUS_SUCCESS == halStatus)
1327 {
1328 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001329 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301330 hddLog(VOS_TRACE_LEVEL_ERROR,
1331 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001332 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001333 }
1334}
1335
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301336static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001337{
Chilam Ngc4244af2013-04-01 15:37:32 -07001338 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001339 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001340 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001341
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301342 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001343 "%s: send wlan resume indication", __func__);
1344
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301345 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1346
1347 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301349 hddLog(VOS_TRACE_LEVEL_FATAL,
1350 "%s: memory allocation failed for wlanResumeParam ", __func__);
1351 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001353
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301354 //Disable supported OffLoads
1355 hdd_conf_hostoffload(pAdapter, FALSE);
1356
1357 wlanResumeParam->configuredMcstBcstFilterSetting =
1358 pHddCtx->configuredMcastBcastFilter;
1359 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1360 if (eHAL_STATUS_SUCCESS != halStatus)
1361 {
c_hpothuffdb5272013-10-02 16:42:35 +05301362 hddLog(VOS_TRACE_LEVEL_ERROR,
1363 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301364 vos_mem_free(wlanResumeParam);
1365 }
1366
1367 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1368
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001369 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1370 pHddCtx->configuredMcastBcastFilter =
1371 pHddCtx->sus_res_mcastbcast_filter;
1372 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1373 }
Amar Singhald53568e2013-09-26 11:03:45 -07001374
1375 hddLog(VOS_TRACE_LEVEL_INFO,
1376 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1377 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1378 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001379
Chilam Ngc4244af2013-04-01 15:37:32 -07001380
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301381#ifdef WLAN_FEATURE_PACKET_FILTERING
1382 /* Filer was applied during suspend inditication
1383 * clear it when we resume.
1384 */
1385 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001386#endif
1387}
Jeff Johnson295189b2012-06-20 16:38:30 -07001388
Jeff Johnson295189b2012-06-20 16:38:30 -07001389//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001390void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001391{
1392 hdd_context_t *pHddCtx = NULL;
1393 v_CONTEXT_t pVosContext = NULL;
1394
Jeff Johnson295189b2012-06-20 16:38:30 -07001395 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301396 hdd_adapter_t *pAdapter = NULL;
1397 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301398 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001399
Jeff Johnson295189b2012-06-20 16:38:30 -07001400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1401
1402 //Get the global VOSS context.
1403 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1404 if(!pVosContext) {
1405 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1406 return;
1407 }
1408
1409 //Get the HDD context.
1410 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1411
1412 if(!pHddCtx) {
1413 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1414 return;
1415 }
1416
1417 if (pHddCtx->isLogpInProgress) {
1418 hddLog(VOS_TRACE_LEVEL_ERROR,
1419 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1420 return;
1421 }
1422
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301423 if (pHddCtx->hdd_wlan_suspended)
1424 {
1425 hddLog(VOS_TRACE_LEVEL_ERROR,
1426 "%s: Ignore suspend wlan, Already suspended!", __func__);
1427 return;
1428 }
1429
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301430 pHddCtx->hdd_wlan_suspended = TRUE;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301431 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001432 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1433 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1434 {
1435 pAdapter = pAdapterNode->pAdapter;
1436 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001437 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1439
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001440 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001441 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1442 pAdapterNode = pNext;
1443 continue;
1444 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301445 /* Avoid multiple enter/exit BMPS in this while loop using
1446 * hdd_enter_bmps flag
1447 */
1448 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1449 {
1450 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001451
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301452 /* If device was already in BMPS, and dynamic DTIM is set,
1453 * exit(set the device to full power) and enter BMPS again
1454 * to reflect new DTIM value */
1455 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1456
1457 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1458
1459 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001461#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1462 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1463 {
1464 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301465 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 netif_tx_disable(pAdapter->dev);
1467 netif_carrier_off(pAdapter->dev);
1468 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301469 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001470 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1471 {
1472 //Execute deep sleep procedure
1473 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1474 }
1475#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301476
1477 /*Suspend notification sent down to driver*/
1478 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1479
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301480 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1481 pAdapterNode = pNext;
1482 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301483
Jeff Johnson295189b2012-06-20 16:38:30 -07001484#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1485 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1486 {
1487 hdd_enter_standby(pHddCtx);
1488 }
1489#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001490
1491 return;
1492}
1493
1494static void hdd_PowerStateChangedCB
1495(
1496 v_PVOID_t callbackContext,
1497 tPmcState newState
1498)
1499{
1500 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301501
Jeff Johnson295189b2012-06-20 16:38:30 -07001502 /* if the driver was not in BMPS during early suspend,
1503 * the dynamic DTIM is now updated at Riva */
1504 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1505 && pHddCtx->cfg_ini->enableDynamicDTIM
1506 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1507 {
1508 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1509 }
1510 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301511 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1512 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001513 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301514 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1515 {
Amar Singhald53568e2013-09-26 11:03:45 -07001516 pHddCtx->sus_res_mcastbcast_filter =
1517 pHddCtx->configuredMcastBcastFilter;
1518 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1519
1520 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1521 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1522 pHddCtx->configuredMcastBcastFilter);
1523 hddLog(VOS_TRACE_LEVEL_INFO,
1524 "offload: calling hdd_conf_mcastbcast_filter");
1525
1526 }
1527
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301531 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001532 else
Mihir Shete793209f2014-01-06 11:01:12 +05301533 {
1534 /* Android framework can send resume request when the WCN chip is
1535 * in IMPS mode. When the chip exits IMPS mode the firmware will
1536 * restore all the registers to the state they were before the chip
1537 * entered IMPS and so our hardware filter settings confgured by the
1538 * resume request will be lost. So reconfigure the filters on detecting
1539 * a change in the power state of the WCN chip.
1540 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301541 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301542 if (IMPS != newState)
1543 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301544 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301545 if (FALSE == pHddCtx->hdd_wlan_suspended)
1546 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301547 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301548 hddLog(VOS_TRACE_LEVEL_INFO,
1549 "Not in IMPS/BMPS and suspended state");
1550 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1551 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301552 else
1553 {
1554 spin_unlock(&pHddCtx->filter_lock);
1555 }
Mihir Shete793209f2014-01-06 11:01:12 +05301556 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001558}
1559
Jeff Johnson295189b2012-06-20 16:38:30 -07001560void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1561{
1562 v_CONTEXT_t pVosContext;
1563 tHalHandle smeContext;
1564
1565 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1566 if (NULL == pVosContext)
1567 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001568 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001569 return;
1570 }
1571 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1572 if (NULL == smeContext)
1573 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001574 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 return;
1576 }
1577
1578 spin_lock_init(&pHddCtx->filter_lock);
1579 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1580 pHddCtx->cfg_ini->nEnableSuspend)
1581 {
1582 pmcRegisterDeviceStateUpdateInd(smeContext,
1583 hdd_PowerStateChangedCB, pHddCtx);
1584 }
1585}
1586
1587void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1588{
1589 v_CONTEXT_t pVosContext;
1590 tHalHandle smeContext;
1591
1592 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1593 if (NULL == pVosContext)
1594 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001595 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001596 return;
1597 }
1598 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1599 if (NULL == smeContext)
1600 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001601 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 return;
1603 }
1604
1605 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1606 pHddCtx->cfg_ini->nEnableSuspend)
1607 {
1608 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1609 }
1610}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301611
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301612#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301613void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301614{
1615 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301616 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301617 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1618
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301619 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301620 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301621 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1622 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1623 {
1624 vos_mem_copy(&hddGtkOffloadReqParams,
1625 &pHddStaCtx->gtkOffloadReqParams,
1626 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301627
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301628 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1629 &hddGtkOffloadReqParams, pAdapter->sessionId);
1630 if (eHAL_STATUS_SUCCESS != ret)
1631 {
1632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1633 "%s: sme_SetGTKOffload failed, returned %d",
1634 __func__, ret);
1635 return;
1636 }
1637
1638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1639 "%s: sme_SetGTKOffload successfull", __func__);
1640 }
1641
1642 }
1643 else
1644 {
1645 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1646 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1647 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1648 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1649 {
1650
1651 /* Host driver has previously offloaded GTK rekey */
1652 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301653 wlan_hdd_cfg80211_update_replayCounterCallback,
1654 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301655 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301656
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301657 {
1658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1659 "%s: sme_GetGTKOffload failed, returned %d",
1660 __func__, ret);
1661 return;
1662 }
1663 else
1664 {
1665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1666 "%s: sme_GetGTKOffload successful",
1667 __func__);
1668
1669 /* Sending GTK offload dissable */
1670 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1671 sizeof (tSirGtkOffloadParams));
1672 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1673 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301674 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301675 if (eHAL_STATUS_SUCCESS != ret)
1676 {
1677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1678 "%s: failed to dissable GTK offload, returned %d",
1679 __func__, ret);
1680 return;
1681 }
1682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1683 "%s: successfully dissabled GTK offload request to HAL",
1684 __func__);
1685 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301686 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301687 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301688 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301689}
1690#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001691
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001692void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001693{
1694 hdd_context_t *pHddCtx = NULL;
1695 hdd_adapter_t *pAdapter = NULL;
1696 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1697 VOS_STATUS status;
1698 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001699
Jeff Johnson295189b2012-06-20 16:38:30 -07001700 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1701
1702 //Get the global VOSS context.
1703 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1704 if(!pVosContext) {
1705 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1706 return;
1707 }
1708
1709 //Get the HDD context.
1710 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1711
1712 if(!pHddCtx) {
1713 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1714 return;
1715 }
1716
Agarwal Ashish971c2882013-10-30 20:11:12 +05301717 if (pHddCtx->isLogpInProgress)
1718 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001719 hddLog(VOS_TRACE_LEVEL_INFO,
1720 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1721 return;
1722 }
1723
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301724 if (!pHddCtx->hdd_wlan_suspended)
1725 {
1726 hddLog(VOS_TRACE_LEVEL_ERROR,
1727 "%s: Ignore resume wlan, Already resumed!", __func__);
1728 return;
1729 }
1730
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 pHddCtx->hdd_wlan_suspended = FALSE;
1732 /*loop through all adapters. Concurrency */
1733 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1734
1735 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1736 {
1737 pAdapter = pAdapterNode->pAdapter;
1738 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001739 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001740 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001741 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1743 pAdapterNode = pNext;
1744 continue;
1745 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301746
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301747
Jeff Johnson295189b2012-06-20 16:38:30 -07001748#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1749 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1750 {
1751 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1752 hdd_exit_deep_sleep(pAdapter);
1753 }
1754#endif
1755
1756 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1757 {
1758 /*Switch back to DTIM 1*/
1759 tSirSetPowerParamsReq powerRequest = { 0 };
1760
1761 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1762 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001763 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001764
1765 /*Disabled ModulatedDTIM if enabled on suspend*/
1766 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1767 powerRequest.uDTIMPeriod = 0;
1768
1769 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1770 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1771 NULL, eANI_BOOLEAN_FALSE);
1772 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1773 NULL, eANI_BOOLEAN_FALSE);
1774
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001776 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001777 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001778
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301779 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1780 {
1781 /* put the device into full power */
1782 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001783
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301784 /* put the device back into BMPS */
1785 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001786
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301787 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 }
1790
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301791 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1793 pAdapterNode = pNext;
1794 }
1795
1796#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1797 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1798 {
1799 hdd_exit_standby(pHddCtx);
1800 }
1801#endif
1802
Jeff Johnson295189b2012-06-20 16:38:30 -07001803 return;
1804}
1805
Jeff Johnson295189b2012-06-20 16:38:30 -07001806VOS_STATUS hdd_wlan_reset_initialization(void)
1807{
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 v_CONTEXT_t pVosContext = NULL;
1809
1810 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1811
1812 //Get the global VOSS context.
1813 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1814 if(!pVosContext)
1815 {
1816 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1817 return VOS_STATUS_E_FAILURE;
1818 }
1819
1820 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1821
1822 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301823 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07001824
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 return VOS_STATUS_SUCCESS;
1826}
1827
1828
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001829/*
1830 * Based on the ioctl command recieved by HDD, put WLAN driver
1831 * into the quiet mode. This is the same as the early suspend
1832 * notification that driver used to listen
1833 */
1834void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001835{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301836 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001837 if (suspend)
1838 hdd_suspend_wlan();
1839 else
1840 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301841 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001842}
1843
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001844static void hdd_ssr_timer_init(void)
1845{
1846 init_timer(&ssr_timer);
1847}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001848
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001849static void hdd_ssr_timer_del(void)
1850{
1851 del_timer(&ssr_timer);
1852 ssr_timer_started = false;
1853}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001854
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001855static void hdd_ssr_timer_cb(unsigned long data)
1856{
1857 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001858
1859#ifdef WCN_PRONTO
1860 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1861 wcnss_pronto_log_debug_regs();
1862#endif
1863
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001864 VOS_BUG(0);
1865}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001866
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001867static void hdd_ssr_timer_start(int msec)
1868{
1869 if(ssr_timer_started)
1870 {
1871 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1872 ,__func__);
1873 }
1874 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1875 ssr_timer.function = hdd_ssr_timer_cb;
1876 add_timer(&ssr_timer);
1877 ssr_timer_started = true;
1878}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001879
Jeff Johnson295189b2012-06-20 16:38:30 -07001880/* the HDD interface to WLAN driver shutdown,
1881 * the primary shutdown function in SSR
1882 */
1883VOS_STATUS hdd_wlan_shutdown(void)
1884{
1885 VOS_STATUS vosStatus;
1886 v_CONTEXT_t pVosContext = NULL;
1887 hdd_context_t *pHddCtx = NULL;
1888 pVosSchedContext vosSchedContext = NULL;
1889
1890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1891
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001892 /* if re-init never happens, then do SSR1 */
1893 hdd_ssr_timer_init();
1894 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1895
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 /* Get the global VOSS context. */
1897 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1898 if(!pVosContext) {
1899 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1900 return VOS_STATUS_E_FAILURE;
1901 }
1902 /* Get the HDD context. */
1903 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1904 if(!pHddCtx) {
1905 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1906 return VOS_STATUS_E_FAILURE;
1907 }
c_hpothud662a352013-12-26 15:09:12 +05301908
1909 //Stop the traffic monitor timer
1910 if ( VOS_TIMER_STATE_RUNNING ==
1911 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1912 {
1913 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1914 }
1915
Jeff Johnson295189b2012-06-20 16:38:30 -07001916 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001917 /* DeRegister with platform driver as client for Suspend/Resume */
1918 vosStatus = hddDeregisterPmOps(pHddCtx);
1919 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1920 {
1921 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1922 }
1923
1924 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1925 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1926 {
1927 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1928 }
1929
1930 /* Disable IMPS/BMPS as we do not want the device to enter any power
1931 * save mode on its own during reset sequence
1932 */
1933 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1934 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1935 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1936
1937 vosSchedContext = get_vos_sched_ctxt();
1938
1939 /* Wakeup all driver threads */
1940 if(TRUE == pHddCtx->isMcThreadSuspended){
1941 complete(&vosSchedContext->ResumeMcEvent);
1942 pHddCtx->isMcThreadSuspended= FALSE;
1943 }
1944 if(TRUE == pHddCtx->isTxThreadSuspended){
1945 complete(&vosSchedContext->ResumeTxEvent);
1946 pHddCtx->isTxThreadSuspended= FALSE;
1947 }
1948 if(TRUE == pHddCtx->isRxThreadSuspended){
1949 complete(&vosSchedContext->ResumeRxEvent);
1950 pHddCtx->isRxThreadSuspended= FALSE;
1951 }
1952 /* Reset the Suspend Variable */
1953 pHddCtx->isWlanSuspended = FALSE;
1954
1955 /* Stop all the threads; we do not want any messages to be a processed,
1956 * any more and the best way to ensure that is to terminate the threads
1957 * gracefully.
1958 */
1959 /* Wait for MC to exit */
1960 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1961 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1962 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1963 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301964 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001965
1966 /* Wait for TX to exit */
1967 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1968 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1969 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1970 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301971 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001972
1973 /* Wait for RX to exit */
1974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1975 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1976 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1977 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301978
Mihir Sheteb5425f72013-12-19 09:06:13 +05301979 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001980
1981#ifdef WLAN_BTAMP_FEATURE
1982 vosStatus = WLANBAP_Stop(pVosContext);
1983 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1984 {
1985 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1986 "%s: Failed to stop BAP",__func__);
1987 }
1988#endif //WLAN_BTAMP_FEATURE
1989 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301990 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1991 {
1992 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1993 "%s: Failed to stop wda %d", __func__, vosStatus);
1994 VOS_ASSERT(0);
1995 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001996
1997 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
1998 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
1999 * on threads being running to process the SYS Stop
2000 */
Kiet Lama72a2322013-11-15 11:18:11 +05302001 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302002 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2003 {
2004 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2005 "%s: Failed to stop sme %d", __func__, vosStatus);
2006 VOS_ASSERT(0);
2007 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002008
2009 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2010 /* Stop MAC (PE and HAL) */
2011 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302012 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2013 {
2014 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2015 "%s: Failed to stop mac %d", __func__, vosStatus);
2016 VOS_ASSERT(0);
2017 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002018
2019 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2020 /* Stop TL */
2021 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302022 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2023 {
2024 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2025 "%s: Failed to stop TL %d", __func__, vosStatus);
2026 VOS_ASSERT(0);
2027 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002028
Jeff Johnson295189b2012-06-20 16:38:30 -07002029 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2031 /* Clean up message queues of TX and MC thread */
2032 vos_sched_flush_mc_mqs(vosSchedContext);
2033 vos_sched_flush_tx_mqs(vosSchedContext);
2034 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302035#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2036 wlan_logging_flush_pkt_queue();
2037#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002038
2039 /* Deinit all the TX and MC queues */
2040 vos_sched_deinit_mqs(vosSchedContext);
2041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2042
2043 /* shutdown VOSS */
2044 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302045
2046 /*mac context has already been released in mac_close call
2047 so setting it to NULL in hdd context*/
2048 pHddCtx->hHal = (tHalHandle)NULL;
2049
Jeff Johnson295189b2012-06-20 16:38:30 -07002050 if (free_riva_power_on_lock("wlan"))
2051 {
2052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2053 __func__);
2054 }
2055 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2056 ,__func__);
2057 return VOS_STATUS_SUCCESS;
2058}
2059
2060
2061
2062/* the HDD interface to WLAN driver re-init.
2063 * This is called to initialize/start WLAN driver after a shutdown.
2064 */
2065VOS_STATUS hdd_wlan_re_init(void)
2066{
2067 VOS_STATUS vosStatus;
2068 v_CONTEXT_t pVosContext = NULL;
2069 hdd_context_t *pHddCtx = NULL;
2070 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002071#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2072 int max_retries = 0;
2073#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302074#ifdef HAVE_CBC_DONE
2075 int max_cbc_retries = 0;
2076#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002077#ifdef WLAN_BTAMP_FEATURE
2078 hdd_config_t *pConfig = NULL;
2079 WLANBAP_ConfigType btAmpConfig;
2080#endif
2081
Katya Nigam82a93062014-06-04 15:15:36 +05302082 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002083 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302084 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002085
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002086#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2087 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002088 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002089 msleep(1000);
2090 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002091 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002092 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2093 goto err_re_init;
2094 }
2095#endif
2096
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302097#ifdef HAVE_CBC_DONE
2098 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2099 msleep(1000);
2100 }
2101 if (max_cbc_retries >= 20) {
2102 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2103 }
2104#endif
2105
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002106 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2107
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002108 /* The driver should always be initialized in STA mode after SSR */
2109 hdd_set_conparam(0);
2110
Katya Nigam82a93062014-06-04 15:15:36 +05302111 dev = wcnss_wlan_get_device();
2112 if (NULL == dev)
2113 {
2114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2115 goto err_re_init;
2116 }
2117
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302119 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2121 {
2122 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2123 goto err_re_init;
2124 }
2125
2126 /* Get the HDD context. */
2127 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2128 if(!pHddCtx)
2129 {
2130 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2131 goto err_vosclose;
2132 }
2133
2134 /* Save the hal context in Adapter */
2135 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2136 if ( NULL == pHddCtx->hHal )
2137 {
2138 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2139 goto err_vosclose;
2140 }
2141
2142 /* Set the SME configuration parameters. */
2143 vosStatus = hdd_set_sme_config(pHddCtx);
2144 if ( VOS_STATUS_SUCCESS != vosStatus )
2145 {
2146 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2147 goto err_vosclose;
2148 }
2149
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 vosStatus = vos_preStart( pHddCtx->pvosContext );
2151 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2152 {
2153 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2154 goto err_vosclose;
2155 }
2156
2157 /* In the integrated architecture we update the configuration from
2158 the INI file and from NV before vOSS has been started so that
2159 the final contents are available to send down to the cCPU */
2160 /* Apply the cfg.ini to cfg.dat */
2161 if (FALSE == hdd_update_config_dat(pHddCtx))
2162 {
2163 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2164 goto err_vosclose;
2165 }
2166
2167 /* Set the MAC Address, currently this is used by HAL to add self sta.
2168 * Remove this once self sta is added as part of session open. */
2169 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2170 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2171 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2172 if (!HAL_STATUS_SUCCESS(halStatus))
2173 {
2174 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2175 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2176 goto err_vosclose;
2177 }
2178
2179 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2180 Note: Firmware image will be read and downloaded inside vos_start API */
2181 vosStatus = vos_start( pVosContext );
2182 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2183 {
2184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
2185 goto err_vosclose;
2186 }
2187
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002188 /* Exchange capability info between Host and FW and also get versioning info from FW */
2189 hdd_exchange_version_and_caps(pHddCtx);
2190
Jeff Johnson295189b2012-06-20 16:38:30 -07002191 vosStatus = hdd_post_voss_start_config( pHddCtx );
2192 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2193 {
2194 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2195 __func__);
2196 goto err_vosstop;
2197 }
2198
Mihir Shete04206452014-11-20 17:50:58 +05302199#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302200 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2201 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2202 {
2203 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2204 __func__);
2205 goto err_vosstop;
2206 }
Mihir Shete04206452014-11-20 17:50:58 +05302207#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302208
Jeff Johnson295189b2012-06-20 16:38:30 -07002209#ifdef WLAN_BTAMP_FEATURE
2210 vosStatus = WLANBAP_Open(pVosContext);
2211 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2212 {
2213 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2214 "%s: Failed to open BAP",__func__);
2215 goto err_vosstop;
2216 }
2217 vosStatus = BSL_Init(pVosContext);
2218 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2219 {
2220 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2221 "%s: Failed to Init BSL",__func__);
2222 goto err_bap_close;
2223 }
2224 vosStatus = WLANBAP_Start(pVosContext);
2225 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2226 {
2227 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2228 "%s: Failed to start TL",__func__);
2229 goto err_bap_close;
2230 }
2231 pConfig = pHddCtx->cfg_ini;
2232 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2233 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2234#endif //WLAN_BTAMP_FEATURE
2235
2236 /* Restart all adapters */
2237 hdd_start_all_adapters(pHddCtx);
2238 pHddCtx->isLogpInProgress = FALSE;
Sameer Thalappilb511beb2013-09-09 17:11:51 -07002239 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002240 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302241 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002242 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302243 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 /* Register with platform driver as client for Suspend/Resume */
2245 vosStatus = hddRegisterPmOps(pHddCtx);
2246 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2247 {
2248 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2249 goto err_bap_stop;
2250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302252 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 /* register for riva power on lock */
2254 if (req_riva_power_on_lock("wlan"))
2255 {
2256 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2257 __func__);
2258 goto err_unregister_pmops;
2259 }
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002260 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302261#ifdef WLAN_FEATURE_EXTSCAN
2262 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2263 wlan_hdd_cfg80211_extscan_callback,
2264 pHddCtx);
2265#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 goto success;
2267
2268err_unregister_pmops:
2269 hddDeregisterPmOps(pHddCtx);
2270
2271err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002272#ifdef CONFIG_HAS_EARLYSUSPEND
2273 hdd_unregister_mcast_bcast_filter(pHddCtx);
2274#endif
2275 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002276#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002277 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002278#endif
2279
2280#ifdef WLAN_BTAMP_FEATURE
2281err_bap_close:
2282 WLANBAP_Close(pVosContext);
2283#endif
2284
2285err_vosstop:
2286 vos_stop(pVosContext);
2287
2288err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302289 if(!isSsrPanicOnFailure())
2290 {
2291 /* If we hit this, it means wlan driver is in bad state and needs
2292 * driver unload and load.
2293 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302294 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2295 return VOS_STATUS_E_FAILURE;
2296 }
2297
Jeff Johnson295189b2012-06-20 16:38:30 -07002298 vos_close(pVosContext);
2299 vos_sched_close(pVosContext);
2300 if (pHddCtx)
2301 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002302 /* Unregister the Net Device Notifier */
2303 unregister_netdevice_notifier(&hdd_netdev_notifier);
2304 /* Clean up HDD Nlink Service */
2305 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002306#ifdef WLAN_KD_READY_NOTIFIER
2307 nl_srv_exit(pHddCtx->ptt_pid);
2308#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002309 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002310#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 /* Free up dynamically allocated members inside HDD Adapter */
2312 kfree(pHddCtx->cfg_ini);
2313 pHddCtx->cfg_ini= NULL;
2314
Jeff Johnson295189b2012-06-20 16:38:30 -07002315 wiphy_unregister(pHddCtx->wiphy);
2316 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 }
2318 vos_preClose(&pVosContext);
2319
2320#ifdef MEMORY_DEBUG
2321 vos_mem_exit();
2322#endif
2323
2324err_re_init:
2325 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302326 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002327 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002328 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002329 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002330
2331success:
2332 /* Trigger replay of BTC events */
2333 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2334 return VOS_STATUS_SUCCESS;
2335}