blob: a6a9e89daf5d816ee0e41616f491d0123127da1d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singh37471cd2016-01-05 17:09:57 +05302 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=============================================================================
29* wlan_hdd_early_suspend.c
30*
31* \brief power management functions
32*
33* Description
Jeff Johnson295189b2012-06-20 16:38:30 -070034*
35==============================================================================**/
36/* $HEADER$ */
37
38/**-----------------------------------------------------------------------------
39* Include files
40* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42#include <linux/pm.h>
43#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070044#include <wlan_hdd_includes.h>
45#include <wlan_qct_driver.h>
46#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48#include "halTypes.h"
49#include "sme_Api.h"
50#include <vos_api.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070051#include <vos_sched.h>
52#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <wlan_qct_sys.h>
54#include <wlan_btc_svc.h>
55#include <wlan_nlink_common.h>
56#include <wlan_hdd_main.h>
57#include <wlan_hdd_assoc.h>
58#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070059#include <wlan_nlink_srv.h>
60#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070061#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062
Jeff Johnson295189b2012-06-20 16:38:30 -070063#include <linux/semaphore.h>
64#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include "cfgApi.h"
Siddharth Bhal7bd19932015-03-03 16:54:36 +053066#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067
68#ifdef WLAN_BTAMP_FEATURE
69#include "bapApi.h"
70#include "bap_hdd_main.h"
71#include "bap_hdd_misc.h"
72#endif
73
Jeff Johnsone7245742012-09-05 17:12:55 -070074#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070075#include <linux/inetdevice.h>
76#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053077#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053078#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070079/**-----------------------------------------------------------------------------
80* Preprocessor definitions and constants
81* ----------------------------------------------------------------------------*/
82
83/**-----------------------------------------------------------------------------
84* Type declarations
85* ----------------------------------------------------------------------------*/
86
87/**-----------------------------------------------------------------------------
88* Function and variables declarations
89* ----------------------------------------------------------------------------*/
90#include "wlan_hdd_power.h"
91#include "wlan_hdd_packet_filtering.h"
92
Sameer Thalappile5637f42013-08-07 15:46:55 -070093#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053094#define NS_DEFAULT_SLOT_INDEX 4
95#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070096
97static eHalStatus g_full_pwr_status;
98static eHalStatus g_standby_status;
99
100extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700104extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700106static struct timer_list ssr_timer;
107static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
Abhishek Singh937ec542016-01-05 18:03:14 +0530109
110#ifdef FEATURE_WLAN_DIAG_SUPPORT
111/**
112 * hdd_wlan_offload_event()- send offloads event
113 *
114 * @type: offload type
115 * @state: enabled or disabled
116 *
117 * This Function send offloads enable/disable diag event
118 *
119 * Return: void.
120 */
121
122void hdd_wlan_offload_event(uint8_t type, uint8_t state)
123{
124 WLAN_VOS_DIAG_EVENT_DEF(host_offload,
125 struct vos_event_offload_req);
126 vos_mem_zero(&host_offload, sizeof(host_offload));
127
128 host_offload.offload_type = type;
129 host_offload.state = state;
130
131 WLAN_VOS_DIAG_EVENT_REPORT(&host_offload, EVENT_OFFLOAD_REQ);
132}
133#endif /* FEATURE_WLAN_DIAG_SUPPORT */
134
Jeff Johnson295189b2012-06-20 16:38:30 -0700135//Callback invoked by PMC to report status of standby request
136void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
137{
138 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
140 g_standby_status = status;
141
142 if(eHAL_STATUS_SUCCESS == status)
143 {
144 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
145 }
146 else
147 {
148 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
149 }
150
151 complete(&pHddCtx->standby_comp_var);
152}
153
154//Callback invoked by PMC to report status of full power request
155void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
156{
157 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
159 g_full_pwr_status = status;
160
161 if(eHAL_STATUS_SUCCESS == status)
162 {
163 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
164 }
165 else
166 {
167 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
168 }
169
170 complete(&pHddCtx->full_pwr_comp_var);
171}
172
173eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
174{
175 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530176 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700177
178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
179 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
180
181 g_full_pwr_status = eHAL_STATUS_FAILURE;
182 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
183 eSME_FULL_PWR_NEEDED_BY_HDD);
184
185 if(status == eHAL_STATUS_PMC_PENDING)
186 {
187 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530188 ret = wait_for_completion_interruptible_timeout(
189 &pHddCtx->full_pwr_comp_var,
190 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
191 if (0 >= ret)
192 {
193 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
194 __func__, ret);
195 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 status = g_full_pwr_status;
197 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
198 {
199 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
200 VOS_ASSERT(0);
201 goto failure;
202 }
203 }
204 else if(status != eHAL_STATUS_SUCCESS)
205 {
206 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
207 __func__, status);
208 VOS_ASSERT(0);
209 goto failure;
210 }
211 else
212 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
213
214failure:
215 //No blocking to reduce latency. No other device should be depending on WLAN
216 //to finish resume and WLAN won't be instantly on after resume
217 return status;
218}
219
220
221//Helper routine to put the chip into standby
222VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
223{
224 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
225 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530226 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700227
228 //Disable IMPS/BMPS as we do not want the device to enter any power
229 //save mode on its own during suspend sequence
230 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
231 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
232
233 //Note we do not disable queues unnecessarily. Queues should already be disabled
234 //if STA is disconnected or the queue will be disabled as and when disconnect
235 //happens because of standby procedure.
236
237 //Ensure that device is in full power first. There is scope for optimization
238 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
239 //Core s/w needs to be optimized to handle this. Until then we request full
240 //power before issuing request for standby.
241 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
242 g_full_pwr_status = eHAL_STATUS_FAILURE;
243 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
244 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
245
246 if(halStatus == eHAL_STATUS_PMC_PENDING)
247 {
248 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530249 ret = wait_for_completion_interruptible_timeout(
250 &pHddCtx->full_pwr_comp_var,
251 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
252 if (0 >= ret)
253 {
254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
255 __func__, ret);
256 }
257
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
259 {
260 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
261 VOS_ASSERT(0);
262 vosStatus = VOS_STATUS_E_FAILURE;
263 goto failure;
264 }
265 }
266 else if(halStatus != eHAL_STATUS_SUCCESS)
267 {
268 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
269 __func__, halStatus);
270 VOS_ASSERT(0);
271 vosStatus = VOS_STATUS_E_FAILURE;
272 goto failure;
273 }
274
275 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
276 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
277 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
278 }
279
280 //Request standby. Standby will cause the STA to disassociate first. TX queues
281 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
282 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
283 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
284 //when there are concurrent sessions.
285 INIT_COMPLETION(pHddCtx->standby_comp_var);
286 g_standby_status = eHAL_STATUS_FAILURE;
287 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
288
289 if (halStatus == eHAL_STATUS_PMC_PENDING)
290 {
291 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530292 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530294 if (0 >= ret)
295 {
296 hddLog(VOS_TRACE_LEVEL_ERROR,
297 FL("wait on standby_comp_var failed %ld"), ret);
298 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
300 {
301 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
302 VOS_ASSERT(0);
303 vosStatus = VOS_STATUS_E_FAILURE;
304 goto failure;
305 }
306 }
307 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
308 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
309 __func__, halStatus);
310 VOS_ASSERT(0);
311 vosStatus = VOS_STATUS_E_FAILURE;
312 goto failure;
313 }
314 else
315 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
316
317failure:
318 //Restore IMPS config
319 if(pHddCtx->cfg_ini->fIsImpsEnabled)
320 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
321
322 //Restore BMPS config
323 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
324 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
325
326 return vosStatus;
327}
328
329
330//Helper routine for Deep sleep entry
331VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
332{
333 eHalStatus halStatus;
334 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530335 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800336
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530338 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700339 netif_tx_disable(pAdapter->dev);
340 netif_carrier_off(pAdapter->dev);
341
342 //Disable IMPS,BMPS as we do not want the device to enter any power
343 //save mode on it own during suspend sequence
344 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
345 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
346
347 //Ensure that device is in full power as we will touch H/W during vos_Stop
348 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
349 g_full_pwr_status = eHAL_STATUS_FAILURE;
350 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
351 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
352
353 if(halStatus == eHAL_STATUS_PMC_PENDING)
354 {
355 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530356 ret = wait_for_completion_interruptible_timeout(
357 &pHddCtx->full_pwr_comp_var,
358 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
359 if (0 >= ret)
360 {
361 hddLog(VOS_TRACE_LEVEL_ERROR,
362 FL("wait on full_pwr_comp_var failed %ld"), ret);
363 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700364 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
365 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
366 VOS_ASSERT(0);
367 }
368 }
369 else if(halStatus != eHAL_STATUS_SUCCESS)
370 {
371 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
372 VOS_ASSERT(0);
373 }
374
375 //Issue a disconnect. This is required to inform the supplicant that
376 //STA is getting disassociated and for GUI to be updated properly
377 INIT_COMPLETION(pAdapter->disconnect_comp_var);
378 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
379
380 //Success implies disconnect command got queued up successfully
381 if(halStatus == eHAL_STATUS_SUCCESS)
382 {
383 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530384 ret = wait_for_completion_interruptible_timeout(
385 &pAdapter->disconnect_comp_var,
386 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
387 if (0 >= ret)
388 {
389 hddLog(VOS_TRACE_LEVEL_ERROR,
390 FL("wait on disconnect_comp_var failed %ld"), ret);
391 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700392 }
393
394
395 //None of the steps should fail after this. Continue even in case of failure
396 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530397 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
398 {
399 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
400 __func__, vosStatus);
401 VOS_ASSERT(0);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +0530402 if (isSsrPanicOnFailure())
403 VOS_BUG(0);
c_hpothuffdb5272013-10-02 16:42:35 +0530404 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700405
Jeff Johnson295189b2012-06-20 16:38:30 -0700406 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
407
408 //Restore IMPS config
409 if(pHddCtx->cfg_ini->fIsImpsEnabled)
410 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
411
412 //Restore BMPS config
413 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
414 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416 return vosStatus;
417}
418
419VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
420{
421 VOS_STATUS vosStatus;
422 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700423
Jeff Johnson295189b2012-06-20 16:38:30 -0700424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
425 "%s: calling hdd_set_sme_config",__func__);
426 vosStatus = hdd_set_sme_config( pHddCtx );
427 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
428 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
429 {
430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
431 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700432 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700433 }
434
435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
436 "%s: calling vos_start",__func__);
437 vosStatus = vos_start( pHddCtx->pvosContext );
438 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
439 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
440 {
441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
442 "%s: Failed in vos_start",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +0530443 if (isSsrPanicOnFailure())
444 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700445 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700446 }
447
448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
449 "%s: calling hdd_post_voss_start_config",__func__);
450 vosStatus = hdd_post_voss_start_config( pHddCtx );
451 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
452 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
453 {
454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
455 "%s: Failed in hdd_post_voss_start_config",__func__);
456 goto err_voss_stop;
457 }
458
459
460 //Open a SME session for future operation
461 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700462 (tANI_U8 *)&pAdapter->macAddressCurrent,
463 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700464 if ( !HAL_STATUS_SUCCESS( halStatus ) )
465 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700466 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700467 halStatus, halStatus );
468 goto err_voss_stop;
469
470 }
471
472 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
473
474 //Trigger the initial scan
475 hdd_wlan_initial_scan(pHddCtx);
476
477 return VOS_STATUS_SUCCESS;
478
479err_voss_stop:
480 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700481err_deep_sleep:
482 return VOS_STATUS_E_FAILURE;
483
484}
485
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530486void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
Atul Mittal37385d72014-03-27 18:15:03 +0530487{
488 hdd_adapter_t* pAdapter =
489 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
490 hdd_context_t *pHddCtx;
491 int status;
492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530493 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530494 if (NULL == pAdapter)
495 {
496 hddLog(LOGE, FL("Adapter is invalid"));
497 return;
498 }
Atul Mittal37385d72014-03-27 18:15:03 +0530499
500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
501 status = wlan_hdd_validate_context(pHddCtx);
502 if (0 != status)
503 {
Atul Mittal37385d72014-03-27 18:15:03 +0530504 return;
505 }
506
507 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
508 {
509 pHddCtx->sus_res_mcastbcast_filter =
510 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530511 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
512 pHddCtx->sus_res_mcastbcast_filter);
Atul Mittal37385d72014-03-27 18:15:03 +0530513 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
514 }
515
516 if ((eConnectionState_Associated ==
517 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
518 && (pHddCtx->hdd_wlan_suspended))
519 {
520 // This invocation being part of the IPv6 registration callback,
521 // set the newly generated ip address to f/w in suspend mode.
522#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530523 if (pHddCtx->cfg_ini->fhostNSOffload)
524 {
525 hdd_conf_ns_offload(pAdapter, 1);
526 }
Atul Mittal37385d72014-03-27 18:15:03 +0530527#endif
528 }
529#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530530 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530531 * only so when new ipv6 address is generated the screen may not
532 * on so we need to call it here to update the list in f/w.
533 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530534 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530535#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530536 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530537}
538
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530539void hdd_ipv6_notifier_work_queue(struct work_struct *work)
540{
541 vos_ssr_protect(__func__);
542 __hdd_ipv6_notifier_work_queue(work);
543 vos_ssr_unprotect(__func__);
544}
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530545int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530546 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530547{
548 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
549 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530550 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530551 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530552 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530553 int status;
554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530555 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530556 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
557 status = wlan_hdd_validate_context(pHddCtx);
558 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530559 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530560 return NOTIFY_DONE;
561 }
Atul Mittal37385d72014-03-27 18:15:03 +0530562
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530563 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
564 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
565 {
566 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
567 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
568 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
569 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +0530570
571 if (eConnectionState_Associated ==
572 WLAN_HDD_GET_STATION_CTX_PTR
573 (pAdapterNode->pAdapter)->conn_info.connState)
574 sme_dhcp_done_ind(pHddCtx->hHal,
575 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530576 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530577 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530578 {
579 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
580 }
581 else
582 {
583 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
584 pHddCtx->cfg_ini->nEnableSuspend);
585 }
586 break;
587 }
588 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
589 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530590 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530591 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530592 return NOTIFY_DONE;
593}
594
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530595int wlan_hdd_ipv6_changed(struct notifier_block *nb,
596 unsigned long data, void *arg)
597{
598 int ret;
599 vos_ssr_protect(__func__);
600 ret = __wlan_hdd_ipv6_changed( nb, data, arg);
601 vos_ssr_unprotect(__func__);
602 return ret;
603}
604
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530605/*
606 * Function: hdd_conf_hostoffload
607 * Central function to configure the supported offloads,
608 * either enable or disable them.
609 */
610void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
611{
612 hdd_context_t *pHddCtx = NULL;
613 v_CONTEXT_t *pVosContext = NULL;
614 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
615
616 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
617 fenable);
618
619 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
620
621 if (NULL == pVosContext)
622 {
623 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
624 return;
625 }
626
627 //Get the HDD context.
628 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
629
630 if (NULL == pHddCtx)
631 {
632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
633 return;
634 }
635
636 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
637 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
638 {
639 if (fenable)
640 {
641 if (eConnectionState_Associated ==
642 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
643 {
644 if ((pHddCtx->cfg_ini->fhostArpOffload))
645 {
646 /*
647 * Configure the ARP Offload.
648 * Even if it fails we have to reconfigure the MC/BC
649 * filter flag as we want RIVA not to drop BroadCast
650 * Packets
651 */
652 hddLog(VOS_TRACE_LEVEL_INFO,
653 FL("Calling ARP Offload with flag: %d"), fenable);
654 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
655 pHddCtx->configuredMcastBcastFilter &=
656 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
657
658 if (!VOS_IS_STATUS_SUCCESS(vstatus))
659 {
Anurag Chouhan8a5f8902016-09-28 18:54:47 +0530660 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530661 "Failed to enable ARPOFfloadFeature %d",
662 vstatus);
663 }
664 }
665 //Configure GTK_OFFLOAD
666#ifdef WLAN_FEATURE_GTK_OFFLOAD
667 hdd_conf_gtk_offload(pAdapter, fenable);
668#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530669
670#ifdef WLAN_NS_OFFLOAD
671 if (pHddCtx->cfg_ini->fhostNSOffload)
672 {
673 /*
674 * Configure the NS Offload.
675 * Even if it fails we have to reconfigure the MC/BC filter flag
676 * as we want RIVA not to drop Multicast Packets
677 */
678
679 hddLog(VOS_TRACE_LEVEL_INFO,
680 FL("Calling NS Offload with flag: %d"), fenable);
681 hdd_conf_ns_offload(pAdapter, fenable);
682 pHddCtx->configuredMcastBcastFilter &=
683 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
684 }
685#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530686
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530687 }
688 }
689 else
690 {
691 //Disable ARPOFFLOAD
692 if (pHddCtx->cfg_ini->fhostArpOffload)
693 {
694 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
695 if (!VOS_IS_STATUS_SUCCESS(vstatus))
696 {
697 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530698 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530699 }
700 }
701 //Disable GTK_OFFLOAD
702#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530703 hdd_conf_gtk_offload(pAdapter, fenable);
704#endif
705
706#ifdef WLAN_NS_OFFLOAD
707 //Disable NSOFFLOAD
708 if (pHddCtx->cfg_ini->fhostNSOffload)
709 {
710 hdd_conf_ns_offload(pAdapter, fenable);
711 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530712#endif
713 }
714 }
715 return;
716}
717
Atul Mittal37385d72014-03-27 18:15:03 +0530718
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530719#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530720/**----------------------------------------------------------------------------
721
722 \brief hdd_conf_ns_offload() - Configure NS offload
723
724 Called during SUSPEND to configure the NS offload (MC BC filter) which
725 reduces power consumption.
726
727 \param - pAdapter - Adapter context for which NS offload is to be configured
728 \param - fenable - 0 - disable.
729 1 - enable. (with IPv6 notifier registration)
730 2 - enable. (without IPv6 notifier registration)
731
732 \return - void
733
734 ---------------------------------------------------------------------------*/
735void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530736{
737 struct inet6_dev *in6_dev;
738 struct inet6_ifaddr *ifp;
739 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530740 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530741 tANI_U8 **selfIPv6Addr = NULL;
742 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530743 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530744 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530745 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530746
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530747 int i = 0, slot = 0;
748 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530749 eHalStatus returnStatus;
750
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530751 ENTER();
752 hddLog(LOG1, FL(" fenable = %d"), fenable);
753
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530754 if (NULL == pAdapter)
755 {
756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
757 return;
758 }
759
760 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530761 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
762
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530763 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530764 if (0 != ret)
765 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530766 return;
767 }
768
769 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
770 {
771 slot_index = NS_EXTENDED_SLOT_INDEX;
772 }
773
774 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
775
776 selfIPv6AddrValid =
777 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
778
779 if (NULL == selfIPv6AddrValid)
780 {
781 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
782 " selfIPv6AddrValid"));
783 goto end;
784 }
785
786 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
787
788 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
789
790 if (NULL == selfIPv6Addr)
791 {
792 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
793 " selfIPv6Addr"));
794 goto end;
795 }
796
797 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
798
799 for (slot = 0; slot < slot_index; slot++)
800 {
801 selfIPv6Addr[slot] =
802 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
803 if (NULL == selfIPv6Addr[slot])
804 {
805 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
806 "for selfIPv6Addr"));
807 goto end;
808 }
809 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
810 }
811
812 i = 0;
813
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530814 if (fenable)
815 {
816 in6_dev = __in6_dev_get(pAdapter->dev);
817 if (NULL != in6_dev)
818 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530819 list_for_each(p, &in6_dev->addr_list)
820 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530821 if (i >= slot_index)
822 {
823 hddLog (VOS_TRACE_LEVEL_ERROR,
824 FL("IPv6 address list is greater than IPv6"
825 "address supported by firmware"));
826 hddLog (VOS_TRACE_LEVEL_ERROR,
827 FL("FW supported IPv6 address = %d"), slot_index);
828 break;
829 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530830 ifp = list_entry(p, struct inet6_ifaddr, if_list);
831 switch(ipv6_addr_src_scope(&ifp->addr))
832 {
833 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530834 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530835 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530836 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530837 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530838 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
839 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530840 break;
841 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530842 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530843 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530844 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530845 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530846 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
847 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530848 break;
849 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("The Scope %d is not supported"),
852 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530853 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530854 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
855 {
856 i++;
857 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530858 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530859
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530860 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530861 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530862 {
863 if (selfIPv6AddrValid[i])
864 {
865 //Filling up the request structure
866 /* Filling the selfIPv6Addr with solicited address
867 * A Solicited-Node multicast address is created by
868 * taking the last 24 bits of a unicast or anycast
869 * address and appending them to the prefix
870 *
871 * FF02:0000:0000:0000:0000:0001:FFXX:XX
872 *
873 * here XX is the unicast/anycast bits
874 */
875 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
876 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
877 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
878 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530879 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
880 selfIPv6Addr[i][13];
881 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
882 selfIPv6Addr[i][14];
883 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
884 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530885 offLoadRequest.nsOffloadInfo.slotIdx = i;
886
887 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530888 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530889 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
890 &pAdapter->macAddressCurrent.bytes,
891 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
892
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530893 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
894 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530895 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
896 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +0530897 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
898 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530899
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530900 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530901 FL("configuredMcastBcastFilter: %d"
902 "NSOffload Slot = %d"),
903 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530904
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530905 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700906 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
907 pHddCtx->sus_res_mcastbcast_filter) ||
908 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
909 pHddCtx->sus_res_mcastbcast_filter)) &&
910 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
911 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
912 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530913 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530914 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700915 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530916 hddLog (VOS_TRACE_LEVEL_INFO,
917 FL("Set offLoadRequest with %d"),
918 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530919 }
Abhishek Singh937ec542016-01-05 18:03:14 +0530920 hdd_wlan_offload_event(
921 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE,
922 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530923 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
924 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
925 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
926
927 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530928 FL("Setting NSOffload with solicitedIp: %pI6,"
929 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530930 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
931 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
932
933 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530934 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530935 pAdapter->sessionId, &offLoadRequest);
936 if(eHAL_STATUS_SUCCESS != returnStatus)
937 {
938 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530939 FL("Failed to enable HostOffload feature with"
940 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530941 }
942 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
943 }
944 }
945 }
946 else
947 {
948 hddLog(VOS_TRACE_LEVEL_ERROR,
949 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530950 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530951 }
952 }
953 else
954 {
955 //Disable NSOffload
956 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
957 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
958 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +0530959 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
960 SIR_OFFLOAD_DISABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530961
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530962 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530963 {
c_hpothu86feba52014-10-28 15:51:18 +0530964 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530965 offLoadRequest.nsOffloadInfo.slotIdx = i;
966 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530967 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
968 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530969 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
971 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530972 }
973 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530974 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530975end:
976 while (slot > 0 && selfIPv6Addr[--slot])
977 {
978 vos_mem_free(selfIPv6Addr[slot]);
979 }
980 if (selfIPv6Addr)
981 {
982 vos_mem_free(selfIPv6Addr);
983 }
984 if (selfIPv6AddrValid)
985 {
986 vos_mem_free(selfIPv6AddrValid);
987 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530988 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530989 return;
990}
991#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530993void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530994{
995 hdd_adapter_t* pAdapter =
996 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
997 hdd_context_t *pHddCtx;
998 int status;
999
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301000 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301001 if (NULL == pAdapter)
1002 {
1003 hddLog(LOGE, FL("Adapter is invalid"));
1004 return;
1005 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301006 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1007 status = wlan_hdd_validate_context(pHddCtx);
1008 if (0 != status)
1009 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301010 return;
1011 }
1012
Deepthi Gowri5933f402014-01-23 17:48:24 +05301013 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1014 {
1015 pHddCtx->sus_res_mcastbcast_filter =
1016 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301017 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
1018 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +05301019 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1020 }
1021
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301022 if ((eConnectionState_Associated ==
1023 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +05301024 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301025 {
1026 // This invocation being part of the IPv4 registration callback,
1027 // we are passing second parameter as 2 to avoid registration
1028 // of IPv4 notifier again.
1029 hdd_conf_arp_offload(pAdapter, 2);
1030 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301031 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301032}
1033
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301034void hdd_ipv4_notifier_work_queue(struct work_struct *work)
1035{
1036 vos_ssr_protect(__func__);
1037 __hdd_ipv4_notifier_work_queue(work);
1038 vos_ssr_unprotect(__func__);
1039}
1040
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301041int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301042 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301043{
1044 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1045 struct in_ifaddr **ifap = NULL;
1046 struct in_device *in_dev;
1047
1048 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301049 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301050 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301051 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301052 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301053
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301054 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301055 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1056 status = wlan_hdd_validate_context(pHddCtx);
1057 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301058 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301059 return NOTIFY_DONE;
1060 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301061
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301062 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1063 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1064 {
1065 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1066 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1067 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1068 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +05301069
1070 if (eConnectionState_Associated ==
1071 WLAN_HDD_GET_STATION_CTX_PTR
1072 (pAdapterNode->pAdapter)->conn_info.connState)
1073 sme_dhcp_done_ind(pHddCtx->hHal,
1074 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301075 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301076 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301077 || (!pHddCtx->cfg_ini->fhostArpOffload))
1078 {
1079 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1080 pHddCtx->cfg_ini->nEnableSuspend,
1081 pHddCtx->cfg_ini->fhostArpOffload);
1082 return NOTIFY_DONE;
1083 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301084
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301085 if ((in_dev =
1086 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1087 {
1088 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1089 ifap = &ifa->ifa_next)
1090 {
1091 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1092 ifa->ifa_label))
1093 {
1094 break; /* found */
1095 }
1096 }
1097 }
1098 if(ifa && ifa->ifa_local)
1099 {
1100 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1101 }
1102 break;
1103 }
1104 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1105 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301106 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301107 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301108 return NOTIFY_DONE;
1109}
1110
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301111int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1112 unsigned long data, void *arg)
1113{
1114 int ret;
1115 vos_ssr_protect(__func__);
1116 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1117 vos_ssr_unprotect(__func__);
1118 return ret;
1119}
1120
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301121/**----------------------------------------------------------------------------
1122
1123 \brief hdd_conf_arp_offload() - Configure ARP offload
1124
1125 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1126 reduces power consumption.
1127
1128 \param - pAdapter -Adapter context for which ARP offload is to be configured
1129 \param - fenable - 0 - disable.
1130 1 - enable. (with IPv4 notifier registration)
1131 2 - enable. (without IPv4 notifier registration)
1132
1133 \return -
1134 VOS_STATUS_SUCCESS - on successful operation
1135 VOS_STATUS_E_FAILURE - on failure of operation
1136-----------------------------------------------------------------------------*/
1137VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001138{
1139 struct in_ifaddr **ifap = NULL;
1140 struct in_ifaddr *ifa = NULL;
1141 struct in_device *in_dev;
1142 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001143 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001144 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001145
Sushant Kaushik87787972015-09-11 16:05:00 +05301146 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001147
Jeff Johnson295189b2012-06-20 16:38:30 -07001148 if(fenable)
1149 {
1150 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1151 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301152 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 ifap = &ifa->ifa_next)
1154 {
1155 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1156 {
1157 break; /* found */
1158 }
1159 }
1160 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001161 if(ifa && ifa->ifa_local)
1162 {
1163 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1164 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +05301165 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1166 SIR_OFFLOAD_ENABLE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001167
Arif Hussain6d2a3322013-11-17 19:50:10 -08001168 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001169
Amar Singhald53568e2013-09-26 11:03:45 -07001170 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1171 pHddCtx->sus_res_mcastbcast_filter) ||
1172 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1173 pHddCtx->sus_res_mcastbcast_filter)) &&
1174 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001175 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301176 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001177 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1178 hddLog(VOS_TRACE_LEVEL_INFO,
1179 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001180 }
Abhishek Singh937ec542016-01-05 18:03:14 +05301181 hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
1182 SIR_OFFLOAD_ENABLE);
Amar Singhald53568e2013-09-26 11:03:45 -07001183
1184 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1185 offLoadRequest.enableOrDisable);
1186
Jeff Johnson295189b2012-06-20 16:38:30 -07001187 //converting u32 to IPV4 address
1188 for(i = 0 ; i < 4; i++)
1189 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301190 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001191 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1192 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301193 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 offLoadRequest.params.hostIpv4Addr[0],
1195 offLoadRequest.params.hostIpv4Addr[1],
1196 offLoadRequest.params.hostIpv4Addr[2],
1197 offLoadRequest.params.hostIpv4Addr[3]);
1198
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301199 if (eHAL_STATUS_SUCCESS !=
1200 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1201 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001202 {
1203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001204 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001205 return VOS_STATUS_E_FAILURE;
1206 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001207 }
1208 else
1209 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301210 hddLog(VOS_TRACE_LEVEL_WARN, FL("IP Address is not assigned"));
Agarwal Ashish971c2882013-10-30 20:11:12 +05301211 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001212 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301213
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301214 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 }
1216 else
1217 {
1218 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1219 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1220 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +05301221 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1222 SIR_OFFLOAD_DISABLE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301223 if (eHAL_STATUS_SUCCESS !=
1224 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1225 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001226 {
1227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001228 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 return VOS_STATUS_E_FAILURE;
1230 }
1231 return VOS_STATUS_SUCCESS;
1232 }
1233}
1234
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301235/*
1236 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301237 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301238*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301239void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301240 tANI_U8 *pMcBcFilter)
1241{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301242 if (NULL == pHddCtx)
1243 {
1244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1245 return;
1246 }
1247
1248 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1249 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301250 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301251 /* ARP offload is enabled, do not block bcast packets at RXP
1252 * Will be using Bitmasking to reset the filter. As we have
1253 * disable Broadcast filtering, Anding with the negation
1254 * of Broadcast BIT
1255 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301256 hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301257 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301258 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301259
1260#ifdef WLAN_NS_OFFLOAD
1261 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301262 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301263 /* NS offload is enabled, do not block mcast packets at RXP
1264 * Will be using Bitmasking to reset the filter. As we have
1265 * disable Multicast filtering, Anding with the negation
1266 * of Multicast BIT
1267 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301268 hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301269 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301270 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301271#endif
1272
Amar Singhald08ce752014-03-21 16:28:27 -07001273 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1274 {
1275 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1276 }
1277
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301278 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301279}
1280
Jeff Johnson295189b2012-06-20 16:38:30 -07001281void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1282{
1283 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1285 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
Agarwal Ashishff451a32015-07-28 01:01:29 +05301286 if (NULL == wlanRxpFilterParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001287 {
1288 hddLog(VOS_TRACE_LEVEL_FATAL,
1289 "%s: vos_mem_alloc failed ", __func__);
1290 return;
1291 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001292 hddLog(VOS_TRACE_LEVEL_INFO,
1293 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301294 if (TRUE == setfilter)
1295 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301296 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301297 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301298 }
1299 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301300 {
1301 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301302 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301303 pHddCtx->configuredMcastBcastFilter;
1304 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301305
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001307 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301308
1309 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
Agarwal Ashishff451a32015-07-28 01:01:29 +05301310 {
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301311 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Agarwal Ashishff451a32015-07-28 01:01:29 +05301312 }
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301313
1314 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1315 "lower mac with status %d"
1316 "configuredMcstBcstFilterSetting = %d"
1317 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1318 "Failed" : "Success", halStatus,
1319 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1320 wlanRxpFilterParam->setMcstBcstFilter);
1321
Chilam Ngc4244af2013-04-01 15:37:32 -07001322 if (eHAL_STATUS_SUCCESS != halStatus)
1323 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001324}
1325
Jeff Johnson295189b2012-06-20 16:38:30 -07001326static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1327 hdd_adapter_t *pAdapter)
1328{
1329 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1330 tpSirWlanSuspendParam wlanSuspendParam =
1331 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1332
Amar Singhald53568e2013-09-26 11:03:45 -07001333 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1334 pHddCtx->sus_res_mcastbcast_filter =
1335 pHddCtx->configuredMcastBcastFilter;
1336 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1337 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1338 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1339 pHddCtx->configuredMcastBcastFilter);
1340
1341 }
1342
Amar Singhal49fdfd52013-08-13 13:25:12 -07001343
Jeff Johnson295189b2012-06-20 16:38:30 -07001344 if(NULL == wlanSuspendParam)
1345 {
1346 hddLog(VOS_TRACE_LEVEL_FATAL,
1347 "%s: vos_mem_alloc failed ", __func__);
1348 return;
1349 }
1350
Amar Singhald53568e2013-09-26 11:03:45 -07001351 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 "%s: send wlan suspend indication", __func__);
1353
1354 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1355 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301356 //Configure supported OffLoads
1357 hdd_conf_hostoffload(pAdapter, TRUE);
1358 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301359 hddLog(VOS_TRACE_LEVEL_INFO,
1360 FL("saving configuredMcastBcastFilterSetting = %d"),
1361 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001362#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301363 /* During suspend, configure MC Addr list filter to the firmware
1364 * function takes care of checking necessary conditions before
1365 * configuring.
1366 */
1367 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001368#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001369
1370 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1371 {
1372
1373 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1374 pHddCtx->configuredMcastBcastFilter &=
1375 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1376 }
1377
1378 wlanSuspendParam->configuredMcstBcstFilterSetting =
1379 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001380 }
1381
1382 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1383 if(eHAL_STATUS_SUCCESS == halStatus)
1384 {
1385 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001386 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301387 hddLog(VOS_TRACE_LEVEL_ERROR,
1388 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001389 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001390 }
1391}
1392
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301393static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001394{
Chilam Ngc4244af2013-04-01 15:37:32 -07001395 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001396 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001397 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001398
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301399 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001400 "%s: send wlan resume indication", __func__);
1401
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301402 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1403
1404 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301406 hddLog(VOS_TRACE_LEVEL_FATAL,
1407 "%s: memory allocation failed for wlanResumeParam ", __func__);
1408 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001410
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301411 //Disable supported OffLoads
1412 hdd_conf_hostoffload(pAdapter, FALSE);
1413
1414 wlanResumeParam->configuredMcstBcstFilterSetting =
1415 pHddCtx->configuredMcastBcastFilter;
1416 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1417 if (eHAL_STATUS_SUCCESS != halStatus)
1418 {
c_hpothuffdb5272013-10-02 16:42:35 +05301419 hddLog(VOS_TRACE_LEVEL_ERROR,
1420 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301421 vos_mem_free(wlanResumeParam);
1422 }
1423
1424 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1425
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001426 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1427 pHddCtx->configuredMcastBcastFilter =
1428 pHddCtx->sus_res_mcastbcast_filter;
1429 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1430 }
Amar Singhald53568e2013-09-26 11:03:45 -07001431
1432 hddLog(VOS_TRACE_LEVEL_INFO,
1433 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1434 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1435 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001436
Chilam Ngc4244af2013-04-01 15:37:32 -07001437
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301438#ifdef WLAN_FEATURE_PACKET_FILTERING
1439 /* Filer was applied during suspend inditication
1440 * clear it when we resume.
1441 */
1442 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001443#endif
1444}
Jeff Johnson295189b2012-06-20 16:38:30 -07001445
Jeff Johnson295189b2012-06-20 16:38:30 -07001446//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001447void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001448{
1449 hdd_context_t *pHddCtx = NULL;
1450 v_CONTEXT_t pVosContext = NULL;
1451
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301453 hdd_adapter_t *pAdapter = NULL;
1454 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301455 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001456
Jeff Johnson295189b2012-06-20 16:38:30 -07001457 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1458
1459 //Get the global VOSS context.
1460 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1461 if(!pVosContext) {
1462 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1463 return;
1464 }
1465
1466 //Get the HDD context.
1467 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1468
1469 if(!pHddCtx) {
1470 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1471 return;
1472 }
1473
1474 if (pHddCtx->isLogpInProgress) {
1475 hddLog(VOS_TRACE_LEVEL_ERROR,
1476 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1477 return;
1478 }
1479
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301480 if (pHddCtx->hdd_wlan_suspended)
1481 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301482 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301483 "%s: Ignore suspend wlan, Already suspended!", __func__);
1484 return;
1485 }
1486
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301487 pHddCtx->hdd_wlan_suspended = TRUE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301488 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301489 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001490 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1491 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1492 {
1493 pAdapter = pAdapterNode->pAdapter;
1494 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001495 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001496 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1497
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001498 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001499 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1500 pAdapterNode = pNext;
1501 continue;
1502 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301503 /* Avoid multiple enter/exit BMPS in this while loop using
1504 * hdd_enter_bmps flag
1505 */
1506 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1507 {
1508 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001509
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301510 /* If device was already in BMPS, and dynamic DTIM is set,
1511 * exit(set the device to full power) and enter BMPS again
1512 * to reflect new DTIM value */
1513 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1514
1515 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1516
1517 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1518 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001519#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1520 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1521 {
1522 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301523 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001524 netif_tx_disable(pAdapter->dev);
1525 netif_carrier_off(pAdapter->dev);
1526 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301527 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1529 {
1530 //Execute deep sleep procedure
1531 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1532 }
1533#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301534
1535 /*Suspend notification sent down to driver*/
1536 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1537
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301538 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1539 pAdapterNode = pNext;
1540 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301541
Jeff Johnson295189b2012-06-20 16:38:30 -07001542#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1543 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1544 {
1545 hdd_enter_standby(pHddCtx);
1546 }
1547#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001548
1549 return;
1550}
1551
1552static void hdd_PowerStateChangedCB
1553(
1554 v_PVOID_t callbackContext,
1555 tPmcState newState
1556)
1557{
1558 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301559
Jeff Johnson295189b2012-06-20 16:38:30 -07001560 /* if the driver was not in BMPS during early suspend,
1561 * the dynamic DTIM is now updated at Riva */
1562 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
Abhishek Singh0ea13232016-02-12 16:46:10 +05301563 && (pHddCtx->cfg_ini->enableDynamicDTIM ||
1564 pHddCtx->cfg_ini->enableModulatedDTIM)
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1566 {
1567 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1568 }
1569 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301570 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1571 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301573 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1574 {
Amar Singhald53568e2013-09-26 11:03:45 -07001575 pHddCtx->sus_res_mcastbcast_filter =
1576 pHddCtx->configuredMcastBcastFilter;
1577 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1578
1579 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1580 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1581 pHddCtx->configuredMcastBcastFilter);
1582 hddLog(VOS_TRACE_LEVEL_INFO,
1583 "offload: calling hdd_conf_mcastbcast_filter");
1584
1585 }
1586
Jeff Johnson295189b2012-06-20 16:38:30 -07001587 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301590 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001591 else
Mihir Shete793209f2014-01-06 11:01:12 +05301592 {
1593 /* Android framework can send resume request when the WCN chip is
1594 * in IMPS mode. When the chip exits IMPS mode the firmware will
1595 * restore all the registers to the state they were before the chip
1596 * entered IMPS and so our hardware filter settings confgured by the
1597 * resume request will be lost. So reconfigure the filters on detecting
1598 * a change in the power state of the WCN chip.
1599 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301600 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301601 if (IMPS != newState)
1602 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301603 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301604 if (FALSE == pHddCtx->hdd_wlan_suspended)
1605 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301606 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301607 hddLog(VOS_TRACE_LEVEL_INFO,
1608 "Not in IMPS/BMPS and suspended state");
1609 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1610 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301611 else
1612 {
1613 spin_unlock(&pHddCtx->filter_lock);
1614 }
Mihir Shete793209f2014-01-06 11:01:12 +05301615 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001617}
1618
Jeff Johnson295189b2012-06-20 16:38:30 -07001619void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1620{
1621 v_CONTEXT_t pVosContext;
1622 tHalHandle smeContext;
1623
1624 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1625 if (NULL == pVosContext)
1626 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001627 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001628 return;
1629 }
1630 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1631 if (NULL == smeContext)
1632 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001633 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 return;
1635 }
1636
1637 spin_lock_init(&pHddCtx->filter_lock);
1638 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1639 pHddCtx->cfg_ini->nEnableSuspend)
1640 {
1641 pmcRegisterDeviceStateUpdateInd(smeContext,
1642 hdd_PowerStateChangedCB, pHddCtx);
1643 }
1644}
1645
1646void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1647{
1648 v_CONTEXT_t pVosContext;
1649 tHalHandle smeContext;
1650
1651 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1652 if (NULL == pVosContext)
1653 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001654 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001655 return;
1656 }
1657 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1658 if (NULL == smeContext)
1659 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001660 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001661 return;
1662 }
1663
1664 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1665 pHddCtx->cfg_ini->nEnableSuspend)
1666 {
1667 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1668 }
1669}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301670
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301671#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301672void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301673{
1674 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301675 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301676 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1677
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301678 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301679 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301680 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1681 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1682 {
1683 vos_mem_copy(&hddGtkOffloadReqParams,
1684 &pHddStaCtx->gtkOffloadReqParams,
1685 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301686
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301687 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1688 &hddGtkOffloadReqParams, pAdapter->sessionId);
1689 if (eHAL_STATUS_SUCCESS != ret)
1690 {
1691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: sme_SetGTKOffload failed, returned %d",
1693 __func__, ret);
1694 return;
1695 }
1696
1697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1698 "%s: sme_SetGTKOffload successfull", __func__);
1699 }
1700
1701 }
1702 else
1703 {
1704 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1705 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1706 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1707 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1708 {
1709
1710 /* Host driver has previously offloaded GTK rekey */
1711 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301712 wlan_hdd_cfg80211_update_replayCounterCallback,
1713 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301714 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301715
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301716 {
1717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1718 "%s: sme_GetGTKOffload failed, returned %d",
1719 __func__, ret);
1720 return;
1721 }
1722 else
1723 {
1724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1725 "%s: sme_GetGTKOffload successful",
1726 __func__);
1727
1728 /* Sending GTK offload dissable */
1729 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1730 sizeof (tSirGtkOffloadParams));
1731 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1732 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301733 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301734 if (eHAL_STATUS_SUCCESS != ret)
1735 {
1736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1737 "%s: failed to dissable GTK offload, returned %d",
1738 __func__, ret);
1739 return;
1740 }
1741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1742 "%s: successfully dissabled GTK offload request to HAL",
1743 __func__);
1744 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301745 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301746 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301747 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301748}
1749#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001750
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001751void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001752{
1753 hdd_context_t *pHddCtx = NULL;
1754 hdd_adapter_t *pAdapter = NULL;
1755 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1756 VOS_STATUS status;
1757 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001758
Jeff Johnson295189b2012-06-20 16:38:30 -07001759 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1760
1761 //Get the global VOSS context.
1762 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1763 if(!pVosContext) {
1764 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1765 return;
1766 }
1767
1768 //Get the HDD context.
1769 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1770
1771 if(!pHddCtx) {
1772 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1773 return;
1774 }
1775
Agarwal Ashish971c2882013-10-30 20:11:12 +05301776 if (pHddCtx->isLogpInProgress)
1777 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001778 hddLog(VOS_TRACE_LEVEL_INFO,
1779 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1780 return;
1781 }
1782
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301783 if (!pHddCtx->hdd_wlan_suspended)
1784 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05301785 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301786 "%s: Ignore resume wlan, Already resumed!", __func__);
1787 return;
1788 }
1789
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 pHddCtx->hdd_wlan_suspended = FALSE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301791 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 /*loop through all adapters. Concurrency */
1793 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1794
1795 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1796 {
1797 pAdapter = pAdapterNode->pAdapter;
1798 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001799 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001801 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1803 pAdapterNode = pNext;
1804 continue;
1805 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301806
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301807
Jeff Johnson295189b2012-06-20 16:38:30 -07001808#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1809 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1810 {
1811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1812 hdd_exit_deep_sleep(pAdapter);
1813 }
1814#endif
1815
1816 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1817 {
1818 /*Switch back to DTIM 1*/
1819 tSirSetPowerParamsReq powerRequest = { 0 };
1820
1821 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1822 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001823 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001824
1825 /*Disabled ModulatedDTIM if enabled on suspend*/
1826 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1827 powerRequest.uDTIMPeriod = 0;
1828
1829 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1830 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1831 NULL, eANI_BOOLEAN_FALSE);
1832 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1833 NULL, eANI_BOOLEAN_FALSE);
1834
1835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001836 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001837 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001838
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301839 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1840 {
1841 /* put the device into full power */
1842 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001843
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301844 /* put the device back into BMPS */
1845 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001846
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301847 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001849 }
1850
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301851 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1853 pAdapterNode = pNext;
1854 }
1855
1856#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1857 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1858 {
1859 hdd_exit_standby(pHddCtx);
1860 }
1861#endif
1862
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 return;
1864}
1865
Jeff Johnson295189b2012-06-20 16:38:30 -07001866VOS_STATUS hdd_wlan_reset_initialization(void)
1867{
Jeff Johnson295189b2012-06-20 16:38:30 -07001868 v_CONTEXT_t pVosContext = NULL;
1869
1870 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1871
1872 //Get the global VOSS context.
1873 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1874 if(!pVosContext)
1875 {
1876 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1877 return VOS_STATUS_E_FAILURE;
1878 }
1879
1880 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1881
1882 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301883 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07001884
Jeff Johnson295189b2012-06-20 16:38:30 -07001885 return VOS_STATUS_SUCCESS;
1886}
1887
1888
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001889/*
1890 * Based on the ioctl command recieved by HDD, put WLAN driver
1891 * into the quiet mode. This is the same as the early suspend
1892 * notification that driver used to listen
1893 */
1894void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001895{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301896 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001897 if (suspend)
1898 hdd_suspend_wlan();
1899 else
1900 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301901 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001902}
1903
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001904static void hdd_ssr_timer_init(void)
1905{
1906 init_timer(&ssr_timer);
1907}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001908
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001909static void hdd_ssr_timer_del(void)
1910{
1911 del_timer(&ssr_timer);
1912 ssr_timer_started = false;
1913}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001914
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001915static void hdd_ssr_timer_cb(unsigned long data)
1916{
1917 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001918
1919#ifdef WCN_PRONTO
1920 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1921 wcnss_pronto_log_debug_regs();
1922#endif
1923
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001924 VOS_BUG(0);
1925}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001926
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001927static void hdd_ssr_timer_start(int msec)
1928{
1929 if(ssr_timer_started)
1930 {
1931 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1932 ,__func__);
1933 }
1934 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1935 ssr_timer.function = hdd_ssr_timer_cb;
1936 add_timer(&ssr_timer);
1937 ssr_timer_started = true;
1938}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001939
Jeff Johnson295189b2012-06-20 16:38:30 -07001940/* the HDD interface to WLAN driver shutdown,
1941 * the primary shutdown function in SSR
1942 */
1943VOS_STATUS hdd_wlan_shutdown(void)
1944{
1945 VOS_STATUS vosStatus;
1946 v_CONTEXT_t pVosContext = NULL;
1947 hdd_context_t *pHddCtx = NULL;
1948 pVosSchedContext vosSchedContext = NULL;
1949
1950 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1951
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001952 /* if re-init never happens, then do SSR1 */
1953 hdd_ssr_timer_init();
1954 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1955
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 /* Get the global VOSS context. */
1957 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1958 if(!pVosContext) {
1959 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1960 return VOS_STATUS_E_FAILURE;
1961 }
1962 /* Get the HDD context. */
1963 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1964 if(!pHddCtx) {
1965 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1966 return VOS_STATUS_E_FAILURE;
1967 }
c_hpothud662a352013-12-26 15:09:12 +05301968
1969 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +05301970 if ((pHddCtx->cfg_ini->dynSplitscan)&& (VOS_TIMER_STATE_RUNNING ==
1971 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
c_hpothud662a352013-12-26 15:09:12 +05301972 {
1973 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1974 }
1975
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05301976 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 hdd_reset_all_adapters(pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +05301978
1979 /* set default value of Tcp delack and stop timer */
1980 hdd_set_default_stop_delack_timer(pHddCtx);
1981
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 /* DeRegister with platform driver as client for Suspend/Resume */
1983 vosStatus = hddDeregisterPmOps(pHddCtx);
1984 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1985 {
1986 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1987 }
1988
1989 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1990 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1991 {
1992 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1993 }
1994
1995 /* Disable IMPS/BMPS as we do not want the device to enter any power
1996 * save mode on its own during reset sequence
1997 */
1998 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1999 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
2000 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
2001
2002 vosSchedContext = get_vos_sched_ctxt();
2003
2004 /* Wakeup all driver threads */
2005 if(TRUE == pHddCtx->isMcThreadSuspended){
2006 complete(&vosSchedContext->ResumeMcEvent);
2007 pHddCtx->isMcThreadSuspended= FALSE;
2008 }
2009 if(TRUE == pHddCtx->isTxThreadSuspended){
2010 complete(&vosSchedContext->ResumeTxEvent);
2011 pHddCtx->isTxThreadSuspended= FALSE;
2012 }
2013 if(TRUE == pHddCtx->isRxThreadSuspended){
2014 complete(&vosSchedContext->ResumeRxEvent);
2015 pHddCtx->isRxThreadSuspended= FALSE;
2016 }
2017 /* Reset the Suspend Variable */
2018 pHddCtx->isWlanSuspended = FALSE;
2019
2020 /* Stop all the threads; we do not want any messages to be a processed,
2021 * any more and the best way to ensure that is to terminate the threads
2022 * gracefully.
2023 */
2024 /* Wait for MC to exit */
2025 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302026 set_bit(MC_SHUTDOWN_EVENT, &vosSchedContext->mcEventFlag);
2027 set_bit(MC_POST_EVENT, &vosSchedContext->mcEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002028 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302029 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002030
2031 /* Wait for TX to exit */
2032 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302033 set_bit(TX_SHUTDOWN_EVENT, &vosSchedContext->txEventFlag);
2034 set_bit(TX_POST_EVENT, &vosSchedContext->txEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302036 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002037
2038 /* Wait for RX to exit */
2039 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302040 set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->rxEventFlag);
2041 set_bit(RX_POST_EVENT, &vosSchedContext->rxEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05302043
Mihir Sheteb5425f72013-12-19 09:06:13 +05302044 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002045
2046#ifdef WLAN_BTAMP_FEATURE
2047 vosStatus = WLANBAP_Stop(pVosContext);
2048 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2049 {
2050 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2051 "%s: Failed to stop BAP",__func__);
2052 }
2053#endif //WLAN_BTAMP_FEATURE
2054 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302055 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2056 {
2057 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2058 "%s: Failed to stop wda %d", __func__, vosStatus);
2059 VOS_ASSERT(0);
2060 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002061
2062 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2063 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2064 * on threads being running to process the SYS Stop
2065 */
Kiet Lama72a2322013-11-15 11:18:11 +05302066 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302067 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2068 {
2069 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2070 "%s: Failed to stop sme %d", __func__, vosStatus);
2071 VOS_ASSERT(0);
2072 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002073
2074 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2075 /* Stop MAC (PE and HAL) */
2076 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302077 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2078 {
2079 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2080 "%s: Failed to stop mac %d", __func__, vosStatus);
2081 VOS_ASSERT(0);
2082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002083
2084 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2085 /* Stop TL */
2086 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302087 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2088 {
2089 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2090 "%s: Failed to stop TL %d", __func__, vosStatus);
2091 VOS_ASSERT(0);
2092 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002093
Jeff Johnson295189b2012-06-20 16:38:30 -07002094 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2096 /* Clean up message queues of TX and MC thread */
2097 vos_sched_flush_mc_mqs(vosSchedContext);
2098 vos_sched_flush_tx_mqs(vosSchedContext);
2099 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302100#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2101 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302102 /*Free fw dump mem in case of SSR/Shutdown */
2103 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2104 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302105#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002106
2107 /* Deinit all the TX and MC queues */
2108 vos_sched_deinit_mqs(vosSchedContext);
2109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2110
2111 /* shutdown VOSS */
2112 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302113
2114 /*mac context has already been released in mac_close call
2115 so setting it to NULL in hdd context*/
2116 pHddCtx->hHal = (tHalHandle)NULL;
2117
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 if (free_riva_power_on_lock("wlan"))
2119 {
2120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2121 __func__);
2122 }
2123 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2124 ,__func__);
2125 return VOS_STATUS_SUCCESS;
2126}
2127
2128
2129
2130/* the HDD interface to WLAN driver re-init.
2131 * This is called to initialize/start WLAN driver after a shutdown.
2132 */
2133VOS_STATUS hdd_wlan_re_init(void)
2134{
2135 VOS_STATUS vosStatus;
2136 v_CONTEXT_t pVosContext = NULL;
2137 hdd_context_t *pHddCtx = NULL;
2138 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002139#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2140 int max_retries = 0;
2141#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302142#ifdef HAVE_CBC_DONE
2143 int max_cbc_retries = 0;
2144#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002145#ifdef WLAN_BTAMP_FEATURE
2146 hdd_config_t *pConfig = NULL;
2147 WLANBAP_ConfigType btAmpConfig;
2148#endif
2149
Katya Nigam82a93062014-06-04 15:15:36 +05302150 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002151 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302152 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002153
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002154#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2155 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002156 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002157 msleep(1000);
2158 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002159 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002160 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2161 goto err_re_init;
2162 }
2163#endif
2164
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302165#ifdef HAVE_CBC_DONE
2166 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2167 msleep(1000);
2168 }
2169 if (max_cbc_retries >= 20) {
2170 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2171 }
2172#endif
2173
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002174 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2175
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002176 /* The driver should always be initialized in STA mode after SSR */
2177 hdd_set_conparam(0);
2178
Katya Nigam82a93062014-06-04 15:15:36 +05302179 dev = wcnss_wlan_get_device();
2180 if (NULL == dev)
2181 {
2182 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2183 goto err_re_init;
2184 }
2185
Jeff Johnson295189b2012-06-20 16:38:30 -07002186 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302187 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002188 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2189 {
2190 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2191 goto err_re_init;
2192 }
2193
2194 /* Get the HDD context. */
2195 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2196 if(!pHddCtx)
2197 {
2198 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2199 goto err_vosclose;
2200 }
2201
2202 /* Save the hal context in Adapter */
2203 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2204 if ( NULL == pHddCtx->hHal )
2205 {
2206 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2207 goto err_vosclose;
2208 }
2209
2210 /* Set the SME configuration parameters. */
2211 vosStatus = hdd_set_sme_config(pHddCtx);
2212 if ( VOS_STATUS_SUCCESS != vosStatus )
2213 {
2214 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2215 goto err_vosclose;
2216 }
2217
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 vosStatus = vos_preStart( pHddCtx->pvosContext );
2219 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2220 {
2221 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2222 goto err_vosclose;
2223 }
2224
2225 /* In the integrated architecture we update the configuration from
2226 the INI file and from NV before vOSS has been started so that
2227 the final contents are available to send down to the cCPU */
2228 /* Apply the cfg.ini to cfg.dat */
2229 if (FALSE == hdd_update_config_dat(pHddCtx))
2230 {
2231 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2232 goto err_vosclose;
2233 }
2234
2235 /* Set the MAC Address, currently this is used by HAL to add self sta.
2236 * Remove this once self sta is added as part of session open. */
2237 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2238 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2239 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2240 if (!HAL_STATUS_SUCCESS(halStatus))
2241 {
2242 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2243 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2244 goto err_vosclose;
2245 }
2246
2247 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2248 Note: Firmware image will be read and downloaded inside vos_start API */
2249 vosStatus = vos_start( pVosContext );
2250 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2251 {
2252 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +05302253 if (isSsrPanicOnFailure())
2254 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 goto err_vosclose;
2256 }
2257
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002258 /* Exchange capability info between Host and FW and also get versioning info from FW */
2259 hdd_exchange_version_and_caps(pHddCtx);
2260
Jeff Johnson295189b2012-06-20 16:38:30 -07002261 vosStatus = hdd_post_voss_start_config( pHddCtx );
2262 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2263 {
2264 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2265 __func__);
2266 goto err_vosstop;
2267 }
2268
Mihir Shete04206452014-11-20 17:50:58 +05302269#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302270 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2271 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2272 {
2273 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2274 __func__);
2275 goto err_vosstop;
2276 }
Mihir Shete04206452014-11-20 17:50:58 +05302277#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302278
Jeff Johnson295189b2012-06-20 16:38:30 -07002279#ifdef WLAN_BTAMP_FEATURE
2280 vosStatus = WLANBAP_Open(pVosContext);
2281 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2282 {
2283 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2284 "%s: Failed to open BAP",__func__);
2285 goto err_vosstop;
2286 }
2287 vosStatus = BSL_Init(pVosContext);
2288 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2289 {
2290 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2291 "%s: Failed to Init BSL",__func__);
2292 goto err_bap_close;
2293 }
2294 vosStatus = WLANBAP_Start(pVosContext);
2295 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2296 {
2297 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2298 "%s: Failed to start TL",__func__);
2299 goto err_bap_close;
2300 }
2301 pConfig = pHddCtx->cfg_ini;
2302 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2303 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2304#endif //WLAN_BTAMP_FEATURE
2305
2306 /* Restart all adapters */
2307 hdd_start_all_adapters(pHddCtx);
Agrawal Ashish4248d692016-08-17 19:21:02 +05302308 pHddCtx->con_scan_abort_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002309 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302310 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302312 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002313 /* Register with platform driver as client for Suspend/Resume */
2314 vosStatus = hddRegisterPmOps(pHddCtx);
2315 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2316 {
2317 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2318 goto err_bap_stop;
2319 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302320
2321#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2322 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2323 (pHddCtx->cfg_ini->enableFWLogging ||
2324 pHddCtx->cfg_ini->enableMgmtLogging ||
2325 pHddCtx->cfg_ini->enableContFWLogging))
2326 {
2327 hdd_init_frame_logging(pHddCtx);
2328 }
2329#endif
2330
Jeff Johnson295189b2012-06-20 16:38:30 -07002331 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302332 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002333 /* register for riva power on lock */
2334 if (req_riva_power_on_lock("wlan"))
2335 {
2336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2337 __func__);
2338 goto err_unregister_pmops;
2339 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302340 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002341 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Deepthi Gowri1ca95bb2016-01-13 19:47:53 +05302342
2343 sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame);
2344
Dasari Srinivas421bde82014-06-25 12:01:44 +05302345#ifdef WLAN_FEATURE_EXTSCAN
2346 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2347 wlan_hdd_cfg80211_extscan_callback,
2348 pHddCtx);
2349#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302350
2351#ifdef FEATURE_OEM_DATA_SUPPORT
2352 sme_OemDataRegisterCallback(pHddCtx->hHal,
2353 wlan_hdd_cfg80211_oemdata_callback,
2354 pHddCtx);
2355#endif /* FEATURE_OEM_DATA_SUPPORT */
2356
Jeff Johnson295189b2012-06-20 16:38:30 -07002357 goto success;
2358
2359err_unregister_pmops:
2360 hddDeregisterPmOps(pHddCtx);
2361
2362err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002363#ifdef CONFIG_HAS_EARLYSUSPEND
2364 hdd_unregister_mcast_bcast_filter(pHddCtx);
2365#endif
2366 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002367#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002368 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002369#endif
2370
2371#ifdef WLAN_BTAMP_FEATURE
2372err_bap_close:
2373 WLANBAP_Close(pVosContext);
2374#endif
2375
2376err_vosstop:
2377 vos_stop(pVosContext);
2378
2379err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302380 if(!isSsrPanicOnFailure())
2381 {
2382 /* If we hit this, it means wlan driver is in bad state and needs
2383 * driver unload and load.
2384 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302385 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2386 return VOS_STATUS_E_FAILURE;
2387 }
2388
Jeff Johnson295189b2012-06-20 16:38:30 -07002389 vos_close(pVosContext);
2390 vos_sched_close(pVosContext);
2391 if (pHddCtx)
2392 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002393 /* Unregister the Net Device Notifier */
2394 unregister_netdevice_notifier(&hdd_netdev_notifier);
2395 /* Clean up HDD Nlink Service */
2396 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002397#ifdef WLAN_KD_READY_NOTIFIER
2398 nl_srv_exit(pHddCtx->ptt_pid);
2399#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002400 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002401#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 /* Free up dynamically allocated members inside HDD Adapter */
2403 kfree(pHddCtx->cfg_ini);
2404 pHddCtx->cfg_ini= NULL;
2405
Jeff Johnson295189b2012-06-20 16:38:30 -07002406 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302407 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002408 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002409 }
2410 vos_preClose(&pVosContext);
2411
2412#ifdef MEMORY_DEBUG
2413 vos_mem_exit();
2414#endif
2415
2416err_re_init:
2417 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302418 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002419 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002420 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002421 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002422
2423success:
2424 /* Trigger replay of BTC events */
2425 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2426 return VOS_STATUS_SUCCESS;
2427}