blob: f54e4148e9432e4bc7bd942b2ed56bb2c013a227 [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;
446 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700447
Jeff Johnson295189b2012-06-20 16:38:30 -0700448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
449 "%s: calling hdd_set_sme_config",__func__);
450 vosStatus = hdd_set_sme_config( pHddCtx );
451 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
452 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
453 {
454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
455 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700456 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700457 }
458
459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
460 "%s: calling vos_start",__func__);
461 vosStatus = vos_start( pHddCtx->pvosContext );
462 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
463 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
464 {
465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
466 "%s: Failed in vos_start",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +0530467 if (isSsrPanicOnFailure())
468 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700469 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700470 }
471
472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
473 "%s: calling hdd_post_voss_start_config",__func__);
474 vosStatus = hdd_post_voss_start_config( pHddCtx );
475 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
476 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
477 {
478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
479 "%s: Failed in hdd_post_voss_start_config",__func__);
480 goto err_voss_stop;
481 }
482
483
484 //Open a SME session for future operation
485 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700486 (tANI_U8 *)&pAdapter->macAddressCurrent,
487 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700488 if ( !HAL_STATUS_SUCCESS( halStatus ) )
489 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700490 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700491 halStatus, halStatus );
492 goto err_voss_stop;
493
494 }
495
496 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
497
498 //Trigger the initial scan
Ravi Kumar Bokka585faca2017-03-01 16:18:41 +0530499 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700500
501 return VOS_STATUS_SUCCESS;
502
503err_voss_stop:
504 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700505err_deep_sleep:
506 return VOS_STATUS_E_FAILURE;
507
508}
509
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530510void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
Atul Mittal37385d72014-03-27 18:15:03 +0530511{
512 hdd_adapter_t* pAdapter =
513 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
514 hdd_context_t *pHddCtx;
515 int status;
516
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530517 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530518 if (NULL == pAdapter)
519 {
520 hddLog(LOGE, FL("Adapter is invalid"));
521 return;
522 }
Atul Mittal37385d72014-03-27 18:15:03 +0530523
524 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
525 status = wlan_hdd_validate_context(pHddCtx);
526 if (0 != status)
527 {
Atul Mittal37385d72014-03-27 18:15:03 +0530528 return;
529 }
530
Atul Mittal37385d72014-03-27 18:15:03 +0530531 if ((eConnectionState_Associated ==
532 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
533 && (pHddCtx->hdd_wlan_suspended))
534 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530535 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Atul Mittal37385d72014-03-27 18:15:03 +0530536 // This invocation being part of the IPv6 registration callback,
537 // set the newly generated ip address to f/w in suspend mode.
538#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530539 if (pHddCtx->cfg_ini->fhostNSOffload)
540 {
541 hdd_conf_ns_offload(pAdapter, 1);
542 }
Atul Mittal37385d72014-03-27 18:15:03 +0530543#endif
544 }
545#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530546 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530547 * only so when new ipv6 address is generated the screen may not
548 * on so we need to call it here to update the list in f/w.
549 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530550 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530551#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530552 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530553}
554
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530555void hdd_ipv6_notifier_work_queue(struct work_struct *work)
556{
557 vos_ssr_protect(__func__);
558 __hdd_ipv6_notifier_work_queue(work);
559 vos_ssr_unprotect(__func__);
560}
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530561int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530562 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530563{
564 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
565 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530566 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530567 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530568 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530569 int status;
570
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530571 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530572 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
573 status = wlan_hdd_validate_context(pHddCtx);
574 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530575 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530576 return NOTIFY_DONE;
577 }
Atul Mittal37385d72014-03-27 18:15:03 +0530578
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530579 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
580 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
581 {
582 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
583 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
584 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
585 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +0530586
587 if (eConnectionState_Associated ==
588 WLAN_HDD_GET_STATION_CTX_PTR
589 (pAdapterNode->pAdapter)->conn_info.connState)
590 sme_dhcp_done_ind(pHddCtx->hHal,
591 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530592 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530593 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530594 {
595 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
596 }
597 else
598 {
599 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
600 pHddCtx->cfg_ini->nEnableSuspend);
601 }
602 break;
603 }
604 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
605 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530606 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530607 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530608 return NOTIFY_DONE;
609}
610
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530611int wlan_hdd_ipv6_changed(struct notifier_block *nb,
612 unsigned long data, void *arg)
613{
614 int ret;
615 vos_ssr_protect(__func__);
616 ret = __wlan_hdd_ipv6_changed( nb, data, arg);
617 vos_ssr_unprotect(__func__);
618 return ret;
619}
620
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530621/*
622 * Function: hdd_conf_hostoffload
623 * Central function to configure the supported offloads,
624 * either enable or disable them.
625 */
626void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
627{
628 hdd_context_t *pHddCtx = NULL;
629 v_CONTEXT_t *pVosContext = NULL;
630 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
631
632 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
633 fenable);
634
635 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
636
637 if (NULL == pVosContext)
638 {
639 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
640 return;
641 }
642
643 //Get the HDD context.
644 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
645
646 if (NULL == pHddCtx)
647 {
648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
649 return;
650 }
651
652 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Arun Khandavalli08bcafd2016-11-08 14:45:48 +0530653 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
654 ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
655 (pHddCtx->is_ap_mode_wow_supported)))
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530656 {
657 if (fenable)
658 {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +0530659 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
660 (eConnectionState_Associated ==
661 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
662 || (WLAN_HDD_SOFTAP == pAdapter->device_mode))
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530663 {
664 if ((pHddCtx->cfg_ini->fhostArpOffload))
665 {
666 /*
667 * Configure the ARP Offload.
668 * Even if it fails we have to reconfigure the MC/BC
669 * filter flag as we want RIVA not to drop BroadCast
670 * Packets
671 */
672 hddLog(VOS_TRACE_LEVEL_INFO,
673 FL("Calling ARP Offload with flag: %d"), fenable);
674 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
675 pHddCtx->configuredMcastBcastFilter &=
676 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
677
678 if (!VOS_IS_STATUS_SUCCESS(vstatus))
679 {
Anurag Chouhan8a5f8902016-09-28 18:54:47 +0530680 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530681 "Failed to enable ARPOFfloadFeature %d",
682 vstatus);
683 }
684 }
685 //Configure GTK_OFFLOAD
686#ifdef WLAN_FEATURE_GTK_OFFLOAD
687 hdd_conf_gtk_offload(pAdapter, fenable);
688#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530689
690#ifdef WLAN_NS_OFFLOAD
691 if (pHddCtx->cfg_ini->fhostNSOffload)
692 {
693 /*
694 * Configure the NS Offload.
695 * Even if it fails we have to reconfigure the MC/BC filter flag
696 * as we want RIVA not to drop Multicast Packets
697 */
698
699 hddLog(VOS_TRACE_LEVEL_INFO,
700 FL("Calling NS Offload with flag: %d"), fenable);
701 hdd_conf_ns_offload(pAdapter, fenable);
702 pHddCtx->configuredMcastBcastFilter &=
703 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
704 }
705#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530706
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530707 }
708 }
709 else
710 {
711 //Disable ARPOFFLOAD
712 if (pHddCtx->cfg_ini->fhostArpOffload)
713 {
714 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
715 if (!VOS_IS_STATUS_SUCCESS(vstatus))
716 {
717 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530718 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530719 }
720 }
721 //Disable GTK_OFFLOAD
722#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530723 hdd_conf_gtk_offload(pAdapter, fenable);
724#endif
725
726#ifdef WLAN_NS_OFFLOAD
727 //Disable NSOFFLOAD
728 if (pHddCtx->cfg_ini->fhostNSOffload)
729 {
730 hdd_conf_ns_offload(pAdapter, fenable);
731 }
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530732 else
733 {
734 hddLog(VOS_TRACE_LEVEL_INFO,
735 FL("ns offload ini is disabled"));
736 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530737#endif
738 }
739 }
740 return;
741}
742
Atul Mittal37385d72014-03-27 18:15:03 +0530743
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530744#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530745/**----------------------------------------------------------------------------
746
747 \brief hdd_conf_ns_offload() - Configure NS offload
748
749 Called during SUSPEND to configure the NS offload (MC BC filter) which
750 reduces power consumption.
751
752 \param - pAdapter - Adapter context for which NS offload is to be configured
753 \param - fenable - 0 - disable.
754 1 - enable. (with IPv6 notifier registration)
755 2 - enable. (without IPv6 notifier registration)
756
757 \return - void
758
759 ---------------------------------------------------------------------------*/
760void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530761{
762 struct inet6_dev *in6_dev;
763 struct inet6_ifaddr *ifp;
764 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530765 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530766 tANI_U8 **selfIPv6Addr = NULL;
767 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530768 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530769 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530770 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530771
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530772 int i = 0, slot = 0;
773 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530774 eHalStatus returnStatus;
775
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530776 ENTER();
777 hddLog(LOG1, FL(" fenable = %d"), fenable);
778
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530779 if (NULL == pAdapter)
780 {
781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
782 return;
783 }
784
785 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530786 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
787
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530788 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530789 if (0 != ret)
790 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530791 return;
792 }
793
794 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
795 {
796 slot_index = NS_EXTENDED_SLOT_INDEX;
797 }
798
799 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
800
801 selfIPv6AddrValid =
802 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
803
804 if (NULL == selfIPv6AddrValid)
805 {
806 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
807 " selfIPv6AddrValid"));
808 goto end;
809 }
810
811 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
812
813 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
814
815 if (NULL == selfIPv6Addr)
816 {
817 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
818 " selfIPv6Addr"));
819 goto end;
820 }
821
822 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
823
824 for (slot = 0; slot < slot_index; slot++)
825 {
826 selfIPv6Addr[slot] =
827 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
828 if (NULL == selfIPv6Addr[slot])
829 {
830 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
831 "for selfIPv6Addr"));
832 goto end;
833 }
834 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
835 }
836
837 i = 0;
838
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530839 if (fenable)
840 {
841 in6_dev = __in6_dev_get(pAdapter->dev);
842 if (NULL != in6_dev)
843 {
Srinivas Girigowdad26a8072016-10-19 20:26:42 +0530844 read_lock_bh(&in6_dev->lock);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530845 list_for_each(p, &in6_dev->addr_list)
846 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530847 if (i >= slot_index)
848 {
849 hddLog (VOS_TRACE_LEVEL_ERROR,
850 FL("IPv6 address list is greater than IPv6"
851 "address supported by firmware"));
852 hddLog (VOS_TRACE_LEVEL_ERROR,
853 FL("FW supported IPv6 address = %d"), slot_index);
854 break;
855 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530856 ifp = list_entry(p, struct inet6_ifaddr, if_list);
857 switch(ipv6_addr_src_scope(&ifp->addr))
858 {
859 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530860 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530861 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530862 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530863 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530864 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
865 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530866 break;
867 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530868 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530869 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530870 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530871 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530872 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
873 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530874 break;
875 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530876 hddLog(VOS_TRACE_LEVEL_ERROR,
877 FL("The Scope %d is not supported"),
878 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530879 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530880 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
881 {
882 i++;
883 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530884 }
Mukul Sharma115869a2017-06-29 17:38:57 +0530885 /* store actual slots being used */
886 pAdapter->ns_slots = i;
Srinivas Girigowdad26a8072016-10-19 20:26:42 +0530887 read_unlock_bh(&in6_dev->lock);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530888
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530889 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530890 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530891 {
892 if (selfIPv6AddrValid[i])
893 {
894 //Filling up the request structure
895 /* Filling the selfIPv6Addr with solicited address
896 * A Solicited-Node multicast address is created by
897 * taking the last 24 bits of a unicast or anycast
898 * address and appending them to the prefix
899 *
900 * FF02:0000:0000:0000:0000:0001:FFXX:XX
901 *
902 * here XX is the unicast/anycast bits
903 */
904 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
905 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
906 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
907 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530908 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
909 selfIPv6Addr[i][13];
910 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
911 selfIPv6Addr[i][14];
912 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
913 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530914 offLoadRequest.nsOffloadInfo.slotIdx = i;
915
916 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530917 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530918 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
919 &pAdapter->macAddressCurrent.bytes,
920 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
921
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530922 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
923 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530924 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
925 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +0530926 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
927 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530928
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530929 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530930 FL("configuredMcastBcastFilter: %d"
931 "NSOffload Slot = %d"),
932 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530933
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530934 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700935 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
936 pHddCtx->sus_res_mcastbcast_filter) ||
937 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
938 pHddCtx->sus_res_mcastbcast_filter)) &&
939 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
940 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
941 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530942 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530943 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700944 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530945 }
Abhishek Singh937ec542016-01-05 18:03:14 +0530946 hdd_wlan_offload_event(
947 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE,
948 SIR_OFFLOAD_ENABLE);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530949 hddLog(VOS_TRACE_LEVEL_INFO,
950 FL("offload: NS filter programmed %d"),
951 offLoadRequest.enableOrDisable);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530952 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
953 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
954 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
955
956 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530957 FL("Setting NSOffload with solicitedIp: %pI6,"
958 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530959 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
960 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
961
962 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530963 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530964 pAdapter->sessionId, &offLoadRequest);
965 if(eHAL_STATUS_SUCCESS != returnStatus)
966 {
967 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530968 FL("Failed to enable HostOffload feature with"
969 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530970 }
971 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
972 }
973 }
974 }
975 else
976 {
977 hddLog(VOS_TRACE_LEVEL_ERROR,
978 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530979 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530980 }
981 }
982 else
983 {
984 //Disable NSOffload
985 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
986 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
987 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +0530988 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
989 SIR_OFFLOAD_DISABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530990
Mukul Sharma115869a2017-06-29 17:38:57 +0530991 for (i = 0; i < pAdapter->ns_slots; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530992 {
c_hpothu86feba52014-10-28 15:51:18 +0530993 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530994 offLoadRequest.nsOffloadInfo.slotIdx = i;
995 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530996 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
997 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530998 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
1000 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +05301001 }
1002 }
Mukul Sharma115869a2017-06-29 17:38:57 +05301003 pAdapter->ns_slots = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301004 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +05301005end:
1006 while (slot > 0 && selfIPv6Addr[--slot])
1007 {
1008 vos_mem_free(selfIPv6Addr[slot]);
1009 }
1010 if (selfIPv6Addr)
1011 {
1012 vos_mem_free(selfIPv6Addr);
1013 }
1014 if (selfIPv6AddrValid)
1015 {
1016 vos_mem_free(selfIPv6AddrValid);
1017 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301018 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301019 return;
1020}
1021#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301022
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301023void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301024{
1025 hdd_adapter_t* pAdapter =
1026 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
1027 hdd_context_t *pHddCtx;
1028 int status;
1029
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301030 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301031 if (NULL == pAdapter)
1032 {
1033 hddLog(LOGE, FL("Adapter is invalid"));
1034 return;
1035 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301036 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1037 status = wlan_hdd_validate_context(pHddCtx);
1038 if (0 != status)
1039 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301040 return;
1041 }
1042
1043 if ((eConnectionState_Associated ==
1044 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +05301045 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301046 {
1047 // This invocation being part of the IPv4 registration callback,
1048 // we are passing second parameter as 2 to avoid registration
1049 // of IPv4 notifier again.
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301050 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1051 if (pHddCtx->cfg_ini->fhostArpOffload)
1052 {
1053 hdd_conf_arp_offload(pAdapter, 2);
1054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_INFO,
1058 FL("offload: arp offload ini is disabled in host"));
1059 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301060 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301061 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301062}
1063
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301064void hdd_ipv4_notifier_work_queue(struct work_struct *work)
1065{
1066 vos_ssr_protect(__func__);
1067 __hdd_ipv4_notifier_work_queue(work);
1068 vos_ssr_unprotect(__func__);
1069}
1070
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301071int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301072 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301073{
1074 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1075 struct in_ifaddr **ifap = NULL;
1076 struct in_device *in_dev;
1077
1078 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301079 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301080 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301081 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301082 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301083
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301084 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301085 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1086 status = wlan_hdd_validate_context(pHddCtx);
1087 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301088 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301089 return NOTIFY_DONE;
1090 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301091
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301092 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1093 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1094 {
1095 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1096 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1097 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1098 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +05301099
1100 if (eConnectionState_Associated ==
1101 WLAN_HDD_GET_STATION_CTX_PTR
1102 (pAdapterNode->pAdapter)->conn_info.connState)
1103 sme_dhcp_done_ind(pHddCtx->hHal,
1104 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301105 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301106 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301107 || (!pHddCtx->cfg_ini->fhostArpOffload))
1108 {
1109 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1110 pHddCtx->cfg_ini->nEnableSuspend,
1111 pHddCtx->cfg_ini->fhostArpOffload);
1112 return NOTIFY_DONE;
1113 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301114
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301115 if ((in_dev =
1116 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1117 {
1118 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1119 ifap = &ifa->ifa_next)
1120 {
1121 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1122 ifa->ifa_label))
1123 {
1124 break; /* found */
1125 }
1126 }
1127 }
1128 if(ifa && ifa->ifa_local)
1129 {
1130 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1131 }
1132 break;
1133 }
1134 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1135 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301136 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301137 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301138 return NOTIFY_DONE;
1139}
1140
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301141int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1142 unsigned long data, void *arg)
1143{
1144 int ret;
1145 vos_ssr_protect(__func__);
1146 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1147 vos_ssr_unprotect(__func__);
1148 return ret;
1149}
1150
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301151/**----------------------------------------------------------------------------
1152
1153 \brief hdd_conf_arp_offload() - Configure ARP offload
1154
1155 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1156 reduces power consumption.
1157
1158 \param - pAdapter -Adapter context for which ARP offload is to be configured
1159 \param - fenable - 0 - disable.
1160 1 - enable. (with IPv4 notifier registration)
1161 2 - enable. (without IPv4 notifier registration)
1162
1163 \return -
1164 VOS_STATUS_SUCCESS - on successful operation
1165 VOS_STATUS_E_FAILURE - on failure of operation
1166-----------------------------------------------------------------------------*/
1167VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001168{
1169 struct in_ifaddr **ifap = NULL;
1170 struct in_ifaddr *ifa = NULL;
1171 struct in_device *in_dev;
1172 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001174 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001175
Sushant Kaushik87787972015-09-11 16:05:00 +05301176 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001177
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 if(fenable)
1179 {
1180 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1181 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301182 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001183 ifap = &ifa->ifa_next)
1184 {
1185 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1186 {
1187 break; /* found */
1188 }
1189 }
1190 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001191 if(ifa && ifa->ifa_local)
1192 {
1193 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1194 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +05301195 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1196 SIR_OFFLOAD_ENABLE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001197
Arif Hussain6d2a3322013-11-17 19:50:10 -08001198 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001199
Amar Singhald53568e2013-09-26 11:03:45 -07001200 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1201 pHddCtx->sus_res_mcastbcast_filter) ||
1202 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1203 pHddCtx->sus_res_mcastbcast_filter)) &&
1204 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001205 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301206 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001207 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1208 hddLog(VOS_TRACE_LEVEL_INFO,
1209 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001210 }
Abhishek Singh937ec542016-01-05 18:03:14 +05301211 hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
1212 SIR_OFFLOAD_ENABLE);
Amar Singhald53568e2013-09-26 11:03:45 -07001213
1214 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1215 offLoadRequest.enableOrDisable);
1216
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 //converting u32 to IPV4 address
1218 for(i = 0 ; i < 4; i++)
1219 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301220 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1222 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301223 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001224 offLoadRequest.params.hostIpv4Addr[0],
1225 offLoadRequest.params.hostIpv4Addr[1],
1226 offLoadRequest.params.hostIpv4Addr[2],
1227 offLoadRequest.params.hostIpv4Addr[3]);
1228
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301229 if (eHAL_STATUS_SUCCESS !=
1230 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1231 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 {
1233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001234 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001235 return VOS_STATUS_E_FAILURE;
1236 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001237 }
1238 else
1239 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301240 hddLog(VOS_TRACE_LEVEL_WARN, FL("IP Address is not assigned"));
Agarwal Ashish971c2882013-10-30 20:11:12 +05301241 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001242 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301243
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301244 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001245 }
1246 else
1247 {
1248 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1249 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1250 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +05301251 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1252 SIR_OFFLOAD_DISABLE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301253 if (eHAL_STATUS_SUCCESS !=
1254 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1255 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001256 {
1257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001258 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 return VOS_STATUS_E_FAILURE;
1260 }
1261 return VOS_STATUS_SUCCESS;
1262 }
1263}
1264
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301265/*
1266 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301267 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301268*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301269void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301270 tANI_U8 *pMcBcFilter)
1271{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301272 if (NULL == pHddCtx)
1273 {
1274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1275 return;
1276 }
1277
1278 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1279 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301280 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301281 /* ARP offload is enabled, do not block bcast packets at RXP
1282 * Will be using Bitmasking to reset the filter. As we have
1283 * disable Broadcast filtering, Anding with the negation
1284 * of Broadcast BIT
1285 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301286 hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301287 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301288 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301289
1290#ifdef WLAN_NS_OFFLOAD
1291 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301292 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301293 /* NS offload is enabled, do not block mcast packets at RXP
1294 * Will be using Bitmasking to reset the filter. As we have
1295 * disable Multicast filtering, Anding with the negation
1296 * of Multicast BIT
1297 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301298 hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301299 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301300 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301301#endif
1302
Amar Singhald08ce752014-03-21 16:28:27 -07001303 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1304 {
1305 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1306 }
1307
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301308 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301309}
1310
Jeff Johnson295189b2012-06-20 16:38:30 -07001311void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1312{
1313 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1315 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
Agarwal Ashishff451a32015-07-28 01:01:29 +05301316 if (NULL == wlanRxpFilterParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 {
1318 hddLog(VOS_TRACE_LEVEL_FATAL,
1319 "%s: vos_mem_alloc failed ", __func__);
1320 return;
1321 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 hddLog(VOS_TRACE_LEVEL_INFO,
1323 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301324 if (TRUE == setfilter)
1325 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301326 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301327 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301328 }
1329 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301330 {
1331 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301332 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301333 pHddCtx->configuredMcastBcastFilter;
1334 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301335
Jeff Johnson295189b2012-06-20 16:38:30 -07001336 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301338
1339 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
Agarwal Ashishff451a32015-07-28 01:01:29 +05301340 {
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301341 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Agarwal Ashishff451a32015-07-28 01:01:29 +05301342 }
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301343
1344 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1345 "lower mac with status %d"
1346 "configuredMcstBcstFilterSetting = %d"
1347 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1348 "Failed" : "Success", halStatus,
1349 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1350 wlanRxpFilterParam->setMcstBcstFilter);
1351
Chilam Ngc4244af2013-04-01 15:37:32 -07001352 if (eHAL_STATUS_SUCCESS != halStatus)
1353 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001354}
1355
mukul sharmae4abd892016-11-24 22:03:31 +05301356/*
1357 * Enable/Disable McAddrList cfg item in fwr.
1358 */
1359eHalStatus hdd_set_mc_list_cfg_item(hdd_context_t* pHddCtx,
1360 bool value)
1361{
1362 eHalStatus ret_val;
1363
1364 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST,
1365 value, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1366 {
1367 ret_val = eHAL_STATUS_FAILURE;
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301368 hddLog(LOGE,
1369 FL("offload: can't pass WNI_CFG_ENABLE_MC_ADDR_LIST to CCM"));
mukul sharmae4abd892016-11-24 22:03:31 +05301370 return ret_val;
1371 }
1372
1373 ret_val = sme_update_cfg_int_param(pHddCtx->hHal,
1374 WNI_CFG_ENABLE_MC_ADDR_LIST);
1375 if (!HAL_STATUS_SUCCESS(ret_val))
1376 {
1377 hddLog(VOS_TRACE_LEVEL_ERROR,
1378 FL("Failed to toggle MC_ADDR_LIST_INI %d "),
1379 ret_val);
1380 return ret_val;
1381 }
1382 /* cache the value configured in fwr */
1383 pHddCtx->mc_list_cfg_in_fwr = value;
mukul sharmae4abd892016-11-24 22:03:31 +05301384 return eHAL_STATUS_SUCCESS;
1385}
1386
1387bool is_mc_list_cfg_disable_required(hdd_context_t* pHddCtx)
1388{
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301389 hddLog(VOS_TRACE_LEVEL_INFO,
1390 FL("offload: fEnableMCList %d sus_res_mcbc_filter %d mc_list_in_fwr %d"),
1391 pHddCtx->cfg_ini->fEnableMCAddrList,
1392 pHddCtx->sus_res_mcastbcast_filter,
1393 pHddCtx->mc_list_cfg_in_fwr);
1394
mukul sharmae4abd892016-11-24 22:03:31 +05301395 /*
1396 * If MCAddrList is enabled in ini and MCBC filter is set to
1397 * Either Filter None or Filter all BC then, Fwr need to push
1398 * all MC to host. This can be achieved by disabling cfg MCAddrList
1399 * in fwr. As in driver load, firmware have this value to 1 we
1400 * need to set it to 0. Same needs to be reverted on resume.
1401 */
1402 if (pHddCtx->cfg_ini->fEnableMCAddrList &&
1403 WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
1404 ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)&&
1405 ((HDD_MCASTBCASTFILTER_FILTER_NONE ==
1406 pHddCtx->sus_res_mcastbcast_filter) ||
1407 (HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1408 pHddCtx->sus_res_mcastbcast_filter)))
1409 )
1410 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301411 hddLog(VOS_TRACE_LEVEL_INFO,
1412 FL("offload: cfg ini need to disable in fwr"));
mukul sharmae4abd892016-11-24 22:03:31 +05301413 return true;
1414 }
1415 else
1416 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301417 hddLog(VOS_TRACE_LEVEL_INFO,
1418 FL("offload: cfg ini disable not needed "));
mukul sharmae4abd892016-11-24 22:03:31 +05301419 return false;
1420 }
1421}
1422
1423/**
1424 * hdd_mc_addr_list_cfg_config() - To set mc list cfg configuration in fwr
1425 * @pHddCtx: hdd context handle
1426 * @action: true to disable MCAddrList in fwr to get all MC pkt to host
1427 * false to set ini value of MCAddrList in fwr if it was toggled
1428 * Return: none
1429 *
1430 * Ensure Below API is invoked always post modification
1431 * of sus_res_mcastbcast_filter.
1432 */
1433void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action)
1434{
1435 if (action)
1436 {
1437 /* check host need to disable mc list ini in fwr */
1438 if (is_mc_list_cfg_disable_required(pHddCtx))
1439 {
1440 /*
1441 * Yes Host should disable the mc list in fwr
1442 * But Ensure host might already disable it
1443 * This can happen when user issue set/clear MCBC
1444 * ioctl with 2 to 0 or vice versa.
1445 */
1446 if (pHddCtx->cfg_ini->fEnableMCAddrList ==
1447 pHddCtx->mc_list_cfg_in_fwr)
1448 {
1449 hdd_set_mc_list_cfg_item(pHddCtx,
1450 !pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301451 hddLog(VOS_TRACE_LEVEL_INFO,
1452 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1453 !pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301454 }
1455 }
1456 else
1457 {
1458 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1459 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1460 pHddCtx->mc_list_cfg_in_fwr)
1461 {
1462 hdd_set_mc_list_cfg_item(pHddCtx,
1463 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301464 hddLog(VOS_TRACE_LEVEL_INFO,
1465 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1466 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301467 }
1468 }
1469 }
1470 else
1471 {
1472 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1473 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1474 pHddCtx->mc_list_cfg_in_fwr)
1475 {
1476 hdd_set_mc_list_cfg_item(pHddCtx,
1477 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301478 hddLog(VOS_TRACE_LEVEL_INFO,
1479 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1480 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301481 }
1482 }
1483}
1484
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301485/**
1486 * hdd_suspend_ind_callback: This API will set completion event for suspend
1487 * @pAdapter: hdd_adapter_t
1488 * @status: suspend status
1489 *
1490 * Return: none
1491 */
1492static void hdd_suspend_ind_callback(void *context, VOS_STATUS status)
1493{
1494 hdd_adapter_t *adapter = (hdd_adapter_t *)context;
1495 if (NULL == adapter)
1496 {
1497 hddLog(VOS_TRACE_LEVEL_ERROR,
1498 "%s: HDD adapter is NULL",__func__);
1499 return;
1500 }
1501 hddLog(VOS_TRACE_LEVEL_INFO, FL("suspend status %d"), status);
1502 complete(&adapter->wlan_suspend_comp_var);
1503}
1504
Jeff Johnson295189b2012-06-20 16:38:30 -07001505static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1506 hdd_adapter_t *pAdapter)
1507{
1508 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1509 tpSirWlanSuspendParam wlanSuspendParam =
1510 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1511
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301512 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001513 if(NULL == wlanSuspendParam)
1514 {
1515 hddLog(VOS_TRACE_LEVEL_FATAL,
1516 "%s: vos_mem_alloc failed ", __func__);
1517 return;
1518 }
1519
Amar Singhald53568e2013-09-26 11:03:45 -07001520 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001521 "%s: send wlan suspend indication", __func__);
1522
1523 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1524 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301525 //Configure supported OffLoads
1526 hdd_conf_hostoffload(pAdapter, TRUE);
1527 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301528 hddLog(VOS_TRACE_LEVEL_INFO,
1529 FL("saving configuredMcastBcastFilterSetting = %d"),
1530 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001531#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301532 /* During suspend, configure MC Addr list filter to the firmware
1533 * function takes care of checking necessary conditions before
1534 * configuring.
1535 */
1536 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001537#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001538
1539 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1540 {
1541
1542 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1543 pHddCtx->configuredMcastBcastFilter &=
1544 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1545 }
1546
1547 wlanSuspendParam->configuredMcstBcstFilterSetting =
1548 pHddCtx->configuredMcastBcastFilter;
mukul sharmae4abd892016-11-24 22:03:31 +05301549
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301550 wlanSuspendParam->wlan_sus_callback = hdd_suspend_ind_callback;
1551 wlanSuspendParam->context = pAdapter;
mukul sharmae4abd892016-11-24 22:03:31 +05301552 /* mc add list cfg item configuration in fwr */
1553 hdd_mc_addr_list_cfg_config(pHddCtx, true);
1554
Jeff Johnson295189b2012-06-20 16:38:30 -07001555 }
1556
1557 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1558 if(eHAL_STATUS_SUCCESS == halStatus)
1559 {
1560 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001561 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301562 hddLog(VOS_TRACE_LEVEL_ERROR,
1563 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001564 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 }
1566}
1567
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301568static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001569{
Chilam Ngc4244af2013-04-01 15:37:32 -07001570 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001571 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001572 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001573
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301574 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 "%s: send wlan resume indication", __func__);
1576
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301577 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1578
1579 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001580 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301581 hddLog(VOS_TRACE_LEVEL_FATAL,
1582 "%s: memory allocation failed for wlanResumeParam ", __func__);
1583 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001585
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301586 //Disable supported OffLoads
1587 hdd_conf_hostoffload(pAdapter, FALSE);
1588
1589 wlanResumeParam->configuredMcstBcstFilterSetting =
1590 pHddCtx->configuredMcastBcastFilter;
1591 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1592 if (eHAL_STATUS_SUCCESS != halStatus)
1593 {
c_hpothuffdb5272013-10-02 16:42:35 +05301594 hddLog(VOS_TRACE_LEVEL_ERROR,
1595 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301596 vos_mem_free(wlanResumeParam);
1597 }
1598
1599 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
mukul sharmae4abd892016-11-24 22:03:31 +05301600 /* mc add list cfg item configuration in fwr */
1601 hdd_mc_addr_list_cfg_config(pHddCtx, false);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301602
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001603 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1604 pHddCtx->configuredMcastBcastFilter =
1605 pHddCtx->sus_res_mcastbcast_filter;
1606 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1607 }
Amar Singhald53568e2013-09-26 11:03:45 -07001608
1609 hddLog(VOS_TRACE_LEVEL_INFO,
1610 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1611 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1612 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001613
Chilam Ngc4244af2013-04-01 15:37:32 -07001614
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301615#ifdef WLAN_FEATURE_PACKET_FILTERING
1616 /* Filer was applied during suspend inditication
1617 * clear it when we resume.
1618 */
1619 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001620#endif
1621}
Jeff Johnson295189b2012-06-20 16:38:30 -07001622
Jeff Johnson295189b2012-06-20 16:38:30 -07001623//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001624void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001625{
1626 hdd_context_t *pHddCtx = NULL;
1627 v_CONTEXT_t pVosContext = NULL;
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301628 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001629 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301630 hdd_adapter_t *pAdapter = NULL;
1631 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301632 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001633
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1635
1636 //Get the global VOSS context.
1637 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1638 if(!pVosContext) {
1639 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1640 return;
1641 }
1642
1643 //Get the HDD context.
1644 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1645
1646 if(!pHddCtx) {
1647 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1648 return;
1649 }
1650
1651 if (pHddCtx->isLogpInProgress) {
1652 hddLog(VOS_TRACE_LEVEL_ERROR,
1653 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1654 return;
1655 }
1656
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301657 if (pHddCtx->hdd_wlan_suspended)
1658 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301659 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301660 "%s: Ignore suspend wlan, Already suspended!", __func__);
1661 return;
1662 }
1663
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301664 pHddCtx->hdd_wlan_suspended = TRUE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301665 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301666 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1668 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1669 {
1670 pAdapter = pAdapterNode->pAdapter;
1671 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001672 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1674
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001675 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001676 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1677 pAdapterNode = pNext;
1678 continue;
1679 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301680 /* Avoid multiple enter/exit BMPS in this while loop using
1681 * hdd_enter_bmps flag
1682 */
1683 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1684 {
1685 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001686
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301687 /* If device was already in BMPS, and dynamic DTIM is set,
1688 * exit(set the device to full power) and enter BMPS again
1689 * to reflect new DTIM value */
1690 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1691
1692 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1693
1694 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001696#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1697 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1698 {
1699 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301700 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001701 netif_tx_disable(pAdapter->dev);
1702 netif_carrier_off(pAdapter->dev);
1703 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301704 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001705 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1706 {
1707 //Execute deep sleep procedure
1708 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1709 }
1710#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301711
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301712 INIT_COMPLETION(pAdapter->wlan_suspend_comp_var);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301713 /*Suspend notification sent down to driver*/
1714 hdd_conf_suspend_ind(pHddCtx, pAdapter);
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301715 ret = wait_for_completion_interruptible_timeout(
1716 &pAdapter->wlan_suspend_comp_var,
1717 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
1718 if (0 >= ret)
1719 {
1720 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on suspend failed %ld",
1721 __func__, ret);
1722 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301723 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1724 pAdapterNode = pNext;
1725 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301726
Jeff Johnson295189b2012-06-20 16:38:30 -07001727#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1728 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1729 {
1730 hdd_enter_standby(pHddCtx);
1731 }
1732#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001733
1734 return;
1735}
1736
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301737/**
1738 * @brief hdd_ReConfigSuspendDataClearedDuringRoaming() - Reconfigure the
1739 * suspend related data which was cleared during roaming in FWR.
1740 */
1741void hdd_ReConfigSuspendDataClearedDuringRoaming(hdd_context_t *pHddCtx)
1742
1743{
1744 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
1745 hdd_adapter_t *pAdapter;
1746 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1747
1748 ENTER();
1749
1750 spin_lock(&pHddCtx->filter_lock);
1751 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1752 spin_unlock(&pHddCtx->filter_lock);
1753
1754 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
1755 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Not able to set mcast/bcast filter "));
1757
1758 vstatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1759 //No need to configure GTK Offload from here because it might possible
1760 //cfg80211_set_rekey_data might not yet came, anyway GTK offload will
1761 //be handled as part of cfg80211_set_rekey_data processing.
1762 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vstatus )
1763 {
1764 pAdapter = pAdapterNode->pAdapter;
1765 if( pAdapter &&
1766 (( pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
1767 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)))
1768 {
1769 if (pHddCtx->cfg_ini->fhostArpOffload)
1770 {
1771 //Configure ARPOFFLOAD
1772 vstatus = hdd_conf_arp_offload(pAdapter, TRUE);
1773 if (!VOS_IS_STATUS_SUCCESS(vstatus))
1774 {
1775 hddLog(VOS_TRACE_LEVEL_INFO,
1776 FL("Failed to disable ARPOffload Feature %d"), vstatus);
1777 }
1778 }
1779#ifdef WLAN_NS_OFFLOAD
1780 //Configure NSOFFLOAD
1781 if (pHddCtx->cfg_ini->fhostNSOffload)
1782 {
1783 hdd_conf_ns_offload(pAdapter, TRUE);
1784 }
1785#endif
1786#ifdef WLAN_FEATURE_PACKET_FILTERING
1787 /* During suspend, configure MC Addr list filter to the firmware
1788 * function takes care of checking necessary conditions before
1789 * configuring.
1790 */
1791 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
1792#endif
1793 }
1794 vstatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1795 pAdapterNode = pNext;
1796 }
1797 EXIT();
1798}
1799
Jeff Johnson295189b2012-06-20 16:38:30 -07001800static void hdd_PowerStateChangedCB
1801(
1802 v_PVOID_t callbackContext,
1803 tPmcState newState
1804)
1805{
1806 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301807
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 /* if the driver was not in BMPS during early suspend,
1809 * the dynamic DTIM is now updated at Riva */
1810 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
Abhishek Singh0ea13232016-02-12 16:46:10 +05301811 && (pHddCtx->cfg_ini->enableDynamicDTIM ||
1812 pHddCtx->cfg_ini->enableModulatedDTIM)
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1814 {
1815 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1816 }
1817 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301818 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1819 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301820 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001821 spin_unlock(&pHddCtx->filter_lock);
1822 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301825 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001826 else
Mihir Shete793209f2014-01-06 11:01:12 +05301827 {
1828 /* Android framework can send resume request when the WCN chip is
1829 * in IMPS mode. When the chip exits IMPS mode the firmware will
1830 * restore all the registers to the state they were before the chip
1831 * entered IMPS and so our hardware filter settings confgured by the
1832 * resume request will be lost. So reconfigure the filters on detecting
1833 * a change in the power state of the WCN chip.
1834 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301835 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301836 if (IMPS != newState)
1837 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301838 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301839 if (FALSE == pHddCtx->hdd_wlan_suspended)
1840 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301841 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301842 hddLog(VOS_TRACE_LEVEL_INFO,
1843 "Not in IMPS/BMPS and suspended state");
1844 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1845 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301846 else
1847 {
1848 spin_unlock(&pHddCtx->filter_lock);
1849 }
Mihir Shete793209f2014-01-06 11:01:12 +05301850 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301851 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001852}
1853
Jeff Johnson295189b2012-06-20 16:38:30 -07001854void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1855{
1856 v_CONTEXT_t pVosContext;
1857 tHalHandle smeContext;
1858
1859 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1860 if (NULL == pVosContext)
1861 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001862 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 return;
1864 }
1865 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1866 if (NULL == smeContext)
1867 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001868 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001869 return;
1870 }
1871
1872 spin_lock_init(&pHddCtx->filter_lock);
1873 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1874 pHddCtx->cfg_ini->nEnableSuspend)
1875 {
1876 pmcRegisterDeviceStateUpdateInd(smeContext,
1877 hdd_PowerStateChangedCB, pHddCtx);
1878 }
1879}
1880
1881void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1882{
1883 v_CONTEXT_t pVosContext;
1884 tHalHandle smeContext;
1885
1886 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1887 if (NULL == pVosContext)
1888 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001889 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001890 return;
1891 }
1892 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1893 if (NULL == smeContext)
1894 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001895 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 return;
1897 }
1898
1899 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1900 pHddCtx->cfg_ini->nEnableSuspend)
1901 {
1902 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1903 }
1904}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301905
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301906#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301907void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301908{
1909 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301910 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301911 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1912
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301913 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301914 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301915 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1916 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1917 {
1918 vos_mem_copy(&hddGtkOffloadReqParams,
1919 &pHddStaCtx->gtkOffloadReqParams,
1920 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301921
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301922 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1923 &hddGtkOffloadReqParams, pAdapter->sessionId);
1924 if (eHAL_STATUS_SUCCESS != ret)
1925 {
1926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1927 "%s: sme_SetGTKOffload failed, returned %d",
1928 __func__, ret);
1929 return;
1930 }
1931
1932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1933 "%s: sme_SetGTKOffload successfull", __func__);
1934 }
1935
1936 }
1937 else
1938 {
1939 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1940 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1941 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1942 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1943 {
1944
1945 /* Host driver has previously offloaded GTK rekey */
1946 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301947 wlan_hdd_cfg80211_update_replayCounterCallback,
1948 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301949 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301950
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301951 {
1952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1953 "%s: sme_GetGTKOffload failed, returned %d",
1954 __func__, ret);
1955 return;
1956 }
1957 else
1958 {
1959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1960 "%s: sme_GetGTKOffload successful",
1961 __func__);
1962
1963 /* Sending GTK offload dissable */
1964 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1965 sizeof (tSirGtkOffloadParams));
1966 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1967 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301968 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301969 if (eHAL_STATUS_SUCCESS != ret)
1970 {
1971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1972 "%s: failed to dissable GTK offload, returned %d",
1973 __func__, ret);
1974 return;
1975 }
1976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1977 "%s: successfully dissabled GTK offload request to HAL",
1978 __func__);
1979 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301980 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301981 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301982 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301983}
1984#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001985
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001986void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001987{
1988 hdd_context_t *pHddCtx = NULL;
1989 hdd_adapter_t *pAdapter = NULL;
1990 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1991 VOS_STATUS status;
1992 v_CONTEXT_t pVosContext = NULL;
Mukul Sharma3da767d2017-06-29 18:25:39 +05301993 tPmcState pmc_state;
1994 hdd_adapter_t *first_adapter = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001995
Jeff Johnson295189b2012-06-20 16:38:30 -07001996 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1997
1998 //Get the global VOSS context.
1999 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2000 if(!pVosContext) {
2001 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2002 return;
2003 }
2004
2005 //Get the HDD context.
2006 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
2007
2008 if(!pHddCtx) {
2009 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2010 return;
2011 }
2012
Agarwal Ashish971c2882013-10-30 20:11:12 +05302013 if (pHddCtx->isLogpInProgress)
2014 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 hddLog(VOS_TRACE_LEVEL_INFO,
2016 "%s: Ignore resume wlan, LOGP in progress!", __func__);
2017 return;
2018 }
2019
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05302020 if (!pHddCtx->hdd_wlan_suspended)
2021 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05302022 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05302023 "%s: Ignore resume wlan, Already resumed!", __func__);
2024 return;
2025 }
2026
Jeff Johnson295189b2012-06-20 16:38:30 -07002027 pHddCtx->hdd_wlan_suspended = FALSE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05302028 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
Mukul Sharma3da767d2017-06-29 18:25:39 +05302029
2030 /* Get first valid adapter for disable/enable bmps purpose */
2031 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2032 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2033 {
2034 first_adapter = pAdapterNode->pAdapter;
2035 if (first_adapter != NULL)
2036 break;
2037 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2038 pAdapterNode = pNext;
2039 }
2040 pmc_state = pmcGetPmcState(pHddCtx->hHal);
2041 if (BMPS == pmc_state && first_adapter)
2042 {
2043 /* put the device into full power */
2044 hddLog(VOS_TRACE_LEVEL_INFO,
2045 "%s: Disaling bmps during resume", __func__);
2046 wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_ACTIVE);
2047 }
2048
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 /*loop through all adapters. Concurrency */
2050 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2051
2052 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2053 {
2054 pAdapter = pAdapterNode->pAdapter;
2055 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07002056 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07002058 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2060 pAdapterNode = pNext;
2061 continue;
2062 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302063
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302064
Jeff Johnson295189b2012-06-20 16:38:30 -07002065#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2066 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
2067 {
2068 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
2069 hdd_exit_deep_sleep(pAdapter);
2070 }
2071#endif
2072
2073 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
2074 {
2075 /*Switch back to DTIM 1*/
2076 tSirSetPowerParamsReq powerRequest = { 0 };
2077
2078 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
2079 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07002080 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002081
2082 /*Disabled ModulatedDTIM if enabled on suspend*/
2083 if(pHddCtx->cfg_ini->enableModulatedDTIM)
2084 powerRequest.uDTIMPeriod = 0;
2085
2086 /* Update ignoreDTIM and ListedInterval in CFG with default values */
2087 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
2088 NULL, eANI_BOOLEAN_FALSE);
2089 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
2090 NULL, eANI_BOOLEAN_FALSE);
2091
2092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002093 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08002094 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002095
Mukul Sharma3da767d2017-06-29 18:25:39 +05302096 if (BMPS == pmc_state)
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302097 {
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302098 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
2099 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 }
2101
Gopichand Nakkala0f276812013-02-24 14:45:51 +05302102 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002103 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2104 pAdapterNode = pNext;
2105 }
2106
Mukul Sharma3da767d2017-06-29 18:25:39 +05302107 if (BMPS == pmc_state && first_adapter)
2108 {
2109 /* put the device into full power */
2110 hddLog(VOS_TRACE_LEVEL_INFO,
2111 "%s: Enable bmps during resume", __func__);
2112 /* put the device back into BMPS */
2113 wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_AUTO);
2114 }
2115
Jeff Johnson295189b2012-06-20 16:38:30 -07002116#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2117 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
2118 {
2119 hdd_exit_standby(pHddCtx);
2120 }
2121#endif
2122
Jeff Johnson295189b2012-06-20 16:38:30 -07002123 return;
2124}
2125
Jeff Johnson295189b2012-06-20 16:38:30 -07002126VOS_STATUS hdd_wlan_reset_initialization(void)
2127{
Jeff Johnson295189b2012-06-20 16:38:30 -07002128 v_CONTEXT_t pVosContext = NULL;
2129
2130 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
2131
2132 //Get the global VOSS context.
2133 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2134 if(!pVosContext)
2135 {
2136 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2137 return VOS_STATUS_E_FAILURE;
2138 }
2139
2140 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
2141
2142 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302143 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002144
Jeff Johnson295189b2012-06-20 16:38:30 -07002145 return VOS_STATUS_SUCCESS;
2146}
2147
2148
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002149/*
2150 * Based on the ioctl command recieved by HDD, put WLAN driver
2151 * into the quiet mode. This is the same as the early suspend
2152 * notification that driver used to listen
2153 */
2154void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07002155{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302156 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002157 if (suspend)
2158 hdd_suspend_wlan();
2159 else
2160 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302161 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002162}
2163
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002164static void hdd_ssr_timer_init(void)
2165{
2166 init_timer(&ssr_timer);
2167}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002168
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002169static void hdd_ssr_timer_del(void)
2170{
2171 del_timer(&ssr_timer);
2172 ssr_timer_started = false;
2173}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002174
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002175static void hdd_ssr_timer_cb(unsigned long data)
2176{
2177 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07002178
2179#ifdef WCN_PRONTO
2180 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
2181 wcnss_pronto_log_debug_regs();
2182#endif
2183
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002184 VOS_BUG(0);
2185}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002186
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002187static void hdd_ssr_timer_start(int msec)
2188{
2189 if(ssr_timer_started)
2190 {
2191 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
2192 ,__func__);
2193 }
2194 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
2195 ssr_timer.function = hdd_ssr_timer_cb;
2196 add_timer(&ssr_timer);
2197 ssr_timer_started = true;
2198}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002199
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302200#ifdef FEATURE_WLAN_DIAG_SUPPORT
2201/**
2202 * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state
2203 *
2204 * This Function send send ssr shutdown state diag event
2205 *
2206 * Return: void.
2207 */
2208static void hdd_wlan_ssr_shutdown_event(void)
2209{
2210 WLAN_VOS_DIAG_EVENT_DEF(ssr_shutdown,
2211 struct host_event_wlan_ssr_shutdown);
2212 vos_mem_zero(&ssr_shutdown, sizeof(ssr_shutdown));
2213 ssr_shutdown.status = SSR_SUB_SYSTEM_SHUTDOWN;
2214 WLAN_VOS_DIAG_EVENT_REPORT(&ssr_shutdown,
2215 EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM);
2216}
2217#else
2218static inline void hdd_wlan_ssr_shutdown_event(void)
2219{
2220
2221};
2222#endif
2223
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05302224/**
2225 * hdd_send_hang_reason() - Send hang reason to the userspace
2226 *
2227 * Return: None
2228 */
2229static void hdd_send_hang_reason(hdd_context_t *hdd_ctx)
2230{
2231 unsigned int reason = 0;
2232
2233 if(!hdd_ctx) {
2234 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2235 return;
2236 }
2237
2238 vos_get_recovery_reason(&reason);
2239 vos_reset_recovery_reason();
2240 wlan_hdd_send_hang_reason_event(hdd_ctx, reason);
2241}
2242
Jeff Johnson295189b2012-06-20 16:38:30 -07002243/* the HDD interface to WLAN driver shutdown,
2244 * the primary shutdown function in SSR
2245 */
2246VOS_STATUS hdd_wlan_shutdown(void)
2247{
2248 VOS_STATUS vosStatus;
2249 v_CONTEXT_t pVosContext = NULL;
2250 hdd_context_t *pHddCtx = NULL;
2251 pVosSchedContext vosSchedContext = NULL;
2252
2253 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
2254
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002255 /* if re-init never happens, then do SSR1 */
2256 hdd_ssr_timer_init();
2257 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
2258
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 /* Get the global VOSS context. */
2260 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2261 if(!pVosContext) {
2262 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2263 return VOS_STATUS_E_FAILURE;
2264 }
2265 /* Get the HDD context. */
2266 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2267 if(!pHddCtx) {
2268 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2269 return VOS_STATUS_E_FAILURE;
2270 }
c_hpothud662a352013-12-26 15:09:12 +05302271
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +05302272 vos_set_snoc_high_freq_voting(false);
c_hpothud662a352013-12-26 15:09:12 +05302273 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +05302274 if ((pHddCtx->cfg_ini->dynSplitscan)&& (VOS_TIMER_STATE_RUNNING ==
2275 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
c_hpothud662a352013-12-26 15:09:12 +05302276 {
2277 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
2278 }
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05302279 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +05302280 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +05302281 vos_flush_work(&pHddCtx->sap_start_work);
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 hdd_reset_all_adapters(pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +05302283
2284 /* set default value of Tcp delack and stop timer */
2285 hdd_set_default_stop_delack_timer(pHddCtx);
2286
Jeff Johnson295189b2012-06-20 16:38:30 -07002287 /* DeRegister with platform driver as client for Suspend/Resume */
2288 vosStatus = hddDeregisterPmOps(pHddCtx);
2289 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2290 {
2291 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
2292 }
2293
2294 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
2295 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2296 {
2297 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
2298 }
2299
2300 /* Disable IMPS/BMPS as we do not want the device to enter any power
2301 * save mode on its own during reset sequence
2302 */
2303 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
2304 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
2305 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
2306
2307 vosSchedContext = get_vos_sched_ctxt();
2308
2309 /* Wakeup all driver threads */
2310 if(TRUE == pHddCtx->isMcThreadSuspended){
2311 complete(&vosSchedContext->ResumeMcEvent);
2312 pHddCtx->isMcThreadSuspended= FALSE;
2313 }
2314 if(TRUE == pHddCtx->isTxThreadSuspended){
2315 complete(&vosSchedContext->ResumeTxEvent);
2316 pHddCtx->isTxThreadSuspended= FALSE;
2317 }
2318 if(TRUE == pHddCtx->isRxThreadSuspended){
2319 complete(&vosSchedContext->ResumeRxEvent);
2320 pHddCtx->isRxThreadSuspended= FALSE;
2321 }
2322 /* Reset the Suspend Variable */
2323 pHddCtx->isWlanSuspended = FALSE;
2324
2325 /* Stop all the threads; we do not want any messages to be a processed,
2326 * any more and the best way to ensure that is to terminate the threads
2327 * gracefully.
2328 */
2329 /* Wait for MC to exit */
2330 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302331 set_bit(MC_SHUTDOWN_EVENT, &vosSchedContext->mcEventFlag);
2332 set_bit(MC_POST_EVENT, &vosSchedContext->mcEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002333 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302334 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002335
2336 /* Wait for TX to exit */
2337 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302338 set_bit(TX_SHUTDOWN_EVENT, &vosSchedContext->txEventFlag);
2339 set_bit(TX_POST_EVENT, &vosSchedContext->txEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002340 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302341 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002342
2343 /* Wait for RX to exit */
2344 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302345 set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->rxEventFlag);
2346 set_bit(RX_POST_EVENT, &vosSchedContext->rxEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002347 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05302348
Mihir Sheteb5425f72013-12-19 09:06:13 +05302349 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002350
2351#ifdef WLAN_BTAMP_FEATURE
2352 vosStatus = WLANBAP_Stop(pVosContext);
2353 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2354 {
2355 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2356 "%s: Failed to stop BAP",__func__);
2357 }
2358#endif //WLAN_BTAMP_FEATURE
2359 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302360 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2361 {
2362 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2363 "%s: Failed to stop wda %d", __func__, vosStatus);
2364 VOS_ASSERT(0);
2365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002366
2367 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2368 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2369 * on threads being running to process the SYS Stop
2370 */
Kiet Lama72a2322013-11-15 11:18:11 +05302371 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302372 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2373 {
2374 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2375 "%s: Failed to stop sme %d", __func__, vosStatus);
2376 VOS_ASSERT(0);
2377 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002378
2379 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2380 /* Stop MAC (PE and HAL) */
2381 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302382 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2383 {
2384 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2385 "%s: Failed to stop mac %d", __func__, vosStatus);
2386 VOS_ASSERT(0);
2387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002388
2389 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2390 /* Stop TL */
2391 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302392 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2393 {
2394 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2395 "%s: Failed to stop TL %d", __func__, vosStatus);
2396 VOS_ASSERT(0);
2397 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002398
Jeff Johnson295189b2012-06-20 16:38:30 -07002399 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2401 /* Clean up message queues of TX and MC thread */
2402 vos_sched_flush_mc_mqs(vosSchedContext);
2403 vos_sched_flush_tx_mqs(vosSchedContext);
2404 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302405#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2406 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302407 /*Free fw dump mem in case of SSR/Shutdown */
2408 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2409 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302410#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002411
2412 /* Deinit all the TX and MC queues */
2413 vos_sched_deinit_mqs(vosSchedContext);
2414 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2415
2416 /* shutdown VOSS */
2417 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302418
2419 /*mac context has already been released in mac_close call
2420 so setting it to NULL in hdd context*/
2421 pHddCtx->hHal = (tHalHandle)NULL;
2422
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 if (free_riva_power_on_lock("wlan"))
2424 {
2425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2426 __func__);
2427 }
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302428 hdd_wlan_ssr_shutdown_event();
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05302429 hdd_send_hang_reason(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002430 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2431 ,__func__);
2432 return VOS_STATUS_SUCCESS;
2433}
2434
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302435int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter)
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302436{
2437 hdd_config_t *config;
2438 int status = VOS_STATUS_SUCCESS;
2439 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2440
2441 config = hdd_ctx->cfg_ini;
2442 if (NULL == config) {
2443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2444 ("cfg_ini is NULL!!"));
2445 return -EINVAL;
2446 }
2447#ifdef DHCP_SERVER_OFFLOAD
2448 /* set dhcp server offload */
2449 if (config->enable_dhcp_srv_offload &&
2450 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302451 vos_event_reset(&adapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +05302452 status = wlan_hdd_set_dhcp_server_offload(adapter, true);
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302453 if (!VOS_IS_STATUS_SUCCESS(status))
2454 {
2455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2456 ("HDD DHCP Server Offload Failed!!"));
2457 return -EINVAL;
2458 }
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302459 status = vos_wait_single_event(&adapter->dhcp_status.vos_event, 2000);
2460 if (!VOS_IS_STATUS_SUCCESS(status) ||
2461 adapter->dhcp_status.dhcp_offload_status)
2462 {
2463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2464 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
2465 adapter->dhcp_status.dhcp_offload_status);
2466 return -EINVAL;
2467 }
2468#ifdef MDNS_OFFLOAD
2469 if (config->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302470 vos_event_reset(&adapter->mdns_status.vos_event);
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302471 status = wlan_hdd_set_mdns_offload(adapter);
2472 if (VOS_IS_STATUS_SUCCESS(status))
2473 {
2474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2475 ("HDD MDNS Server Offload Failed!!"));
2476 return -EINVAL;
2477 }
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302478 status = vos_wait_single_event(&adapter->
2479 mdns_status.vos_event, 2000);
2480 if (!VOS_IS_STATUS_SUCCESS(status) ||
2481 adapter->mdns_status.mdns_enable_status ||
2482 adapter->mdns_status.mdns_fqdn_status ||
2483 adapter->mdns_status.mdns_resp_status)
2484 {
2485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2486 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
2487 adapter->mdns_status.mdns_enable_status,
2488 adapter->mdns_status.mdns_fqdn_status,
2489 adapter->mdns_status.mdns_resp_status);
2490 return -EINVAL;
2491 }
2492 }
2493#endif /* MDNS_OFFLOAD */
2494 } else {
2495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2496 ("DHCP Disabled ini %d, FW %d"),
2497 config->enable_dhcp_srv_offload,
2498 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
2499 }
2500#endif /* DHCP_SERVER_OFFLOAD */
2501 return status;
2502}
2503
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302504/**
2505 * hdd_ssr_restart_sap() - restart sap on SSR
2506 * @hdd_ctx: hdd context
2507 *
2508 * Return: nothing
2509 */
2510static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx)
2511{
2512 VOS_STATUS status;
2513 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
2514 hdd_adapter_t *adapter;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302515 hdd_hostapd_state_t *hostapd_state;
Jeff Johnson295189b2012-06-20 16:38:30 -07002516
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302517 ENTER();
2518
2519 status = hdd_get_front_adapter (hdd_ctx, &adapter_node);
2520 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
2521 adapter = adapter_node->pAdapter;
2522 if (adapter && adapter->device_mode == WLAN_HDD_SOFTAP) {
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05302523 if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) {
2524 hostapd_state =
2525 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
2526 hddLog(VOS_TRACE_LEVEL_INFO, FL("Restart prev SAP session"));
2527 wlan_hdd_start_sap(adapter);
2528 if (!VOS_IS_STATUS_SUCCESS(
2529 hdd_dhcp_mdns_offload(adapter))) {
2530 vos_event_reset(
2531 &hostapd_state->vosEvent);
2532 hddLog(VOS_TRACE_LEVEL_ERROR,
2533 FL("DHCP/MDNS offload Failed!!"));
2534 if (VOS_STATUS_SUCCESS ==
2535 WLANSAP_StopBss(
2536 hdd_ctx->pvosContext)) {
2537 status = vos_wait_single_event(
2538 &hostapd_state->vosEvent
2539 , 10000);
2540 if (!VOS_IS_STATUS_SUCCESS(
2541 status)) {
2542 hddLog(LOGE, FL("SAP Stop Failed"));
2543 return;
2544 }
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302545 }
2546 }
2547 }
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302548 }
2549 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
2550 adapter_node = next;
2551 }
2552
2553 EXIT();
2554}
Jeff Johnson295189b2012-06-20 16:38:30 -07002555
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302556#ifdef FEATURE_WLAN_DIAG_SUPPORT
2557/**
2558* hdd_wlan_ssr_reinit_event()- send ssr reinit state
2559*
2560* This Function send send ssr reinit state diag event
2561*
2562* Return: void.
2563*/
2564static void hdd_wlan_ssr_reinit_event(void)
2565{
2566 WLAN_VOS_DIAG_EVENT_DEF(ssr_reinit, struct host_event_wlan_ssr_reinit);
2567 vos_mem_zero(&ssr_reinit, sizeof(ssr_reinit));
2568 ssr_reinit.status = SSR_SUB_SYSTEM_REINIT;
2569 WLAN_VOS_DIAG_EVENT_REPORT(&ssr_reinit,
2570 EVENT_WLAN_SSR_REINIT_SUBSYSTEM);
2571}
2572#else
2573static inline void hdd_wlan_ssr_reinit_event(void)
2574{
2575
2576}
2577#endif
2578
Jeff Johnson295189b2012-06-20 16:38:30 -07002579/* the HDD interface to WLAN driver re-init.
2580 * This is called to initialize/start WLAN driver after a shutdown.
2581 */
2582VOS_STATUS hdd_wlan_re_init(void)
2583{
2584 VOS_STATUS vosStatus;
2585 v_CONTEXT_t pVosContext = NULL;
2586 hdd_context_t *pHddCtx = NULL;
2587 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002588#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2589 int max_retries = 0;
2590#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302591#ifdef HAVE_CBC_DONE
2592 int max_cbc_retries = 0;
2593#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002594#ifdef WLAN_BTAMP_FEATURE
2595 hdd_config_t *pConfig = NULL;
2596 WLANBAP_ConfigType btAmpConfig;
2597#endif
2598
Katya Nigam82a93062014-06-04 15:15:36 +05302599 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002600 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302601 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002602
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002603#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2604 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002605 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002606 msleep(1000);
2607 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002608 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002609 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2610 goto err_re_init;
2611 }
2612#endif
2613
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302614#ifdef HAVE_CBC_DONE
2615 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2616 msleep(1000);
2617 }
2618 if (max_cbc_retries >= 20) {
2619 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2620 }
2621#endif
2622
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002623 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2624
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002625 /* The driver should always be initialized in STA mode after SSR */
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302626 if (VOS_STA_SAP_MODE != hdd_get_conparam())
2627 hdd_set_conparam(0);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002628
Katya Nigam82a93062014-06-04 15:15:36 +05302629 dev = wcnss_wlan_get_device();
2630 if (NULL == dev)
2631 {
2632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2633 goto err_re_init;
2634 }
2635
Jeff Johnson295189b2012-06-20 16:38:30 -07002636 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302637 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002638 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2639 {
2640 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2641 goto err_re_init;
2642 }
2643
2644 /* Get the HDD context. */
2645 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2646 if(!pHddCtx)
2647 {
2648 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2649 goto err_vosclose;
2650 }
2651
2652 /* Save the hal context in Adapter */
2653 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2654 if ( NULL == pHddCtx->hHal )
2655 {
2656 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2657 goto err_vosclose;
2658 }
2659
2660 /* Set the SME configuration parameters. */
2661 vosStatus = hdd_set_sme_config(pHddCtx);
2662 if ( VOS_STATUS_SUCCESS != vosStatus )
2663 {
2664 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2665 goto err_vosclose;
2666 }
2667
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 vosStatus = vos_preStart( pHddCtx->pvosContext );
2669 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2670 {
2671 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2672 goto err_vosclose;
2673 }
2674
2675 /* In the integrated architecture we update the configuration from
2676 the INI file and from NV before vOSS has been started so that
2677 the final contents are available to send down to the cCPU */
2678 /* Apply the cfg.ini to cfg.dat */
2679 if (FALSE == hdd_update_config_dat(pHddCtx))
2680 {
2681 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2682 goto err_vosclose;
2683 }
2684
2685 /* Set the MAC Address, currently this is used by HAL to add self sta.
2686 * Remove this once self sta is added as part of session open. */
2687 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2688 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2689 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2690 if (!HAL_STATUS_SUCCESS(halStatus))
2691 {
2692 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2693 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2694 goto err_vosclose;
2695 }
2696
2697 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2698 Note: Firmware image will be read and downloaded inside vos_start API */
2699 vosStatus = vos_start( pVosContext );
2700 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2701 {
2702 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +05302703 if (isSsrPanicOnFailure())
2704 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002705 goto err_vosclose;
2706 }
2707
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002708 /* Exchange capability info between Host and FW and also get versioning info from FW */
2709 hdd_exchange_version_and_caps(pHddCtx);
2710
Jeff Johnson295189b2012-06-20 16:38:30 -07002711 vosStatus = hdd_post_voss_start_config( pHddCtx );
2712 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2713 {
2714 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2715 __func__);
2716 goto err_vosstop;
2717 }
2718
Mihir Shete04206452014-11-20 17:50:58 +05302719#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302720 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2721 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2722 {
2723 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2724 __func__);
2725 goto err_vosstop;
2726 }
Mihir Shete04206452014-11-20 17:50:58 +05302727#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302728
Jeff Johnson295189b2012-06-20 16:38:30 -07002729#ifdef WLAN_BTAMP_FEATURE
2730 vosStatus = WLANBAP_Open(pVosContext);
2731 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2732 {
2733 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2734 "%s: Failed to open BAP",__func__);
2735 goto err_vosstop;
2736 }
2737 vosStatus = BSL_Init(pVosContext);
2738 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2739 {
2740 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2741 "%s: Failed to Init BSL",__func__);
2742 goto err_bap_close;
2743 }
2744 vosStatus = WLANBAP_Start(pVosContext);
2745 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2746 {
2747 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2748 "%s: Failed to start TL",__func__);
2749 goto err_bap_close;
2750 }
2751 pConfig = pHddCtx->cfg_ini;
2752 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2753 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2754#endif //WLAN_BTAMP_FEATURE
2755
2756 /* Restart all adapters */
2757 hdd_start_all_adapters(pHddCtx);
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +05302758 pHddCtx->last_scan_reject_session_id = 0xFF;
2759 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +05302760 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +05302761 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002762 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302763 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002764 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302765 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002766 /* Register with platform driver as client for Suspend/Resume */
2767 vosStatus = hddRegisterPmOps(pHddCtx);
2768 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2769 {
2770 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2771 goto err_bap_stop;
2772 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302773
2774#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2775 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2776 (pHddCtx->cfg_ini->enableFWLogging ||
2777 pHddCtx->cfg_ini->enableMgmtLogging ||
2778 pHddCtx->cfg_ini->enableContFWLogging))
2779 {
2780 hdd_init_frame_logging(pHddCtx);
2781 }
2782#endif
2783
Jeff Johnson295189b2012-06-20 16:38:30 -07002784 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302785 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002786 /* register for riva power on lock */
2787 if (req_riva_power_on_lock("wlan"))
2788 {
2789 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2790 __func__);
2791 goto err_unregister_pmops;
2792 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302793 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002794 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Deepthi Gowri1ca95bb2016-01-13 19:47:53 +05302795
2796 sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame);
2797
Dasari Srinivas421bde82014-06-25 12:01:44 +05302798#ifdef WLAN_FEATURE_EXTSCAN
2799 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2800 wlan_hdd_cfg80211_extscan_callback,
2801 pHddCtx);
2802#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302803
2804#ifdef FEATURE_OEM_DATA_SUPPORT
2805 sme_OemDataRegisterCallback(pHddCtx->hHal,
2806 wlan_hdd_cfg80211_oemdata_callback,
2807 pHddCtx);
2808#endif /* FEATURE_OEM_DATA_SUPPORT */
2809
Jeff Johnson295189b2012-06-20 16:38:30 -07002810 goto success;
2811
2812err_unregister_pmops:
2813 hddDeregisterPmOps(pHddCtx);
2814
2815err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002816#ifdef CONFIG_HAS_EARLYSUSPEND
2817 hdd_unregister_mcast_bcast_filter(pHddCtx);
2818#endif
2819 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002820#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002821 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002822#endif
2823
2824#ifdef WLAN_BTAMP_FEATURE
2825err_bap_close:
2826 WLANBAP_Close(pVosContext);
2827#endif
2828
2829err_vosstop:
2830 vos_stop(pVosContext);
2831
2832err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302833 if(!isSsrPanicOnFailure())
2834 {
2835 /* If we hit this, it means wlan driver is in bad state and needs
2836 * driver unload and load.
2837 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302838 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2839 return VOS_STATUS_E_FAILURE;
2840 }
2841
Jeff Johnson295189b2012-06-20 16:38:30 -07002842 vos_close(pVosContext);
2843 vos_sched_close(pVosContext);
2844 if (pHddCtx)
2845 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002846 /* Unregister the Net Device Notifier */
2847 unregister_netdevice_notifier(&hdd_netdev_notifier);
2848 /* Clean up HDD Nlink Service */
2849 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002850#ifdef WLAN_KD_READY_NOTIFIER
2851 nl_srv_exit(pHddCtx->ptt_pid);
2852#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002853 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002854#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002855 /* Free up dynamically allocated members inside HDD Adapter */
2856 kfree(pHddCtx->cfg_ini);
2857 pHddCtx->cfg_ini= NULL;
2858
Jeff Johnson295189b2012-06-20 16:38:30 -07002859 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302860 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002861 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002862 }
2863 vos_preClose(&pVosContext);
2864
2865#ifdef MEMORY_DEBUG
2866 vos_mem_exit();
2867#endif
2868
2869err_re_init:
2870 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302871 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002872 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002873 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002874 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002875
2876success:
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302877 hdd_wlan_ssr_reinit_event();
Jeff Johnson295189b2012-06-20 16:38:30 -07002878 /* Trigger replay of BTC events */
2879 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302880
2881 if (pHddCtx->cfg_ini->sap_internal_restart)
2882 hdd_ssr_restart_sap(pHddCtx);
2883
Jeff Johnson295189b2012-06-20 16:38:30 -07002884 return VOS_STATUS_SUCCESS;
2885}