blob: 43db79440b5a2151b5e44b72c7d769c1fda3a2dc [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302 * Copyright (c) 2012-2018 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>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053046
47#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && \
48 defined(WLAN_OPEN_SOURCE)
49#include <linux/device.h>
50#include <linux/pm_wakeup.h>
51#else
Jeff Johnson295189b2012-06-20 16:38:30 -070052#include <linux/wakelock.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053053#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55#include "halTypes.h"
56#include "sme_Api.h"
57#include <vos_api.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070058#include <vos_sched.h>
59#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070060#include <wlan_qct_sys.h>
61#include <wlan_btc_svc.h>
62#include <wlan_nlink_common.h>
63#include <wlan_hdd_main.h>
64#include <wlan_hdd_assoc.h>
65#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <wlan_nlink_srv.h>
67#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070068#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070069
Jeff Johnson295189b2012-06-20 16:38:30 -070070#include <linux/semaphore.h>
71#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070072#include "cfgApi.h"
Siddharth Bhal7bd19932015-03-03 16:54:36 +053073#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070074
75#ifdef WLAN_BTAMP_FEATURE
76#include "bapApi.h"
77#include "bap_hdd_main.h"
78#include "bap_hdd_misc.h"
79#endif
80
Jeff Johnsone7245742012-09-05 17:12:55 -070081#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <linux/inetdevice.h>
83#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053084#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053085#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070086/**-----------------------------------------------------------------------------
87* Preprocessor definitions and constants
88* ----------------------------------------------------------------------------*/
89
90/**-----------------------------------------------------------------------------
91* Type declarations
92* ----------------------------------------------------------------------------*/
93
94/**-----------------------------------------------------------------------------
95* Function and variables declarations
96* ----------------------------------------------------------------------------*/
97#include "wlan_hdd_power.h"
98#include "wlan_hdd_packet_filtering.h"
99
Sameer Thalappile5637f42013-08-07 15:46:55 -0700100#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530101#define NS_DEFAULT_SLOT_INDEX 4
102#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104static eHalStatus g_full_pwr_status;
105static eHalStatus g_standby_status;
106
107extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Ravi Kumar Bokka585faca2017-03-01 16:18:41 +0530108extern void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700111extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700113static struct timer_list ssr_timer;
114static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700115
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530116void inline check_and_set_suspend_resume_mcbc_filter(hdd_context_t *pHddCtx)
117{
118 hddLog(VOS_TRACE_LEVEL_INFO,
119 FL("offload: sus_res_mcbc_filter_valid: %d sus_res_mcbc_filter: %d configuredMcBcFilter: %d"),
120 pHddCtx->sus_res_mcastbcast_filter_valid,
121 pHddCtx->sus_res_mcastbcast_filter,
122 pHddCtx->configuredMcastBcastFilter);
123 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
124 {
125 pHddCtx->sus_res_mcastbcast_filter =
126 pHddCtx->configuredMcastBcastFilter;
127 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
128 hddLog(VOS_TRACE_LEVEL_INFO,
129 FL("offload: saving sus_res_mcastbcast_filter = %d"),
130 pHddCtx->sus_res_mcastbcast_filter);
131 }
132}
Abhishek Singh937ec542016-01-05 18:03:14 +0530133
134#ifdef FEATURE_WLAN_DIAG_SUPPORT
135/**
136 * hdd_wlan_offload_event()- send offloads event
137 *
138 * @type: offload type
139 * @state: enabled or disabled
140 *
141 * This Function send offloads enable/disable diag event
142 *
143 * Return: void.
144 */
145
146void hdd_wlan_offload_event(uint8_t type, uint8_t state)
147{
148 WLAN_VOS_DIAG_EVENT_DEF(host_offload,
149 struct vos_event_offload_req);
150 vos_mem_zero(&host_offload, sizeof(host_offload));
151
152 host_offload.offload_type = type;
153 host_offload.state = state;
154
155 WLAN_VOS_DIAG_EVENT_REPORT(&host_offload, EVENT_OFFLOAD_REQ);
156}
157#endif /* FEATURE_WLAN_DIAG_SUPPORT */
158
Jeff Johnson295189b2012-06-20 16:38:30 -0700159//Callback invoked by PMC to report status of standby request
160void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
161{
162 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
163 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
164 g_standby_status = status;
165
166 if(eHAL_STATUS_SUCCESS == status)
167 {
168 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
169 }
170 else
171 {
172 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
173 }
174
175 complete(&pHddCtx->standby_comp_var);
176}
177
178//Callback invoked by PMC to report status of full power request
179void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
180{
181 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
183 g_full_pwr_status = status;
184
185 if(eHAL_STATUS_SUCCESS == status)
186 {
187 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
188 }
189 else
190 {
191 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
192 }
193
194 complete(&pHddCtx->full_pwr_comp_var);
195}
196
197eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
198{
199 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530200 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
203 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
204
205 g_full_pwr_status = eHAL_STATUS_FAILURE;
206 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
207 eSME_FULL_PWR_NEEDED_BY_HDD);
208
209 if(status == eHAL_STATUS_PMC_PENDING)
210 {
211 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530212 ret = wait_for_completion_interruptible_timeout(
213 &pHddCtx->full_pwr_comp_var,
214 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
215 if (0 >= ret)
216 {
217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
218 __func__, ret);
219 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700220 status = g_full_pwr_status;
221 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
222 {
223 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
224 VOS_ASSERT(0);
225 goto failure;
226 }
227 }
228 else if(status != eHAL_STATUS_SUCCESS)
229 {
230 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
231 __func__, status);
232 VOS_ASSERT(0);
233 goto failure;
234 }
235 else
236 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
237
238failure:
239 //No blocking to reduce latency. No other device should be depending on WLAN
240 //to finish resume and WLAN won't be instantly on after resume
241 return status;
242}
243
244
245//Helper routine to put the chip into standby
246VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
247{
248 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
249 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530250 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700251
252 //Disable IMPS/BMPS as we do not want the device to enter any power
253 //save mode on its own during suspend sequence
254 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
255 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
256
257 //Note we do not disable queues unnecessarily. Queues should already be disabled
258 //if STA is disconnected or the queue will be disabled as and when disconnect
259 //happens because of standby procedure.
260
261 //Ensure that device is in full power first. There is scope for optimization
262 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
263 //Core s/w needs to be optimized to handle this. Until then we request full
264 //power before issuing request for standby.
265 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
266 g_full_pwr_status = eHAL_STATUS_FAILURE;
267 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
268 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
269
270 if(halStatus == eHAL_STATUS_PMC_PENDING)
271 {
272 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530273 ret = wait_for_completion_interruptible_timeout(
274 &pHddCtx->full_pwr_comp_var,
275 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
276 if (0 >= ret)
277 {
278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
279 __func__, ret);
280 }
281
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
283 {
284 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
285 VOS_ASSERT(0);
286 vosStatus = VOS_STATUS_E_FAILURE;
287 goto failure;
288 }
289 }
290 else if(halStatus != eHAL_STATUS_SUCCESS)
291 {
292 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
293 __func__, halStatus);
294 VOS_ASSERT(0);
295 vosStatus = VOS_STATUS_E_FAILURE;
296 goto failure;
297 }
298
299 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
300 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
301 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
302 }
303
304 //Request standby. Standby will cause the STA to disassociate first. TX queues
305 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
306 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
307 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
308 //when there are concurrent sessions.
309 INIT_COMPLETION(pHddCtx->standby_comp_var);
310 g_standby_status = eHAL_STATUS_FAILURE;
311 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
312
313 if (halStatus == eHAL_STATUS_PMC_PENDING)
314 {
315 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530316 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530318 if (0 >= ret)
319 {
320 hddLog(VOS_TRACE_LEVEL_ERROR,
321 FL("wait on standby_comp_var failed %ld"), ret);
322 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
324 {
325 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
326 VOS_ASSERT(0);
327 vosStatus = VOS_STATUS_E_FAILURE;
328 goto failure;
329 }
330 }
331 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
332 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
333 __func__, halStatus);
334 VOS_ASSERT(0);
335 vosStatus = VOS_STATUS_E_FAILURE;
336 goto failure;
337 }
338 else
339 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
340
341failure:
342 //Restore IMPS config
343 if(pHddCtx->cfg_ini->fIsImpsEnabled)
344 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
345
346 //Restore BMPS config
347 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
348 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
349
350 return vosStatus;
351}
352
353
354//Helper routine for Deep sleep entry
355VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
356{
357 eHalStatus halStatus;
358 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530359 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800360
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 netif_tx_disable(pAdapter->dev);
364 netif_carrier_off(pAdapter->dev);
365
366 //Disable IMPS,BMPS as we do not want the device to enter any power
367 //save mode on it own during suspend sequence
368 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
369 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
370
371 //Ensure that device is in full power as we will touch H/W during vos_Stop
372 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
373 g_full_pwr_status = eHAL_STATUS_FAILURE;
374 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
375 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
376
377 if(halStatus == eHAL_STATUS_PMC_PENDING)
378 {
379 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530380 ret = wait_for_completion_interruptible_timeout(
381 &pHddCtx->full_pwr_comp_var,
382 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
383 if (0 >= ret)
384 {
385 hddLog(VOS_TRACE_LEVEL_ERROR,
386 FL("wait on full_pwr_comp_var failed %ld"), ret);
387 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700388 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
389 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
390 VOS_ASSERT(0);
391 }
392 }
393 else if(halStatus != eHAL_STATUS_SUCCESS)
394 {
395 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
396 VOS_ASSERT(0);
397 }
398
399 //Issue a disconnect. This is required to inform the supplicant that
400 //STA is getting disassociated and for GUI to be updated properly
401 INIT_COMPLETION(pAdapter->disconnect_comp_var);
402 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
403
404 //Success implies disconnect command got queued up successfully
405 if(halStatus == eHAL_STATUS_SUCCESS)
406 {
407 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530408 ret = wait_for_completion_interruptible_timeout(
409 &pAdapter->disconnect_comp_var,
410 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
411 if (0 >= ret)
412 {
413 hddLog(VOS_TRACE_LEVEL_ERROR,
414 FL("wait on disconnect_comp_var failed %ld"), ret);
415 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700416 }
417
418
419 //None of the steps should fail after this. Continue even in case of failure
420 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530421 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
422 {
423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
424 __func__, vosStatus);
425 VOS_ASSERT(0);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +0530426 if (isSsrPanicOnFailure())
427 VOS_BUG(0);
c_hpothuffdb5272013-10-02 16:42:35 +0530428 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700429
Jeff Johnson295189b2012-06-20 16:38:30 -0700430 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
431
432 //Restore IMPS config
433 if(pHddCtx->cfg_ini->fIsImpsEnabled)
434 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
435
436 //Restore BMPS config
437 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
438 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
439
Jeff Johnson295189b2012-06-20 16:38:30 -0700440 return vosStatus;
441}
442
443VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
444{
445 VOS_STATUS vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700446
Jeff Johnson295189b2012-06-20 16:38:30 -0700447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
448 "%s: calling hdd_set_sme_config",__func__);
449 vosStatus = hdd_set_sme_config( pHddCtx );
450 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
451 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
452 {
453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
454 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700455 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700456 }
457
458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
459 "%s: calling vos_start",__func__);
460 vosStatus = vos_start( pHddCtx->pvosContext );
461 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
462 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
463 {
464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
465 "%s: Failed in vos_start",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +0530466 if (isSsrPanicOnFailure())
467 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700468 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700469 }
470
471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
472 "%s: calling hdd_post_voss_start_config",__func__);
473 vosStatus = hdd_post_voss_start_config( pHddCtx );
474 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
475 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
476 {
477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
478 "%s: Failed in hdd_post_voss_start_config",__func__);
479 goto err_voss_stop;
480 }
481
Jeff Johnson295189b2012-06-20 16:38:30 -0700482 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
483
Jeff Johnson295189b2012-06-20 16:38:30 -0700484 return VOS_STATUS_SUCCESS;
485
486err_voss_stop:
487 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700488err_deep_sleep:
489 return VOS_STATUS_E_FAILURE;
490
491}
492
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530493void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
Atul Mittal37385d72014-03-27 18:15:03 +0530494{
495 hdd_adapter_t* pAdapter =
496 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
497 hdd_context_t *pHddCtx;
498 int status;
499
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530500 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530501 if (NULL == pAdapter)
502 {
503 hddLog(LOGE, FL("Adapter is invalid"));
504 return;
505 }
Atul Mittal37385d72014-03-27 18:15:03 +0530506
507 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
508 status = wlan_hdd_validate_context(pHddCtx);
509 if (0 != status)
510 {
Atul Mittal37385d72014-03-27 18:15:03 +0530511 return;
512 }
513
Atul Mittal37385d72014-03-27 18:15:03 +0530514 if ((eConnectionState_Associated ==
515 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
516 && (pHddCtx->hdd_wlan_suspended))
517 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530518 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Atul Mittal37385d72014-03-27 18:15:03 +0530519 // This invocation being part of the IPv6 registration callback,
520 // set the newly generated ip address to f/w in suspend mode.
521#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530522 if (pHddCtx->cfg_ini->fhostNSOffload)
523 {
524 hdd_conf_ns_offload(pAdapter, 1);
525 }
Atul Mittal37385d72014-03-27 18:15:03 +0530526#endif
527 }
528#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530529 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530530 * only so when new ipv6 address is generated the screen may not
531 * on so we need to call it here to update the list in f/w.
532 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530533 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530534#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530535 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530536}
537
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530538void hdd_ipv6_notifier_work_queue(struct work_struct *work)
539{
540 vos_ssr_protect(__func__);
541 __hdd_ipv6_notifier_work_queue(work);
542 vos_ssr_unprotect(__func__);
543}
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530544int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530545 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530546{
547 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
548 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530549 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530550 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530551 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530552 int status;
553
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530554 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530555 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
556 status = wlan_hdd_validate_context(pHddCtx);
557 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530558 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530559 return NOTIFY_DONE;
560 }
Atul Mittal37385d72014-03-27 18:15:03 +0530561
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530562 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
563 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
564 {
565 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
566 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
567 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
568 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +0530569
570 if (eConnectionState_Associated ==
571 WLAN_HDD_GET_STATION_CTX_PTR
572 (pAdapterNode->pAdapter)->conn_info.connState)
573 sme_dhcp_done_ind(pHddCtx->hHal,
574 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530575 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530576 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530577 {
578 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
579 }
580 else
581 {
582 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
583 pHddCtx->cfg_ini->nEnableSuspend);
584 }
585 break;
586 }
587 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
588 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530589 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530590 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530591 return NOTIFY_DONE;
592}
593
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530594int wlan_hdd_ipv6_changed(struct notifier_block *nb,
595 unsigned long data, void *arg)
596{
597 int ret;
598 vos_ssr_protect(__func__);
599 ret = __wlan_hdd_ipv6_changed( nb, data, arg);
600 vos_ssr_unprotect(__func__);
601 return ret;
602}
603
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530604/*
605 * Function: hdd_conf_hostoffload
606 * Central function to configure the supported offloads,
607 * either enable or disable them.
608 */
609void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
610{
611 hdd_context_t *pHddCtx = NULL;
612 v_CONTEXT_t *pVosContext = NULL;
613 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
614
615 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
616 fenable);
617
618 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
619
620 if (NULL == pVosContext)
621 {
622 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
623 return;
624 }
625
626 //Get the HDD context.
627 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
628
629 if (NULL == pHddCtx)
630 {
631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
632 return;
633 }
634
635 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Arun Khandavalli08bcafd2016-11-08 14:45:48 +0530636 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
637 ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
638 (pHddCtx->is_ap_mode_wow_supported)))
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530639 {
640 if (fenable)
641 {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +0530642 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
643 (eConnectionState_Associated ==
644 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
645 || (WLAN_HDD_SOFTAP == pAdapter->device_mode))
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530646 {
647 if ((pHddCtx->cfg_ini->fhostArpOffload))
648 {
649 /*
650 * Configure the ARP Offload.
651 * Even if it fails we have to reconfigure the MC/BC
652 * filter flag as we want RIVA not to drop BroadCast
653 * Packets
654 */
655 hddLog(VOS_TRACE_LEVEL_INFO,
656 FL("Calling ARP Offload with flag: %d"), fenable);
657 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
658 pHddCtx->configuredMcastBcastFilter &=
659 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
660
661 if (!VOS_IS_STATUS_SUCCESS(vstatus))
662 {
Anurag Chouhan8a5f8902016-09-28 18:54:47 +0530663 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530664 "Failed to enable ARPOFfloadFeature %d",
665 vstatus);
666 }
667 }
668 //Configure GTK_OFFLOAD
669#ifdef WLAN_FEATURE_GTK_OFFLOAD
670 hdd_conf_gtk_offload(pAdapter, fenable);
671#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530672
673#ifdef WLAN_NS_OFFLOAD
674 if (pHddCtx->cfg_ini->fhostNSOffload)
675 {
676 /*
677 * Configure the NS Offload.
678 * Even if it fails we have to reconfigure the MC/BC filter flag
679 * as we want RIVA not to drop Multicast Packets
680 */
681
682 hddLog(VOS_TRACE_LEVEL_INFO,
683 FL("Calling NS Offload with flag: %d"), fenable);
684 hdd_conf_ns_offload(pAdapter, fenable);
685 pHddCtx->configuredMcastBcastFilter &=
686 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
687 }
688#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530689
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530690 }
691 }
692 else
693 {
694 //Disable ARPOFFLOAD
695 if (pHddCtx->cfg_ini->fhostArpOffload)
696 {
697 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
698 if (!VOS_IS_STATUS_SUCCESS(vstatus))
699 {
700 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530701 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530702 }
703 }
704 //Disable GTK_OFFLOAD
705#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530706 hdd_conf_gtk_offload(pAdapter, fenable);
707#endif
708
709#ifdef WLAN_NS_OFFLOAD
710 //Disable NSOFFLOAD
711 if (pHddCtx->cfg_ini->fhostNSOffload)
712 {
713 hdd_conf_ns_offload(pAdapter, fenable);
714 }
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530715 else
716 {
717 hddLog(VOS_TRACE_LEVEL_INFO,
718 FL("ns offload ini is disabled"));
719 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530720#endif
721 }
722 }
723 return;
724}
725
Atul Mittal37385d72014-03-27 18:15:03 +0530726
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530727#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530728/**----------------------------------------------------------------------------
729
730 \brief hdd_conf_ns_offload() - Configure NS offload
731
732 Called during SUSPEND to configure the NS offload (MC BC filter) which
733 reduces power consumption.
734
735 \param - pAdapter - Adapter context for which NS offload is to be configured
736 \param - fenable - 0 - disable.
737 1 - enable. (with IPv6 notifier registration)
738 2 - enable. (without IPv6 notifier registration)
739
740 \return - void
741
742 ---------------------------------------------------------------------------*/
743void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530744{
745 struct inet6_dev *in6_dev;
746 struct inet6_ifaddr *ifp;
747 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530748 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530749 tANI_U8 **selfIPv6Addr = NULL;
750 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530751 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530752 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530753 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530754
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530755 int i = 0, slot = 0;
756 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530757 eHalStatus returnStatus;
758
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530759 ENTER();
760 hddLog(LOG1, FL(" fenable = %d"), fenable);
761
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530762 if (NULL == pAdapter)
763 {
764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
765 return;
766 }
767
768 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530769 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
770
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530771 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530772 if (0 != ret)
773 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530774 return;
775 }
776
777 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
778 {
779 slot_index = NS_EXTENDED_SLOT_INDEX;
780 }
781
782 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
783
784 selfIPv6AddrValid =
785 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
786
787 if (NULL == selfIPv6AddrValid)
788 {
789 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
790 " selfIPv6AddrValid"));
791 goto end;
792 }
793
794 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
795
796 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
797
798 if (NULL == selfIPv6Addr)
799 {
800 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
801 " selfIPv6Addr"));
802 goto end;
803 }
804
805 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
806
807 for (slot = 0; slot < slot_index; slot++)
808 {
809 selfIPv6Addr[slot] =
810 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
811 if (NULL == selfIPv6Addr[slot])
812 {
813 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
814 "for selfIPv6Addr"));
815 goto end;
816 }
817 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
818 }
819
820 i = 0;
821
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530822 if (fenable)
823 {
824 in6_dev = __in6_dev_get(pAdapter->dev);
825 if (NULL != in6_dev)
826 {
Srinivas Girigowdad26a8072016-10-19 20:26:42 +0530827 read_lock_bh(&in6_dev->lock);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530828 list_for_each(p, &in6_dev->addr_list)
829 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530830 if (i >= slot_index)
831 {
832 hddLog (VOS_TRACE_LEVEL_ERROR,
833 FL("IPv6 address list is greater than IPv6"
834 "address supported by firmware"));
835 hddLog (VOS_TRACE_LEVEL_ERROR,
836 FL("FW supported IPv6 address = %d"), slot_index);
837 break;
838 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530839 ifp = list_entry(p, struct inet6_ifaddr, if_list);
840 switch(ipv6_addr_src_scope(&ifp->addr))
841 {
842 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530843 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530844 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530845 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530846 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530847 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
848 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530849 break;
850 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530851 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530852 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530853 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530854 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530855 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
856 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530857 break;
858 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530859 hddLog(VOS_TRACE_LEVEL_ERROR,
860 FL("The Scope %d is not supported"),
861 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530862 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530863 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
864 {
865 i++;
866 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530867 }
Mukul Sharma115869a2017-06-29 17:38:57 +0530868 /* store actual slots being used */
869 pAdapter->ns_slots = i;
Srinivas Girigowdad26a8072016-10-19 20:26:42 +0530870 read_unlock_bh(&in6_dev->lock);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530871
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530872 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530873 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530874 {
875 if (selfIPv6AddrValid[i])
876 {
877 //Filling up the request structure
878 /* Filling the selfIPv6Addr with solicited address
879 * A Solicited-Node multicast address is created by
880 * taking the last 24 bits of a unicast or anycast
881 * address and appending them to the prefix
882 *
883 * FF02:0000:0000:0000:0000:0001:FFXX:XX
884 *
885 * here XX is the unicast/anycast bits
886 */
887 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
888 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
889 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
890 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530891 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
892 selfIPv6Addr[i][13];
893 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
894 selfIPv6Addr[i][14];
895 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
896 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530897 offLoadRequest.nsOffloadInfo.slotIdx = i;
898
899 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530900 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530901 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
902 &pAdapter->macAddressCurrent.bytes,
903 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
904
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530905 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
906 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530907 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
908 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +0530909 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
910 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530911
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530912 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530913 FL("configuredMcastBcastFilter: %d"
914 "NSOffload Slot = %d"),
915 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530916
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530917 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700918 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
919 pHddCtx->sus_res_mcastbcast_filter) ||
920 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
921 pHddCtx->sus_res_mcastbcast_filter)) &&
922 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
923 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
924 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530925 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530926 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700927 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530928 }
Abhishek Singh937ec542016-01-05 18:03:14 +0530929 hdd_wlan_offload_event(
930 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE,
931 SIR_OFFLOAD_ENABLE);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530932 hddLog(VOS_TRACE_LEVEL_INFO,
933 FL("offload: NS filter programmed %d"),
934 offLoadRequest.enableOrDisable);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530935 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
936 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
937 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
938
939 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530940 FL("Setting NSOffload with solicitedIp: %pI6,"
941 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530942 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
943 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
944
945 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530946 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530947 pAdapter->sessionId, &offLoadRequest);
948 if(eHAL_STATUS_SUCCESS != returnStatus)
949 {
950 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530951 FL("Failed to enable HostOffload feature with"
952 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530953 }
954 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
955 }
956 }
957 }
958 else
959 {
960 hddLog(VOS_TRACE_LEVEL_ERROR,
961 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530962 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530963 }
964 }
965 else
966 {
967 //Disable NSOffload
968 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
969 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
970 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +0530971 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
972 SIR_OFFLOAD_DISABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530973
Mukul Sharma115869a2017-06-29 17:38:57 +0530974 for (i = 0; i < pAdapter->ns_slots; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530975 {
c_hpothu86feba52014-10-28 15:51:18 +0530976 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530977 offLoadRequest.nsOffloadInfo.slotIdx = i;
978 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530979 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
980 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530981 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
983 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530984 }
985 }
Mukul Sharma115869a2017-06-29 17:38:57 +0530986 pAdapter->ns_slots = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530987 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530988end:
989 while (slot > 0 && selfIPv6Addr[--slot])
990 {
991 vos_mem_free(selfIPv6Addr[slot]);
992 }
993 if (selfIPv6Addr)
994 {
995 vos_mem_free(selfIPv6Addr);
996 }
997 if (selfIPv6AddrValid)
998 {
999 vos_mem_free(selfIPv6AddrValid);
1000 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301001 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301002 return;
1003}
1004#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301005
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301006void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301007{
1008 hdd_adapter_t* pAdapter =
1009 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
1010 hdd_context_t *pHddCtx;
1011 int status;
1012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301013 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301014 if (NULL == pAdapter)
1015 {
1016 hddLog(LOGE, FL("Adapter is invalid"));
1017 return;
1018 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301019 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1020 status = wlan_hdd_validate_context(pHddCtx);
1021 if (0 != status)
1022 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301023 return;
1024 }
1025
1026 if ((eConnectionState_Associated ==
1027 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +05301028 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301029 {
1030 // This invocation being part of the IPv4 registration callback,
1031 // we are passing second parameter as 2 to avoid registration
1032 // of IPv4 notifier again.
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301033 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1034 if (pHddCtx->cfg_ini->fhostArpOffload)
1035 {
1036 hdd_conf_arp_offload(pAdapter, 2);
1037 }
1038 else
1039 {
1040 hddLog(VOS_TRACE_LEVEL_INFO,
1041 FL("offload: arp offload ini is disabled in host"));
1042 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301043 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301044 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301045}
1046
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301047void hdd_ipv4_notifier_work_queue(struct work_struct *work)
1048{
1049 vos_ssr_protect(__func__);
1050 __hdd_ipv4_notifier_work_queue(work);
1051 vos_ssr_unprotect(__func__);
1052}
1053
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301054int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301055 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301056{
1057 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1058 struct in_ifaddr **ifap = NULL;
1059 struct in_device *in_dev;
1060
1061 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301062 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301063 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301064 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301065 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301067 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301068 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1069 status = wlan_hdd_validate_context(pHddCtx);
1070 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301071 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301072 return NOTIFY_DONE;
1073 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301074
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301075 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1076 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1077 {
1078 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1079 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1080 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1081 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +05301082
1083 if (eConnectionState_Associated ==
1084 WLAN_HDD_GET_STATION_CTX_PTR
1085 (pAdapterNode->pAdapter)->conn_info.connState)
1086 sme_dhcp_done_ind(pHddCtx->hHal,
1087 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301088 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301089 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301090 || (!pHddCtx->cfg_ini->fhostArpOffload))
1091 {
1092 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1093 pHddCtx->cfg_ini->nEnableSuspend,
1094 pHddCtx->cfg_ini->fhostArpOffload);
1095 return NOTIFY_DONE;
1096 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301097
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301098 if ((in_dev =
1099 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1100 {
1101 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1102 ifap = &ifa->ifa_next)
1103 {
1104 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1105 ifa->ifa_label))
1106 {
1107 break; /* found */
1108 }
1109 }
1110 }
1111 if(ifa && ifa->ifa_local)
1112 {
1113 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1114 }
1115 break;
1116 }
1117 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1118 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301119 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301120 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301121 return NOTIFY_DONE;
1122}
1123
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301124int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1125 unsigned long data, void *arg)
1126{
1127 int ret;
1128 vos_ssr_protect(__func__);
1129 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1130 vos_ssr_unprotect(__func__);
1131 return ret;
1132}
1133
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301134/**----------------------------------------------------------------------------
1135
1136 \brief hdd_conf_arp_offload() - Configure ARP offload
1137
1138 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1139 reduces power consumption.
1140
1141 \param - pAdapter -Adapter context for which ARP offload is to be configured
1142 \param - fenable - 0 - disable.
1143 1 - enable. (with IPv4 notifier registration)
1144 2 - enable. (without IPv4 notifier registration)
1145
1146 \return -
1147 VOS_STATUS_SUCCESS - on successful operation
1148 VOS_STATUS_E_FAILURE - on failure of operation
1149-----------------------------------------------------------------------------*/
1150VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001151{
1152 struct in_ifaddr **ifap = NULL;
1153 struct in_ifaddr *ifa = NULL;
1154 struct in_device *in_dev;
1155 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001156 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001157 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001158
Sushant Kaushik87787972015-09-11 16:05:00 +05301159 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001160
Jeff Johnson295189b2012-06-20 16:38:30 -07001161 if(fenable)
1162 {
1163 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1164 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301165 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 ifap = &ifa->ifa_next)
1167 {
1168 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1169 {
1170 break; /* found */
1171 }
1172 }
1173 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 if(ifa && ifa->ifa_local)
1175 {
1176 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1177 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +05301178 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1179 SIR_OFFLOAD_ENABLE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001180
Arif Hussain6d2a3322013-11-17 19:50:10 -08001181 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001182
Amar Singhald53568e2013-09-26 11:03:45 -07001183 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1184 pHddCtx->sus_res_mcastbcast_filter) ||
1185 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1186 pHddCtx->sus_res_mcastbcast_filter)) &&
1187 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001188 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301189 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001190 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1191 hddLog(VOS_TRACE_LEVEL_INFO,
1192 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 }
Abhishek Singh937ec542016-01-05 18:03:14 +05301194 hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
1195 SIR_OFFLOAD_ENABLE);
Amar Singhald53568e2013-09-26 11:03:45 -07001196
1197 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1198 offLoadRequest.enableOrDisable);
1199
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 //converting u32 to IPV4 address
1201 for(i = 0 ; i < 4; i++)
1202 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301203 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001204 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1205 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301206 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001207 offLoadRequest.params.hostIpv4Addr[0],
1208 offLoadRequest.params.hostIpv4Addr[1],
1209 offLoadRequest.params.hostIpv4Addr[2],
1210 offLoadRequest.params.hostIpv4Addr[3]);
1211
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301212 if (eHAL_STATUS_SUCCESS !=
1213 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1214 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 {
1216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001217 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 return VOS_STATUS_E_FAILURE;
1219 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001220 }
1221 else
1222 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301223 hddLog(VOS_TRACE_LEVEL_WARN, FL("IP Address is not assigned"));
Agarwal Ashish971c2882013-10-30 20:11:12 +05301224 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301226
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301227 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001228 }
1229 else
1230 {
1231 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1232 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1233 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +05301234 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1235 SIR_OFFLOAD_DISABLE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301236 if (eHAL_STATUS_SUCCESS !=
1237 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1238 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 {
1240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001241 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001242 return VOS_STATUS_E_FAILURE;
1243 }
1244 return VOS_STATUS_SUCCESS;
1245 }
1246}
1247
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301248/*
1249 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301250 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301251*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301252void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301253 tANI_U8 *pMcBcFilter)
1254{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301255 if (NULL == pHddCtx)
1256 {
1257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1258 return;
1259 }
1260
1261 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1262 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301263 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301264 /* ARP offload is enabled, do not block bcast packets at RXP
1265 * Will be using Bitmasking to reset the filter. As we have
1266 * disable Broadcast filtering, Anding with the negation
1267 * of Broadcast BIT
1268 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301269 hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301270 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301271 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301272
1273#ifdef WLAN_NS_OFFLOAD
1274 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301275 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301276 /* NS offload is enabled, do not block mcast packets at RXP
1277 * Will be using Bitmasking to reset the filter. As we have
1278 * disable Multicast filtering, Anding with the negation
1279 * of Multicast BIT
1280 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301281 hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301282 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301283 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301284#endif
1285
Amar Singhald08ce752014-03-21 16:28:27 -07001286 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1287 {
1288 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1289 }
1290
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301291 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301292}
1293
Jeff Johnson295189b2012-06-20 16:38:30 -07001294void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1295{
1296 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1298 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
Agarwal Ashishff451a32015-07-28 01:01:29 +05301299 if (NULL == wlanRxpFilterParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 {
1301 hddLog(VOS_TRACE_LEVEL_FATAL,
1302 "%s: vos_mem_alloc failed ", __func__);
1303 return;
1304 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001305 hddLog(VOS_TRACE_LEVEL_INFO,
1306 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301307 if (TRUE == setfilter)
1308 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301309 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301310 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301311 }
1312 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301313 {
1314 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301315 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301316 pHddCtx->configuredMcastBcastFilter;
1317 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301318
Jeff Johnson295189b2012-06-20 16:38:30 -07001319 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001320 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301321
1322 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
Agarwal Ashishff451a32015-07-28 01:01:29 +05301323 {
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301324 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Agarwal Ashishff451a32015-07-28 01:01:29 +05301325 }
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301326
1327 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1328 "lower mac with status %d"
1329 "configuredMcstBcstFilterSetting = %d"
1330 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1331 "Failed" : "Success", halStatus,
1332 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1333 wlanRxpFilterParam->setMcstBcstFilter);
1334
Chilam Ngc4244af2013-04-01 15:37:32 -07001335 if (eHAL_STATUS_SUCCESS != halStatus)
1336 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001337}
1338
mukul sharmae4abd892016-11-24 22:03:31 +05301339/*
1340 * Enable/Disable McAddrList cfg item in fwr.
1341 */
1342eHalStatus hdd_set_mc_list_cfg_item(hdd_context_t* pHddCtx,
1343 bool value)
1344{
1345 eHalStatus ret_val;
1346
1347 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST,
1348 value, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1349 {
1350 ret_val = eHAL_STATUS_FAILURE;
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301351 hddLog(LOGE,
1352 FL("offload: can't pass WNI_CFG_ENABLE_MC_ADDR_LIST to CCM"));
mukul sharmae4abd892016-11-24 22:03:31 +05301353 return ret_val;
1354 }
1355
1356 ret_val = sme_update_cfg_int_param(pHddCtx->hHal,
1357 WNI_CFG_ENABLE_MC_ADDR_LIST);
1358 if (!HAL_STATUS_SUCCESS(ret_val))
1359 {
1360 hddLog(VOS_TRACE_LEVEL_ERROR,
1361 FL("Failed to toggle MC_ADDR_LIST_INI %d "),
1362 ret_val);
1363 return ret_val;
1364 }
1365 /* cache the value configured in fwr */
1366 pHddCtx->mc_list_cfg_in_fwr = value;
mukul sharmae4abd892016-11-24 22:03:31 +05301367 return eHAL_STATUS_SUCCESS;
1368}
1369
1370bool is_mc_list_cfg_disable_required(hdd_context_t* pHddCtx)
1371{
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301372 hddLog(VOS_TRACE_LEVEL_INFO,
1373 FL("offload: fEnableMCList %d sus_res_mcbc_filter %d mc_list_in_fwr %d"),
1374 pHddCtx->cfg_ini->fEnableMCAddrList,
1375 pHddCtx->sus_res_mcastbcast_filter,
1376 pHddCtx->mc_list_cfg_in_fwr);
1377
mukul sharmae4abd892016-11-24 22:03:31 +05301378 /*
1379 * If MCAddrList is enabled in ini and MCBC filter is set to
1380 * Either Filter None or Filter all BC then, Fwr need to push
1381 * all MC to host. This can be achieved by disabling cfg MCAddrList
1382 * in fwr. As in driver load, firmware have this value to 1 we
1383 * need to set it to 0. Same needs to be reverted on resume.
1384 */
1385 if (pHddCtx->cfg_ini->fEnableMCAddrList &&
1386 WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
1387 ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)&&
1388 ((HDD_MCASTBCASTFILTER_FILTER_NONE ==
1389 pHddCtx->sus_res_mcastbcast_filter) ||
1390 (HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1391 pHddCtx->sus_res_mcastbcast_filter)))
1392 )
1393 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301394 hddLog(VOS_TRACE_LEVEL_INFO,
1395 FL("offload: cfg ini need to disable in fwr"));
mukul sharmae4abd892016-11-24 22:03:31 +05301396 return true;
1397 }
1398 else
1399 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301400 hddLog(VOS_TRACE_LEVEL_INFO,
1401 FL("offload: cfg ini disable not needed "));
mukul sharmae4abd892016-11-24 22:03:31 +05301402 return false;
1403 }
1404}
1405
1406/**
1407 * hdd_mc_addr_list_cfg_config() - To set mc list cfg configuration in fwr
1408 * @pHddCtx: hdd context handle
1409 * @action: true to disable MCAddrList in fwr to get all MC pkt to host
1410 * false to set ini value of MCAddrList in fwr if it was toggled
1411 * Return: none
1412 *
1413 * Ensure Below API is invoked always post modification
1414 * of sus_res_mcastbcast_filter.
1415 */
1416void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action)
1417{
1418 if (action)
1419 {
1420 /* check host need to disable mc list ini in fwr */
1421 if (is_mc_list_cfg_disable_required(pHddCtx))
1422 {
1423 /*
1424 * Yes Host should disable the mc list in fwr
1425 * But Ensure host might already disable it
1426 * This can happen when user issue set/clear MCBC
1427 * ioctl with 2 to 0 or vice versa.
1428 */
1429 if (pHddCtx->cfg_ini->fEnableMCAddrList ==
1430 pHddCtx->mc_list_cfg_in_fwr)
1431 {
1432 hdd_set_mc_list_cfg_item(pHddCtx,
1433 !pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301434 hddLog(VOS_TRACE_LEVEL_INFO,
1435 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1436 !pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301437 }
1438 }
1439 else
1440 {
1441 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1442 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1443 pHddCtx->mc_list_cfg_in_fwr)
1444 {
1445 hdd_set_mc_list_cfg_item(pHddCtx,
1446 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301447 hddLog(VOS_TRACE_LEVEL_INFO,
1448 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1449 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301450 }
1451 }
1452 }
1453 else
1454 {
1455 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1456 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1457 pHddCtx->mc_list_cfg_in_fwr)
1458 {
1459 hdd_set_mc_list_cfg_item(pHddCtx,
1460 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301461 hddLog(VOS_TRACE_LEVEL_INFO,
1462 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1463 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301464 }
1465 }
1466}
1467
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301468/**
1469 * hdd_suspend_ind_callback: This API will set completion event for suspend
1470 * @pAdapter: hdd_adapter_t
1471 * @status: suspend status
1472 *
1473 * Return: none
1474 */
1475static void hdd_suspend_ind_callback(void *context, VOS_STATUS status)
1476{
1477 hdd_adapter_t *adapter = (hdd_adapter_t *)context;
1478 if (NULL == adapter)
1479 {
1480 hddLog(VOS_TRACE_LEVEL_ERROR,
1481 "%s: HDD adapter is NULL",__func__);
1482 return;
1483 }
1484 hddLog(VOS_TRACE_LEVEL_INFO, FL("suspend status %d"), status);
1485 complete(&adapter->wlan_suspend_comp_var);
1486}
1487
Jeff Johnson295189b2012-06-20 16:38:30 -07001488static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1489 hdd_adapter_t *pAdapter)
1490{
1491 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1492 tpSirWlanSuspendParam wlanSuspendParam =
1493 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1494
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301495 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001496 if(NULL == wlanSuspendParam)
1497 {
1498 hddLog(VOS_TRACE_LEVEL_FATAL,
1499 "%s: vos_mem_alloc failed ", __func__);
1500 return;
1501 }
1502
Amar Singhald53568e2013-09-26 11:03:45 -07001503 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001504 "%s: send wlan suspend indication", __func__);
1505
1506 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1507 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301508 //Configure supported OffLoads
1509 hdd_conf_hostoffload(pAdapter, TRUE);
1510 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301511 hddLog(VOS_TRACE_LEVEL_INFO,
1512 FL("saving configuredMcastBcastFilterSetting = %d"),
1513 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001514#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301515 /* During suspend, configure MC Addr list filter to the firmware
1516 * function takes care of checking necessary conditions before
1517 * configuring.
1518 */
1519 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001520#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001521
1522 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1523 {
1524
1525 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1526 pHddCtx->configuredMcastBcastFilter &=
1527 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1528 }
1529
1530 wlanSuspendParam->configuredMcstBcstFilterSetting =
1531 pHddCtx->configuredMcastBcastFilter;
mukul sharmae4abd892016-11-24 22:03:31 +05301532
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301533 wlanSuspendParam->wlan_sus_callback = hdd_suspend_ind_callback;
1534 wlanSuspendParam->context = pAdapter;
mukul sharmae4abd892016-11-24 22:03:31 +05301535 /* mc add list cfg item configuration in fwr */
1536 hdd_mc_addr_list_cfg_config(pHddCtx, true);
1537
Jeff Johnson295189b2012-06-20 16:38:30 -07001538 }
1539
1540 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1541 if(eHAL_STATUS_SUCCESS == halStatus)
1542 {
1543 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001544 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301545 hddLog(VOS_TRACE_LEVEL_ERROR,
1546 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001547 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 }
1549}
1550
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301551static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001552{
Chilam Ngc4244af2013-04-01 15:37:32 -07001553 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001554 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001555 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001556
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301557 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001558 "%s: send wlan resume indication", __func__);
1559
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301560 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1561
1562 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001563 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301564 hddLog(VOS_TRACE_LEVEL_FATAL,
1565 "%s: memory allocation failed for wlanResumeParam ", __func__);
1566 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001567 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001568
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301569 //Disable supported OffLoads
1570 hdd_conf_hostoffload(pAdapter, FALSE);
1571
1572 wlanResumeParam->configuredMcstBcstFilterSetting =
1573 pHddCtx->configuredMcastBcastFilter;
1574 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1575 if (eHAL_STATUS_SUCCESS != halStatus)
1576 {
c_hpothuffdb5272013-10-02 16:42:35 +05301577 hddLog(VOS_TRACE_LEVEL_ERROR,
1578 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301579 vos_mem_free(wlanResumeParam);
1580 }
1581
1582 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
mukul sharmae4abd892016-11-24 22:03:31 +05301583 /* mc add list cfg item configuration in fwr */
1584 hdd_mc_addr_list_cfg_config(pHddCtx, false);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301585
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001586 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1587 pHddCtx->configuredMcastBcastFilter =
1588 pHddCtx->sus_res_mcastbcast_filter;
1589 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1590 }
Amar Singhald53568e2013-09-26 11:03:45 -07001591
1592 hddLog(VOS_TRACE_LEVEL_INFO,
1593 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1594 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1595 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001596
Chilam Ngc4244af2013-04-01 15:37:32 -07001597
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301598#ifdef WLAN_FEATURE_PACKET_FILTERING
1599 /* Filer was applied during suspend inditication
1600 * clear it when we resume.
1601 */
1602 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001603#endif
1604}
Jeff Johnson295189b2012-06-20 16:38:30 -07001605
Jeff Johnson295189b2012-06-20 16:38:30 -07001606//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001607void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001608{
1609 hdd_context_t *pHddCtx = NULL;
1610 v_CONTEXT_t pVosContext = NULL;
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301611 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001612 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301613 hdd_adapter_t *pAdapter = NULL;
1614 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301615 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001616
Jeff Johnson295189b2012-06-20 16:38:30 -07001617 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1618
1619 //Get the global VOSS context.
1620 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1621 if(!pVosContext) {
1622 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1623 return;
1624 }
1625
1626 //Get the HDD context.
1627 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1628
1629 if(!pHddCtx) {
1630 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1631 return;
1632 }
1633
1634 if (pHddCtx->isLogpInProgress) {
1635 hddLog(VOS_TRACE_LEVEL_ERROR,
1636 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1637 return;
1638 }
1639
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301640 if (pHddCtx->hdd_wlan_suspended)
1641 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301642 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301643 "%s: Ignore suspend wlan, Already suspended!", __func__);
1644 return;
1645 }
1646
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301647 pHddCtx->hdd_wlan_suspended = TRUE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301648 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301649 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1651 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1652 {
1653 pAdapter = pAdapterNode->pAdapter;
1654 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001655 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1657
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001658 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001659 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1660 pAdapterNode = pNext;
1661 continue;
1662 }
Sourav Mohapatra47b07a02019-08-22 10:23:18 +05301663 dev_hold(pAdapter->dev);
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301664 /* Avoid multiple enter/exit BMPS in this while loop using
1665 * hdd_enter_bmps flag
1666 */
1667 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1668 {
1669 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001670
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301671 /* If device was already in BMPS, and dynamic DTIM is set,
1672 * exit(set the device to full power) and enter BMPS again
1673 * to reflect new DTIM value */
1674 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1675
1676 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1677
1678 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001680#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1681 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1682 {
1683 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301684 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001685 netif_tx_disable(pAdapter->dev);
1686 netif_carrier_off(pAdapter->dev);
1687 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301688 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001689 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1690 {
1691 //Execute deep sleep procedure
1692 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1693 }
1694#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301695
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301696 INIT_COMPLETION(pAdapter->wlan_suspend_comp_var);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301697 /*Suspend notification sent down to driver*/
1698 hdd_conf_suspend_ind(pHddCtx, pAdapter);
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301699 ret = wait_for_completion_interruptible_timeout(
1700 &pAdapter->wlan_suspend_comp_var,
1701 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
1702 if (0 >= ret)
1703 {
1704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on suspend failed %ld",
1705 __func__, ret);
1706 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301707 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
Sourav Mohapatra47b07a02019-08-22 10:23:18 +05301708 dev_put(pAdapter->dev);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301709 pAdapterNode = pNext;
1710 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301711
Jeff Johnson295189b2012-06-20 16:38:30 -07001712#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1713 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1714 {
1715 hdd_enter_standby(pHddCtx);
1716 }
1717#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001718
1719 return;
1720}
1721
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301722/**
1723 * @brief hdd_ReConfigSuspendDataClearedDuringRoaming() - Reconfigure the
1724 * suspend related data which was cleared during roaming in FWR.
1725 */
1726void hdd_ReConfigSuspendDataClearedDuringRoaming(hdd_context_t *pHddCtx)
1727
1728{
1729 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
1730 hdd_adapter_t *pAdapter;
1731 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1732
1733 ENTER();
1734
1735 spin_lock(&pHddCtx->filter_lock);
1736 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1737 spin_unlock(&pHddCtx->filter_lock);
1738
1739 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
1740 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Not able to set mcast/bcast filter "));
1742
1743 vstatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1744 //No need to configure GTK Offload from here because it might possible
1745 //cfg80211_set_rekey_data might not yet came, anyway GTK offload will
1746 //be handled as part of cfg80211_set_rekey_data processing.
1747 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vstatus )
1748 {
1749 pAdapter = pAdapterNode->pAdapter;
1750 if( pAdapter &&
1751 (( pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
1752 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)))
1753 {
1754 if (pHddCtx->cfg_ini->fhostArpOffload)
1755 {
1756 //Configure ARPOFFLOAD
1757 vstatus = hdd_conf_arp_offload(pAdapter, TRUE);
1758 if (!VOS_IS_STATUS_SUCCESS(vstatus))
1759 {
1760 hddLog(VOS_TRACE_LEVEL_INFO,
1761 FL("Failed to disable ARPOffload Feature %d"), vstatus);
1762 }
1763 }
1764#ifdef WLAN_NS_OFFLOAD
1765 //Configure NSOFFLOAD
1766 if (pHddCtx->cfg_ini->fhostNSOffload)
1767 {
1768 hdd_conf_ns_offload(pAdapter, TRUE);
1769 }
1770#endif
1771#ifdef WLAN_FEATURE_PACKET_FILTERING
1772 /* During suspend, configure MC Addr list filter to the firmware
1773 * function takes care of checking necessary conditions before
1774 * configuring.
1775 */
1776 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
1777#endif
1778 }
1779 vstatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1780 pAdapterNode = pNext;
1781 }
1782 EXIT();
1783}
1784
Jeff Johnson295189b2012-06-20 16:38:30 -07001785static void hdd_PowerStateChangedCB
1786(
1787 v_PVOID_t callbackContext,
1788 tPmcState newState
1789)
1790{
1791 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301792
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 /* if the driver was not in BMPS during early suspend,
1794 * the dynamic DTIM is now updated at Riva */
1795 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
Abhishek Singh0ea13232016-02-12 16:46:10 +05301796 && (pHddCtx->cfg_ini->enableDynamicDTIM ||
1797 pHddCtx->cfg_ini->enableModulatedDTIM)
Jeff Johnson295189b2012-06-20 16:38:30 -07001798 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1799 {
1800 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1801 }
1802 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301803 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1804 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301805 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001806 spin_unlock(&pHddCtx->filter_lock);
1807 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1809 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301810 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001811 else
Mihir Shete793209f2014-01-06 11:01:12 +05301812 {
1813 /* Android framework can send resume request when the WCN chip is
1814 * in IMPS mode. When the chip exits IMPS mode the firmware will
1815 * restore all the registers to the state they were before the chip
1816 * entered IMPS and so our hardware filter settings confgured by the
1817 * resume request will be lost. So reconfigure the filters on detecting
1818 * a change in the power state of the WCN chip.
1819 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301820 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301821 if (IMPS != newState)
1822 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301823 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301824 if (FALSE == pHddCtx->hdd_wlan_suspended)
1825 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301826 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301827 hddLog(VOS_TRACE_LEVEL_INFO,
1828 "Not in IMPS/BMPS and suspended state");
1829 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1830 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301831 else
1832 {
1833 spin_unlock(&pHddCtx->filter_lock);
1834 }
Mihir Shete793209f2014-01-06 11:01:12 +05301835 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301836 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001837}
1838
Jeff Johnson295189b2012-06-20 16:38:30 -07001839void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1840{
1841 v_CONTEXT_t pVosContext;
1842 tHalHandle smeContext;
1843
1844 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1845 if (NULL == pVosContext)
1846 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001847 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001848 return;
1849 }
1850 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1851 if (NULL == smeContext)
1852 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001853 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001854 return;
1855 }
1856
1857 spin_lock_init(&pHddCtx->filter_lock);
1858 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1859 pHddCtx->cfg_ini->nEnableSuspend)
1860 {
1861 pmcRegisterDeviceStateUpdateInd(smeContext,
1862 hdd_PowerStateChangedCB, pHddCtx);
1863 }
1864}
1865
1866void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1867{
1868 v_CONTEXT_t pVosContext;
1869 tHalHandle smeContext;
1870
1871 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1872 if (NULL == pVosContext)
1873 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001874 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 return;
1876 }
1877 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1878 if (NULL == smeContext)
1879 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001880 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001881 return;
1882 }
1883
1884 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1885 pHddCtx->cfg_ini->nEnableSuspend)
1886 {
1887 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1888 }
1889}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301890
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301891#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301892void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301893{
1894 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301895 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301896 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1897
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301898 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301899 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301900 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1901 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1902 {
1903 vos_mem_copy(&hddGtkOffloadReqParams,
1904 &pHddStaCtx->gtkOffloadReqParams,
1905 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301906
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301907 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1908 &hddGtkOffloadReqParams, pAdapter->sessionId);
1909 if (eHAL_STATUS_SUCCESS != ret)
1910 {
1911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1912 "%s: sme_SetGTKOffload failed, returned %d",
1913 __func__, ret);
1914 return;
1915 }
1916
1917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1918 "%s: sme_SetGTKOffload successfull", __func__);
1919 }
1920
1921 }
1922 else
1923 {
1924 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1925 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1926 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1927 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1928 {
1929
1930 /* Host driver has previously offloaded GTK rekey */
1931 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301932 wlan_hdd_cfg80211_update_replayCounterCallback,
1933 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301934 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301935
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301936 {
1937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1938 "%s: sme_GetGTKOffload failed, returned %d",
1939 __func__, ret);
1940 return;
1941 }
1942 else
1943 {
1944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1945 "%s: sme_GetGTKOffload successful",
1946 __func__);
1947
1948 /* Sending GTK offload dissable */
1949 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1950 sizeof (tSirGtkOffloadParams));
1951 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1952 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301953 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301954 if (eHAL_STATUS_SUCCESS != ret)
1955 {
1956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1957 "%s: failed to dissable GTK offload, returned %d",
1958 __func__, ret);
1959 return;
1960 }
1961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1962 "%s: successfully dissabled GTK offload request to HAL",
1963 __func__);
1964 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301965 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301966 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301967 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301968}
1969#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001970
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001971void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001972{
1973 hdd_context_t *pHddCtx = NULL;
1974 hdd_adapter_t *pAdapter = NULL;
1975 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1976 VOS_STATUS status;
1977 v_CONTEXT_t pVosContext = NULL;
Mukul Sharma3da767d2017-06-29 18:25:39 +05301978 tPmcState pmc_state;
1979 hdd_adapter_t *first_adapter = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001980
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1982
1983 //Get the global VOSS context.
1984 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1985 if(!pVosContext) {
1986 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1987 return;
1988 }
1989
1990 //Get the HDD context.
1991 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1992
1993 if(!pHddCtx) {
1994 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1995 return;
1996 }
1997
Agarwal Ashish971c2882013-10-30 20:11:12 +05301998 if (pHddCtx->isLogpInProgress)
1999 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 hddLog(VOS_TRACE_LEVEL_INFO,
2001 "%s: Ignore resume wlan, LOGP in progress!", __func__);
2002 return;
2003 }
2004
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05302005 if (!pHddCtx->hdd_wlan_suspended)
2006 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05302007 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05302008 "%s: Ignore resume wlan, Already resumed!", __func__);
2009 return;
2010 }
2011
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 pHddCtx->hdd_wlan_suspended = FALSE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05302013 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
Mukul Sharma3da767d2017-06-29 18:25:39 +05302014
2015 /* Get first valid adapter for disable/enable bmps purpose */
2016 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2017 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2018 {
2019 first_adapter = pAdapterNode->pAdapter;
2020 if (first_adapter != NULL)
2021 break;
2022 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2023 pAdapterNode = pNext;
2024 }
2025 pmc_state = pmcGetPmcState(pHddCtx->hHal);
2026 if (BMPS == pmc_state && first_adapter)
2027 {
2028 /* put the device into full power */
2029 hddLog(VOS_TRACE_LEVEL_INFO,
2030 "%s: Disaling bmps during resume", __func__);
2031 wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_ACTIVE);
2032 }
2033
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 /*loop through all adapters. Concurrency */
2035 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2036
2037 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2038 {
2039 pAdapter = pAdapterNode->pAdapter;
2040 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07002041 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07002043 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07002044 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2045 pAdapterNode = pNext;
2046 continue;
2047 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302048
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302049
Jeff Johnson295189b2012-06-20 16:38:30 -07002050#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2051 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
2052 {
2053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
2054 hdd_exit_deep_sleep(pAdapter);
2055 }
2056#endif
2057
2058 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
2059 {
2060 /*Switch back to DTIM 1*/
2061 tSirSetPowerParamsReq powerRequest = { 0 };
2062
2063 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
2064 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07002065 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002066
2067 /*Disabled ModulatedDTIM if enabled on suspend*/
2068 if(pHddCtx->cfg_ini->enableModulatedDTIM)
2069 powerRequest.uDTIMPeriod = 0;
2070
2071 /* Update ignoreDTIM and ListedInterval in CFG with default values */
2072 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
2073 NULL, eANI_BOOLEAN_FALSE);
2074 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
2075 NULL, eANI_BOOLEAN_FALSE);
2076
2077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002078 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08002079 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002080
Mukul Sharma3da767d2017-06-29 18:25:39 +05302081 if (BMPS == pmc_state)
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302082 {
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302083 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
2084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002085 }
2086
Gopichand Nakkala0f276812013-02-24 14:45:51 +05302087 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002088 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2089 pAdapterNode = pNext;
2090 }
2091
Mukul Sharma3da767d2017-06-29 18:25:39 +05302092 if (BMPS == pmc_state && first_adapter)
2093 {
2094 /* put the device into full power */
2095 hddLog(VOS_TRACE_LEVEL_INFO,
2096 "%s: Enable bmps during resume", __func__);
2097 /* put the device back into BMPS */
2098 wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_AUTO);
2099 }
2100
Jeff Johnson295189b2012-06-20 16:38:30 -07002101#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2102 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
2103 {
2104 hdd_exit_standby(pHddCtx);
2105 }
2106#endif
2107
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 return;
2109}
2110
Jeff Johnson295189b2012-06-20 16:38:30 -07002111VOS_STATUS hdd_wlan_reset_initialization(void)
2112{
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 v_CONTEXT_t pVosContext = NULL;
2114
2115 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
2116
2117 //Get the global VOSS context.
2118 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2119 if(!pVosContext)
2120 {
2121 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2122 return VOS_STATUS_E_FAILURE;
2123 }
2124
2125 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
2126
2127 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302128 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002129
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 return VOS_STATUS_SUCCESS;
2131}
2132
2133
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002134/*
2135 * Based on the ioctl command recieved by HDD, put WLAN driver
2136 * into the quiet mode. This is the same as the early suspend
2137 * notification that driver used to listen
2138 */
2139void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07002140{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302141 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002142 if (suspend)
2143 hdd_suspend_wlan();
2144 else
2145 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302146 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002147}
2148
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002149static void hdd_ssr_timer_init(void)
2150{
2151 init_timer(&ssr_timer);
2152}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002153
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002154static void hdd_ssr_timer_del(void)
2155{
2156 del_timer(&ssr_timer);
2157 ssr_timer_started = false;
2158}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002159
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002160static void hdd_ssr_timer_cb(unsigned long data)
2161{
2162 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07002163
2164#ifdef WCN_PRONTO
2165 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
2166 wcnss_pronto_log_debug_regs();
2167#endif
2168
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002169 VOS_BUG(0);
2170}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002171
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002172static void hdd_ssr_timer_start(int msec)
2173{
2174 if(ssr_timer_started)
2175 {
2176 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
2177 ,__func__);
2178 }
2179 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
2180 ssr_timer.function = hdd_ssr_timer_cb;
2181 add_timer(&ssr_timer);
2182 ssr_timer_started = true;
2183}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002184
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302185#ifdef FEATURE_WLAN_DIAG_SUPPORT
2186/**
2187 * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state
2188 *
2189 * This Function send send ssr shutdown state diag event
2190 *
2191 * Return: void.
2192 */
2193static void hdd_wlan_ssr_shutdown_event(void)
2194{
2195 WLAN_VOS_DIAG_EVENT_DEF(ssr_shutdown,
2196 struct host_event_wlan_ssr_shutdown);
2197 vos_mem_zero(&ssr_shutdown, sizeof(ssr_shutdown));
2198 ssr_shutdown.status = SSR_SUB_SYSTEM_SHUTDOWN;
2199 WLAN_VOS_DIAG_EVENT_REPORT(&ssr_shutdown,
2200 EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM);
2201}
2202#else
2203static inline void hdd_wlan_ssr_shutdown_event(void)
2204{
2205
2206};
2207#endif
2208
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05302209/**
2210 * hdd_send_hang_reason() - Send hang reason to the userspace
2211 *
2212 * Return: None
2213 */
2214static void hdd_send_hang_reason(hdd_context_t *hdd_ctx)
2215{
2216 unsigned int reason = 0;
2217
2218 if(!hdd_ctx) {
2219 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2220 return;
2221 }
2222
2223 vos_get_recovery_reason(&reason);
2224 vos_reset_recovery_reason();
2225 wlan_hdd_send_hang_reason_event(hdd_ctx, reason);
2226}
2227
Jeff Johnson295189b2012-06-20 16:38:30 -07002228/* the HDD interface to WLAN driver shutdown,
2229 * the primary shutdown function in SSR
2230 */
2231VOS_STATUS hdd_wlan_shutdown(void)
2232{
2233 VOS_STATUS vosStatus;
2234 v_CONTEXT_t pVosContext = NULL;
2235 hdd_context_t *pHddCtx = NULL;
2236 pVosSchedContext vosSchedContext = NULL;
2237
2238 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
2239
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002240 /* if re-init never happens, then do SSR1 */
2241 hdd_ssr_timer_init();
2242 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
2243
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 /* Get the global VOSS context. */
2245 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2246 if(!pVosContext) {
2247 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2248 return VOS_STATUS_E_FAILURE;
2249 }
2250 /* Get the HDD context. */
2251 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2252 if(!pHddCtx) {
2253 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2254 return VOS_STATUS_E_FAILURE;
2255 }
c_hpothud662a352013-12-26 15:09:12 +05302256
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +05302257 vos_set_snoc_high_freq_voting(false);
c_hpothud662a352013-12-26 15:09:12 +05302258 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +05302259 if ((pHddCtx->cfg_ini->dynSplitscan)&& (VOS_TIMER_STATE_RUNNING ==
2260 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
c_hpothud662a352013-12-26 15:09:12 +05302261 {
2262 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
2263 }
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05302264 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +05302265 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +05302266 vos_flush_work(&pHddCtx->sap_start_work);
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 hdd_reset_all_adapters(pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +05302268
2269 /* set default value of Tcp delack and stop timer */
2270 hdd_set_default_stop_delack_timer(pHddCtx);
2271
Bala Venkateshbd197a32018-06-06 13:06:10 +05302272 if (VOS_TIMER_STATE_RUNNING ==
2273 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer))
2274 vos_timer_stop(&pHddCtx->tdls_source_timer);
2275
Jeff Johnson295189b2012-06-20 16:38:30 -07002276 /* DeRegister with platform driver as client for Suspend/Resume */
2277 vosStatus = hddDeregisterPmOps(pHddCtx);
2278 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2279 {
2280 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
2281 }
2282
2283 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
2284 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2285 {
2286 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
2287 }
2288
2289 /* Disable IMPS/BMPS as we do not want the device to enter any power
2290 * save mode on its own during reset sequence
2291 */
2292 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
2293 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
2294 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
2295
2296 vosSchedContext = get_vos_sched_ctxt();
2297
2298 /* Wakeup all driver threads */
2299 if(TRUE == pHddCtx->isMcThreadSuspended){
2300 complete(&vosSchedContext->ResumeMcEvent);
2301 pHddCtx->isMcThreadSuspended= FALSE;
2302 }
2303 if(TRUE == pHddCtx->isTxThreadSuspended){
2304 complete(&vosSchedContext->ResumeTxEvent);
2305 pHddCtx->isTxThreadSuspended= FALSE;
2306 }
2307 if(TRUE == pHddCtx->isRxThreadSuspended){
2308 complete(&vosSchedContext->ResumeRxEvent);
2309 pHddCtx->isRxThreadSuspended= FALSE;
2310 }
2311 /* Reset the Suspend Variable */
2312 pHddCtx->isWlanSuspended = FALSE;
2313
2314 /* Stop all the threads; we do not want any messages to be a processed,
2315 * any more and the best way to ensure that is to terminate the threads
2316 * gracefully.
2317 */
2318 /* Wait for MC to exit */
2319 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302320 set_bit(MC_SHUTDOWN_EVENT, &vosSchedContext->mcEventFlag);
2321 set_bit(MC_POST_EVENT, &vosSchedContext->mcEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002322 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302323 wait_for_completion(&vosSchedContext->McShutdown);
Bala Venkateshbd197a32018-06-06 13:06:10 +05302324 vosSchedContext->McThread = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002325
2326 /* Wait for TX to exit */
2327 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302328 set_bit(TX_SHUTDOWN_EVENT, &vosSchedContext->txEventFlag);
2329 set_bit(TX_POST_EVENT, &vosSchedContext->txEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002330 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302331 wait_for_completion(&vosSchedContext->TxShutdown);
Bala Venkateshbd197a32018-06-06 13:06:10 +05302332 vosSchedContext->TxThread = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002333
2334 /* Wait for RX to exit */
2335 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302336 set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->rxEventFlag);
2337 set_bit(RX_POST_EVENT, &vosSchedContext->rxEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002338 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302339 wait_for_completion(&vosSchedContext->RxShutdown);
Bala Venkateshbd197a32018-06-06 13:06:10 +05302340 vosSchedContext->RxThread = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002341
2342#ifdef WLAN_BTAMP_FEATURE
2343 vosStatus = WLANBAP_Stop(pVosContext);
2344 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2345 {
2346 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2347 "%s: Failed to stop BAP",__func__);
2348 }
2349#endif //WLAN_BTAMP_FEATURE
2350 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302351 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2352 {
2353 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2354 "%s: Failed to stop wda %d", __func__, vosStatus);
2355 VOS_ASSERT(0);
2356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002357
2358 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2359 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2360 * on threads being running to process the SYS Stop
2361 */
Kiet Lama72a2322013-11-15 11:18:11 +05302362 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302363 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2364 {
2365 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2366 "%s: Failed to stop sme %d", __func__, vosStatus);
2367 VOS_ASSERT(0);
2368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002369
2370 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2371 /* Stop MAC (PE and HAL) */
2372 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302373 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2374 {
2375 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2376 "%s: Failed to stop mac %d", __func__, vosStatus);
2377 VOS_ASSERT(0);
2378 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002379
2380 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2381 /* Stop TL */
2382 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302383 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2384 {
2385 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2386 "%s: Failed to stop TL %d", __func__, vosStatus);
2387 VOS_ASSERT(0);
2388 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002389
Jeff Johnson295189b2012-06-20 16:38:30 -07002390 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2392 /* Clean up message queues of TX and MC thread */
2393 vos_sched_flush_mc_mqs(vosSchedContext);
2394 vos_sched_flush_tx_mqs(vosSchedContext);
2395 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302396#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2397 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302398 /*Free fw dump mem in case of SSR/Shutdown */
2399 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2400 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302401#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002402
2403 /* Deinit all the TX and MC queues */
2404 vos_sched_deinit_mqs(vosSchedContext);
2405 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2406
2407 /* shutdown VOSS */
2408 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302409
2410 /*mac context has already been released in mac_close call
2411 so setting it to NULL in hdd context*/
2412 pHddCtx->hHal = (tHalHandle)NULL;
2413
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 if (free_riva_power_on_lock("wlan"))
2415 {
2416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2417 __func__);
2418 }
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302419 hdd_wlan_ssr_shutdown_event();
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05302420 hdd_send_hang_reason(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2422 ,__func__);
2423 return VOS_STATUS_SUCCESS;
2424}
2425
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302426int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter)
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302427{
2428 hdd_config_t *config;
2429 int status = VOS_STATUS_SUCCESS;
2430 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2431
2432 config = hdd_ctx->cfg_ini;
2433 if (NULL == config) {
2434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2435 ("cfg_ini is NULL!!"));
2436 return -EINVAL;
2437 }
2438#ifdef DHCP_SERVER_OFFLOAD
2439 /* set dhcp server offload */
2440 if (config->enable_dhcp_srv_offload &&
2441 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302442 vos_event_reset(&adapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +05302443 status = wlan_hdd_set_dhcp_server_offload(adapter, true);
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302444 if (!VOS_IS_STATUS_SUCCESS(status))
2445 {
2446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2447 ("HDD DHCP Server Offload Failed!!"));
2448 return -EINVAL;
2449 }
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302450 status = vos_wait_single_event(&adapter->dhcp_status.vos_event, 2000);
2451 if (!VOS_IS_STATUS_SUCCESS(status) ||
2452 adapter->dhcp_status.dhcp_offload_status)
2453 {
2454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2455 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
2456 adapter->dhcp_status.dhcp_offload_status);
2457 return -EINVAL;
2458 }
2459#ifdef MDNS_OFFLOAD
2460 if (config->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302461 vos_event_reset(&adapter->mdns_status.vos_event);
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302462 status = wlan_hdd_set_mdns_offload(adapter);
2463 if (VOS_IS_STATUS_SUCCESS(status))
2464 {
2465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2466 ("HDD MDNS Server Offload Failed!!"));
2467 return -EINVAL;
2468 }
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302469 status = vos_wait_single_event(&adapter->
2470 mdns_status.vos_event, 2000);
2471 if (!VOS_IS_STATUS_SUCCESS(status) ||
2472 adapter->mdns_status.mdns_enable_status ||
2473 adapter->mdns_status.mdns_fqdn_status ||
2474 adapter->mdns_status.mdns_resp_status)
2475 {
2476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2477 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
2478 adapter->mdns_status.mdns_enable_status,
2479 adapter->mdns_status.mdns_fqdn_status,
2480 adapter->mdns_status.mdns_resp_status);
2481 return -EINVAL;
2482 }
2483 }
2484#endif /* MDNS_OFFLOAD */
2485 } else {
2486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2487 ("DHCP Disabled ini %d, FW %d"),
2488 config->enable_dhcp_srv_offload,
2489 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
2490 }
2491#endif /* DHCP_SERVER_OFFLOAD */
2492 return status;
2493}
2494
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302495/**
2496 * hdd_ssr_restart_sap() - restart sap on SSR
2497 * @hdd_ctx: hdd context
2498 *
2499 * Return: nothing
2500 */
2501static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx)
2502{
2503 VOS_STATUS status;
2504 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
2505 hdd_adapter_t *adapter;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302506 hdd_hostapd_state_t *hostapd_state;
Jeff Johnson295189b2012-06-20 16:38:30 -07002507
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302508 ENTER();
2509
2510 status = hdd_get_front_adapter (hdd_ctx, &adapter_node);
2511 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
2512 adapter = adapter_node->pAdapter;
2513 if (adapter && adapter->device_mode == WLAN_HDD_SOFTAP) {
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05302514 if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) {
2515 hostapd_state =
2516 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
2517 hddLog(VOS_TRACE_LEVEL_INFO, FL("Restart prev SAP session"));
2518 wlan_hdd_start_sap(adapter);
2519 if (!VOS_IS_STATUS_SUCCESS(
2520 hdd_dhcp_mdns_offload(adapter))) {
2521 vos_event_reset(
2522 &hostapd_state->vosEvent);
2523 hddLog(VOS_TRACE_LEVEL_ERROR,
2524 FL("DHCP/MDNS offload Failed!!"));
2525 if (VOS_STATUS_SUCCESS ==
2526 WLANSAP_StopBss(
2527 hdd_ctx->pvosContext)) {
2528 status = vos_wait_single_event(
2529 &hostapd_state->vosEvent
2530 , 10000);
2531 if (!VOS_IS_STATUS_SUCCESS(
2532 status)) {
2533 hddLog(LOGE, FL("SAP Stop Failed"));
2534 return;
2535 }
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302536 }
2537 }
2538 }
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302539 }
2540 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
2541 adapter_node = next;
2542 }
2543
2544 EXIT();
2545}
Jeff Johnson295189b2012-06-20 16:38:30 -07002546
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302547#ifdef FEATURE_WLAN_DIAG_SUPPORT
2548/**
2549* hdd_wlan_ssr_reinit_event()- send ssr reinit state
2550*
2551* This Function send send ssr reinit state diag event
2552*
2553* Return: void.
2554*/
2555static void hdd_wlan_ssr_reinit_event(void)
2556{
2557 WLAN_VOS_DIAG_EVENT_DEF(ssr_reinit, struct host_event_wlan_ssr_reinit);
2558 vos_mem_zero(&ssr_reinit, sizeof(ssr_reinit));
2559 ssr_reinit.status = SSR_SUB_SYSTEM_REINIT;
2560 WLAN_VOS_DIAG_EVENT_REPORT(&ssr_reinit,
2561 EVENT_WLAN_SSR_REINIT_SUBSYSTEM);
2562}
2563#else
2564static inline void hdd_wlan_ssr_reinit_event(void)
2565{
2566
2567}
2568#endif
2569
Jeff Johnson295189b2012-06-20 16:38:30 -07002570/* the HDD interface to WLAN driver re-init.
2571 * This is called to initialize/start WLAN driver after a shutdown.
2572 */
2573VOS_STATUS hdd_wlan_re_init(void)
2574{
2575 VOS_STATUS vosStatus;
2576 v_CONTEXT_t pVosContext = NULL;
2577 hdd_context_t *pHddCtx = NULL;
2578 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002579#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2580 int max_retries = 0;
2581#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302582#ifdef HAVE_CBC_DONE
2583 int max_cbc_retries = 0;
2584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002585#ifdef WLAN_BTAMP_FEATURE
2586 hdd_config_t *pConfig = NULL;
2587 WLANBAP_ConfigType btAmpConfig;
2588#endif
2589
Katya Nigam82a93062014-06-04 15:15:36 +05302590 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002591 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302592 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002593
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002594#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2595 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002596 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002597 msleep(1000);
2598 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002599 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002600 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2601 goto err_re_init;
2602 }
2603#endif
2604
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302605#ifdef HAVE_CBC_DONE
2606 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2607 msleep(1000);
2608 }
2609 if (max_cbc_retries >= 20) {
2610 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2611 }
2612#endif
2613
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002614 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2615
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002616 /* The driver should always be initialized in STA mode after SSR */
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302617 if (VOS_STA_SAP_MODE != hdd_get_conparam())
2618 hdd_set_conparam(0);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002619
Katya Nigam82a93062014-06-04 15:15:36 +05302620 dev = wcnss_wlan_get_device();
2621 if (NULL == dev)
2622 {
2623 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2624 goto err_re_init;
2625 }
2626
Jeff Johnson295189b2012-06-20 16:38:30 -07002627 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302628 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002629 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2630 {
2631 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2632 goto err_re_init;
2633 }
2634
2635 /* Get the HDD context. */
2636 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2637 if(!pHddCtx)
2638 {
2639 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2640 goto err_vosclose;
2641 }
2642
2643 /* Save the hal context in Adapter */
2644 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2645 if ( NULL == pHddCtx->hHal )
2646 {
2647 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2648 goto err_vosclose;
2649 }
2650
2651 /* Set the SME configuration parameters. */
2652 vosStatus = hdd_set_sme_config(pHddCtx);
2653 if ( VOS_STATUS_SUCCESS != vosStatus )
2654 {
2655 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2656 goto err_vosclose;
2657 }
2658
Jeff Johnson295189b2012-06-20 16:38:30 -07002659 vosStatus = vos_preStart( pHddCtx->pvosContext );
2660 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2661 {
2662 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2663 goto err_vosclose;
2664 }
2665
2666 /* In the integrated architecture we update the configuration from
2667 the INI file and from NV before vOSS has been started so that
2668 the final contents are available to send down to the cCPU */
2669 /* Apply the cfg.ini to cfg.dat */
2670 if (FALSE == hdd_update_config_dat(pHddCtx))
2671 {
2672 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2673 goto err_vosclose;
2674 }
2675
2676 /* Set the MAC Address, currently this is used by HAL to add self sta.
2677 * Remove this once self sta is added as part of session open. */
2678 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2679 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2680 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2681 if (!HAL_STATUS_SUCCESS(halStatus))
2682 {
2683 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2684 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2685 goto err_vosclose;
2686 }
2687
2688 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2689 Note: Firmware image will be read and downloaded inside vos_start API */
2690 vosStatus = vos_start( pVosContext );
2691 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2692 {
2693 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +05302694 if (isSsrPanicOnFailure())
2695 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 goto err_vosclose;
2697 }
2698
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002699 /* Exchange capability info between Host and FW and also get versioning info from FW */
2700 hdd_exchange_version_and_caps(pHddCtx);
2701
Jeff Johnson295189b2012-06-20 16:38:30 -07002702 vosStatus = hdd_post_voss_start_config( pHddCtx );
2703 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2704 {
2705 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2706 __func__);
2707 goto err_vosstop;
2708 }
2709
Mihir Shete04206452014-11-20 17:50:58 +05302710#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302711 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2712 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2713 {
2714 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2715 __func__);
2716 goto err_vosstop;
2717 }
Mihir Shete04206452014-11-20 17:50:58 +05302718#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302719
Jeff Johnson295189b2012-06-20 16:38:30 -07002720#ifdef WLAN_BTAMP_FEATURE
2721 vosStatus = WLANBAP_Open(pVosContext);
2722 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2723 {
2724 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2725 "%s: Failed to open BAP",__func__);
2726 goto err_vosstop;
2727 }
2728 vosStatus = BSL_Init(pVosContext);
2729 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2730 {
2731 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2732 "%s: Failed to Init BSL",__func__);
2733 goto err_bap_close;
2734 }
2735 vosStatus = WLANBAP_Start(pVosContext);
2736 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2737 {
2738 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2739 "%s: Failed to start TL",__func__);
2740 goto err_bap_close;
2741 }
2742 pConfig = pHddCtx->cfg_ini;
2743 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2744 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2745#endif //WLAN_BTAMP_FEATURE
2746
2747 /* Restart all adapters */
2748 hdd_start_all_adapters(pHddCtx);
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +05302749 pHddCtx->last_scan_reject_session_id = 0xFF;
2750 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +05302751 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +05302752 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002753 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302754 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002755 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302756 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002757 /* Register with platform driver as client for Suspend/Resume */
2758 vosStatus = hddRegisterPmOps(pHddCtx);
2759 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2760 {
2761 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2762 goto err_bap_stop;
2763 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302764
2765#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2766 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2767 (pHddCtx->cfg_ini->enableFWLogging ||
2768 pHddCtx->cfg_ini->enableMgmtLogging ||
2769 pHddCtx->cfg_ini->enableContFWLogging))
2770 {
2771 hdd_init_frame_logging(pHddCtx);
2772 }
2773#endif
2774
Jeff Johnson295189b2012-06-20 16:38:30 -07002775 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302776 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002777 /* register for riva power on lock */
2778 if (req_riva_power_on_lock("wlan"))
2779 {
2780 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2781 __func__);
2782 goto err_unregister_pmops;
2783 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302784 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002785 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Deepthi Gowri1ca95bb2016-01-13 19:47:53 +05302786
2787 sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame);
2788
Dasari Srinivas421bde82014-06-25 12:01:44 +05302789#ifdef WLAN_FEATURE_EXTSCAN
2790 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2791 wlan_hdd_cfg80211_extscan_callback,
2792 pHddCtx);
2793#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302794
2795#ifdef FEATURE_OEM_DATA_SUPPORT
2796 sme_OemDataRegisterCallback(pHddCtx->hHal,
2797 wlan_hdd_cfg80211_oemdata_callback,
2798 pHddCtx);
2799#endif /* FEATURE_OEM_DATA_SUPPORT */
2800
Jeff Johnson295189b2012-06-20 16:38:30 -07002801 goto success;
2802
2803err_unregister_pmops:
2804 hddDeregisterPmOps(pHddCtx);
2805
2806err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002807#ifdef CONFIG_HAS_EARLYSUSPEND
2808 hdd_unregister_mcast_bcast_filter(pHddCtx);
2809#endif
2810 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002811#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002812 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002813#endif
2814
2815#ifdef WLAN_BTAMP_FEATURE
2816err_bap_close:
2817 WLANBAP_Close(pVosContext);
2818#endif
2819
2820err_vosstop:
2821 vos_stop(pVosContext);
2822
2823err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302824 if(!isSsrPanicOnFailure())
2825 {
2826 /* If we hit this, it means wlan driver is in bad state and needs
2827 * driver unload and load.
2828 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302829 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2830 return VOS_STATUS_E_FAILURE;
2831 }
2832
Jeff Johnson295189b2012-06-20 16:38:30 -07002833 vos_close(pVosContext);
2834 vos_sched_close(pVosContext);
2835 if (pHddCtx)
2836 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002837 /* Unregister the Net Device Notifier */
2838 unregister_netdevice_notifier(&hdd_netdev_notifier);
2839 /* Clean up HDD Nlink Service */
2840 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002841#ifdef WLAN_KD_READY_NOTIFIER
2842 nl_srv_exit(pHddCtx->ptt_pid);
2843#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002844 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002845#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002846 /* Free up dynamically allocated members inside HDD Adapter */
2847 kfree(pHddCtx->cfg_ini);
2848 pHddCtx->cfg_ini= NULL;
2849
Jeff Johnson295189b2012-06-20 16:38:30 -07002850 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302851 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002852 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002853 }
2854 vos_preClose(&pVosContext);
2855
2856#ifdef MEMORY_DEBUG
2857 vos_mem_exit();
2858#endif
2859
2860err_re_init:
2861 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302862 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002863 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002864 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002865 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002866
2867success:
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302868 hdd_wlan_ssr_reinit_event();
Jeff Johnson295189b2012-06-20 16:38:30 -07002869 /* Trigger replay of BTC events */
2870 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302871
2872 if (pHddCtx->cfg_ini->sap_internal_restart)
2873 hdd_ssr_restart_sap(pHddCtx);
2874
Jeff Johnson295189b2012-06-20 16:38:30 -07002875 return VOS_STATUS_SUCCESS;
2876}