blob: ca0119f0ef336f6ef8ccae79ce311526515de864 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=============================================================================
29* wlan_hdd_early_suspend.c
30*
31* \brief power management functions
32*
33* Description
Jeff Johnson295189b2012-06-20 16:38:30 -070034*
35==============================================================================**/
36/* $HEADER$ */
37
38/**-----------------------------------------------------------------------------
39* Include files
40* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42#include <linux/pm.h>
43#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070044#include <wlan_hdd_includes.h>
45#include <wlan_qct_driver.h>
46#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48#include "halTypes.h"
49#include "sme_Api.h"
50#include <vos_api.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070051#include <vos_sched.h>
52#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <wlan_qct_sys.h>
54#include <wlan_btc_svc.h>
55#include <wlan_nlink_common.h>
56#include <wlan_hdd_main.h>
57#include <wlan_hdd_assoc.h>
58#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070059#include <wlan_nlink_srv.h>
60#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070061#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062
Jeff Johnson295189b2012-06-20 16:38:30 -070063#include <linux/semaphore.h>
64#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include "cfgApi.h"
Siddharth Bhal7bd19932015-03-03 16:54:36 +053066#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067
68#ifdef WLAN_BTAMP_FEATURE
69#include "bapApi.h"
70#include "bap_hdd_main.h"
71#include "bap_hdd_misc.h"
72#endif
73
Jeff Johnsone7245742012-09-05 17:12:55 -070074#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070075#include <linux/inetdevice.h>
76#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053077#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053078#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070079/**-----------------------------------------------------------------------------
80* Preprocessor definitions and constants
81* ----------------------------------------------------------------------------*/
82
83/**-----------------------------------------------------------------------------
84* Type declarations
85* ----------------------------------------------------------------------------*/
86
87/**-----------------------------------------------------------------------------
88* Function and variables declarations
89* ----------------------------------------------------------------------------*/
90#include "wlan_hdd_power.h"
91#include "wlan_hdd_packet_filtering.h"
92
Sameer Thalappile5637f42013-08-07 15:46:55 -070093#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053094#define NS_DEFAULT_SLOT_INDEX 4
95#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070096
97static eHalStatus g_full_pwr_status;
98static eHalStatus g_standby_status;
99
100extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700104extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700106static struct timer_list ssr_timer;
107static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109//Callback invoked by PMC to report status of standby request
110void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
111{
112 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
114 g_standby_status = status;
115
116 if(eHAL_STATUS_SUCCESS == status)
117 {
118 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
119 }
120 else
121 {
122 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
123 }
124
125 complete(&pHddCtx->standby_comp_var);
126}
127
128//Callback invoked by PMC to report status of full power request
129void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
130{
131 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
133 g_full_pwr_status = status;
134
135 if(eHAL_STATUS_SUCCESS == status)
136 {
137 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
138 }
139 else
140 {
141 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
142 }
143
144 complete(&pHddCtx->full_pwr_comp_var);
145}
146
147eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
148{
149 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530150 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700151
152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
153 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
154
155 g_full_pwr_status = eHAL_STATUS_FAILURE;
156 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
157 eSME_FULL_PWR_NEEDED_BY_HDD);
158
159 if(status == eHAL_STATUS_PMC_PENDING)
160 {
161 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530162 ret = wait_for_completion_interruptible_timeout(
163 &pHddCtx->full_pwr_comp_var,
164 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
165 if (0 >= ret)
166 {
167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
168 __func__, ret);
169 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700170 status = g_full_pwr_status;
171 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
172 {
173 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
174 VOS_ASSERT(0);
175 goto failure;
176 }
177 }
178 else if(status != eHAL_STATUS_SUCCESS)
179 {
180 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
181 __func__, status);
182 VOS_ASSERT(0);
183 goto failure;
184 }
185 else
186 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
187
188failure:
189 //No blocking to reduce latency. No other device should be depending on WLAN
190 //to finish resume and WLAN won't be instantly on after resume
191 return status;
192}
193
194
195//Helper routine to put the chip into standby
196VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
197{
198 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
199 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530200 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202 //Disable IMPS/BMPS as we do not want the device to enter any power
203 //save mode on its own during suspend sequence
204 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
205 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
206
207 //Note we do not disable queues unnecessarily. Queues should already be disabled
208 //if STA is disconnected or the queue will be disabled as and when disconnect
209 //happens because of standby procedure.
210
211 //Ensure that device is in full power first. There is scope for optimization
212 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
213 //Core s/w needs to be optimized to handle this. Until then we request full
214 //power before issuing request for standby.
215 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
216 g_full_pwr_status = eHAL_STATUS_FAILURE;
217 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
218 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
219
220 if(halStatus == eHAL_STATUS_PMC_PENDING)
221 {
222 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530223 ret = wait_for_completion_interruptible_timeout(
224 &pHddCtx->full_pwr_comp_var,
225 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
226 if (0 >= ret)
227 {
228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
229 __func__, ret);
230 }
231
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
233 {
234 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
235 VOS_ASSERT(0);
236 vosStatus = VOS_STATUS_E_FAILURE;
237 goto failure;
238 }
239 }
240 else if(halStatus != eHAL_STATUS_SUCCESS)
241 {
242 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
243 __func__, halStatus);
244 VOS_ASSERT(0);
245 vosStatus = VOS_STATUS_E_FAILURE;
246 goto failure;
247 }
248
249 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
250 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
251 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
252 }
253
254 //Request standby. Standby will cause the STA to disassociate first. TX queues
255 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
256 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
257 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
258 //when there are concurrent sessions.
259 INIT_COMPLETION(pHddCtx->standby_comp_var);
260 g_standby_status = eHAL_STATUS_FAILURE;
261 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
262
263 if (halStatus == eHAL_STATUS_PMC_PENDING)
264 {
265 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530266 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530268 if (0 >= ret)
269 {
270 hddLog(VOS_TRACE_LEVEL_ERROR,
271 FL("wait on standby_comp_var failed %ld"), ret);
272 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
274 {
275 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
276 VOS_ASSERT(0);
277 vosStatus = VOS_STATUS_E_FAILURE;
278 goto failure;
279 }
280 }
281 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
283 __func__, halStatus);
284 VOS_ASSERT(0);
285 vosStatus = VOS_STATUS_E_FAILURE;
286 goto failure;
287 }
288 else
289 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
290
291failure:
292 //Restore IMPS config
293 if(pHddCtx->cfg_ini->fIsImpsEnabled)
294 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
295
296 //Restore BMPS config
297 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
298 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
299
300 return vosStatus;
301}
302
303
304//Helper routine for Deep sleep entry
305VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
306{
307 eHalStatus halStatus;
308 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530309 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800310
Jeff Johnson295189b2012-06-20 16:38:30 -0700311 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530312 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700313 netif_tx_disable(pAdapter->dev);
314 netif_carrier_off(pAdapter->dev);
315
316 //Disable IMPS,BMPS as we do not want the device to enter any power
317 //save mode on it own during suspend sequence
318 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
319 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
320
321 //Ensure that device is in full power as we will touch H/W during vos_Stop
322 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
323 g_full_pwr_status = eHAL_STATUS_FAILURE;
324 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
325 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
326
327 if(halStatus == eHAL_STATUS_PMC_PENDING)
328 {
329 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530330 ret = wait_for_completion_interruptible_timeout(
331 &pHddCtx->full_pwr_comp_var,
332 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
333 if (0 >= ret)
334 {
335 hddLog(VOS_TRACE_LEVEL_ERROR,
336 FL("wait on full_pwr_comp_var failed %ld"), ret);
337 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
339 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
340 VOS_ASSERT(0);
341 }
342 }
343 else if(halStatus != eHAL_STATUS_SUCCESS)
344 {
345 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
346 VOS_ASSERT(0);
347 }
348
349 //Issue a disconnect. This is required to inform the supplicant that
350 //STA is getting disassociated and for GUI to be updated properly
351 INIT_COMPLETION(pAdapter->disconnect_comp_var);
352 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
353
354 //Success implies disconnect command got queued up successfully
355 if(halStatus == eHAL_STATUS_SUCCESS)
356 {
357 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530358 ret = wait_for_completion_interruptible_timeout(
359 &pAdapter->disconnect_comp_var,
360 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
361 if (0 >= ret)
362 {
363 hddLog(VOS_TRACE_LEVEL_ERROR,
364 FL("wait on disconnect_comp_var failed %ld"), ret);
365 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700366 }
367
368
369 //None of the steps should fail after this. Continue even in case of failure
370 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530371 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
372 {
373 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
374 __func__, vosStatus);
375 VOS_ASSERT(0);
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;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301437 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1439 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1440 {
1441 pAdapter = pAdapterNode->pAdapter;
1442 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001443 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001444 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1445
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001446 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1448 pAdapterNode = pNext;
1449 continue;
1450 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301451 /* Avoid multiple enter/exit BMPS in this while loop using
1452 * hdd_enter_bmps flag
1453 */
1454 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1455 {
1456 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001457
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301458 /* If device was already in BMPS, and dynamic DTIM is set,
1459 * exit(set the device to full power) and enter BMPS again
1460 * to reflect new DTIM value */
1461 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1462
1463 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1464
1465 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001467#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1468 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1469 {
1470 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301471 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001472 netif_tx_disable(pAdapter->dev);
1473 netif_carrier_off(pAdapter->dev);
1474 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301475 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001476 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1477 {
1478 //Execute deep sleep procedure
1479 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1480 }
1481#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301482
1483 /*Suspend notification sent down to driver*/
1484 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1485
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301486 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1487 pAdapterNode = pNext;
1488 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301489
Jeff Johnson295189b2012-06-20 16:38:30 -07001490#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1491 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1492 {
1493 hdd_enter_standby(pHddCtx);
1494 }
1495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001496
1497 return;
1498}
1499
1500static void hdd_PowerStateChangedCB
1501(
1502 v_PVOID_t callbackContext,
1503 tPmcState newState
1504)
1505{
1506 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301507
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 /* if the driver was not in BMPS during early suspend,
1509 * the dynamic DTIM is now updated at Riva */
1510 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1511 && pHddCtx->cfg_ini->enableDynamicDTIM
1512 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1513 {
1514 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1515 }
1516 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301517 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1518 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301520 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1521 {
Amar Singhald53568e2013-09-26 11:03:45 -07001522 pHddCtx->sus_res_mcastbcast_filter =
1523 pHddCtx->configuredMcastBcastFilter;
1524 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1525
1526 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1527 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1528 pHddCtx->configuredMcastBcastFilter);
1529 hddLog(VOS_TRACE_LEVEL_INFO,
1530 "offload: calling hdd_conf_mcastbcast_filter");
1531
1532 }
1533
Jeff Johnson295189b2012-06-20 16:38:30 -07001534 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301537 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001538 else
Mihir Shete793209f2014-01-06 11:01:12 +05301539 {
1540 /* Android framework can send resume request when the WCN chip is
1541 * in IMPS mode. When the chip exits IMPS mode the firmware will
1542 * restore all the registers to the state they were before the chip
1543 * entered IMPS and so our hardware filter settings confgured by the
1544 * resume request will be lost. So reconfigure the filters on detecting
1545 * a change in the power state of the WCN chip.
1546 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301547 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301548 if (IMPS != newState)
1549 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301550 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301551 if (FALSE == pHddCtx->hdd_wlan_suspended)
1552 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301553 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301554 hddLog(VOS_TRACE_LEVEL_INFO,
1555 "Not in IMPS/BMPS and suspended state");
1556 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1557 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301558 else
1559 {
1560 spin_unlock(&pHddCtx->filter_lock);
1561 }
Mihir Shete793209f2014-01-06 11:01:12 +05301562 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001564}
1565
Jeff Johnson295189b2012-06-20 16:38:30 -07001566void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1567{
1568 v_CONTEXT_t pVosContext;
1569 tHalHandle smeContext;
1570
1571 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1572 if (NULL == pVosContext)
1573 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001574 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 return;
1576 }
1577 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1578 if (NULL == smeContext)
1579 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001580 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 return;
1582 }
1583
1584 spin_lock_init(&pHddCtx->filter_lock);
1585 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1586 pHddCtx->cfg_ini->nEnableSuspend)
1587 {
1588 pmcRegisterDeviceStateUpdateInd(smeContext,
1589 hdd_PowerStateChangedCB, pHddCtx);
1590 }
1591}
1592
1593void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1594{
1595 v_CONTEXT_t pVosContext;
1596 tHalHandle smeContext;
1597
1598 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1599 if (NULL == pVosContext)
1600 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001601 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 return;
1603 }
1604 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1605 if (NULL == smeContext)
1606 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001607 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 return;
1609 }
1610
1611 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1612 pHddCtx->cfg_ini->nEnableSuspend)
1613 {
1614 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1615 }
1616}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301617
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301618#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301619void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301620{
1621 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301622 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301623 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1624
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301625 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301626 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301627 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1628 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1629 {
1630 vos_mem_copy(&hddGtkOffloadReqParams,
1631 &pHddStaCtx->gtkOffloadReqParams,
1632 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301633
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301634 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1635 &hddGtkOffloadReqParams, pAdapter->sessionId);
1636 if (eHAL_STATUS_SUCCESS != ret)
1637 {
1638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1639 "%s: sme_SetGTKOffload failed, returned %d",
1640 __func__, ret);
1641 return;
1642 }
1643
1644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1645 "%s: sme_SetGTKOffload successfull", __func__);
1646 }
1647
1648 }
1649 else
1650 {
1651 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1652 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1653 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1654 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1655 {
1656
1657 /* Host driver has previously offloaded GTK rekey */
1658 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301659 wlan_hdd_cfg80211_update_replayCounterCallback,
1660 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301661 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301662
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301663 {
1664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 "%s: sme_GetGTKOffload failed, returned %d",
1666 __func__, ret);
1667 return;
1668 }
1669 else
1670 {
1671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1672 "%s: sme_GetGTKOffload successful",
1673 __func__);
1674
1675 /* Sending GTK offload dissable */
1676 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1677 sizeof (tSirGtkOffloadParams));
1678 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1679 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301680 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301681 if (eHAL_STATUS_SUCCESS != ret)
1682 {
1683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1684 "%s: failed to dissable GTK offload, returned %d",
1685 __func__, ret);
1686 return;
1687 }
1688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1689 "%s: successfully dissabled GTK offload request to HAL",
1690 __func__);
1691 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301692 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301693 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301694 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301695}
1696#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001697
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001698void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001699{
1700 hdd_context_t *pHddCtx = NULL;
1701 hdd_adapter_t *pAdapter = NULL;
1702 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1703 VOS_STATUS status;
1704 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001705
Jeff Johnson295189b2012-06-20 16:38:30 -07001706 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1707
1708 //Get the global VOSS context.
1709 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1710 if(!pVosContext) {
1711 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1712 return;
1713 }
1714
1715 //Get the HDD context.
1716 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1717
1718 if(!pHddCtx) {
1719 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1720 return;
1721 }
1722
Agarwal Ashish971c2882013-10-30 20:11:12 +05301723 if (pHddCtx->isLogpInProgress)
1724 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001725 hddLog(VOS_TRACE_LEVEL_INFO,
1726 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1727 return;
1728 }
1729
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301730 if (!pHddCtx->hdd_wlan_suspended)
1731 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05301732 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301733 "%s: Ignore resume wlan, Already resumed!", __func__);
1734 return;
1735 }
1736
Jeff Johnson295189b2012-06-20 16:38:30 -07001737 pHddCtx->hdd_wlan_suspended = FALSE;
1738 /*loop through all adapters. Concurrency */
1739 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1740
1741 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1742 {
1743 pAdapter = pAdapterNode->pAdapter;
1744 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001745 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001747 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1749 pAdapterNode = pNext;
1750 continue;
1751 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301752
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301753
Jeff Johnson295189b2012-06-20 16:38:30 -07001754#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1755 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1756 {
1757 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1758 hdd_exit_deep_sleep(pAdapter);
1759 }
1760#endif
1761
1762 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1763 {
1764 /*Switch back to DTIM 1*/
1765 tSirSetPowerParamsReq powerRequest = { 0 };
1766
1767 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1768 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001769 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001770
1771 /*Disabled ModulatedDTIM if enabled on suspend*/
1772 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1773 powerRequest.uDTIMPeriod = 0;
1774
1775 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1776 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1777 NULL, eANI_BOOLEAN_FALSE);
1778 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1779 NULL, eANI_BOOLEAN_FALSE);
1780
1781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001782 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001783 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001784
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301785 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1786 {
1787 /* put the device into full power */
1788 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001789
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301790 /* put the device back into BMPS */
1791 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001792
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301793 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001795 }
1796
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301797 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001798 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1799 pAdapterNode = pNext;
1800 }
1801
1802#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1803 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1804 {
1805 hdd_exit_standby(pHddCtx);
1806 }
1807#endif
1808
Jeff Johnson295189b2012-06-20 16:38:30 -07001809 return;
1810}
1811
Jeff Johnson295189b2012-06-20 16:38:30 -07001812VOS_STATUS hdd_wlan_reset_initialization(void)
1813{
Jeff Johnson295189b2012-06-20 16:38:30 -07001814 v_CONTEXT_t pVosContext = NULL;
1815
1816 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1817
1818 //Get the global VOSS context.
1819 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1820 if(!pVosContext)
1821 {
1822 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1823 return VOS_STATUS_E_FAILURE;
1824 }
1825
1826 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1827
1828 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301829 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07001830
Jeff Johnson295189b2012-06-20 16:38:30 -07001831 return VOS_STATUS_SUCCESS;
1832}
1833
1834
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001835/*
1836 * Based on the ioctl command recieved by HDD, put WLAN driver
1837 * into the quiet mode. This is the same as the early suspend
1838 * notification that driver used to listen
1839 */
1840void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001841{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301842 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001843 if (suspend)
1844 hdd_suspend_wlan();
1845 else
1846 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301847 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001848}
1849
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001850static void hdd_ssr_timer_init(void)
1851{
1852 init_timer(&ssr_timer);
1853}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001854
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001855static void hdd_ssr_timer_del(void)
1856{
1857 del_timer(&ssr_timer);
1858 ssr_timer_started = false;
1859}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001860
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001861static void hdd_ssr_timer_cb(unsigned long data)
1862{
1863 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001864
1865#ifdef WCN_PRONTO
1866 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1867 wcnss_pronto_log_debug_regs();
1868#endif
1869
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001870 VOS_BUG(0);
1871}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001872
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001873static void hdd_ssr_timer_start(int msec)
1874{
1875 if(ssr_timer_started)
1876 {
1877 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1878 ,__func__);
1879 }
1880 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1881 ssr_timer.function = hdd_ssr_timer_cb;
1882 add_timer(&ssr_timer);
1883 ssr_timer_started = true;
1884}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001885
Jeff Johnson295189b2012-06-20 16:38:30 -07001886/* the HDD interface to WLAN driver shutdown,
1887 * the primary shutdown function in SSR
1888 */
1889VOS_STATUS hdd_wlan_shutdown(void)
1890{
1891 VOS_STATUS vosStatus;
1892 v_CONTEXT_t pVosContext = NULL;
1893 hdd_context_t *pHddCtx = NULL;
1894 pVosSchedContext vosSchedContext = NULL;
1895
1896 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1897
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001898 /* if re-init never happens, then do SSR1 */
1899 hdd_ssr_timer_init();
1900 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1901
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 /* Get the global VOSS context. */
1903 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1904 if(!pVosContext) {
1905 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1906 return VOS_STATUS_E_FAILURE;
1907 }
1908 /* Get the HDD context. */
1909 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1910 if(!pHddCtx) {
1911 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1912 return VOS_STATUS_E_FAILURE;
1913 }
c_hpothud662a352013-12-26 15:09:12 +05301914
1915 //Stop the traffic monitor timer
1916 if ( VOS_TIMER_STATE_RUNNING ==
1917 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1918 {
1919 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1920 }
1921
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 hdd_reset_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 /* DeRegister with platform driver as client for Suspend/Resume */
1924 vosStatus = hddDeregisterPmOps(pHddCtx);
1925 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1926 {
1927 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1928 }
1929
1930 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1931 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1932 {
1933 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1934 }
1935
1936 /* Disable IMPS/BMPS as we do not want the device to enter any power
1937 * save mode on its own during reset sequence
1938 */
1939 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1940 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1941 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1942
1943 vosSchedContext = get_vos_sched_ctxt();
1944
1945 /* Wakeup all driver threads */
1946 if(TRUE == pHddCtx->isMcThreadSuspended){
1947 complete(&vosSchedContext->ResumeMcEvent);
1948 pHddCtx->isMcThreadSuspended= FALSE;
1949 }
1950 if(TRUE == pHddCtx->isTxThreadSuspended){
1951 complete(&vosSchedContext->ResumeTxEvent);
1952 pHddCtx->isTxThreadSuspended= FALSE;
1953 }
1954 if(TRUE == pHddCtx->isRxThreadSuspended){
1955 complete(&vosSchedContext->ResumeRxEvent);
1956 pHddCtx->isRxThreadSuspended= FALSE;
1957 }
1958 /* Reset the Suspend Variable */
1959 pHddCtx->isWlanSuspended = FALSE;
1960
1961 /* Stop all the threads; we do not want any messages to be a processed,
1962 * any more and the best way to ensure that is to terminate the threads
1963 * gracefully.
1964 */
1965 /* Wait for MC to exit */
1966 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
1967 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
1968 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
1969 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301970 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001971
1972 /* Wait for TX to exit */
1973 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
1974 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
1975 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
1976 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05301977 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001978
1979 /* Wait for RX to exit */
1980 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
1981 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
1982 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
1983 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05301984
Mihir Sheteb5425f72013-12-19 09:06:13 +05301985 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07001986
1987#ifdef WLAN_BTAMP_FEATURE
1988 vosStatus = WLANBAP_Stop(pVosContext);
1989 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1990 {
1991 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1992 "%s: Failed to stop BAP",__func__);
1993 }
1994#endif //WLAN_BTAMP_FEATURE
1995 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05301996 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1997 {
1998 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1999 "%s: Failed to stop wda %d", __func__, vosStatus);
2000 VOS_ASSERT(0);
2001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002002
2003 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2004 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2005 * on threads being running to process the SYS Stop
2006 */
Kiet Lama72a2322013-11-15 11:18:11 +05302007 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302008 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2009 {
2010 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2011 "%s: Failed to stop sme %d", __func__, vosStatus);
2012 VOS_ASSERT(0);
2013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002014
2015 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2016 /* Stop MAC (PE and HAL) */
2017 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302018 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2019 {
2020 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2021 "%s: Failed to stop mac %d", __func__, vosStatus);
2022 VOS_ASSERT(0);
2023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002024
2025 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2026 /* Stop TL */
2027 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302028 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2029 {
2030 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2031 "%s: Failed to stop TL %d", __func__, vosStatus);
2032 VOS_ASSERT(0);
2033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002034
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2037 /* Clean up message queues of TX and MC thread */
2038 vos_sched_flush_mc_mqs(vosSchedContext);
2039 vos_sched_flush_tx_mqs(vosSchedContext);
2040 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302041#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2042 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302043 /*Free fw dump mem in case of SSR/Shutdown */
2044 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2045 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002047
2048 /* Deinit all the TX and MC queues */
2049 vos_sched_deinit_mqs(vosSchedContext);
2050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2051
2052 /* shutdown VOSS */
2053 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302054
2055 /*mac context has already been released in mac_close call
2056 so setting it to NULL in hdd context*/
2057 pHddCtx->hHal = (tHalHandle)NULL;
2058
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 if (free_riva_power_on_lock("wlan"))
2060 {
2061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2062 __func__);
2063 }
2064 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2065 ,__func__);
2066 return VOS_STATUS_SUCCESS;
2067}
2068
2069
2070
2071/* the HDD interface to WLAN driver re-init.
2072 * This is called to initialize/start WLAN driver after a shutdown.
2073 */
2074VOS_STATUS hdd_wlan_re_init(void)
2075{
2076 VOS_STATUS vosStatus;
2077 v_CONTEXT_t pVosContext = NULL;
2078 hdd_context_t *pHddCtx = NULL;
2079 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002080#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2081 int max_retries = 0;
2082#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302083#ifdef HAVE_CBC_DONE
2084 int max_cbc_retries = 0;
2085#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002086#ifdef WLAN_BTAMP_FEATURE
2087 hdd_config_t *pConfig = NULL;
2088 WLANBAP_ConfigType btAmpConfig;
2089#endif
2090
Katya Nigam82a93062014-06-04 15:15:36 +05302091 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002092 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302093 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002094
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002095#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2096 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002097 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002098 msleep(1000);
2099 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002100 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002101 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2102 goto err_re_init;
2103 }
2104#endif
2105
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302106#ifdef HAVE_CBC_DONE
2107 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2108 msleep(1000);
2109 }
2110 if (max_cbc_retries >= 20) {
2111 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2112 }
2113#endif
2114
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002115 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2116
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002117 /* The driver should always be initialized in STA mode after SSR */
2118 hdd_set_conparam(0);
2119
Katya Nigam82a93062014-06-04 15:15:36 +05302120 dev = wcnss_wlan_get_device();
2121 if (NULL == dev)
2122 {
2123 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2124 goto err_re_init;
2125 }
2126
Jeff Johnson295189b2012-06-20 16:38:30 -07002127 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302128 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2130 {
2131 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2132 goto err_re_init;
2133 }
2134
2135 /* Get the HDD context. */
2136 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2137 if(!pHddCtx)
2138 {
2139 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2140 goto err_vosclose;
2141 }
2142
2143 /* Save the hal context in Adapter */
2144 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2145 if ( NULL == pHddCtx->hHal )
2146 {
2147 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2148 goto err_vosclose;
2149 }
2150
2151 /* Set the SME configuration parameters. */
2152 vosStatus = hdd_set_sme_config(pHddCtx);
2153 if ( VOS_STATUS_SUCCESS != vosStatus )
2154 {
2155 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2156 goto err_vosclose;
2157 }
2158
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 vosStatus = vos_preStart( pHddCtx->pvosContext );
2160 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2161 {
2162 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2163 goto err_vosclose;
2164 }
2165
2166 /* In the integrated architecture we update the configuration from
2167 the INI file and from NV before vOSS has been started so that
2168 the final contents are available to send down to the cCPU */
2169 /* Apply the cfg.ini to cfg.dat */
2170 if (FALSE == hdd_update_config_dat(pHddCtx))
2171 {
2172 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2173 goto err_vosclose;
2174 }
2175
2176 /* Set the MAC Address, currently this is used by HAL to add self sta.
2177 * Remove this once self sta is added as part of session open. */
2178 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2179 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2180 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2181 if (!HAL_STATUS_SUCCESS(halStatus))
2182 {
2183 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2184 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2185 goto err_vosclose;
2186 }
2187
2188 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2189 Note: Firmware image will be read and downloaded inside vos_start API */
2190 vosStatus = vos_start( pVosContext );
2191 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2192 {
2193 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +05302194 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002195 goto err_vosclose;
2196 }
2197
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002198 /* Exchange capability info between Host and FW and also get versioning info from FW */
2199 hdd_exchange_version_and_caps(pHddCtx);
2200
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 vosStatus = hdd_post_voss_start_config( pHddCtx );
2202 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2203 {
2204 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2205 __func__);
2206 goto err_vosstop;
2207 }
2208
Mihir Shete04206452014-11-20 17:50:58 +05302209#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302210 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2211 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2212 {
2213 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2214 __func__);
2215 goto err_vosstop;
2216 }
Mihir Shete04206452014-11-20 17:50:58 +05302217#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302218
Jeff Johnson295189b2012-06-20 16:38:30 -07002219#ifdef WLAN_BTAMP_FEATURE
2220 vosStatus = WLANBAP_Open(pVosContext);
2221 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2222 {
2223 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2224 "%s: Failed to open BAP",__func__);
2225 goto err_vosstop;
2226 }
2227 vosStatus = BSL_Init(pVosContext);
2228 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2229 {
2230 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2231 "%s: Failed to Init BSL",__func__);
2232 goto err_bap_close;
2233 }
2234 vosStatus = WLANBAP_Start(pVosContext);
2235 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2236 {
2237 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2238 "%s: Failed to start TL",__func__);
2239 goto err_bap_close;
2240 }
2241 pConfig = pHddCtx->cfg_ini;
2242 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2243 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2244#endif //WLAN_BTAMP_FEATURE
2245
2246 /* Restart all adapters */
2247 hdd_start_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302249 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002250 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302251 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252 /* Register with platform driver as client for Suspend/Resume */
2253 vosStatus = hddRegisterPmOps(pHddCtx);
2254 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2255 {
2256 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2257 goto err_bap_stop;
2258 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302259
2260#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2261 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2262 (pHddCtx->cfg_ini->enableFWLogging ||
2263 pHddCtx->cfg_ini->enableMgmtLogging ||
2264 pHddCtx->cfg_ini->enableContFWLogging))
2265 {
2266 hdd_init_frame_logging(pHddCtx);
2267 }
2268#endif
2269
Jeff Johnson295189b2012-06-20 16:38:30 -07002270 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302271 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002272 /* register for riva power on lock */
2273 if (req_riva_power_on_lock("wlan"))
2274 {
2275 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2276 __func__);
2277 goto err_unregister_pmops;
2278 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302279 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002280 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Dasari Srinivas421bde82014-06-25 12:01:44 +05302281#ifdef WLAN_FEATURE_EXTSCAN
2282 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2283 wlan_hdd_cfg80211_extscan_callback,
2284 pHddCtx);
2285#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302286
2287#ifdef FEATURE_OEM_DATA_SUPPORT
2288 sme_OemDataRegisterCallback(pHddCtx->hHal,
2289 wlan_hdd_cfg80211_oemdata_callback,
2290 pHddCtx);
2291#endif /* FEATURE_OEM_DATA_SUPPORT */
2292
Jeff Johnson295189b2012-06-20 16:38:30 -07002293 goto success;
2294
2295err_unregister_pmops:
2296 hddDeregisterPmOps(pHddCtx);
2297
2298err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002299#ifdef CONFIG_HAS_EARLYSUSPEND
2300 hdd_unregister_mcast_bcast_filter(pHddCtx);
2301#endif
2302 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002303#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002304 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002305#endif
2306
2307#ifdef WLAN_BTAMP_FEATURE
2308err_bap_close:
2309 WLANBAP_Close(pVosContext);
2310#endif
2311
2312err_vosstop:
2313 vos_stop(pVosContext);
2314
2315err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302316 if(!isSsrPanicOnFailure())
2317 {
2318 /* If we hit this, it means wlan driver is in bad state and needs
2319 * driver unload and load.
2320 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302321 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2322 return VOS_STATUS_E_FAILURE;
2323 }
2324
Jeff Johnson295189b2012-06-20 16:38:30 -07002325 vos_close(pVosContext);
2326 vos_sched_close(pVosContext);
2327 if (pHddCtx)
2328 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002329 /* Unregister the Net Device Notifier */
2330 unregister_netdevice_notifier(&hdd_netdev_notifier);
2331 /* Clean up HDD Nlink Service */
2332 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002333#ifdef WLAN_KD_READY_NOTIFIER
2334 nl_srv_exit(pHddCtx->ptt_pid);
2335#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002336 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002337#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002338 /* Free up dynamically allocated members inside HDD Adapter */
2339 kfree(pHddCtx->cfg_ini);
2340 pHddCtx->cfg_ini= NULL;
2341
Jeff Johnson295189b2012-06-20 16:38:30 -07002342 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302343 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002344 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002345 }
2346 vos_preClose(&pVosContext);
2347
2348#ifdef MEMORY_DEBUG
2349 vos_mem_exit();
2350#endif
2351
2352err_re_init:
2353 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302354 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002355 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002356 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002357 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002358
2359success:
2360 /* Trigger replay of BTC events */
2361 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2362 return VOS_STATUS_SUCCESS;
2363}