blob: 5bd0762bd9baed10a394d3b7b0b09e5740663d85 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singh37471cd2016-01-05 17:09:57 +05302 * Copyright (c) 2012-2016 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);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +0530376 VOS_BUG(0);
c_hpothuffdb5272013-10-02 16:42:35 +0530377 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700378
Jeff Johnson295189b2012-06-20 16:38:30 -0700379 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
380
381 //Restore IMPS config
382 if(pHddCtx->cfg_ini->fIsImpsEnabled)
383 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
384
385 //Restore BMPS config
386 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
387 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
388
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 return vosStatus;
390}
391
392VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
393{
394 VOS_STATUS vosStatus;
395 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700396
Jeff Johnson295189b2012-06-20 16:38:30 -0700397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
398 "%s: calling hdd_set_sme_config",__func__);
399 vosStatus = hdd_set_sme_config( pHddCtx );
400 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
401 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
402 {
403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
404 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700405 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700406 }
407
408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
409 "%s: calling vos_start",__func__);
410 vosStatus = vos_start( pHddCtx->pvosContext );
411 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
412 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
413 {
414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
415 "%s: Failed in vos_start",__func__);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +0530416 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700417 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700418 }
419
420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
421 "%s: calling hdd_post_voss_start_config",__func__);
422 vosStatus = hdd_post_voss_start_config( pHddCtx );
423 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
424 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
425 {
426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
427 "%s: Failed in hdd_post_voss_start_config",__func__);
428 goto err_voss_stop;
429 }
430
431
432 //Open a SME session for future operation
433 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700434 (tANI_U8 *)&pAdapter->macAddressCurrent,
435 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700436 if ( !HAL_STATUS_SUCCESS( halStatus ) )
437 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700438 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700439 halStatus, halStatus );
440 goto err_voss_stop;
441
442 }
443
444 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
445
446 //Trigger the initial scan
447 hdd_wlan_initial_scan(pHddCtx);
448
449 return VOS_STATUS_SUCCESS;
450
451err_voss_stop:
452 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700453err_deep_sleep:
454 return VOS_STATUS_E_FAILURE;
455
456}
457
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530458void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
Atul Mittal37385d72014-03-27 18:15:03 +0530459{
460 hdd_adapter_t* pAdapter =
461 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
462 hdd_context_t *pHddCtx;
463 int status;
464
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530465 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530466 if (NULL == pAdapter)
467 {
468 hddLog(LOGE, FL("Adapter is invalid"));
469 return;
470 }
Atul Mittal37385d72014-03-27 18:15:03 +0530471
472 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
473 status = wlan_hdd_validate_context(pHddCtx);
474 if (0 != status)
475 {
Atul Mittal37385d72014-03-27 18:15:03 +0530476 return;
477 }
478
479 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
480 {
481 pHddCtx->sus_res_mcastbcast_filter =
482 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530483 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
484 pHddCtx->sus_res_mcastbcast_filter);
Atul Mittal37385d72014-03-27 18:15:03 +0530485 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
486 }
487
488 if ((eConnectionState_Associated ==
489 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
490 && (pHddCtx->hdd_wlan_suspended))
491 {
492 // This invocation being part of the IPv6 registration callback,
493 // set the newly generated ip address to f/w in suspend mode.
494#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530495 if (pHddCtx->cfg_ini->fhostNSOffload)
496 {
497 hdd_conf_ns_offload(pAdapter, 1);
498 }
Atul Mittal37385d72014-03-27 18:15:03 +0530499#endif
500 }
501#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530502 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530503 * only so when new ipv6 address is generated the screen may not
504 * on so we need to call it here to update the list in f/w.
505 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530506 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530507#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530508 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530509}
510
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530511void hdd_ipv6_notifier_work_queue(struct work_struct *work)
512{
513 vos_ssr_protect(__func__);
514 __hdd_ipv6_notifier_work_queue(work);
515 vos_ssr_unprotect(__func__);
516}
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530517int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530518 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530519{
520 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
521 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530522 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530523 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530524 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530525 int status;
526
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530527 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530528 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
529 status = wlan_hdd_validate_context(pHddCtx);
530 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530531 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530532 return NOTIFY_DONE;
533 }
Atul Mittal37385d72014-03-27 18:15:03 +0530534
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530535 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
536 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
537 {
538 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
539 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
540 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
541 {
542 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530543 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530544 {
545 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
546 }
547 else
548 {
549 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
550 pHddCtx->cfg_ini->nEnableSuspend);
551 }
552 break;
553 }
554 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
555 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530556 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530557 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530558 return NOTIFY_DONE;
559}
560
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530561int wlan_hdd_ipv6_changed(struct notifier_block *nb,
562 unsigned long data, void *arg)
563{
564 int ret;
565 vos_ssr_protect(__func__);
566 ret = __wlan_hdd_ipv6_changed( nb, data, arg);
567 vos_ssr_unprotect(__func__);
568 return ret;
569}
570
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530571/*
572 * Function: hdd_conf_hostoffload
573 * Central function to configure the supported offloads,
574 * either enable or disable them.
575 */
576void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
577{
578 hdd_context_t *pHddCtx = NULL;
579 v_CONTEXT_t *pVosContext = NULL;
580 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
581
582 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
583 fenable);
584
585 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
586
587 if (NULL == pVosContext)
588 {
589 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
590 return;
591 }
592
593 //Get the HDD context.
594 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
595
596 if (NULL == pHddCtx)
597 {
598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
599 return;
600 }
601
602 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
603 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
604 {
605 if (fenable)
606 {
607 if (eConnectionState_Associated ==
608 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
609 {
610 if ((pHddCtx->cfg_ini->fhostArpOffload))
611 {
612 /*
613 * Configure the ARP Offload.
614 * Even if it fails we have to reconfigure the MC/BC
615 * filter flag as we want RIVA not to drop BroadCast
616 * Packets
617 */
618 hddLog(VOS_TRACE_LEVEL_INFO,
619 FL("Calling ARP Offload with flag: %d"), fenable);
620 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
621 pHddCtx->configuredMcastBcastFilter &=
622 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
623
624 if (!VOS_IS_STATUS_SUCCESS(vstatus))
625 {
626 hddLog(VOS_TRACE_LEVEL_ERROR,
627 "Failed to enable ARPOFfloadFeature %d",
628 vstatus);
629 }
630 }
631 //Configure GTK_OFFLOAD
632#ifdef WLAN_FEATURE_GTK_OFFLOAD
633 hdd_conf_gtk_offload(pAdapter, fenable);
634#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530635
636#ifdef WLAN_NS_OFFLOAD
637 if (pHddCtx->cfg_ini->fhostNSOffload)
638 {
639 /*
640 * Configure the NS Offload.
641 * Even if it fails we have to reconfigure the MC/BC filter flag
642 * as we want RIVA not to drop Multicast Packets
643 */
644
645 hddLog(VOS_TRACE_LEVEL_INFO,
646 FL("Calling NS Offload with flag: %d"), fenable);
647 hdd_conf_ns_offload(pAdapter, fenable);
648 pHddCtx->configuredMcastBcastFilter &=
649 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
650 }
651#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530652
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530653 }
654 }
655 else
656 {
657 //Disable ARPOFFLOAD
658 if (pHddCtx->cfg_ini->fhostArpOffload)
659 {
660 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
661 if (!VOS_IS_STATUS_SUCCESS(vstatus))
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530664 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530665 }
666 }
667 //Disable GTK_OFFLOAD
668#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530669 hdd_conf_gtk_offload(pAdapter, fenable);
670#endif
671
672#ifdef WLAN_NS_OFFLOAD
673 //Disable NSOFFLOAD
674 if (pHddCtx->cfg_ini->fhostNSOffload)
675 {
676 hdd_conf_ns_offload(pAdapter, fenable);
677 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530678#endif
679 }
680 }
681 return;
682}
683
Atul Mittal37385d72014-03-27 18:15:03 +0530684
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530685#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530686/**----------------------------------------------------------------------------
687
688 \brief hdd_conf_ns_offload() - Configure NS offload
689
690 Called during SUSPEND to configure the NS offload (MC BC filter) which
691 reduces power consumption.
692
693 \param - pAdapter - Adapter context for which NS offload is to be configured
694 \param - fenable - 0 - disable.
695 1 - enable. (with IPv6 notifier registration)
696 2 - enable. (without IPv6 notifier registration)
697
698 \return - void
699
700 ---------------------------------------------------------------------------*/
701void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530702{
703 struct inet6_dev *in6_dev;
704 struct inet6_ifaddr *ifp;
705 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530706 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530707 tANI_U8 **selfIPv6Addr = NULL;
708 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530709 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530710 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530711 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530712
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530713 int i = 0, slot = 0;
714 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530715 eHalStatus returnStatus;
716
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530717 ENTER();
718 hddLog(LOG1, FL(" fenable = %d"), fenable);
719
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530720 if (NULL == pAdapter)
721 {
722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
723 return;
724 }
725
726 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
728
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530729 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530730 if (0 != ret)
731 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530732 return;
733 }
734
735 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
736 {
737 slot_index = NS_EXTENDED_SLOT_INDEX;
738 }
739
740 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
741
742 selfIPv6AddrValid =
743 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
744
745 if (NULL == selfIPv6AddrValid)
746 {
747 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
748 " selfIPv6AddrValid"));
749 goto end;
750 }
751
752 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
753
754 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
755
756 if (NULL == selfIPv6Addr)
757 {
758 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
759 " selfIPv6Addr"));
760 goto end;
761 }
762
763 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
764
765 for (slot = 0; slot < slot_index; slot++)
766 {
767 selfIPv6Addr[slot] =
768 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
769 if (NULL == selfIPv6Addr[slot])
770 {
771 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
772 "for selfIPv6Addr"));
773 goto end;
774 }
775 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
776 }
777
778 i = 0;
779
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530780 if (fenable)
781 {
782 in6_dev = __in6_dev_get(pAdapter->dev);
783 if (NULL != in6_dev)
784 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530785 list_for_each(p, &in6_dev->addr_list)
786 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530787 if (i >= slot_index)
788 {
789 hddLog (VOS_TRACE_LEVEL_ERROR,
790 FL("IPv6 address list is greater than IPv6"
791 "address supported by firmware"));
792 hddLog (VOS_TRACE_LEVEL_ERROR,
793 FL("FW supported IPv6 address = %d"), slot_index);
794 break;
795 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530796 ifp = list_entry(p, struct inet6_ifaddr, if_list);
797 switch(ipv6_addr_src_scope(&ifp->addr))
798 {
799 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530800 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530801 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530802 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530803 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530804 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
805 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530806 break;
807 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530808 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530809 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530810 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530811 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530812 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
813 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530814 break;
815 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530816 hddLog(VOS_TRACE_LEVEL_ERROR,
817 FL("The Scope %d is not supported"),
818 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530819 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530820 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
821 {
822 i++;
823 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530824 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530825
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530826 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530827 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530828 {
829 if (selfIPv6AddrValid[i])
830 {
831 //Filling up the request structure
832 /* Filling the selfIPv6Addr with solicited address
833 * A Solicited-Node multicast address is created by
834 * taking the last 24 bits of a unicast or anycast
835 * address and appending them to the prefix
836 *
837 * FF02:0000:0000:0000:0000:0001:FFXX:XX
838 *
839 * here XX is the unicast/anycast bits
840 */
841 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
842 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
843 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
844 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530845 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
846 selfIPv6Addr[i][13];
847 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
848 selfIPv6Addr[i][14];
849 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
850 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530851 offLoadRequest.nsOffloadInfo.slotIdx = i;
852
853 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530854 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530855 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
856 &pAdapter->macAddressCurrent.bytes,
857 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
858
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530859 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
860 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530861 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
862 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
863
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530864 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530865 FL("configuredMcastBcastFilter: %d"
866 "NSOffload Slot = %d"),
867 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530868
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530869 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700870 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
871 pHddCtx->sus_res_mcastbcast_filter) ||
872 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
873 pHddCtx->sus_res_mcastbcast_filter)) &&
874 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
875 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
876 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530877 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530878 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700879 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530880 hddLog (VOS_TRACE_LEVEL_INFO,
881 FL("Set offLoadRequest with %d"),
882 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530883 }
884
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530885 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
886 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
887 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
888
889 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530890 FL("Setting NSOffload with solicitedIp: %pI6,"
891 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530892 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
893 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
894
895 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530896 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530897 pAdapter->sessionId, &offLoadRequest);
898 if(eHAL_STATUS_SUCCESS != returnStatus)
899 {
900 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530901 FL("Failed to enable HostOffload feature with"
902 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530903 }
904 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
905 }
906 }
907 }
908 else
909 {
910 hddLog(VOS_TRACE_LEVEL_ERROR,
911 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530912 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530913 }
914 }
915 else
916 {
917 //Disable NSOffload
918 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
919 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
920 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
921
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530922 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530923 {
c_hpothu86feba52014-10-28 15:51:18 +0530924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530925 offLoadRequest.nsOffloadInfo.slotIdx = i;
926 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530927 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
928 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530929 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
931 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530932 }
933 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530934 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530935end:
936 while (slot > 0 && selfIPv6Addr[--slot])
937 {
938 vos_mem_free(selfIPv6Addr[slot]);
939 }
940 if (selfIPv6Addr)
941 {
942 vos_mem_free(selfIPv6Addr);
943 }
944 if (selfIPv6AddrValid)
945 {
946 vos_mem_free(selfIPv6AddrValid);
947 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530948 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530949 return;
950}
951#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530952
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530953void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530954{
955 hdd_adapter_t* pAdapter =
956 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
957 hdd_context_t *pHddCtx;
958 int status;
959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530960 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530961 if (NULL == pAdapter)
962 {
963 hddLog(LOGE, FL("Adapter is invalid"));
964 return;
965 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530966 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
967 status = wlan_hdd_validate_context(pHddCtx);
968 if (0 != status)
969 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530970 return;
971 }
972
Deepthi Gowri5933f402014-01-23 17:48:24 +0530973 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
974 {
975 pHddCtx->sus_res_mcastbcast_filter =
976 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530977 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
978 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +0530979 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
980 }
981
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530982 if ((eConnectionState_Associated ==
983 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +0530984 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530985 {
986 // This invocation being part of the IPv4 registration callback,
987 // we are passing second parameter as 2 to avoid registration
988 // of IPv4 notifier again.
989 hdd_conf_arp_offload(pAdapter, 2);
990 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530991 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530992}
993
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530994void hdd_ipv4_notifier_work_queue(struct work_struct *work)
995{
996 vos_ssr_protect(__func__);
997 __hdd_ipv4_notifier_work_queue(work);
998 vos_ssr_unprotect(__func__);
999}
1000
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301001int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301002 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301003{
1004 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1005 struct in_ifaddr **ifap = NULL;
1006 struct in_device *in_dev;
1007
1008 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301009 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301010 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301011 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301012 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301014 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301015 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1016 status = wlan_hdd_validate_context(pHddCtx);
1017 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301018 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301019 return NOTIFY_DONE;
1020 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301021
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301022 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1023 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1024 {
1025 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1026 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1027 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1028 {
1029 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301030 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301031 || (!pHddCtx->cfg_ini->fhostArpOffload))
1032 {
1033 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1034 pHddCtx->cfg_ini->nEnableSuspend,
1035 pHddCtx->cfg_ini->fhostArpOffload);
1036 return NOTIFY_DONE;
1037 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301038
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301039 if ((in_dev =
1040 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1041 {
1042 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1043 ifap = &ifa->ifa_next)
1044 {
1045 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1046 ifa->ifa_label))
1047 {
1048 break; /* found */
1049 }
1050 }
1051 }
1052 if(ifa && ifa->ifa_local)
1053 {
1054 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1055 }
1056 break;
1057 }
1058 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1059 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301060 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301061 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301062 return NOTIFY_DONE;
1063}
1064
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301065int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1066 unsigned long data, void *arg)
1067{
1068 int ret;
1069 vos_ssr_protect(__func__);
1070 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1071 vos_ssr_unprotect(__func__);
1072 return ret;
1073}
1074
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301075/**----------------------------------------------------------------------------
1076
1077 \brief hdd_conf_arp_offload() - Configure ARP offload
1078
1079 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1080 reduces power consumption.
1081
1082 \param - pAdapter -Adapter context for which ARP offload is to be configured
1083 \param - fenable - 0 - disable.
1084 1 - enable. (with IPv4 notifier registration)
1085 2 - enable. (without IPv4 notifier registration)
1086
1087 \return -
1088 VOS_STATUS_SUCCESS - on successful operation
1089 VOS_STATUS_E_FAILURE - on failure of operation
1090-----------------------------------------------------------------------------*/
1091VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001092{
1093 struct in_ifaddr **ifap = NULL;
1094 struct in_ifaddr *ifa = NULL;
1095 struct in_device *in_dev;
1096 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001098 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001099
Sushant Kaushik87787972015-09-11 16:05:00 +05301100 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001101
Jeff Johnson295189b2012-06-20 16:38:30 -07001102 if(fenable)
1103 {
1104 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1105 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301106 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 ifap = &ifa->ifa_next)
1108 {
1109 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1110 {
1111 break; /* found */
1112 }
1113 }
1114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001115 if(ifa && ifa->ifa_local)
1116 {
1117 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1118 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
1119
Arif Hussain6d2a3322013-11-17 19:50:10 -08001120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001121
Amar Singhald53568e2013-09-26 11:03:45 -07001122 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1123 pHddCtx->sus_res_mcastbcast_filter) ||
1124 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1125 pHddCtx->sus_res_mcastbcast_filter)) &&
1126 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001127 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301128 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001129 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1130 hddLog(VOS_TRACE_LEVEL_INFO,
1131 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 }
Amar Singhald53568e2013-09-26 11:03:45 -07001133
1134 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1135 offLoadRequest.enableOrDisable);
1136
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 //converting u32 to IPV4 address
1138 for(i = 0 ; i < 4; i++)
1139 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301140 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1142 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301143 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 offLoadRequest.params.hostIpv4Addr[0],
1145 offLoadRequest.params.hostIpv4Addr[1],
1146 offLoadRequest.params.hostIpv4Addr[2],
1147 offLoadRequest.params.hostIpv4Addr[3]);
1148
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301149 if (eHAL_STATUS_SUCCESS !=
1150 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1151 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 {
1153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001154 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 return VOS_STATUS_E_FAILURE;
1156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 }
1158 else
1159 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1161 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301163
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301164 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001165 }
1166 else
1167 {
1168 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1169 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1170 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1171
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301172 if (eHAL_STATUS_SUCCESS !=
1173 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1174 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 {
1176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001177 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 return VOS_STATUS_E_FAILURE;
1179 }
1180 return VOS_STATUS_SUCCESS;
1181 }
1182}
1183
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301184/*
1185 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301186 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301187*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301188void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301189 tANI_U8 *pMcBcFilter)
1190{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301191 if (NULL == pHddCtx)
1192 {
1193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1194 return;
1195 }
1196
1197 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1198 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301199 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301200 /* ARP offload is enabled, do not block bcast packets at RXP
1201 * Will be using Bitmasking to reset the filter. As we have
1202 * disable Broadcast filtering, Anding with the negation
1203 * of Broadcast BIT
1204 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301205 hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301206 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301207 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301208
1209#ifdef WLAN_NS_OFFLOAD
1210 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301211 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301212 /* NS offload is enabled, do not block mcast packets at RXP
1213 * Will be using Bitmasking to reset the filter. As we have
1214 * disable Multicast filtering, Anding with the negation
1215 * of Multicast BIT
1216 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301217 hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301218 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301219 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301220#endif
1221
Amar Singhald08ce752014-03-21 16:28:27 -07001222 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1223 {
1224 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1225 }
1226
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301227 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301228}
1229
Jeff Johnson295189b2012-06-20 16:38:30 -07001230void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1231{
1232 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001233 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1234 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
Agarwal Ashishff451a32015-07-28 01:01:29 +05301235 if (NULL == wlanRxpFilterParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001236 {
1237 hddLog(VOS_TRACE_LEVEL_FATAL,
1238 "%s: vos_mem_alloc failed ", __func__);
1239 return;
1240 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 hddLog(VOS_TRACE_LEVEL_INFO,
1242 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301243 if (TRUE == setfilter)
1244 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301245 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301246 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301247 }
1248 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301249 {
1250 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301251 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301252 pHddCtx->configuredMcastBcastFilter;
1253 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301254
Jeff Johnson295189b2012-06-20 16:38:30 -07001255 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001256 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301257
1258 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
Agarwal Ashishff451a32015-07-28 01:01:29 +05301259 {
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301260 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Agarwal Ashishff451a32015-07-28 01:01:29 +05301261 }
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301262
1263 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1264 "lower mac with status %d"
1265 "configuredMcstBcstFilterSetting = %d"
1266 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1267 "Failed" : "Success", halStatus,
1268 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1269 wlanRxpFilterParam->setMcstBcstFilter);
1270
Chilam Ngc4244af2013-04-01 15:37:32 -07001271 if (eHAL_STATUS_SUCCESS != halStatus)
1272 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001273}
1274
Jeff Johnson295189b2012-06-20 16:38:30 -07001275static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1276 hdd_adapter_t *pAdapter)
1277{
1278 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1279 tpSirWlanSuspendParam wlanSuspendParam =
1280 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1281
Amar Singhald53568e2013-09-26 11:03:45 -07001282 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1283 pHddCtx->sus_res_mcastbcast_filter =
1284 pHddCtx->configuredMcastBcastFilter;
1285 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1286 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1287 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1288 pHddCtx->configuredMcastBcastFilter);
1289
1290 }
1291
Amar Singhal49fdfd52013-08-13 13:25:12 -07001292
Jeff Johnson295189b2012-06-20 16:38:30 -07001293 if(NULL == wlanSuspendParam)
1294 {
1295 hddLog(VOS_TRACE_LEVEL_FATAL,
1296 "%s: vos_mem_alloc failed ", __func__);
1297 return;
1298 }
1299
Amar Singhald53568e2013-09-26 11:03:45 -07001300 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001301 "%s: send wlan suspend indication", __func__);
1302
1303 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1304 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301305 //Configure supported OffLoads
1306 hdd_conf_hostoffload(pAdapter, TRUE);
1307 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301308 hddLog(VOS_TRACE_LEVEL_INFO,
1309 FL("saving configuredMcastBcastFilterSetting = %d"),
1310 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001311#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301312 /* During suspend, configure MC Addr list filter to the firmware
1313 * function takes care of checking necessary conditions before
1314 * configuring.
1315 */
1316 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001317#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001318
1319 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1320 {
1321
1322 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1323 pHddCtx->configuredMcastBcastFilter &=
1324 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1325 }
1326
1327 wlanSuspendParam->configuredMcstBcstFilterSetting =
1328 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001329 }
1330
1331 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1332 if(eHAL_STATUS_SUCCESS == halStatus)
1333 {
1334 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001335 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301336 hddLog(VOS_TRACE_LEVEL_ERROR,
1337 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001338 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001339 }
1340}
1341
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301342static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001343{
Chilam Ngc4244af2013-04-01 15:37:32 -07001344 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001345 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001346 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001347
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301348 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001349 "%s: send wlan resume indication", __func__);
1350
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301351 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1352
1353 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001354 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301355 hddLog(VOS_TRACE_LEVEL_FATAL,
1356 "%s: memory allocation failed for wlanResumeParam ", __func__);
1357 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001359
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301360 //Disable supported OffLoads
1361 hdd_conf_hostoffload(pAdapter, FALSE);
1362
1363 wlanResumeParam->configuredMcstBcstFilterSetting =
1364 pHddCtx->configuredMcastBcastFilter;
1365 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1366 if (eHAL_STATUS_SUCCESS != halStatus)
1367 {
c_hpothuffdb5272013-10-02 16:42:35 +05301368 hddLog(VOS_TRACE_LEVEL_ERROR,
1369 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301370 vos_mem_free(wlanResumeParam);
1371 }
1372
1373 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1374
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001375 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1376 pHddCtx->configuredMcastBcastFilter =
1377 pHddCtx->sus_res_mcastbcast_filter;
1378 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1379 }
Amar Singhald53568e2013-09-26 11:03:45 -07001380
1381 hddLog(VOS_TRACE_LEVEL_INFO,
1382 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1383 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1384 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001385
Chilam Ngc4244af2013-04-01 15:37:32 -07001386
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301387#ifdef WLAN_FEATURE_PACKET_FILTERING
1388 /* Filer was applied during suspend inditication
1389 * clear it when we resume.
1390 */
1391 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001392#endif
1393}
Jeff Johnson295189b2012-06-20 16:38:30 -07001394
Jeff Johnson295189b2012-06-20 16:38:30 -07001395//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001396void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001397{
1398 hdd_context_t *pHddCtx = NULL;
1399 v_CONTEXT_t pVosContext = NULL;
1400
Jeff Johnson295189b2012-06-20 16:38:30 -07001401 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301402 hdd_adapter_t *pAdapter = NULL;
1403 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301404 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001405
Jeff Johnson295189b2012-06-20 16:38:30 -07001406 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1407
1408 //Get the global VOSS context.
1409 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1410 if(!pVosContext) {
1411 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1412 return;
1413 }
1414
1415 //Get the HDD context.
1416 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1417
1418 if(!pHddCtx) {
1419 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1420 return;
1421 }
1422
1423 if (pHddCtx->isLogpInProgress) {
1424 hddLog(VOS_TRACE_LEVEL_ERROR,
1425 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1426 return;
1427 }
1428
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301429 if (pHddCtx->hdd_wlan_suspended)
1430 {
1431 hddLog(VOS_TRACE_LEVEL_ERROR,
1432 "%s: Ignore suspend wlan, Already suspended!", __func__);
1433 return;
1434 }
1435
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301436 pHddCtx->hdd_wlan_suspended = TRUE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301437 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301438 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001439 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1440 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1441 {
1442 pAdapter = pAdapterNode->pAdapter;
1443 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001444 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001445 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1446
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001447 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1449 pAdapterNode = pNext;
1450 continue;
1451 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301452 /* Avoid multiple enter/exit BMPS in this while loop using
1453 * hdd_enter_bmps flag
1454 */
1455 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1456 {
1457 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001458
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301459 /* If device was already in BMPS, and dynamic DTIM is set,
1460 * exit(set the device to full power) and enter BMPS again
1461 * to reflect new DTIM value */
1462 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1463
1464 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1465
1466 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001468#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1469 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1470 {
1471 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001473 netif_tx_disable(pAdapter->dev);
1474 netif_carrier_off(pAdapter->dev);
1475 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301476 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001477 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1478 {
1479 //Execute deep sleep procedure
1480 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1481 }
1482#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301483
1484 /*Suspend notification sent down to driver*/
1485 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1486
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301487 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1488 pAdapterNode = pNext;
1489 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301490
Jeff Johnson295189b2012-06-20 16:38:30 -07001491#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1492 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1493 {
1494 hdd_enter_standby(pHddCtx);
1495 }
1496#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001497
1498 return;
1499}
1500
1501static void hdd_PowerStateChangedCB
1502(
1503 v_PVOID_t callbackContext,
1504 tPmcState newState
1505)
1506{
1507 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301508
Jeff Johnson295189b2012-06-20 16:38:30 -07001509 /* if the driver was not in BMPS during early suspend,
1510 * the dynamic DTIM is now updated at Riva */
1511 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1512 && pHddCtx->cfg_ini->enableDynamicDTIM
1513 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1514 {
1515 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1516 }
1517 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301518 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1519 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001520 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301521 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1522 {
Amar Singhald53568e2013-09-26 11:03:45 -07001523 pHddCtx->sus_res_mcastbcast_filter =
1524 pHddCtx->configuredMcastBcastFilter;
1525 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1526
1527 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1528 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1529 pHddCtx->configuredMcastBcastFilter);
1530 hddLog(VOS_TRACE_LEVEL_INFO,
1531 "offload: calling hdd_conf_mcastbcast_filter");
1532
1533 }
1534
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001536 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301538 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001539 else
Mihir Shete793209f2014-01-06 11:01:12 +05301540 {
1541 /* Android framework can send resume request when the WCN chip is
1542 * in IMPS mode. When the chip exits IMPS mode the firmware will
1543 * restore all the registers to the state they were before the chip
1544 * entered IMPS and so our hardware filter settings confgured by the
1545 * resume request will be lost. So reconfigure the filters on detecting
1546 * a change in the power state of the WCN chip.
1547 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301548 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301549 if (IMPS != newState)
1550 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301551 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301552 if (FALSE == pHddCtx->hdd_wlan_suspended)
1553 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301554 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301555 hddLog(VOS_TRACE_LEVEL_INFO,
1556 "Not in IMPS/BMPS and suspended state");
1557 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1558 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301559 else
1560 {
1561 spin_unlock(&pHddCtx->filter_lock);
1562 }
Mihir Shete793209f2014-01-06 11:01:12 +05301563 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301564 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001565}
1566
Jeff Johnson295189b2012-06-20 16:38:30 -07001567void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1568{
1569 v_CONTEXT_t pVosContext;
1570 tHalHandle smeContext;
1571
1572 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1573 if (NULL == pVosContext)
1574 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001575 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001576 return;
1577 }
1578 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1579 if (NULL == smeContext)
1580 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001581 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 return;
1583 }
1584
1585 spin_lock_init(&pHddCtx->filter_lock);
1586 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1587 pHddCtx->cfg_ini->nEnableSuspend)
1588 {
1589 pmcRegisterDeviceStateUpdateInd(smeContext,
1590 hdd_PowerStateChangedCB, pHddCtx);
1591 }
1592}
1593
1594void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1595{
1596 v_CONTEXT_t pVosContext;
1597 tHalHandle smeContext;
1598
1599 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1600 if (NULL == pVosContext)
1601 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001602 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001603 return;
1604 }
1605 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1606 if (NULL == smeContext)
1607 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001608 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001609 return;
1610 }
1611
1612 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1613 pHddCtx->cfg_ini->nEnableSuspend)
1614 {
1615 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1616 }
1617}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301618
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301619#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301620void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301621{
1622 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301623 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301624 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1625
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301626 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301627 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301628 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1629 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1630 {
1631 vos_mem_copy(&hddGtkOffloadReqParams,
1632 &pHddStaCtx->gtkOffloadReqParams,
1633 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301634
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301635 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1636 &hddGtkOffloadReqParams, pAdapter->sessionId);
1637 if (eHAL_STATUS_SUCCESS != ret)
1638 {
1639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1640 "%s: sme_SetGTKOffload failed, returned %d",
1641 __func__, ret);
1642 return;
1643 }
1644
1645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1646 "%s: sme_SetGTKOffload successfull", __func__);
1647 }
1648
1649 }
1650 else
1651 {
1652 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1653 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1654 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1655 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1656 {
1657
1658 /* Host driver has previously offloaded GTK rekey */
1659 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301660 wlan_hdd_cfg80211_update_replayCounterCallback,
1661 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301662 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301663
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301664 {
1665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1666 "%s: sme_GetGTKOffload failed, returned %d",
1667 __func__, ret);
1668 return;
1669 }
1670 else
1671 {
1672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1673 "%s: sme_GetGTKOffload successful",
1674 __func__);
1675
1676 /* Sending GTK offload dissable */
1677 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1678 sizeof (tSirGtkOffloadParams));
1679 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1680 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301681 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301682 if (eHAL_STATUS_SUCCESS != ret)
1683 {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1685 "%s: failed to dissable GTK offload, returned %d",
1686 __func__, ret);
1687 return;
1688 }
1689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1690 "%s: successfully dissabled GTK offload request to HAL",
1691 __func__);
1692 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301693 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301694 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301695 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301696}
1697#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001698
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001699void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001700{
1701 hdd_context_t *pHddCtx = NULL;
1702 hdd_adapter_t *pAdapter = NULL;
1703 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1704 VOS_STATUS status;
1705 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001706
Jeff Johnson295189b2012-06-20 16:38:30 -07001707 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1708
1709 //Get the global VOSS context.
1710 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1711 if(!pVosContext) {
1712 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1713 return;
1714 }
1715
1716 //Get the HDD context.
1717 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1718
1719 if(!pHddCtx) {
1720 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1721 return;
1722 }
1723
Agarwal Ashish971c2882013-10-30 20:11:12 +05301724 if (pHddCtx->isLogpInProgress)
1725 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001726 hddLog(VOS_TRACE_LEVEL_INFO,
1727 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1728 return;
1729 }
1730
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301731 if (!pHddCtx->hdd_wlan_suspended)
1732 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05301733 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301734 "%s: Ignore resume wlan, Already resumed!", __func__);
1735 return;
1736 }
1737
Jeff Johnson295189b2012-06-20 16:38:30 -07001738 pHddCtx->hdd_wlan_suspended = FALSE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301739 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
Jeff Johnson295189b2012-06-20 16:38:30 -07001740 /*loop through all adapters. Concurrency */
1741 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1742
1743 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1744 {
1745 pAdapter = pAdapterNode->pAdapter;
1746 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001747 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001749 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001750 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1751 pAdapterNode = pNext;
1752 continue;
1753 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301754
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301755
Jeff Johnson295189b2012-06-20 16:38:30 -07001756#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1757 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1758 {
1759 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1760 hdd_exit_deep_sleep(pAdapter);
1761 }
1762#endif
1763
1764 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1765 {
1766 /*Switch back to DTIM 1*/
1767 tSirSetPowerParamsReq powerRequest = { 0 };
1768
1769 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1770 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001771 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001772
1773 /*Disabled ModulatedDTIM if enabled on suspend*/
1774 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1775 powerRequest.uDTIMPeriod = 0;
1776
1777 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1778 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1779 NULL, eANI_BOOLEAN_FALSE);
1780 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1781 NULL, eANI_BOOLEAN_FALSE);
1782
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001784 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001785 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001786
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301787 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1788 {
1789 /* put the device into full power */
1790 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001791
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301792 /* put the device back into BMPS */
1793 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001794
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301795 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1796 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 }
1798
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301799 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1801 pAdapterNode = pNext;
1802 }
1803
1804#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1805 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1806 {
1807 hdd_exit_standby(pHddCtx);
1808 }
1809#endif
1810
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 return;
1812}
1813
Jeff Johnson295189b2012-06-20 16:38:30 -07001814VOS_STATUS hdd_wlan_reset_initialization(void)
1815{
Jeff Johnson295189b2012-06-20 16:38:30 -07001816 v_CONTEXT_t pVosContext = NULL;
1817
1818 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1819
1820 //Get the global VOSS context.
1821 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1822 if(!pVosContext)
1823 {
1824 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1825 return VOS_STATUS_E_FAILURE;
1826 }
1827
1828 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1829
1830 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301831 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07001832
Jeff Johnson295189b2012-06-20 16:38:30 -07001833 return VOS_STATUS_SUCCESS;
1834}
1835
1836
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001837/*
1838 * Based on the ioctl command recieved by HDD, put WLAN driver
1839 * into the quiet mode. This is the same as the early suspend
1840 * notification that driver used to listen
1841 */
1842void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001843{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301844 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001845 if (suspend)
1846 hdd_suspend_wlan();
1847 else
1848 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301849 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001850}
1851
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001852static void hdd_ssr_timer_init(void)
1853{
1854 init_timer(&ssr_timer);
1855}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001856
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001857static void hdd_ssr_timer_del(void)
1858{
1859 del_timer(&ssr_timer);
1860 ssr_timer_started = false;
1861}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001862
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001863static void hdd_ssr_timer_cb(unsigned long data)
1864{
1865 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001866
1867#ifdef WCN_PRONTO
1868 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1869 wcnss_pronto_log_debug_regs();
1870#endif
1871
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001872 VOS_BUG(0);
1873}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001874
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001875static void hdd_ssr_timer_start(int msec)
1876{
1877 if(ssr_timer_started)
1878 {
1879 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1880 ,__func__);
1881 }
1882 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1883 ssr_timer.function = hdd_ssr_timer_cb;
1884 add_timer(&ssr_timer);
1885 ssr_timer_started = true;
1886}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001887
Jeff Johnson295189b2012-06-20 16:38:30 -07001888/* the HDD interface to WLAN driver shutdown,
1889 * the primary shutdown function in SSR
1890 */
1891VOS_STATUS hdd_wlan_shutdown(void)
1892{
1893 VOS_STATUS vosStatus;
1894 v_CONTEXT_t pVosContext = NULL;
1895 hdd_context_t *pHddCtx = NULL;
1896 pVosSchedContext vosSchedContext = NULL;
1897
1898 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1899
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001900 /* if re-init never happens, then do SSR1 */
1901 hdd_ssr_timer_init();
1902 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1903
Jeff Johnson295189b2012-06-20 16:38:30 -07001904 /* Get the global VOSS context. */
1905 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1906 if(!pVosContext) {
1907 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1908 return VOS_STATUS_E_FAILURE;
1909 }
1910 /* Get the HDD context. */
1911 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1912 if(!pHddCtx) {
1913 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1914 return VOS_STATUS_E_FAILURE;
1915 }
c_hpothud662a352013-12-26 15:09:12 +05301916
1917 //Stop the traffic monitor timer
1918 if ( VOS_TIMER_STATE_RUNNING ==
1919 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1920 {
1921 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1922 }
1923
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05301924 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Jeff Johnson295189b2012-06-20 16:38:30 -07001925 hdd_reset_all_adapters(pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +05301926
1927 /* set default value of Tcp delack and stop timer */
1928 hdd_set_default_stop_delack_timer(pHddCtx);
1929
Jeff Johnson295189b2012-06-20 16:38:30 -07001930 /* DeRegister with platform driver as client for Suspend/Resume */
1931 vosStatus = hddDeregisterPmOps(pHddCtx);
1932 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1933 {
1934 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1935 }
1936
1937 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1938 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1939 {
1940 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1941 }
1942
1943 /* Disable IMPS/BMPS as we do not want the device to enter any power
1944 * save mode on its own during reset sequence
1945 */
1946 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1947 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1948 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1949
1950 vosSchedContext = get_vos_sched_ctxt();
1951
1952 /* Wakeup all driver threads */
1953 if(TRUE == pHddCtx->isMcThreadSuspended){
1954 complete(&vosSchedContext->ResumeMcEvent);
1955 pHddCtx->isMcThreadSuspended= FALSE;
1956 }
1957 if(TRUE == pHddCtx->isTxThreadSuspended){
1958 complete(&vosSchedContext->ResumeTxEvent);
1959 pHddCtx->isTxThreadSuspended= FALSE;
1960 }
1961 if(TRUE == pHddCtx->isRxThreadSuspended){
1962 complete(&vosSchedContext->ResumeRxEvent);
1963 pHddCtx->isRxThreadSuspended= FALSE;
1964 }
1965 /* Reset the Suspend Variable */
1966 pHddCtx->isWlanSuspended = FALSE;
1967
1968 /* Stop all the threads; we do not want any messages to be a processed,
1969 * any more and the best way to ensure that is to terminate the threads
1970 * gracefully.
1971 */
1972 /* Wait for MC to exit */
1973 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1974 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1975 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1976 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301977 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001978
1979 /* Wait for TX to exit */
1980 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1981 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1982 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1983 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301984 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001985
1986 /* Wait for RX to exit */
1987 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1988 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1989 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1990 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301991
Mihir Sheteb5425f72013-12-19 09:06:13 +05301992 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001993
1994#ifdef WLAN_BTAMP_FEATURE
1995 vosStatus = WLANBAP_Stop(pVosContext);
1996 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1997 {
1998 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1999 "%s: Failed to stop BAP",__func__);
2000 }
2001#endif //WLAN_BTAMP_FEATURE
2002 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302003 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2004 {
2005 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2006 "%s: Failed to stop wda %d", __func__, vosStatus);
2007 VOS_ASSERT(0);
2008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002009
2010 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2011 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2012 * on threads being running to process the SYS Stop
2013 */
Kiet Lama72a2322013-11-15 11:18:11 +05302014 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302015 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2016 {
2017 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2018 "%s: Failed to stop sme %d", __func__, vosStatus);
2019 VOS_ASSERT(0);
2020 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002021
2022 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2023 /* Stop MAC (PE and HAL) */
2024 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302025 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2026 {
2027 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2028 "%s: Failed to stop mac %d", __func__, vosStatus);
2029 VOS_ASSERT(0);
2030 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002031
2032 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2033 /* Stop TL */
2034 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302035 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2036 {
2037 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2038 "%s: Failed to stop TL %d", __func__, vosStatus);
2039 VOS_ASSERT(0);
2040 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002041
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002043 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2044 /* Clean up message queues of TX and MC thread */
2045 vos_sched_flush_mc_mqs(vosSchedContext);
2046 vos_sched_flush_tx_mqs(vosSchedContext);
2047 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302048#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2049 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302050 /*Free fw dump mem in case of SSR/Shutdown */
2051 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2052 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302053#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002054
2055 /* Deinit all the TX and MC queues */
2056 vos_sched_deinit_mqs(vosSchedContext);
2057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2058
2059 /* shutdown VOSS */
2060 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302061
2062 /*mac context has already been released in mac_close call
2063 so setting it to NULL in hdd context*/
2064 pHddCtx->hHal = (tHalHandle)NULL;
2065
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 if (free_riva_power_on_lock("wlan"))
2067 {
2068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2069 __func__);
2070 }
2071 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2072 ,__func__);
2073 return VOS_STATUS_SUCCESS;
2074}
2075
2076
2077
2078/* the HDD interface to WLAN driver re-init.
2079 * This is called to initialize/start WLAN driver after a shutdown.
2080 */
2081VOS_STATUS hdd_wlan_re_init(void)
2082{
2083 VOS_STATUS vosStatus;
2084 v_CONTEXT_t pVosContext = NULL;
2085 hdd_context_t *pHddCtx = NULL;
2086 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002087#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2088 int max_retries = 0;
2089#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302090#ifdef HAVE_CBC_DONE
2091 int max_cbc_retries = 0;
2092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002093#ifdef WLAN_BTAMP_FEATURE
2094 hdd_config_t *pConfig = NULL;
2095 WLANBAP_ConfigType btAmpConfig;
2096#endif
2097
Katya Nigam82a93062014-06-04 15:15:36 +05302098 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002099 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302100 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002101
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002102#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2103 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002104 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002105 msleep(1000);
2106 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002107 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002108 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2109 goto err_re_init;
2110 }
2111#endif
2112
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302113#ifdef HAVE_CBC_DONE
2114 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2115 msleep(1000);
2116 }
2117 if (max_cbc_retries >= 20) {
2118 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2119 }
2120#endif
2121
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002122 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2123
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002124 /* The driver should always be initialized in STA mode after SSR */
2125 hdd_set_conparam(0);
2126
Katya Nigam82a93062014-06-04 15:15:36 +05302127 dev = wcnss_wlan_get_device();
2128 if (NULL == dev)
2129 {
2130 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2131 goto err_re_init;
2132 }
2133
Jeff Johnson295189b2012-06-20 16:38:30 -07002134 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302135 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002136 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2137 {
2138 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2139 goto err_re_init;
2140 }
2141
2142 /* Get the HDD context. */
2143 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2144 if(!pHddCtx)
2145 {
2146 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2147 goto err_vosclose;
2148 }
2149
2150 /* Save the hal context in Adapter */
2151 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2152 if ( NULL == pHddCtx->hHal )
2153 {
2154 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2155 goto err_vosclose;
2156 }
2157
2158 /* Set the SME configuration parameters. */
2159 vosStatus = hdd_set_sme_config(pHddCtx);
2160 if ( VOS_STATUS_SUCCESS != vosStatus )
2161 {
2162 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2163 goto err_vosclose;
2164 }
2165
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 vosStatus = vos_preStart( pHddCtx->pvosContext );
2167 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2168 {
2169 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2170 goto err_vosclose;
2171 }
2172
2173 /* In the integrated architecture we update the configuration from
2174 the INI file and from NV before vOSS has been started so that
2175 the final contents are available to send down to the cCPU */
2176 /* Apply the cfg.ini to cfg.dat */
2177 if (FALSE == hdd_update_config_dat(pHddCtx))
2178 {
2179 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2180 goto err_vosclose;
2181 }
2182
2183 /* Set the MAC Address, currently this is used by HAL to add self sta.
2184 * Remove this once self sta is added as part of session open. */
2185 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2186 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2187 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2188 if (!HAL_STATUS_SUCCESS(halStatus))
2189 {
2190 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2191 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2192 goto err_vosclose;
2193 }
2194
2195 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2196 Note: Firmware image will be read and downloaded inside vos_start API */
2197 vosStatus = vos_start( pVosContext );
2198 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2199 {
2200 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +05302201 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 goto err_vosclose;
2203 }
2204
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002205 /* Exchange capability info between Host and FW and also get versioning info from FW */
2206 hdd_exchange_version_and_caps(pHddCtx);
2207
Jeff Johnson295189b2012-06-20 16:38:30 -07002208 vosStatus = hdd_post_voss_start_config( pHddCtx );
2209 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2210 {
2211 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2212 __func__);
2213 goto err_vosstop;
2214 }
2215
Mihir Shete04206452014-11-20 17:50:58 +05302216#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302217 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2218 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2219 {
2220 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2221 __func__);
2222 goto err_vosstop;
2223 }
Mihir Shete04206452014-11-20 17:50:58 +05302224#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302225
Jeff Johnson295189b2012-06-20 16:38:30 -07002226#ifdef WLAN_BTAMP_FEATURE
2227 vosStatus = WLANBAP_Open(pVosContext);
2228 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2229 {
2230 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2231 "%s: Failed to open BAP",__func__);
2232 goto err_vosstop;
2233 }
2234 vosStatus = BSL_Init(pVosContext);
2235 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2236 {
2237 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2238 "%s: Failed to Init BSL",__func__);
2239 goto err_bap_close;
2240 }
2241 vosStatus = WLANBAP_Start(pVosContext);
2242 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2243 {
2244 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2245 "%s: Failed to start TL",__func__);
2246 goto err_bap_close;
2247 }
2248 pConfig = pHddCtx->cfg_ini;
2249 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2250 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2251#endif //WLAN_BTAMP_FEATURE
2252
2253 /* Restart all adapters */
2254 hdd_start_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302256 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002257 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302258 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 /* Register with platform driver as client for Suspend/Resume */
2260 vosStatus = hddRegisterPmOps(pHddCtx);
2261 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2262 {
2263 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2264 goto err_bap_stop;
2265 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302266
2267#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2268 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2269 (pHddCtx->cfg_ini->enableFWLogging ||
2270 pHddCtx->cfg_ini->enableMgmtLogging ||
2271 pHddCtx->cfg_ini->enableContFWLogging))
2272 {
2273 hdd_init_frame_logging(pHddCtx);
2274 }
2275#endif
2276
Jeff Johnson295189b2012-06-20 16:38:30 -07002277 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302278 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002279 /* register for riva power on lock */
2280 if (req_riva_power_on_lock("wlan"))
2281 {
2282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2283 __func__);
2284 goto err_unregister_pmops;
2285 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302286 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002287 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302288#ifdef WLAN_FEATURE_EXTSCAN
2289 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2290 wlan_hdd_cfg80211_extscan_callback,
2291 pHddCtx);
2292#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302293
2294#ifdef FEATURE_OEM_DATA_SUPPORT
2295 sme_OemDataRegisterCallback(pHddCtx->hHal,
2296 wlan_hdd_cfg80211_oemdata_callback,
2297 pHddCtx);
2298#endif /* FEATURE_OEM_DATA_SUPPORT */
2299
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 goto success;
2301
2302err_unregister_pmops:
2303 hddDeregisterPmOps(pHddCtx);
2304
2305err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002306#ifdef CONFIG_HAS_EARLYSUSPEND
2307 hdd_unregister_mcast_bcast_filter(pHddCtx);
2308#endif
2309 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002310#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002311 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002312#endif
2313
2314#ifdef WLAN_BTAMP_FEATURE
2315err_bap_close:
2316 WLANBAP_Close(pVosContext);
2317#endif
2318
2319err_vosstop:
2320 vos_stop(pVosContext);
2321
2322err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302323 if(!isSsrPanicOnFailure())
2324 {
2325 /* If we hit this, it means wlan driver is in bad state and needs
2326 * driver unload and load.
2327 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302328 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2329 return VOS_STATUS_E_FAILURE;
2330 }
2331
Jeff Johnson295189b2012-06-20 16:38:30 -07002332 vos_close(pVosContext);
2333 vos_sched_close(pVosContext);
2334 if (pHddCtx)
2335 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002336 /* Unregister the Net Device Notifier */
2337 unregister_netdevice_notifier(&hdd_netdev_notifier);
2338 /* Clean up HDD Nlink Service */
2339 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002340#ifdef WLAN_KD_READY_NOTIFIER
2341 nl_srv_exit(pHddCtx->ptt_pid);
2342#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002344#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002345 /* Free up dynamically allocated members inside HDD Adapter */
2346 kfree(pHddCtx->cfg_ini);
2347 pHddCtx->cfg_ini= NULL;
2348
Jeff Johnson295189b2012-06-20 16:38:30 -07002349 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302350 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002351 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002352 }
2353 vos_preClose(&pVosContext);
2354
2355#ifdef MEMORY_DEBUG
2356 vos_mem_exit();
2357#endif
2358
2359err_re_init:
2360 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302361 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002362 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002363 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002364 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002365
2366success:
2367 /* Trigger replay of BTC events */
2368 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2369 return VOS_STATUS_SUCCESS;
2370}