blob: 906aa378a9de84d4644c4c07eb3357cbe35c345e [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 {
570 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530571 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530572 {
573 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
574 }
575 else
576 {
577 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
578 pHddCtx->cfg_ini->nEnableSuspend);
579 }
580 break;
581 }
582 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
583 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530584 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530585 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530586 return NOTIFY_DONE;
587}
588
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530589int wlan_hdd_ipv6_changed(struct notifier_block *nb,
590 unsigned long data, void *arg)
591{
592 int ret;
593 vos_ssr_protect(__func__);
594 ret = __wlan_hdd_ipv6_changed( nb, data, arg);
595 vos_ssr_unprotect(__func__);
596 return ret;
597}
598
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530599/*
600 * Function: hdd_conf_hostoffload
601 * Central function to configure the supported offloads,
602 * either enable or disable them.
603 */
604void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
605{
606 hdd_context_t *pHddCtx = NULL;
607 v_CONTEXT_t *pVosContext = NULL;
608 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
609
610 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
611 fenable);
612
613 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
614
615 if (NULL == pVosContext)
616 {
617 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
618 return;
619 }
620
621 //Get the HDD context.
622 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
623
624 if (NULL == pHddCtx)
625 {
626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
627 return;
628 }
629
630 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
631 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
632 {
633 if (fenable)
634 {
635 if (eConnectionState_Associated ==
636 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
637 {
638 if ((pHddCtx->cfg_ini->fhostArpOffload))
639 {
640 /*
641 * Configure the ARP Offload.
642 * Even if it fails we have to reconfigure the MC/BC
643 * filter flag as we want RIVA not to drop BroadCast
644 * Packets
645 */
646 hddLog(VOS_TRACE_LEVEL_INFO,
647 FL("Calling ARP Offload with flag: %d"), fenable);
648 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
649 pHddCtx->configuredMcastBcastFilter &=
650 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
651
652 if (!VOS_IS_STATUS_SUCCESS(vstatus))
653 {
654 hddLog(VOS_TRACE_LEVEL_ERROR,
655 "Failed to enable ARPOFfloadFeature %d",
656 vstatus);
657 }
658 }
659 //Configure GTK_OFFLOAD
660#ifdef WLAN_FEATURE_GTK_OFFLOAD
661 hdd_conf_gtk_offload(pAdapter, fenable);
662#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530663
664#ifdef WLAN_NS_OFFLOAD
665 if (pHddCtx->cfg_ini->fhostNSOffload)
666 {
667 /*
668 * Configure the NS Offload.
669 * Even if it fails we have to reconfigure the MC/BC filter flag
670 * as we want RIVA not to drop Multicast Packets
671 */
672
673 hddLog(VOS_TRACE_LEVEL_INFO,
674 FL("Calling NS Offload with flag: %d"), fenable);
675 hdd_conf_ns_offload(pAdapter, fenable);
676 pHddCtx->configuredMcastBcastFilter &=
677 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
678 }
679#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530680
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530681 }
682 }
683 else
684 {
685 //Disable ARPOFFLOAD
686 if (pHddCtx->cfg_ini->fhostArpOffload)
687 {
688 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
689 if (!VOS_IS_STATUS_SUCCESS(vstatus))
690 {
691 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530692 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530693 }
694 }
695 //Disable GTK_OFFLOAD
696#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530697 hdd_conf_gtk_offload(pAdapter, fenable);
698#endif
699
700#ifdef WLAN_NS_OFFLOAD
701 //Disable NSOFFLOAD
702 if (pHddCtx->cfg_ini->fhostNSOffload)
703 {
704 hdd_conf_ns_offload(pAdapter, fenable);
705 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530706#endif
707 }
708 }
709 return;
710}
711
Atul Mittal37385d72014-03-27 18:15:03 +0530712
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530713#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530714/**----------------------------------------------------------------------------
715
716 \brief hdd_conf_ns_offload() - Configure NS offload
717
718 Called during SUSPEND to configure the NS offload (MC BC filter) which
719 reduces power consumption.
720
721 \param - pAdapter - Adapter context for which NS offload is to be configured
722 \param - fenable - 0 - disable.
723 1 - enable. (with IPv6 notifier registration)
724 2 - enable. (without IPv6 notifier registration)
725
726 \return - void
727
728 ---------------------------------------------------------------------------*/
729void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530730{
731 struct inet6_dev *in6_dev;
732 struct inet6_ifaddr *ifp;
733 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530734 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530735 tANI_U8 **selfIPv6Addr = NULL;
736 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530737 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530738 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530739 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530740
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530741 int i = 0, slot = 0;
742 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530743 eHalStatus returnStatus;
744
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530745 ENTER();
746 hddLog(LOG1, FL(" fenable = %d"), fenable);
747
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530748 if (NULL == pAdapter)
749 {
750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
751 return;
752 }
753
754 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530755 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
756
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530757 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530758 if (0 != ret)
759 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530760 return;
761 }
762
763 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
764 {
765 slot_index = NS_EXTENDED_SLOT_INDEX;
766 }
767
768 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
769
770 selfIPv6AddrValid =
771 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
772
773 if (NULL == selfIPv6AddrValid)
774 {
775 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
776 " selfIPv6AddrValid"));
777 goto end;
778 }
779
780 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
781
782 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
783
784 if (NULL == selfIPv6Addr)
785 {
786 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
787 " selfIPv6Addr"));
788 goto end;
789 }
790
791 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
792
793 for (slot = 0; slot < slot_index; slot++)
794 {
795 selfIPv6Addr[slot] =
796 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
797 if (NULL == selfIPv6Addr[slot])
798 {
799 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
800 "for selfIPv6Addr"));
801 goto end;
802 }
803 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
804 }
805
806 i = 0;
807
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530808 if (fenable)
809 {
810 in6_dev = __in6_dev_get(pAdapter->dev);
811 if (NULL != in6_dev)
812 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530813 list_for_each(p, &in6_dev->addr_list)
814 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530815 if (i >= slot_index)
816 {
817 hddLog (VOS_TRACE_LEVEL_ERROR,
818 FL("IPv6 address list is greater than IPv6"
819 "address supported by firmware"));
820 hddLog (VOS_TRACE_LEVEL_ERROR,
821 FL("FW supported IPv6 address = %d"), slot_index);
822 break;
823 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530824 ifp = list_entry(p, struct inet6_ifaddr, if_list);
825 switch(ipv6_addr_src_scope(&ifp->addr))
826 {
827 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530828 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530829 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530830 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530831 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530832 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
833 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530834 break;
835 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530836 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530837 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530838 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530839 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530840 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
841 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530842 break;
843 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530844 hddLog(VOS_TRACE_LEVEL_ERROR,
845 FL("The Scope %d is not supported"),
846 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530847 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530848 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
849 {
850 i++;
851 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530852 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530853
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530854 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530855 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530856 {
857 if (selfIPv6AddrValid[i])
858 {
859 //Filling up the request structure
860 /* Filling the selfIPv6Addr with solicited address
861 * A Solicited-Node multicast address is created by
862 * taking the last 24 bits of a unicast or anycast
863 * address and appending them to the prefix
864 *
865 * FF02:0000:0000:0000:0000:0001:FFXX:XX
866 *
867 * here XX is the unicast/anycast bits
868 */
869 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
870 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
871 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
872 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530873 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
874 selfIPv6Addr[i][13];
875 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
876 selfIPv6Addr[i][14];
877 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
878 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530879 offLoadRequest.nsOffloadInfo.slotIdx = i;
880
881 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530882 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530883 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
884 &pAdapter->macAddressCurrent.bytes,
885 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
886
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530887 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
888 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530889 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
890 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +0530891 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
892 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530893
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530894 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530895 FL("configuredMcastBcastFilter: %d"
896 "NSOffload Slot = %d"),
897 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530898
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530899 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700900 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
901 pHddCtx->sus_res_mcastbcast_filter) ||
902 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
903 pHddCtx->sus_res_mcastbcast_filter)) &&
904 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
905 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
906 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530907 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530908 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700909 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Sushant Kaushik439d4c72014-05-12 16:39:51 +0530910 hddLog (VOS_TRACE_LEVEL_INFO,
911 FL("Set offLoadRequest with %d"),
912 offLoadRequest.enableOrDisable);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530913 }
Abhishek Singh937ec542016-01-05 18:03:14 +0530914 hdd_wlan_offload_event(
915 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE,
916 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530917 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
918 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
919 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
920
921 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530922 FL("Setting NSOffload with solicitedIp: %pI6,"
923 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530924 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
925 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
926
927 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530928 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530929 pAdapter->sessionId, &offLoadRequest);
930 if(eHAL_STATUS_SUCCESS != returnStatus)
931 {
932 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530933 FL("Failed to enable HostOffload feature with"
934 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530935 }
936 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
937 }
938 }
939 }
940 else
941 {
942 hddLog(VOS_TRACE_LEVEL_ERROR,
943 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530944 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530945 }
946 }
947 else
948 {
949 //Disable NSOffload
950 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
951 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
952 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +0530953 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
954 SIR_OFFLOAD_DISABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530955
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530956 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530957 {
c_hpothu86feba52014-10-28 15:51:18 +0530958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530959 offLoadRequest.nsOffloadInfo.slotIdx = i;
960 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530961 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
962 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530963 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
965 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530966 }
967 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530968 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530969end:
970 while (slot > 0 && selfIPv6Addr[--slot])
971 {
972 vos_mem_free(selfIPv6Addr[slot]);
973 }
974 if (selfIPv6Addr)
975 {
976 vos_mem_free(selfIPv6Addr);
977 }
978 if (selfIPv6AddrValid)
979 {
980 vos_mem_free(selfIPv6AddrValid);
981 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530982 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530983 return;
984}
985#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530986
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530987void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +0530988{
989 hdd_adapter_t* pAdapter =
990 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
991 hdd_context_t *pHddCtx;
992 int status;
993
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530994 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530995 if (NULL == pAdapter)
996 {
997 hddLog(LOGE, FL("Adapter is invalid"));
998 return;
999 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1001 status = wlan_hdd_validate_context(pHddCtx);
1002 if (0 != status)
1003 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301004 return;
1005 }
1006
Deepthi Gowri5933f402014-01-23 17:48:24 +05301007 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1008 {
1009 pHddCtx->sus_res_mcastbcast_filter =
1010 pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301011 hddLog(LOG1, FL("saving configuredMcastBcastFilter = %d"),
1012 pHddCtx->sus_res_mcastbcast_filter);
Deepthi Gowri5933f402014-01-23 17:48:24 +05301013 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1014 }
1015
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301016 if ((eConnectionState_Associated ==
1017 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +05301018 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301019 {
1020 // This invocation being part of the IPv4 registration callback,
1021 // we are passing second parameter as 2 to avoid registration
1022 // of IPv4 notifier again.
1023 hdd_conf_arp_offload(pAdapter, 2);
1024 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301025 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301026}
1027
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301028void hdd_ipv4_notifier_work_queue(struct work_struct *work)
1029{
1030 vos_ssr_protect(__func__);
1031 __hdd_ipv4_notifier_work_queue(work);
1032 vos_ssr_unprotect(__func__);
1033}
1034
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301035int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301036 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301037{
1038 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1039 struct in_ifaddr **ifap = NULL;
1040 struct in_device *in_dev;
1041
1042 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301043 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301044 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301045 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301046 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301047
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301048 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301049 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1050 status = wlan_hdd_validate_context(pHddCtx);
1051 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301052 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301053 return NOTIFY_DONE;
1054 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301055
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301056 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1057 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1058 {
1059 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1060 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1061 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1062 {
1063 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301064 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301065 || (!pHddCtx->cfg_ini->fhostArpOffload))
1066 {
1067 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1068 pHddCtx->cfg_ini->nEnableSuspend,
1069 pHddCtx->cfg_ini->fhostArpOffload);
1070 return NOTIFY_DONE;
1071 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301072
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301073 if ((in_dev =
1074 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1075 {
1076 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1077 ifap = &ifa->ifa_next)
1078 {
1079 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1080 ifa->ifa_label))
1081 {
1082 break; /* found */
1083 }
1084 }
1085 }
1086 if(ifa && ifa->ifa_local)
1087 {
1088 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1089 }
1090 break;
1091 }
1092 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1093 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301094 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301095 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301096 return NOTIFY_DONE;
1097}
1098
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301099int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1100 unsigned long data, void *arg)
1101{
1102 int ret;
1103 vos_ssr_protect(__func__);
1104 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1105 vos_ssr_unprotect(__func__);
1106 return ret;
1107}
1108
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301109/**----------------------------------------------------------------------------
1110
1111 \brief hdd_conf_arp_offload() - Configure ARP offload
1112
1113 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1114 reduces power consumption.
1115
1116 \param - pAdapter -Adapter context for which ARP offload is to be configured
1117 \param - fenable - 0 - disable.
1118 1 - enable. (with IPv4 notifier registration)
1119 2 - enable. (without IPv4 notifier registration)
1120
1121 \return -
1122 VOS_STATUS_SUCCESS - on successful operation
1123 VOS_STATUS_E_FAILURE - on failure of operation
1124-----------------------------------------------------------------------------*/
1125VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001126{
1127 struct in_ifaddr **ifap = NULL;
1128 struct in_ifaddr *ifa = NULL;
1129 struct in_device *in_dev;
1130 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001131 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001132 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001133
Sushant Kaushik87787972015-09-11 16:05:00 +05301134 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001135
Jeff Johnson295189b2012-06-20 16:38:30 -07001136 if(fenable)
1137 {
1138 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1139 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301140 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 ifap = &ifa->ifa_next)
1142 {
1143 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1144 {
1145 break; /* found */
1146 }
1147 }
1148 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 if(ifa && ifa->ifa_local)
1150 {
1151 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1152 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +05301153 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1154 SIR_OFFLOAD_ENABLE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001155
Arif Hussain6d2a3322013-11-17 19:50:10 -08001156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001157
Amar Singhald53568e2013-09-26 11:03:45 -07001158 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1159 pHddCtx->sus_res_mcastbcast_filter) ||
1160 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1161 pHddCtx->sus_res_mcastbcast_filter)) &&
1162 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001163 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301164 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001165 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1166 hddLog(VOS_TRACE_LEVEL_INFO,
1167 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001168 }
Abhishek Singh937ec542016-01-05 18:03:14 +05301169 hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
1170 SIR_OFFLOAD_ENABLE);
Amar Singhald53568e2013-09-26 11:03:45 -07001171
1172 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1173 offLoadRequest.enableOrDisable);
1174
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 //converting u32 to IPV4 address
1176 for(i = 0 ; i < 4; i++)
1177 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301178 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001179 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1180 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301181 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001182 offLoadRequest.params.hostIpv4Addr[0],
1183 offLoadRequest.params.hostIpv4Addr[1],
1184 offLoadRequest.params.hostIpv4Addr[2],
1185 offLoadRequest.params.hostIpv4Addr[3]);
1186
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301187 if (eHAL_STATUS_SUCCESS !=
1188 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1189 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 {
1191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001192 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 return VOS_STATUS_E_FAILURE;
1194 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001195 }
1196 else
1197 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05301198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("IP Address is not assigned"));
1199 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301201
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301202 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 }
1204 else
1205 {
1206 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1207 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1208 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +05301209 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1210 SIR_OFFLOAD_DISABLE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301211 if (eHAL_STATUS_SUCCESS !=
1212 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1213 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001214 {
1215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001216 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 return VOS_STATUS_E_FAILURE;
1218 }
1219 return VOS_STATUS_SUCCESS;
1220 }
1221}
1222
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301223/*
1224 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301225 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301226*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301227void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301228 tANI_U8 *pMcBcFilter)
1229{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301230 if (NULL == pHddCtx)
1231 {
1232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1233 return;
1234 }
1235
1236 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1237 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301238 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301239 /* ARP offload is enabled, do not block bcast packets at RXP
1240 * Will be using Bitmasking to reset the filter. As we have
1241 * disable Broadcast filtering, Anding with the negation
1242 * of Broadcast BIT
1243 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301244 hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301245 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301246 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301247
1248#ifdef WLAN_NS_OFFLOAD
1249 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301250 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301251 /* NS offload is enabled, do not block mcast packets at RXP
1252 * Will be using Bitmasking to reset the filter. As we have
1253 * disable Multicast filtering, Anding with the negation
1254 * of Multicast BIT
1255 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301256 hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301257 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301258 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301259#endif
1260
Amar Singhald08ce752014-03-21 16:28:27 -07001261 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1262 {
1263 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1264 }
1265
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301266 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301267}
1268
Jeff Johnson295189b2012-06-20 16:38:30 -07001269void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1270{
1271 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001272 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1273 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
Agarwal Ashishff451a32015-07-28 01:01:29 +05301274 if (NULL == wlanRxpFilterParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001275 {
1276 hddLog(VOS_TRACE_LEVEL_FATAL,
1277 "%s: vos_mem_alloc failed ", __func__);
1278 return;
1279 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001280 hddLog(VOS_TRACE_LEVEL_INFO,
1281 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301282 if (TRUE == setfilter)
1283 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301284 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301285 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301286 }
1287 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301288 {
1289 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301290 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301291 pHddCtx->configuredMcastBcastFilter;
1292 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301293
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001295 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301296
1297 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
Agarwal Ashishff451a32015-07-28 01:01:29 +05301298 {
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301299 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Agarwal Ashishff451a32015-07-28 01:01:29 +05301300 }
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301301
1302 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1303 "lower mac with status %d"
1304 "configuredMcstBcstFilterSetting = %d"
1305 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1306 "Failed" : "Success", halStatus,
1307 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1308 wlanRxpFilterParam->setMcstBcstFilter);
1309
Chilam Ngc4244af2013-04-01 15:37:32 -07001310 if (eHAL_STATUS_SUCCESS != halStatus)
1311 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001312}
1313
Jeff Johnson295189b2012-06-20 16:38:30 -07001314static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1315 hdd_adapter_t *pAdapter)
1316{
1317 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1318 tpSirWlanSuspendParam wlanSuspendParam =
1319 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1320
Amar Singhald53568e2013-09-26 11:03:45 -07001321 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1322 pHddCtx->sus_res_mcastbcast_filter =
1323 pHddCtx->configuredMcastBcastFilter;
1324 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1325 hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
1326 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d",
1327 pHddCtx->configuredMcastBcastFilter);
1328
1329 }
1330
Amar Singhal49fdfd52013-08-13 13:25:12 -07001331
Jeff Johnson295189b2012-06-20 16:38:30 -07001332 if(NULL == wlanSuspendParam)
1333 {
1334 hddLog(VOS_TRACE_LEVEL_FATAL,
1335 "%s: vos_mem_alloc failed ", __func__);
1336 return;
1337 }
1338
Amar Singhald53568e2013-09-26 11:03:45 -07001339 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001340 "%s: send wlan suspend indication", __func__);
1341
1342 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1343 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301344 //Configure supported OffLoads
1345 hdd_conf_hostoffload(pAdapter, TRUE);
1346 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301347 hddLog(VOS_TRACE_LEVEL_INFO,
1348 FL("saving configuredMcastBcastFilterSetting = %d"),
1349 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001350#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301351 /* During suspend, configure MC Addr list filter to the firmware
1352 * function takes care of checking necessary conditions before
1353 * configuring.
1354 */
1355 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001356#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001357
1358 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1359 {
1360
1361 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1362 pHddCtx->configuredMcastBcastFilter &=
1363 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1364 }
1365
1366 wlanSuspendParam->configuredMcstBcstFilterSetting =
1367 pHddCtx->configuredMcastBcastFilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001368 }
1369
1370 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1371 if(eHAL_STATUS_SUCCESS == halStatus)
1372 {
1373 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001374 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301375 hddLog(VOS_TRACE_LEVEL_ERROR,
1376 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001377 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001378 }
1379}
1380
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301381static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001382{
Chilam Ngc4244af2013-04-01 15:37:32 -07001383 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001384 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001385 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001386
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301387 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 "%s: send wlan resume indication", __func__);
1389
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301390 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1391
1392 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001393 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301394 hddLog(VOS_TRACE_LEVEL_FATAL,
1395 "%s: memory allocation failed for wlanResumeParam ", __func__);
1396 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001397 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001398
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301399 //Disable supported OffLoads
1400 hdd_conf_hostoffload(pAdapter, FALSE);
1401
1402 wlanResumeParam->configuredMcstBcstFilterSetting =
1403 pHddCtx->configuredMcastBcastFilter;
1404 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1405 if (eHAL_STATUS_SUCCESS != halStatus)
1406 {
c_hpothuffdb5272013-10-02 16:42:35 +05301407 hddLog(VOS_TRACE_LEVEL_ERROR,
1408 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301409 vos_mem_free(wlanResumeParam);
1410 }
1411
1412 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
1413
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001414 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1415 pHddCtx->configuredMcastBcastFilter =
1416 pHddCtx->sus_res_mcastbcast_filter;
1417 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1418 }
Amar Singhald53568e2013-09-26 11:03:45 -07001419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1422 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1423 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001424
Chilam Ngc4244af2013-04-01 15:37:32 -07001425
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301426#ifdef WLAN_FEATURE_PACKET_FILTERING
1427 /* Filer was applied during suspend inditication
1428 * clear it when we resume.
1429 */
1430 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001431#endif
1432}
Jeff Johnson295189b2012-06-20 16:38:30 -07001433
Jeff Johnson295189b2012-06-20 16:38:30 -07001434//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001435void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001436{
1437 hdd_context_t *pHddCtx = NULL;
1438 v_CONTEXT_t pVosContext = NULL;
1439
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301441 hdd_adapter_t *pAdapter = NULL;
1442 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301443 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001444
Jeff Johnson295189b2012-06-20 16:38:30 -07001445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1446
1447 //Get the global VOSS context.
1448 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1449 if(!pVosContext) {
1450 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1451 return;
1452 }
1453
1454 //Get the HDD context.
1455 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1456
1457 if(!pHddCtx) {
1458 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1459 return;
1460 }
1461
1462 if (pHddCtx->isLogpInProgress) {
1463 hddLog(VOS_TRACE_LEVEL_ERROR,
1464 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1465 return;
1466 }
1467
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301468 if (pHddCtx->hdd_wlan_suspended)
1469 {
1470 hddLog(VOS_TRACE_LEVEL_ERROR,
1471 "%s: Ignore suspend wlan, Already suspended!", __func__);
1472 return;
1473 }
1474
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301475 pHddCtx->hdd_wlan_suspended = TRUE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301476 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301477 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001478 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1479 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1480 {
1481 pAdapter = pAdapterNode->pAdapter;
1482 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001483 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1485
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001486 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001487 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1488 pAdapterNode = pNext;
1489 continue;
1490 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301491 /* Avoid multiple enter/exit BMPS in this while loop using
1492 * hdd_enter_bmps flag
1493 */
1494 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1495 {
1496 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001497
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301498 /* If device was already in BMPS, and dynamic DTIM is set,
1499 * exit(set the device to full power) and enter BMPS again
1500 * to reflect new DTIM value */
1501 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1502
1503 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1504
1505 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001507#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1508 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1509 {
1510 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301511 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001512 netif_tx_disable(pAdapter->dev);
1513 netif_carrier_off(pAdapter->dev);
1514 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301515 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001516 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1517 {
1518 //Execute deep sleep procedure
1519 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1520 }
1521#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301522
1523 /*Suspend notification sent down to driver*/
1524 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1525
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301526 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1527 pAdapterNode = pNext;
1528 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301529
Jeff Johnson295189b2012-06-20 16:38:30 -07001530#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1531 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1532 {
1533 hdd_enter_standby(pHddCtx);
1534 }
1535#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001536
1537 return;
1538}
1539
1540static void hdd_PowerStateChangedCB
1541(
1542 v_PVOID_t callbackContext,
1543 tPmcState newState
1544)
1545{
1546 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301547
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 /* if the driver was not in BMPS during early suspend,
1549 * the dynamic DTIM is now updated at Riva */
1550 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
1551 && pHddCtx->cfg_ini->enableDynamicDTIM
1552 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1553 {
1554 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1555 }
1556 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301557 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1558 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001559 spin_unlock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301560 if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
1561 {
Amar Singhald53568e2013-09-26 11:03:45 -07001562 pHddCtx->sus_res_mcastbcast_filter =
1563 pHddCtx->configuredMcastBcastFilter;
1564 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
1565
1566 hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated");
1567 hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d",
1568 pHddCtx->configuredMcastBcastFilter);
1569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "offload: calling hdd_conf_mcastbcast_filter");
1571
1572 }
1573
Jeff Johnson295189b2012-06-20 16:38:30 -07001574 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301577 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001578 else
Mihir Shete793209f2014-01-06 11:01:12 +05301579 {
1580 /* Android framework can send resume request when the WCN chip is
1581 * in IMPS mode. When the chip exits IMPS mode the firmware will
1582 * restore all the registers to the state they were before the chip
1583 * entered IMPS and so our hardware filter settings confgured by the
1584 * resume request will be lost. So reconfigure the filters on detecting
1585 * a change in the power state of the WCN chip.
1586 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301587 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301588 if (IMPS != newState)
1589 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301590 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301591 if (FALSE == pHddCtx->hdd_wlan_suspended)
1592 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301593 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301594 hddLog(VOS_TRACE_LEVEL_INFO,
1595 "Not in IMPS/BMPS and suspended state");
1596 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1597 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301598 else
1599 {
1600 spin_unlock(&pHddCtx->filter_lock);
1601 }
Mihir Shete793209f2014-01-06 11:01:12 +05301602 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001604}
1605
Jeff Johnson295189b2012-06-20 16:38:30 -07001606void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1607{
1608 v_CONTEXT_t pVosContext;
1609 tHalHandle smeContext;
1610
1611 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1612 if (NULL == pVosContext)
1613 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001614 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001615 return;
1616 }
1617 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1618 if (NULL == smeContext)
1619 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001620 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001621 return;
1622 }
1623
1624 spin_lock_init(&pHddCtx->filter_lock);
1625 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1626 pHddCtx->cfg_ini->nEnableSuspend)
1627 {
1628 pmcRegisterDeviceStateUpdateInd(smeContext,
1629 hdd_PowerStateChangedCB, pHddCtx);
1630 }
1631}
1632
1633void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1634{
1635 v_CONTEXT_t pVosContext;
1636 tHalHandle smeContext;
1637
1638 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1639 if (NULL == pVosContext)
1640 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001641 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 return;
1643 }
1644 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1645 if (NULL == smeContext)
1646 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001647 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 return;
1649 }
1650
1651 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1652 pHddCtx->cfg_ini->nEnableSuspend)
1653 {
1654 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1655 }
1656}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301657
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301658#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301659void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301660{
1661 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301662 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301663 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1664
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301665 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301666 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301667 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1668 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1669 {
1670 vos_mem_copy(&hddGtkOffloadReqParams,
1671 &pHddStaCtx->gtkOffloadReqParams,
1672 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301673
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301674 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1675 &hddGtkOffloadReqParams, pAdapter->sessionId);
1676 if (eHAL_STATUS_SUCCESS != ret)
1677 {
1678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1679 "%s: sme_SetGTKOffload failed, returned %d",
1680 __func__, ret);
1681 return;
1682 }
1683
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1685 "%s: sme_SetGTKOffload successfull", __func__);
1686 }
1687
1688 }
1689 else
1690 {
1691 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1692 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1693 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1694 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1695 {
1696
1697 /* Host driver has previously offloaded GTK rekey */
1698 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301699 wlan_hdd_cfg80211_update_replayCounterCallback,
1700 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301701 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301702
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301703 {
1704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1705 "%s: sme_GetGTKOffload failed, returned %d",
1706 __func__, ret);
1707 return;
1708 }
1709 else
1710 {
1711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1712 "%s: sme_GetGTKOffload successful",
1713 __func__);
1714
1715 /* Sending GTK offload dissable */
1716 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1717 sizeof (tSirGtkOffloadParams));
1718 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1719 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301720 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301721 if (eHAL_STATUS_SUCCESS != ret)
1722 {
1723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1724 "%s: failed to dissable GTK offload, returned %d",
1725 __func__, ret);
1726 return;
1727 }
1728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1729 "%s: successfully dissabled GTK offload request to HAL",
1730 __func__);
1731 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301732 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301733 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301734 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301735}
1736#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001737
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001738void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001739{
1740 hdd_context_t *pHddCtx = NULL;
1741 hdd_adapter_t *pAdapter = NULL;
1742 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1743 VOS_STATUS status;
1744 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001745
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1747
1748 //Get the global VOSS context.
1749 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1750 if(!pVosContext) {
1751 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1752 return;
1753 }
1754
1755 //Get the HDD context.
1756 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1757
1758 if(!pHddCtx) {
1759 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1760 return;
1761 }
1762
Agarwal Ashish971c2882013-10-30 20:11:12 +05301763 if (pHddCtx->isLogpInProgress)
1764 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001765 hddLog(VOS_TRACE_LEVEL_INFO,
1766 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1767 return;
1768 }
1769
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301770 if (!pHddCtx->hdd_wlan_suspended)
1771 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05301772 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301773 "%s: Ignore resume wlan, Already resumed!", __func__);
1774 return;
1775 }
1776
Jeff Johnson295189b2012-06-20 16:38:30 -07001777 pHddCtx->hdd_wlan_suspended = FALSE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301778 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 /*loop through all adapters. Concurrency */
1780 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1781
1782 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1783 {
1784 pAdapter = pAdapterNode->pAdapter;
1785 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001786 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001787 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001788 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1790 pAdapterNode = pNext;
1791 continue;
1792 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301793
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301794
Jeff Johnson295189b2012-06-20 16:38:30 -07001795#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1796 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
1797 {
1798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
1799 hdd_exit_deep_sleep(pAdapter);
1800 }
1801#endif
1802
1803 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
1804 {
1805 /*Switch back to DTIM 1*/
1806 tSirSetPowerParamsReq powerRequest = { 0 };
1807
1808 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
1809 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07001810 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001811
1812 /*Disabled ModulatedDTIM if enabled on suspend*/
1813 if(pHddCtx->cfg_ini->enableModulatedDTIM)
1814 powerRequest.uDTIMPeriod = 0;
1815
1816 /* Update ignoreDTIM and ListedInterval in CFG with default values */
1817 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
1818 NULL, eANI_BOOLEAN_FALSE);
1819 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
1820 NULL, eANI_BOOLEAN_FALSE);
1821
1822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001823 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08001824 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001825
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301826 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
1827 {
1828 /* put the device into full power */
1829 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001830
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301831 /* put the device back into BMPS */
1832 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07001833
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05301834 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
1835 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 }
1837
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301838 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1840 pAdapterNode = pNext;
1841 }
1842
1843#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1844 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
1845 {
1846 hdd_exit_standby(pHddCtx);
1847 }
1848#endif
1849
Jeff Johnson295189b2012-06-20 16:38:30 -07001850 return;
1851}
1852
Jeff Johnson295189b2012-06-20 16:38:30 -07001853VOS_STATUS hdd_wlan_reset_initialization(void)
1854{
Jeff Johnson295189b2012-06-20 16:38:30 -07001855 v_CONTEXT_t pVosContext = NULL;
1856
1857 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
1858
1859 //Get the global VOSS context.
1860 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1861 if(!pVosContext)
1862 {
1863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1864 return VOS_STATUS_E_FAILURE;
1865 }
1866
1867 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
1868
1869 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301870 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07001871
Jeff Johnson295189b2012-06-20 16:38:30 -07001872 return VOS_STATUS_SUCCESS;
1873}
1874
1875
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001876/*
1877 * Based on the ioctl command recieved by HDD, put WLAN driver
1878 * into the quiet mode. This is the same as the early suspend
1879 * notification that driver used to listen
1880 */
1881void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07001882{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301883 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001884 if (suspend)
1885 hdd_suspend_wlan();
1886 else
1887 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05301888 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001889}
1890
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001891static void hdd_ssr_timer_init(void)
1892{
1893 init_timer(&ssr_timer);
1894}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001895
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001896static void hdd_ssr_timer_del(void)
1897{
1898 del_timer(&ssr_timer);
1899 ssr_timer_started = false;
1900}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001901
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001902static void hdd_ssr_timer_cb(unsigned long data)
1903{
1904 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07001905
1906#ifdef WCN_PRONTO
1907 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
1908 wcnss_pronto_log_debug_regs();
1909#endif
1910
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001911 VOS_BUG(0);
1912}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001913
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001914static void hdd_ssr_timer_start(int msec)
1915{
1916 if(ssr_timer_started)
1917 {
1918 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
1919 ,__func__);
1920 }
1921 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
1922 ssr_timer.function = hdd_ssr_timer_cb;
1923 add_timer(&ssr_timer);
1924 ssr_timer_started = true;
1925}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001926
Jeff Johnson295189b2012-06-20 16:38:30 -07001927/* the HDD interface to WLAN driver shutdown,
1928 * the primary shutdown function in SSR
1929 */
1930VOS_STATUS hdd_wlan_shutdown(void)
1931{
1932 VOS_STATUS vosStatus;
1933 v_CONTEXT_t pVosContext = NULL;
1934 hdd_context_t *pHddCtx = NULL;
1935 pVosSchedContext vosSchedContext = NULL;
1936
1937 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
1938
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07001939 /* if re-init never happens, then do SSR1 */
1940 hdd_ssr_timer_init();
1941 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
1942
Jeff Johnson295189b2012-06-20 16:38:30 -07001943 /* Get the global VOSS context. */
1944 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1945 if(!pVosContext) {
1946 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1947 return VOS_STATUS_E_FAILURE;
1948 }
1949 /* Get the HDD context. */
1950 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
1951 if(!pHddCtx) {
1952 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1953 return VOS_STATUS_E_FAILURE;
1954 }
c_hpothud662a352013-12-26 15:09:12 +05301955
1956 //Stop the traffic monitor timer
1957 if ( VOS_TIMER_STATE_RUNNING ==
1958 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
1959 {
1960 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
1961 }
1962
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05301963 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 hdd_reset_all_adapters(pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +05301965
1966 /* set default value of Tcp delack and stop timer */
1967 hdd_set_default_stop_delack_timer(pHddCtx);
1968
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 /* DeRegister with platform driver as client for Suspend/Resume */
1970 vosStatus = hddDeregisterPmOps(pHddCtx);
1971 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1972 {
1973 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
1974 }
1975
1976 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
1977 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1978 {
1979 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
1980 }
1981
1982 /* Disable IMPS/BMPS as we do not want the device to enter any power
1983 * save mode on its own during reset sequence
1984 */
1985 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
1986 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
1987 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
1988
1989 vosSchedContext = get_vos_sched_ctxt();
1990
1991 /* Wakeup all driver threads */
1992 if(TRUE == pHddCtx->isMcThreadSuspended){
1993 complete(&vosSchedContext->ResumeMcEvent);
1994 pHddCtx->isMcThreadSuspended= FALSE;
1995 }
1996 if(TRUE == pHddCtx->isTxThreadSuspended){
1997 complete(&vosSchedContext->ResumeTxEvent);
1998 pHddCtx->isTxThreadSuspended= FALSE;
1999 }
2000 if(TRUE == pHddCtx->isRxThreadSuspended){
2001 complete(&vosSchedContext->ResumeRxEvent);
2002 pHddCtx->isRxThreadSuspended= FALSE;
2003 }
2004 /* Reset the Suspend Variable */
2005 pHddCtx->isWlanSuspended = FALSE;
2006
2007 /* Stop all the threads; we do not want any messages to be a processed,
2008 * any more and the best way to ensure that is to terminate the threads
2009 * gracefully.
2010 */
2011 /* Wait for MC to exit */
2012 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
2013 set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag);
2014 set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag);
2015 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302016 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002017
2018 /* Wait for TX to exit */
2019 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
2020 set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag);
2021 set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag);
2022 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302023 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002024
2025 /* Wait for RX to exit */
2026 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
2027 set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag);
2028 set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag);
2029 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05302030
Mihir Sheteb5425f72013-12-19 09:06:13 +05302031 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002032
2033#ifdef WLAN_BTAMP_FEATURE
2034 vosStatus = WLANBAP_Stop(pVosContext);
2035 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2036 {
2037 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2038 "%s: Failed to stop BAP",__func__);
2039 }
2040#endif //WLAN_BTAMP_FEATURE
2041 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302042 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2043 {
2044 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2045 "%s: Failed to stop wda %d", __func__, vosStatus);
2046 VOS_ASSERT(0);
2047 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002048
2049 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2050 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2051 * on threads being running to process the SYS Stop
2052 */
Kiet Lama72a2322013-11-15 11:18:11 +05302053 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302054 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2055 {
2056 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2057 "%s: Failed to stop sme %d", __func__, vosStatus);
2058 VOS_ASSERT(0);
2059 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002060
2061 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2062 /* Stop MAC (PE and HAL) */
2063 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302064 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2065 {
2066 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2067 "%s: Failed to stop mac %d", __func__, vosStatus);
2068 VOS_ASSERT(0);
2069 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002070
2071 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2072 /* Stop TL */
2073 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302074 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2075 {
2076 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2077 "%s: Failed to stop TL %d", __func__, vosStatus);
2078 VOS_ASSERT(0);
2079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002080
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2083 /* Clean up message queues of TX and MC thread */
2084 vos_sched_flush_mc_mqs(vosSchedContext);
2085 vos_sched_flush_tx_mqs(vosSchedContext);
2086 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302087#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2088 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302089 /*Free fw dump mem in case of SSR/Shutdown */
2090 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2091 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002093
2094 /* Deinit all the TX and MC queues */
2095 vos_sched_deinit_mqs(vosSchedContext);
2096 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2097
2098 /* shutdown VOSS */
2099 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302100
2101 /*mac context has already been released in mac_close call
2102 so setting it to NULL in hdd context*/
2103 pHddCtx->hHal = (tHalHandle)NULL;
2104
Jeff Johnson295189b2012-06-20 16:38:30 -07002105 if (free_riva_power_on_lock("wlan"))
2106 {
2107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2108 __func__);
2109 }
2110 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2111 ,__func__);
2112 return VOS_STATUS_SUCCESS;
2113}
2114
2115
2116
2117/* the HDD interface to WLAN driver re-init.
2118 * This is called to initialize/start WLAN driver after a shutdown.
2119 */
2120VOS_STATUS hdd_wlan_re_init(void)
2121{
2122 VOS_STATUS vosStatus;
2123 v_CONTEXT_t pVosContext = NULL;
2124 hdd_context_t *pHddCtx = NULL;
2125 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002126#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2127 int max_retries = 0;
2128#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302129#ifdef HAVE_CBC_DONE
2130 int max_cbc_retries = 0;
2131#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002132#ifdef WLAN_BTAMP_FEATURE
2133 hdd_config_t *pConfig = NULL;
2134 WLANBAP_ConfigType btAmpConfig;
2135#endif
2136
Katya Nigam82a93062014-06-04 15:15:36 +05302137 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002138 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302139 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002140
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002141#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2142 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002143 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002144 msleep(1000);
2145 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002146 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002147 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2148 goto err_re_init;
2149 }
2150#endif
2151
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302152#ifdef HAVE_CBC_DONE
2153 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2154 msleep(1000);
2155 }
2156 if (max_cbc_retries >= 20) {
2157 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2158 }
2159#endif
2160
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002161 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2162
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002163 /* The driver should always be initialized in STA mode after SSR */
2164 hdd_set_conparam(0);
2165
Katya Nigam82a93062014-06-04 15:15:36 +05302166 dev = wcnss_wlan_get_device();
2167 if (NULL == dev)
2168 {
2169 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2170 goto err_re_init;
2171 }
2172
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302174 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002175 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2176 {
2177 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2178 goto err_re_init;
2179 }
2180
2181 /* Get the HDD context. */
2182 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2183 if(!pHddCtx)
2184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2186 goto err_vosclose;
2187 }
2188
2189 /* Save the hal context in Adapter */
2190 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2191 if ( NULL == pHddCtx->hHal )
2192 {
2193 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2194 goto err_vosclose;
2195 }
2196
2197 /* Set the SME configuration parameters. */
2198 vosStatus = hdd_set_sme_config(pHddCtx);
2199 if ( VOS_STATUS_SUCCESS != vosStatus )
2200 {
2201 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2202 goto err_vosclose;
2203 }
2204
Jeff Johnson295189b2012-06-20 16:38:30 -07002205 vosStatus = vos_preStart( pHddCtx->pvosContext );
2206 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2207 {
2208 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2209 goto err_vosclose;
2210 }
2211
2212 /* In the integrated architecture we update the configuration from
2213 the INI file and from NV before vOSS has been started so that
2214 the final contents are available to send down to the cCPU */
2215 /* Apply the cfg.ini to cfg.dat */
2216 if (FALSE == hdd_update_config_dat(pHddCtx))
2217 {
2218 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2219 goto err_vosclose;
2220 }
2221
2222 /* Set the MAC Address, currently this is used by HAL to add self sta.
2223 * Remove this once self sta is added as part of session open. */
2224 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2225 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2226 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2227 if (!HAL_STATUS_SUCCESS(halStatus))
2228 {
2229 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2230 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2231 goto err_vosclose;
2232 }
2233
2234 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2235 Note: Firmware image will be read and downloaded inside vos_start API */
2236 vosStatus = vos_start( pVosContext );
2237 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2238 {
2239 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +05302240 if (isSsrPanicOnFailure())
2241 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002242 goto err_vosclose;
2243 }
2244
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002245 /* Exchange capability info between Host and FW and also get versioning info from FW */
2246 hdd_exchange_version_and_caps(pHddCtx);
2247
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 vosStatus = hdd_post_voss_start_config( pHddCtx );
2249 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2250 {
2251 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2252 __func__);
2253 goto err_vosstop;
2254 }
2255
Mihir Shete04206452014-11-20 17:50:58 +05302256#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302257 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2258 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2259 {
2260 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2261 __func__);
2262 goto err_vosstop;
2263 }
Mihir Shete04206452014-11-20 17:50:58 +05302264#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302265
Jeff Johnson295189b2012-06-20 16:38:30 -07002266#ifdef WLAN_BTAMP_FEATURE
2267 vosStatus = WLANBAP_Open(pVosContext);
2268 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2269 {
2270 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2271 "%s: Failed to open BAP",__func__);
2272 goto err_vosstop;
2273 }
2274 vosStatus = BSL_Init(pVosContext);
2275 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2276 {
2277 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2278 "%s: Failed to Init BSL",__func__);
2279 goto err_bap_close;
2280 }
2281 vosStatus = WLANBAP_Start(pVosContext);
2282 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2283 {
2284 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2285 "%s: Failed to start TL",__func__);
2286 goto err_bap_close;
2287 }
2288 pConfig = pHddCtx->cfg_ini;
2289 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2290 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2291#endif //WLAN_BTAMP_FEATURE
2292
2293 /* Restart all adapters */
2294 hdd_start_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302296 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002297 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302298 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002299 /* Register with platform driver as client for Suspend/Resume */
2300 vosStatus = hddRegisterPmOps(pHddCtx);
2301 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2302 {
2303 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2304 goto err_bap_stop;
2305 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302306
2307#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2308 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2309 (pHddCtx->cfg_ini->enableFWLogging ||
2310 pHddCtx->cfg_ini->enableMgmtLogging ||
2311 pHddCtx->cfg_ini->enableContFWLogging))
2312 {
2313 hdd_init_frame_logging(pHddCtx);
2314 }
2315#endif
2316
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302318 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002319 /* register for riva power on lock */
2320 if (req_riva_power_on_lock("wlan"))
2321 {
2322 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2323 __func__);
2324 goto err_unregister_pmops;
2325 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302326 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002327 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Deepthi Gowri1ca95bb2016-01-13 19:47:53 +05302328
2329 sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame);
2330
Dasari Srinivas421bde82014-06-25 12:01:44 +05302331#ifdef WLAN_FEATURE_EXTSCAN
2332 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2333 wlan_hdd_cfg80211_extscan_callback,
2334 pHddCtx);
2335#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302336
2337#ifdef FEATURE_OEM_DATA_SUPPORT
2338 sme_OemDataRegisterCallback(pHddCtx->hHal,
2339 wlan_hdd_cfg80211_oemdata_callback,
2340 pHddCtx);
2341#endif /* FEATURE_OEM_DATA_SUPPORT */
2342
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 goto success;
2344
2345err_unregister_pmops:
2346 hddDeregisterPmOps(pHddCtx);
2347
2348err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002349#ifdef CONFIG_HAS_EARLYSUSPEND
2350 hdd_unregister_mcast_bcast_filter(pHddCtx);
2351#endif
2352 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002353#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002354 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002355#endif
2356
2357#ifdef WLAN_BTAMP_FEATURE
2358err_bap_close:
2359 WLANBAP_Close(pVosContext);
2360#endif
2361
2362err_vosstop:
2363 vos_stop(pVosContext);
2364
2365err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302366 if(!isSsrPanicOnFailure())
2367 {
2368 /* If we hit this, it means wlan driver is in bad state and needs
2369 * driver unload and load.
2370 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302371 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2372 return VOS_STATUS_E_FAILURE;
2373 }
2374
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 vos_close(pVosContext);
2376 vos_sched_close(pVosContext);
2377 if (pHddCtx)
2378 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 /* Unregister the Net Device Notifier */
2380 unregister_netdevice_notifier(&hdd_netdev_notifier);
2381 /* Clean up HDD Nlink Service */
2382 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002383#ifdef WLAN_KD_READY_NOTIFIER
2384 nl_srv_exit(pHddCtx->ptt_pid);
2385#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002386 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002387#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002388 /* Free up dynamically allocated members inside HDD Adapter */
2389 kfree(pHddCtx->cfg_ini);
2390 pHddCtx->cfg_ini= NULL;
2391
Jeff Johnson295189b2012-06-20 16:38:30 -07002392 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302393 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002394 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002395 }
2396 vos_preClose(&pVosContext);
2397
2398#ifdef MEMORY_DEBUG
2399 vos_mem_exit();
2400#endif
2401
2402err_re_init:
2403 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302404 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002405 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002406 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002407 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002408
2409success:
2410 /* Trigger replay of BTC events */
2411 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2412 return VOS_STATUS_SUCCESS;
2413}