blob: c14890ccb2e2fa3dfbea1f048cc9a711df242244 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=============================================================================
29* wlan_hdd_early_suspend.c
30*
31* \brief power management functions
32*
33* Description
Jeff Johnson295189b2012-06-20 16:38:30 -070034*
35==============================================================================**/
36/* $HEADER$ */
37
38/**-----------------------------------------------------------------------------
39* Include files
40* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42#include <linux/pm.h>
43#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070044#include <wlan_hdd_includes.h>
45#include <wlan_qct_driver.h>
46#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48#include "halTypes.h"
49#include "sme_Api.h"
50#include <vos_api.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070051#include <vos_sched.h>
52#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <wlan_qct_sys.h>
54#include <wlan_btc_svc.h>
55#include <wlan_nlink_common.h>
56#include <wlan_hdd_main.h>
57#include <wlan_hdd_assoc.h>
58#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070059#include <wlan_nlink_srv.h>
60#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070061#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062
Jeff Johnson295189b2012-06-20 16:38:30 -070063#include <linux/semaphore.h>
64#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include "cfgApi.h"
Siddharth Bhal7bd19932015-03-03 16:54:36 +053066#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067
68#ifdef WLAN_BTAMP_FEATURE
69#include "bapApi.h"
70#include "bap_hdd_main.h"
71#include "bap_hdd_misc.h"
72#endif
73
Jeff Johnsone7245742012-09-05 17:12:55 -070074#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070075#include <linux/inetdevice.h>
76#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053077#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053078#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070079/**-----------------------------------------------------------------------------
80* Preprocessor definitions and constants
81* ----------------------------------------------------------------------------*/
82
83/**-----------------------------------------------------------------------------
84* Type declarations
85* ----------------------------------------------------------------------------*/
86
87/**-----------------------------------------------------------------------------
88* Function and variables declarations
89* ----------------------------------------------------------------------------*/
90#include "wlan_hdd_power.h"
91#include "wlan_hdd_packet_filtering.h"
92
Sameer Thalappile5637f42013-08-07 15:46:55 -070093#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053094#define NS_DEFAULT_SLOT_INDEX 4
95#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070096
97static eHalStatus g_full_pwr_status;
98static eHalStatus g_standby_status;
99
100extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Ravi Kumar Bokka585faca2017-03-01 16:18:41 +0530101extern void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700104extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700106static struct timer_list ssr_timer;
107static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530109void inline check_and_set_suspend_resume_mcbc_filter(hdd_context_t *pHddCtx)
110{
111 hddLog(VOS_TRACE_LEVEL_INFO,
112 FL("offload: sus_res_mcbc_filter_valid: %d sus_res_mcbc_filter: %d configuredMcBcFilter: %d"),
113 pHddCtx->sus_res_mcastbcast_filter_valid,
114 pHddCtx->sus_res_mcastbcast_filter,
115 pHddCtx->configuredMcastBcastFilter);
116 if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid)
117 {
118 pHddCtx->sus_res_mcastbcast_filter =
119 pHddCtx->configuredMcastBcastFilter;
120 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE;
121 hddLog(VOS_TRACE_LEVEL_INFO,
122 FL("offload: saving sus_res_mcastbcast_filter = %d"),
123 pHddCtx->sus_res_mcastbcast_filter);
124 }
125}
Abhishek Singh937ec542016-01-05 18:03:14 +0530126
127#ifdef FEATURE_WLAN_DIAG_SUPPORT
128/**
129 * hdd_wlan_offload_event()- send offloads event
130 *
131 * @type: offload type
132 * @state: enabled or disabled
133 *
134 * This Function send offloads enable/disable diag event
135 *
136 * Return: void.
137 */
138
139void hdd_wlan_offload_event(uint8_t type, uint8_t state)
140{
141 WLAN_VOS_DIAG_EVENT_DEF(host_offload,
142 struct vos_event_offload_req);
143 vos_mem_zero(&host_offload, sizeof(host_offload));
144
145 host_offload.offload_type = type;
146 host_offload.state = state;
147
148 WLAN_VOS_DIAG_EVENT_REPORT(&host_offload, EVENT_OFFLOAD_REQ);
149}
150#endif /* FEATURE_WLAN_DIAG_SUPPORT */
151
Jeff Johnson295189b2012-06-20 16:38:30 -0700152//Callback invoked by PMC to report status of standby request
153void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status)
154{
155 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status);
157 g_standby_status = status;
158
159 if(eHAL_STATUS_SUCCESS == status)
160 {
161 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
162 }
163 else
164 {
165 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
166 }
167
168 complete(&pHddCtx->standby_comp_var);
169}
170
171//Callback invoked by PMC to report status of full power request
172void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status)
173{
174 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status);
176 g_full_pwr_status = status;
177
178 if(eHAL_STATUS_SUCCESS == status)
179 {
180 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
181 }
182 else
183 {
184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
185 }
186
187 complete(&pHddCtx->full_pwr_comp_var);
188}
189
190eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx)
191{
192 eHalStatus status = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530193 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700194
195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__);
196 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
197
198 g_full_pwr_status = eHAL_STATUS_FAILURE;
199 status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx,
200 eSME_FULL_PWR_NEEDED_BY_HDD);
201
202 if(status == eHAL_STATUS_PMC_PENDING)
203 {
204 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530205 ret = wait_for_completion_interruptible_timeout(
206 &pHddCtx->full_pwr_comp_var,
207 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
208 if (0 >= ret)
209 {
210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
211 __func__, ret);
212 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700213 status = g_full_pwr_status;
214 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
215 {
216 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
217 VOS_ASSERT(0);
218 goto failure;
219 }
220 }
221 else if(status != eHAL_STATUS_SUCCESS)
222 {
223 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
224 __func__, status);
225 VOS_ASSERT(0);
226 goto failure;
227 }
228 else
229 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
230
231failure:
232 //No blocking to reduce latency. No other device should be depending on WLAN
233 //to finish resume and WLAN won't be instantly on after resume
234 return status;
235}
236
237
238//Helper routine to put the chip into standby
239VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx)
240{
241 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
242 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530243 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700244
245 //Disable IMPS/BMPS as we do not want the device to enter any power
246 //save mode on its own during suspend sequence
247 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
248 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
249
250 //Note we do not disable queues unnecessarily. Queues should already be disabled
251 //if STA is disconnected or the queue will be disabled as and when disconnect
252 //happens because of standby procedure.
253
254 //Ensure that device is in full power first. There is scope for optimization
255 //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS.
256 //Core s/w needs to be optimized to handle this. Until then we request full
257 //power before issuing request for standby.
258 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
259 g_full_pwr_status = eHAL_STATUS_FAILURE;
260 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
261 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
262
263 if(halStatus == eHAL_STATUS_PMC_PENDING)
264 {
265 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530266 ret = wait_for_completion_interruptible_timeout(
267 &pHddCtx->full_pwr_comp_var,
268 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
269 if (0 >= ret)
270 {
271 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld",
272 __func__, ret);
273 }
274
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 if(g_full_pwr_status != eHAL_STATUS_SUCCESS)
276 {
277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__);
278 VOS_ASSERT(0);
279 vosStatus = VOS_STATUS_E_FAILURE;
280 goto failure;
281 }
282 }
283 else if(halStatus != eHAL_STATUS_SUCCESS)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d",
286 __func__, halStatus);
287 VOS_ASSERT(0);
288 vosStatus = VOS_STATUS_E_FAILURE;
289 goto failure;
290 }
291
292 if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
293 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
294 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
295 }
296
297 //Request standby. Standby will cause the STA to disassociate first. TX queues
298 //will be disabled (by HDD) when STA disconnects. You do not want to disable TX
299 //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC
300 //will send this failure code in case of concurrent sessions. Power Save cannot be supported
301 //when there are concurrent sessions.
302 INIT_COMPLETION(pHddCtx->standby_comp_var);
303 g_standby_status = eHAL_STATUS_FAILURE;
304 halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx);
305
306 if (halStatus == eHAL_STATUS_PMC_PENDING)
307 {
308 //Wait till WLAN device enters standby mode
c_hpothuffdb5272013-10-02 16:42:35 +0530309 ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY));
c_hpothuffdb5272013-10-02 16:42:35 +0530311 if (0 >= ret)
312 {
313 hddLog(VOS_TRACE_LEVEL_ERROR,
314 FL("wait on standby_comp_var failed %ld"), ret);
315 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700316 if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW)
317 {
318 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__);
319 VOS_ASSERT(0);
320 vosStatus = VOS_STATUS_E_FAILURE;
321 goto failure;
322 }
323 }
324 else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) {
325 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d",
326 __func__, halStatus);
327 VOS_ASSERT(0);
328 vosStatus = VOS_STATUS_E_FAILURE;
329 goto failure;
330 }
331 else
332 pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY;
333
334failure:
335 //Restore IMPS config
336 if(pHddCtx->cfg_ini->fIsImpsEnabled)
337 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
338
339 //Restore BMPS config
340 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
341 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
342
343 return vosStatus;
344}
345
346
347//Helper routine for Deep sleep entry
348VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
349{
350 eHalStatus halStatus;
351 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
c_hpothuffdb5272013-10-02 16:42:35 +0530352 long ret;
Jeff Johnsonbc676b42013-02-14 16:04:08 -0800353
Jeff Johnson295189b2012-06-20 16:38:30 -0700354 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 netif_tx_disable(pAdapter->dev);
357 netif_carrier_off(pAdapter->dev);
358
359 //Disable IMPS,BMPS as we do not want the device to enter any power
360 //save mode on it own during suspend sequence
361 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
362 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
363
364 //Ensure that device is in full power as we will touch H/W during vos_Stop
365 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
366 g_full_pwr_status = eHAL_STATUS_FAILURE;
367 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback,
368 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
369
370 if(halStatus == eHAL_STATUS_PMC_PENDING)
371 {
372 //Block on a completion variable. Can't wait forever though
c_hpothuffdb5272013-10-02 16:42:35 +0530373 ret = wait_for_completion_interruptible_timeout(
374 &pHddCtx->full_pwr_comp_var,
375 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
376 if (0 >= ret)
377 {
378 hddLog(VOS_TRACE_LEVEL_ERROR,
379 FL("wait on full_pwr_comp_var failed %ld"), ret);
380 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 if(g_full_pwr_status != eHAL_STATUS_SUCCESS){
382 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__);
383 VOS_ASSERT(0);
384 }
385 }
386 else if(halStatus != eHAL_STATUS_SUCCESS)
387 {
388 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__);
389 VOS_ASSERT(0);
390 }
391
392 //Issue a disconnect. This is required to inform the supplicant that
393 //STA is getting disassociated and for GUI to be updated properly
394 INIT_COMPLETION(pAdapter->disconnect_comp_var);
395 halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
396
397 //Success implies disconnect command got queued up successfully
398 if(halStatus == eHAL_STATUS_SUCCESS)
399 {
400 //Block on a completion variable. Can't wait forever though.
c_hpothuffdb5272013-10-02 16:42:35 +0530401 ret = wait_for_completion_interruptible_timeout(
402 &pAdapter->disconnect_comp_var,
403 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
404 if (0 >= ret)
405 {
406 hddLog(VOS_TRACE_LEVEL_ERROR,
407 FL("wait on disconnect_comp_var failed %ld"), ret);
408 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700409 }
410
411
412 //None of the steps should fail after this. Continue even in case of failure
413 vosStatus = vos_stop( pHddCtx->pvosContext );
c_hpothuffdb5272013-10-02 16:42:35 +0530414 if( !VOS_IS_STATUS_SUCCESS( vosStatus ))
415 {
416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d",
417 __func__, vosStatus);
418 VOS_ASSERT(0);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +0530419 if (isSsrPanicOnFailure())
420 VOS_BUG(0);
c_hpothuffdb5272013-10-02 16:42:35 +0530421 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700422
Jeff Johnson295189b2012-06-20 16:38:30 -0700423 pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP;
424
425 //Restore IMPS config
426 if(pHddCtx->cfg_ini->fIsImpsEnabled)
427 sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
428
429 //Restore BMPS config
430 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
431 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
432
Jeff Johnson295189b2012-06-20 16:38:30 -0700433 return vosStatus;
434}
435
436VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter)
437{
438 VOS_STATUS vosStatus;
439 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700440
Jeff Johnson295189b2012-06-20 16:38:30 -0700441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
442 "%s: calling hdd_set_sme_config",__func__);
443 vosStatus = hdd_set_sme_config( pHddCtx );
444 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
445 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
446 {
447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
448 "%s: Failed in hdd_set_sme_config",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700449 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700450 }
451
452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
453 "%s: calling vos_start",__func__);
454 vosStatus = vos_start( pHddCtx->pvosContext );
455 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
456 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
457 {
458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
459 "%s: Failed in vos_start",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +0530460 if (isSsrPanicOnFailure())
461 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700462 goto err_deep_sleep;
Jeff Johnson295189b2012-06-20 16:38:30 -0700463 }
464
465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
466 "%s: calling hdd_post_voss_start_config",__func__);
467 vosStatus = hdd_post_voss_start_config( pHddCtx );
468 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
469 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
470 {
471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
472 "%s: Failed in hdd_post_voss_start_config",__func__);
473 goto err_voss_stop;
474 }
475
476
477 //Open a SME session for future operation
478 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -0700479 (tANI_U8 *)&pAdapter->macAddressCurrent,
480 &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700481 if ( !HAL_STATUS_SUCCESS( halStatus ) )
482 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700483 hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -0700484 halStatus, halStatus );
485 goto err_voss_stop;
486
487 }
488
489 pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE;
490
491 //Trigger the initial scan
Ravi Kumar Bokka585faca2017-03-01 16:18:41 +0530492 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700493
494 return VOS_STATUS_SUCCESS;
495
496err_voss_stop:
497 vos_stop(pHddCtx->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700498err_deep_sleep:
499 return VOS_STATUS_E_FAILURE;
500
501}
502
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530503void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
Atul Mittal37385d72014-03-27 18:15:03 +0530504{
505 hdd_adapter_t* pAdapter =
506 container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
507 hdd_context_t *pHddCtx;
508 int status;
509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530510 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530511 if (NULL == pAdapter)
512 {
513 hddLog(LOGE, FL("Adapter is invalid"));
514 return;
515 }
Atul Mittal37385d72014-03-27 18:15:03 +0530516
517 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
518 status = wlan_hdd_validate_context(pHddCtx);
519 if (0 != status)
520 {
Atul Mittal37385d72014-03-27 18:15:03 +0530521 return;
522 }
523
Atul Mittal37385d72014-03-27 18:15:03 +0530524 if ((eConnectionState_Associated ==
525 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
526 && (pHddCtx->hdd_wlan_suspended))
527 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530528 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Atul Mittal37385d72014-03-27 18:15:03 +0530529 // This invocation being part of the IPv6 registration callback,
530 // set the newly generated ip address to f/w in suspend mode.
531#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530532 if (pHddCtx->cfg_ini->fhostNSOffload)
533 {
534 hdd_conf_ns_offload(pAdapter, 1);
535 }
Atul Mittal37385d72014-03-27 18:15:03 +0530536#endif
537 }
538#ifdef WLAN_FEATURE_PACKET_FILTERING
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530539 /* wlan_hdd_set_mc_addr_list() is called from the early suspend
Atul Mittal37385d72014-03-27 18:15:03 +0530540 * only so when new ipv6 address is generated the screen may not
541 * on so we need to call it here to update the list in f/w.
542 */
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530543 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Atul Mittal37385d72014-03-27 18:15:03 +0530544#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530545 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530546}
547
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530548void hdd_ipv6_notifier_work_queue(struct work_struct *work)
549{
550 vos_ssr_protect(__func__);
551 __hdd_ipv6_notifier_work_queue(work);
552 vos_ssr_unprotect(__func__);
553}
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530554int __wlan_hdd_ipv6_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530555 unsigned long data, void *arg)
Atul Mittal37385d72014-03-27 18:15:03 +0530556{
557 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
558 struct net_device *ndev = ifa->idev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530559 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Atul Mittal37385d72014-03-27 18:15:03 +0530560 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530561 VOS_STATUS vos_status;
Atul Mittal37385d72014-03-27 18:15:03 +0530562 int status;
563
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530564 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530565 pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier);
566 status = wlan_hdd_validate_context(pHddCtx);
567 if (0 != status)
Atul Mittal37385d72014-03-27 18:15:03 +0530568 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530569 return NOTIFY_DONE;
570 }
Atul Mittal37385d72014-03-27 18:15:03 +0530571
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530572 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
573 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
574 {
575 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
576 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
577 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
578 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +0530579
580 if (eConnectionState_Associated ==
581 WLAN_HDD_GET_STATION_CTX_PTR
582 (pAdapterNode->pAdapter)->conn_info.connState)
583 sme_dhcp_done_ind(pHddCtx->hHal,
584 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530585 if (pHddCtx->cfg_ini->nEnableSuspend ==
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +0530586 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +0530587 {
588 schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue);
589 }
590 else
591 {
592 hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"),
593 pHddCtx->cfg_ini->nEnableSuspend);
594 }
595 break;
596 }
597 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
598 pAdapterNode = pNext;
Atul Mittal37385d72014-03-27 18:15:03 +0530599 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530600 EXIT();
Atul Mittal37385d72014-03-27 18:15:03 +0530601 return NOTIFY_DONE;
602}
603
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530604int wlan_hdd_ipv6_changed(struct notifier_block *nb,
605 unsigned long data, void *arg)
606{
607 int ret;
608 vos_ssr_protect(__func__);
609 ret = __wlan_hdd_ipv6_changed( nb, data, arg);
610 vos_ssr_unprotect(__func__);
611 return ret;
612}
613
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530614/*
615 * Function: hdd_conf_hostoffload
616 * Central function to configure the supported offloads,
617 * either enable or disable them.
618 */
619void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
620{
621 hdd_context_t *pHddCtx = NULL;
622 v_CONTEXT_t *pVosContext = NULL;
623 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
624
625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"),
626 fenable);
627
628 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
629
630 if (NULL == pVosContext)
631 {
632 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null"));
633 return;
634 }
635
636 //Get the HDD context.
637 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
638
639 if (NULL == pHddCtx)
640 {
641 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__);
642 return;
643 }
644
645 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Arun Khandavalli08bcafd2016-11-08 14:45:48 +0530646 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
647 ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
648 (pHddCtx->is_ap_mode_wow_supported)))
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530649 {
650 if (fenable)
651 {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +0530652 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
653 (eConnectionState_Associated ==
654 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
655 || (WLAN_HDD_SOFTAP == pAdapter->device_mode))
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530656 {
657 if ((pHddCtx->cfg_ini->fhostArpOffload))
658 {
659 /*
660 * Configure the ARP Offload.
661 * Even if it fails we have to reconfigure the MC/BC
662 * filter flag as we want RIVA not to drop BroadCast
663 * Packets
664 */
665 hddLog(VOS_TRACE_LEVEL_INFO,
666 FL("Calling ARP Offload with flag: %d"), fenable);
667 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
668 pHddCtx->configuredMcastBcastFilter &=
669 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
670
671 if (!VOS_IS_STATUS_SUCCESS(vstatus))
672 {
Anurag Chouhan8a5f8902016-09-28 18:54:47 +0530673 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530674 "Failed to enable ARPOFfloadFeature %d",
675 vstatus);
676 }
677 }
678 //Configure GTK_OFFLOAD
679#ifdef WLAN_FEATURE_GTK_OFFLOAD
680 hdd_conf_gtk_offload(pAdapter, fenable);
681#endif
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530682
683#ifdef WLAN_NS_OFFLOAD
684 if (pHddCtx->cfg_ini->fhostNSOffload)
685 {
686 /*
687 * Configure the NS Offload.
688 * Even if it fails we have to reconfigure the MC/BC filter flag
689 * as we want RIVA not to drop Multicast Packets
690 */
691
692 hddLog(VOS_TRACE_LEVEL_INFO,
693 FL("Calling NS Offload with flag: %d"), fenable);
694 hdd_conf_ns_offload(pAdapter, fenable);
695 pHddCtx->configuredMcastBcastFilter &=
696 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
697 }
698#endif
Atul Mittal37385d72014-03-27 18:15:03 +0530699
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530700 }
701 }
702 else
703 {
704 //Disable ARPOFFLOAD
705 if (pHddCtx->cfg_ini->fhostArpOffload)
706 {
707 vstatus = hdd_conf_arp_offload(pAdapter, fenable);
708 if (!VOS_IS_STATUS_SUCCESS(vstatus))
709 {
710 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530711 "Failed to disable ARPOffload Feature %d", vstatus);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530712 }
713 }
714 //Disable GTK_OFFLOAD
715#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530716 hdd_conf_gtk_offload(pAdapter, fenable);
717#endif
718
719#ifdef WLAN_NS_OFFLOAD
720 //Disable NSOFFLOAD
721 if (pHddCtx->cfg_ini->fhostNSOffload)
722 {
723 hdd_conf_ns_offload(pAdapter, fenable);
724 }
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530725 else
726 {
727 hddLog(VOS_TRACE_LEVEL_INFO,
728 FL("ns offload ini is disabled"));
729 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +0530730#endif
731 }
732 }
733 return;
734}
735
Atul Mittal37385d72014-03-27 18:15:03 +0530736
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530737#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +0530738/**----------------------------------------------------------------------------
739
740 \brief hdd_conf_ns_offload() - Configure NS offload
741
742 Called during SUSPEND to configure the NS offload (MC BC filter) which
743 reduces power consumption.
744
745 \param - pAdapter - Adapter context for which NS offload is to be configured
746 \param - fenable - 0 - disable.
747 1 - enable. (with IPv6 notifier registration)
748 2 - enable. (without IPv6 notifier registration)
749
750 \return - void
751
752 ---------------------------------------------------------------------------*/
753void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530754{
755 struct inet6_dev *in6_dev;
756 struct inet6_ifaddr *ifp;
757 struct list_head *p;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530758 int slot_index = NS_DEFAULT_SLOT_INDEX;
Girish Gowli1b6114f2014-05-17 17:17:09 +0530759 tANI_U8 **selfIPv6Addr = NULL;
760 tANI_U8 *selfIPv6AddrValid = NULL;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530761 tSirHostOffloadReq offLoadRequest;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530762 hdd_context_t *pHddCtx;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530763 tHalHandle halHandle;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530764
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530765 int i = 0, slot = 0;
766 int ret = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530767 eHalStatus returnStatus;
768
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +0530769 ENTER();
770 hddLog(LOG1, FL(" fenable = %d"), fenable);
771
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530772 if (NULL == pAdapter)
773 {
774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null"));
775 return;
776 }
777
778 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530779 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
780
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530781 ret = wlan_hdd_validate_context(pHddCtx);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530782 if (0 != ret)
783 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530784 return;
785 }
786
787 if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT))
788 {
789 slot_index = NS_EXTENDED_SLOT_INDEX;
790 }
791
792 hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index);
793
794 selfIPv6AddrValid =
795 (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index);
796
797 if (NULL == selfIPv6AddrValid)
798 {
799 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
800 " selfIPv6AddrValid"));
801 goto end;
802 }
803
804 vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8));
805
806 selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index);
807
808 if (NULL == selfIPv6Addr)
809 {
810 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for"
811 " selfIPv6Addr"));
812 goto end;
813 }
814
815 vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *));
816
817 for (slot = 0; slot < slot_index; slot++)
818 {
819 selfIPv6Addr[slot] =
820 (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN);
821 if (NULL == selfIPv6Addr[slot])
822 {
823 hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory"
824 "for selfIPv6Addr"));
825 goto end;
826 }
827 vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN);
828 }
829
830 i = 0;
831
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530832 if (fenable)
833 {
834 in6_dev = __in6_dev_get(pAdapter->dev);
835 if (NULL != in6_dev)
836 {
Srinivas Girigowdad26a8072016-10-19 20:26:42 +0530837 read_lock_bh(&in6_dev->lock);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530838 list_for_each(p, &in6_dev->addr_list)
839 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530840 if (i >= slot_index)
841 {
842 hddLog (VOS_TRACE_LEVEL_ERROR,
843 FL("IPv6 address list is greater than IPv6"
844 "address supported by firmware"));
845 hddLog (VOS_TRACE_LEVEL_ERROR,
846 FL("FW supported IPv6 address = %d"), slot_index);
847 break;
848 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530849 ifp = list_entry(p, struct inet6_ifaddr, if_list);
850 switch(ipv6_addr_src_scope(&ifp->addr))
851 {
852 case IPV6_ADDR_SCOPE_LINKLOCAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530853 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530854 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530855 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530856 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530857 FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"),
858 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530859 break;
860 case IPV6_ADDR_SCOPE_GLOBAL:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530861 vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530862 sizeof(ifp->addr.s6_addr));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530863 selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID;
Hardik Kantilal Patel1341bdf2013-08-22 20:27:15 +0530864 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530865 FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"),
866 selfIPv6Addr[i]);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530867 break;
868 default:
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530869 hddLog(VOS_TRACE_LEVEL_ERROR,
870 FL("The Scope %d is not supported"),
871 ipv6_addr_src_scope(&ifp->addr));
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530872 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530873 if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID)
874 {
875 i++;
876 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530877 }
Mukul Sharma115869a2017-06-29 17:38:57 +0530878 /* store actual slots being used */
879 pAdapter->ns_slots = i;
Srinivas Girigowdad26a8072016-10-19 20:26:42 +0530880 read_unlock_bh(&in6_dev->lock);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530881
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530882 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530883 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530884 {
885 if (selfIPv6AddrValid[i])
886 {
887 //Filling up the request structure
888 /* Filling the selfIPv6Addr with solicited address
889 * A Solicited-Node multicast address is created by
890 * taking the last 24 bits of a unicast or anycast
891 * address and appending them to the prefix
892 *
893 * FF02:0000:0000:0000:0000:0001:FFXX:XX
894 *
895 * here XX is the unicast/anycast bits
896 */
897 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
898 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
899 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
900 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530901 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
902 selfIPv6Addr[i][13];
903 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
904 selfIPv6Addr[i][14];
905 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
906 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530907 offLoadRequest.nsOffloadInfo.slotIdx = i;
908
909 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530910 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530911 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
912 &pAdapter->macAddressCurrent.bytes,
913 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
914
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530915 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
916 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530917 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
918 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +0530919 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
920 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530921
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530922 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530923 FL("configuredMcastBcastFilter: %d"
924 "NSOffload Slot = %d"),
925 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530926
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530927 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700928 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
929 pHddCtx->sus_res_mcastbcast_filter) ||
930 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
931 pHddCtx->sus_res_mcastbcast_filter)) &&
932 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
933 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
934 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530935 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530936 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700937 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530938 }
Abhishek Singh937ec542016-01-05 18:03:14 +0530939 hdd_wlan_offload_event(
940 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE,
941 SIR_OFFLOAD_ENABLE);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530942 hddLog(VOS_TRACE_LEVEL_INFO,
943 FL("offload: NS filter programmed %d"),
944 offLoadRequest.enableOrDisable);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530945 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
946 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
947 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
948
949 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530950 FL("Setting NSOffload with solicitedIp: %pI6,"
951 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530952 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
953 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
954
955 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530956 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530957 pAdapter->sessionId, &offLoadRequest);
958 if(eHAL_STATUS_SUCCESS != returnStatus)
959 {
960 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530961 FL("Failed to enable HostOffload feature with"
962 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530963 }
964 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
965 }
966 }
967 }
968 else
969 {
970 hddLog(VOS_TRACE_LEVEL_ERROR,
971 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530972 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530973 }
974 }
975 else
976 {
977 //Disable NSOffload
978 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
979 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
980 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +0530981 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
982 SIR_OFFLOAD_DISABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530983
Mukul Sharma115869a2017-06-29 17:38:57 +0530984 for (i = 0; i < pAdapter->ns_slots; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530985 {
c_hpothu86feba52014-10-28 15:51:18 +0530986 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530987 offLoadRequest.nsOffloadInfo.slotIdx = i;
988 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530989 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
990 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530991 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
993 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530994 }
995 }
Mukul Sharma115869a2017-06-29 17:38:57 +0530996 pAdapter->ns_slots = 0;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530997 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530998end:
999 while (slot > 0 && selfIPv6Addr[--slot])
1000 {
1001 vos_mem_free(selfIPv6Addr[slot]);
1002 }
1003 if (selfIPv6Addr)
1004 {
1005 vos_mem_free(selfIPv6Addr);
1006 }
1007 if (selfIPv6AddrValid)
1008 {
1009 vos_mem_free(selfIPv6AddrValid);
1010 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301011 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301012 return;
1013}
1014#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301015
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301016void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301017{
1018 hdd_adapter_t* pAdapter =
1019 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
1020 hdd_context_t *pHddCtx;
1021 int status;
1022
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301023 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301024 if (NULL == pAdapter)
1025 {
1026 hddLog(LOGE, FL("Adapter is invalid"));
1027 return;
1028 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301029 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1030 status = wlan_hdd_validate_context(pHddCtx);
1031 if (0 != status)
1032 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301033 return;
1034 }
1035
1036 if ((eConnectionState_Associated ==
1037 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +05301038 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301039 {
1040 // This invocation being part of the IPv4 registration callback,
1041 // we are passing second parameter as 2 to avoid registration
1042 // of IPv4 notifier again.
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301043 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1044 if (pHddCtx->cfg_ini->fhostArpOffload)
1045 {
1046 hdd_conf_arp_offload(pAdapter, 2);
1047 }
1048 else
1049 {
1050 hddLog(VOS_TRACE_LEVEL_INFO,
1051 FL("offload: arp offload ini is disabled in host"));
1052 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301053 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301054 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301055}
1056
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301057void hdd_ipv4_notifier_work_queue(struct work_struct *work)
1058{
1059 vos_ssr_protect(__func__);
1060 __hdd_ipv4_notifier_work_queue(work);
1061 vos_ssr_unprotect(__func__);
1062}
1063
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301064int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301065 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301066{
1067 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1068 struct in_ifaddr **ifap = NULL;
1069 struct in_device *in_dev;
1070
1071 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301072 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301073 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301074 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301075 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301076
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301077 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301078 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1079 status = wlan_hdd_validate_context(pHddCtx);
1080 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301081 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301082 return NOTIFY_DONE;
1083 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301084
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301085 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1086 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1087 {
1088 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1089 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1090 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1091 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +05301092
1093 if (eConnectionState_Associated ==
1094 WLAN_HDD_GET_STATION_CTX_PTR
1095 (pAdapterNode->pAdapter)->conn_info.connState)
1096 sme_dhcp_done_ind(pHddCtx->hHal,
1097 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301098 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301099 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301100 || (!pHddCtx->cfg_ini->fhostArpOffload))
1101 {
1102 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1103 pHddCtx->cfg_ini->nEnableSuspend,
1104 pHddCtx->cfg_ini->fhostArpOffload);
1105 return NOTIFY_DONE;
1106 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301107
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301108 if ((in_dev =
1109 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1110 {
1111 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1112 ifap = &ifa->ifa_next)
1113 {
1114 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1115 ifa->ifa_label))
1116 {
1117 break; /* found */
1118 }
1119 }
1120 }
1121 if(ifa && ifa->ifa_local)
1122 {
1123 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1124 }
1125 break;
1126 }
1127 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1128 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301129 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301130 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301131 return NOTIFY_DONE;
1132}
1133
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301134int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1135 unsigned long data, void *arg)
1136{
1137 int ret;
1138 vos_ssr_protect(__func__);
1139 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1140 vos_ssr_unprotect(__func__);
1141 return ret;
1142}
1143
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301144/**----------------------------------------------------------------------------
1145
1146 \brief hdd_conf_arp_offload() - Configure ARP offload
1147
1148 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1149 reduces power consumption.
1150
1151 \param - pAdapter -Adapter context for which ARP offload is to be configured
1152 \param - fenable - 0 - disable.
1153 1 - enable. (with IPv4 notifier registration)
1154 2 - enable. (without IPv4 notifier registration)
1155
1156 \return -
1157 VOS_STATUS_SUCCESS - on successful operation
1158 VOS_STATUS_E_FAILURE - on failure of operation
1159-----------------------------------------------------------------------------*/
1160VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001161{
1162 struct in_ifaddr **ifap = NULL;
1163 struct in_ifaddr *ifa = NULL;
1164 struct in_device *in_dev;
1165 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001167 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001168
Sushant Kaushik87787972015-09-11 16:05:00 +05301169 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001170
Jeff Johnson295189b2012-06-20 16:38:30 -07001171 if(fenable)
1172 {
1173 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1174 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301175 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001176 ifap = &ifa->ifa_next)
1177 {
1178 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1179 {
1180 break; /* found */
1181 }
1182 }
1183 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001184 if(ifa && ifa->ifa_local)
1185 {
1186 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1187 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +05301188 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1189 SIR_OFFLOAD_ENABLE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001190
Arif Hussain6d2a3322013-11-17 19:50:10 -08001191 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001192
Amar Singhald53568e2013-09-26 11:03:45 -07001193 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1194 pHddCtx->sus_res_mcastbcast_filter) ||
1195 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1196 pHddCtx->sus_res_mcastbcast_filter)) &&
1197 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001198 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301199 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001200 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1201 hddLog(VOS_TRACE_LEVEL_INFO,
1202 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 }
Abhishek Singh937ec542016-01-05 18:03:14 +05301204 hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
1205 SIR_OFFLOAD_ENABLE);
Amar Singhald53568e2013-09-26 11:03:45 -07001206
1207 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1208 offLoadRequest.enableOrDisable);
1209
Jeff Johnson295189b2012-06-20 16:38:30 -07001210 //converting u32 to IPV4 address
1211 for(i = 0 ; i < 4; i++)
1212 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301213 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001214 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1215 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301216 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 offLoadRequest.params.hostIpv4Addr[0],
1218 offLoadRequest.params.hostIpv4Addr[1],
1219 offLoadRequest.params.hostIpv4Addr[2],
1220 offLoadRequest.params.hostIpv4Addr[3]);
1221
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301222 if (eHAL_STATUS_SUCCESS !=
1223 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1224 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 {
1226 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001227 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001228 return VOS_STATUS_E_FAILURE;
1229 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001230 }
1231 else
1232 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301233 hddLog(VOS_TRACE_LEVEL_WARN, FL("IP Address is not assigned"));
Agarwal Ashish971c2882013-10-30 20:11:12 +05301234 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001235 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301236
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301237 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001238 }
1239 else
1240 {
1241 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1242 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1243 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +05301244 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1245 SIR_OFFLOAD_DISABLE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301246 if (eHAL_STATUS_SUCCESS !=
1247 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1248 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001249 {
1250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001251 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001252 return VOS_STATUS_E_FAILURE;
1253 }
1254 return VOS_STATUS_SUCCESS;
1255 }
1256}
1257
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301258/*
1259 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301260 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301261*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301262void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301263 tANI_U8 *pMcBcFilter)
1264{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301265 if (NULL == pHddCtx)
1266 {
1267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1268 return;
1269 }
1270
1271 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1272 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301273 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301274 /* ARP offload is enabled, do not block bcast packets at RXP
1275 * Will be using Bitmasking to reset the filter. As we have
1276 * disable Broadcast filtering, Anding with the negation
1277 * of Broadcast BIT
1278 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301279 hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301280 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301281 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301282
1283#ifdef WLAN_NS_OFFLOAD
1284 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301285 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301286 /* NS offload is enabled, do not block mcast packets at RXP
1287 * Will be using Bitmasking to reset the filter. As we have
1288 * disable Multicast filtering, Anding with the negation
1289 * of Multicast BIT
1290 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301291 hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301292 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301293 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301294#endif
1295
Amar Singhald08ce752014-03-21 16:28:27 -07001296 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1297 {
1298 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1299 }
1300
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301301 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301302}
1303
Jeff Johnson295189b2012-06-20 16:38:30 -07001304void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1305{
1306 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001307 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1308 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
Agarwal Ashishff451a32015-07-28 01:01:29 +05301309 if (NULL == wlanRxpFilterParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001310 {
1311 hddLog(VOS_TRACE_LEVEL_FATAL,
1312 "%s: vos_mem_alloc failed ", __func__);
1313 return;
1314 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001315 hddLog(VOS_TRACE_LEVEL_INFO,
1316 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301317 if (TRUE == setfilter)
1318 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301319 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301320 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301321 }
1322 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301323 {
1324 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301325 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301326 pHddCtx->configuredMcastBcastFilter;
1327 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301328
Jeff Johnson295189b2012-06-20 16:38:30 -07001329 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301331
1332 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
Agarwal Ashishff451a32015-07-28 01:01:29 +05301333 {
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301334 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Agarwal Ashishff451a32015-07-28 01:01:29 +05301335 }
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301336
1337 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1338 "lower mac with status %d"
1339 "configuredMcstBcstFilterSetting = %d"
1340 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1341 "Failed" : "Success", halStatus,
1342 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1343 wlanRxpFilterParam->setMcstBcstFilter);
1344
Chilam Ngc4244af2013-04-01 15:37:32 -07001345 if (eHAL_STATUS_SUCCESS != halStatus)
1346 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001347}
1348
mukul sharmae4abd892016-11-24 22:03:31 +05301349/*
1350 * Enable/Disable McAddrList cfg item in fwr.
1351 */
1352eHalStatus hdd_set_mc_list_cfg_item(hdd_context_t* pHddCtx,
1353 bool value)
1354{
1355 eHalStatus ret_val;
1356
1357 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST,
1358 value, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1359 {
1360 ret_val = eHAL_STATUS_FAILURE;
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301361 hddLog(LOGE,
1362 FL("offload: can't pass WNI_CFG_ENABLE_MC_ADDR_LIST to CCM"));
mukul sharmae4abd892016-11-24 22:03:31 +05301363 return ret_val;
1364 }
1365
1366 ret_val = sme_update_cfg_int_param(pHddCtx->hHal,
1367 WNI_CFG_ENABLE_MC_ADDR_LIST);
1368 if (!HAL_STATUS_SUCCESS(ret_val))
1369 {
1370 hddLog(VOS_TRACE_LEVEL_ERROR,
1371 FL("Failed to toggle MC_ADDR_LIST_INI %d "),
1372 ret_val);
1373 return ret_val;
1374 }
1375 /* cache the value configured in fwr */
1376 pHddCtx->mc_list_cfg_in_fwr = value;
mukul sharmae4abd892016-11-24 22:03:31 +05301377 return eHAL_STATUS_SUCCESS;
1378}
1379
1380bool is_mc_list_cfg_disable_required(hdd_context_t* pHddCtx)
1381{
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301382 hddLog(VOS_TRACE_LEVEL_INFO,
1383 FL("offload: fEnableMCList %d sus_res_mcbc_filter %d mc_list_in_fwr %d"),
1384 pHddCtx->cfg_ini->fEnableMCAddrList,
1385 pHddCtx->sus_res_mcastbcast_filter,
1386 pHddCtx->mc_list_cfg_in_fwr);
1387
mukul sharmae4abd892016-11-24 22:03:31 +05301388 /*
1389 * If MCAddrList is enabled in ini and MCBC filter is set to
1390 * Either Filter None or Filter all BC then, Fwr need to push
1391 * all MC to host. This can be achieved by disabling cfg MCAddrList
1392 * in fwr. As in driver load, firmware have this value to 1 we
1393 * need to set it to 0. Same needs to be reverted on resume.
1394 */
1395 if (pHddCtx->cfg_ini->fEnableMCAddrList &&
1396 WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
1397 ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)&&
1398 ((HDD_MCASTBCASTFILTER_FILTER_NONE ==
1399 pHddCtx->sus_res_mcastbcast_filter) ||
1400 (HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1401 pHddCtx->sus_res_mcastbcast_filter)))
1402 )
1403 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301404 hddLog(VOS_TRACE_LEVEL_INFO,
1405 FL("offload: cfg ini need to disable in fwr"));
mukul sharmae4abd892016-11-24 22:03:31 +05301406 return true;
1407 }
1408 else
1409 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301410 hddLog(VOS_TRACE_LEVEL_INFO,
1411 FL("offload: cfg ini disable not needed "));
mukul sharmae4abd892016-11-24 22:03:31 +05301412 return false;
1413 }
1414}
1415
1416/**
1417 * hdd_mc_addr_list_cfg_config() - To set mc list cfg configuration in fwr
1418 * @pHddCtx: hdd context handle
1419 * @action: true to disable MCAddrList in fwr to get all MC pkt to host
1420 * false to set ini value of MCAddrList in fwr if it was toggled
1421 * Return: none
1422 *
1423 * Ensure Below API is invoked always post modification
1424 * of sus_res_mcastbcast_filter.
1425 */
1426void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action)
1427{
1428 if (action)
1429 {
1430 /* check host need to disable mc list ini in fwr */
1431 if (is_mc_list_cfg_disable_required(pHddCtx))
1432 {
1433 /*
1434 * Yes Host should disable the mc list in fwr
1435 * But Ensure host might already disable it
1436 * This can happen when user issue set/clear MCBC
1437 * ioctl with 2 to 0 or vice versa.
1438 */
1439 if (pHddCtx->cfg_ini->fEnableMCAddrList ==
1440 pHddCtx->mc_list_cfg_in_fwr)
1441 {
1442 hdd_set_mc_list_cfg_item(pHddCtx,
1443 !pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301444 hddLog(VOS_TRACE_LEVEL_INFO,
1445 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1446 !pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301447 }
1448 }
1449 else
1450 {
1451 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1452 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1453 pHddCtx->mc_list_cfg_in_fwr)
1454 {
1455 hdd_set_mc_list_cfg_item(pHddCtx,
1456 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301457 hddLog(VOS_TRACE_LEVEL_INFO,
1458 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1459 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301460 }
1461 }
1462 }
1463 else
1464 {
1465 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1466 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1467 pHddCtx->mc_list_cfg_in_fwr)
1468 {
1469 hdd_set_mc_list_cfg_item(pHddCtx,
1470 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301471 hddLog(VOS_TRACE_LEVEL_INFO,
1472 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1473 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301474 }
1475 }
1476}
1477
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301478/**
1479 * hdd_suspend_ind_callback: This API will set completion event for suspend
1480 * @pAdapter: hdd_adapter_t
1481 * @status: suspend status
1482 *
1483 * Return: none
1484 */
1485static void hdd_suspend_ind_callback(void *context, VOS_STATUS status)
1486{
1487 hdd_adapter_t *adapter = (hdd_adapter_t *)context;
1488 if (NULL == adapter)
1489 {
1490 hddLog(VOS_TRACE_LEVEL_ERROR,
1491 "%s: HDD adapter is NULL",__func__);
1492 return;
1493 }
1494 hddLog(VOS_TRACE_LEVEL_INFO, FL("suspend status %d"), status);
1495 complete(&adapter->wlan_suspend_comp_var);
1496}
1497
Jeff Johnson295189b2012-06-20 16:38:30 -07001498static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1499 hdd_adapter_t *pAdapter)
1500{
1501 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1502 tpSirWlanSuspendParam wlanSuspendParam =
1503 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1504
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301505 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001506 if(NULL == wlanSuspendParam)
1507 {
1508 hddLog(VOS_TRACE_LEVEL_FATAL,
1509 "%s: vos_mem_alloc failed ", __func__);
1510 return;
1511 }
1512
Amar Singhald53568e2013-09-26 11:03:45 -07001513 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001514 "%s: send wlan suspend indication", __func__);
1515
1516 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1517 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301518 //Configure supported OffLoads
1519 hdd_conf_hostoffload(pAdapter, TRUE);
1520 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301521 hddLog(VOS_TRACE_LEVEL_INFO,
1522 FL("saving configuredMcastBcastFilterSetting = %d"),
1523 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001524#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301525 /* During suspend, configure MC Addr list filter to the firmware
1526 * function takes care of checking necessary conditions before
1527 * configuring.
1528 */
1529 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001530#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001531
1532 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1533 {
1534
1535 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1536 pHddCtx->configuredMcastBcastFilter &=
1537 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1538 }
1539
1540 wlanSuspendParam->configuredMcstBcstFilterSetting =
1541 pHddCtx->configuredMcastBcastFilter;
mukul sharmae4abd892016-11-24 22:03:31 +05301542
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301543 wlanSuspendParam->wlan_sus_callback = hdd_suspend_ind_callback;
1544 wlanSuspendParam->context = pAdapter;
mukul sharmae4abd892016-11-24 22:03:31 +05301545 /* mc add list cfg item configuration in fwr */
1546 hdd_mc_addr_list_cfg_config(pHddCtx, true);
1547
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 }
1549
1550 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1551 if(eHAL_STATUS_SUCCESS == halStatus)
1552 {
1553 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001554 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301555 hddLog(VOS_TRACE_LEVEL_ERROR,
1556 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001557 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001558 }
1559}
1560
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301561static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001562{
Chilam Ngc4244af2013-04-01 15:37:32 -07001563 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001564 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001565 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001566
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301567 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001568 "%s: send wlan resume indication", __func__);
1569
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301570 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1571
1572 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001573 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301574 hddLog(VOS_TRACE_LEVEL_FATAL,
1575 "%s: memory allocation failed for wlanResumeParam ", __func__);
1576 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001578
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301579 //Disable supported OffLoads
1580 hdd_conf_hostoffload(pAdapter, FALSE);
1581
1582 wlanResumeParam->configuredMcstBcstFilterSetting =
1583 pHddCtx->configuredMcastBcastFilter;
1584 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1585 if (eHAL_STATUS_SUCCESS != halStatus)
1586 {
c_hpothuffdb5272013-10-02 16:42:35 +05301587 hddLog(VOS_TRACE_LEVEL_ERROR,
1588 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301589 vos_mem_free(wlanResumeParam);
1590 }
1591
1592 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
mukul sharmae4abd892016-11-24 22:03:31 +05301593 /* mc add list cfg item configuration in fwr */
1594 hdd_mc_addr_list_cfg_config(pHddCtx, false);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301595
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001596 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1597 pHddCtx->configuredMcastBcastFilter =
1598 pHddCtx->sus_res_mcastbcast_filter;
1599 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1600 }
Amar Singhald53568e2013-09-26 11:03:45 -07001601
1602 hddLog(VOS_TRACE_LEVEL_INFO,
1603 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1604 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1605 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001606
Chilam Ngc4244af2013-04-01 15:37:32 -07001607
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301608#ifdef WLAN_FEATURE_PACKET_FILTERING
1609 /* Filer was applied during suspend inditication
1610 * clear it when we resume.
1611 */
1612 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001613#endif
1614}
Jeff Johnson295189b2012-06-20 16:38:30 -07001615
Jeff Johnson295189b2012-06-20 16:38:30 -07001616//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001617void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001618{
1619 hdd_context_t *pHddCtx = NULL;
1620 v_CONTEXT_t pVosContext = NULL;
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301621 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001622 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301623 hdd_adapter_t *pAdapter = NULL;
1624 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301625 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001626
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1628
1629 //Get the global VOSS context.
1630 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1631 if(!pVosContext) {
1632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1633 return;
1634 }
1635
1636 //Get the HDD context.
1637 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1638
1639 if(!pHddCtx) {
1640 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1641 return;
1642 }
1643
1644 if (pHddCtx->isLogpInProgress) {
1645 hddLog(VOS_TRACE_LEVEL_ERROR,
1646 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1647 return;
1648 }
1649
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301650 if (pHddCtx->hdd_wlan_suspended)
1651 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301652 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301653 "%s: Ignore suspend wlan, Already suspended!", __func__);
1654 return;
1655 }
1656
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301657 pHddCtx->hdd_wlan_suspended = TRUE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301658 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301659 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001660 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1661 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1662 {
1663 pAdapter = pAdapterNode->pAdapter;
1664 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001665 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001666 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1667
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001668 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1670 pAdapterNode = pNext;
1671 continue;
1672 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301673 /* Avoid multiple enter/exit BMPS in this while loop using
1674 * hdd_enter_bmps flag
1675 */
1676 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1677 {
1678 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001679
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301680 /* If device was already in BMPS, and dynamic DTIM is set,
1681 * exit(set the device to full power) and enter BMPS again
1682 * to reflect new DTIM value */
1683 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1684
1685 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1686
1687 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1688 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001689#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1690 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1691 {
1692 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301693 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001694 netif_tx_disable(pAdapter->dev);
1695 netif_carrier_off(pAdapter->dev);
1696 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301697 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1699 {
1700 //Execute deep sleep procedure
1701 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1702 }
1703#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301704
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301705 INIT_COMPLETION(pAdapter->wlan_suspend_comp_var);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301706 /*Suspend notification sent down to driver*/
1707 hdd_conf_suspend_ind(pHddCtx, pAdapter);
Kapil Gupta2b44acb2016-12-30 16:49:51 +05301708 ret = wait_for_completion_interruptible_timeout(
1709 &pAdapter->wlan_suspend_comp_var,
1710 msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR));
1711 if (0 >= ret)
1712 {
1713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on suspend failed %ld",
1714 __func__, ret);
1715 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301716 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1717 pAdapterNode = pNext;
1718 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301719
Jeff Johnson295189b2012-06-20 16:38:30 -07001720#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1721 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1722 {
1723 hdd_enter_standby(pHddCtx);
1724 }
1725#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001726
1727 return;
1728}
1729
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301730/**
1731 * @brief hdd_ReConfigSuspendDataClearedDuringRoaming() - Reconfigure the
1732 * suspend related data which was cleared during roaming in FWR.
1733 */
1734void hdd_ReConfigSuspendDataClearedDuringRoaming(hdd_context_t *pHddCtx)
1735
1736{
1737 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
1738 hdd_adapter_t *pAdapter;
1739 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1740
1741 ENTER();
1742
1743 spin_lock(&pHddCtx->filter_lock);
1744 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1745 spin_unlock(&pHddCtx->filter_lock);
1746
1747 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
1748 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Not able to set mcast/bcast filter "));
1750
1751 vstatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1752 //No need to configure GTK Offload from here because it might possible
1753 //cfg80211_set_rekey_data might not yet came, anyway GTK offload will
1754 //be handled as part of cfg80211_set_rekey_data processing.
1755 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vstatus )
1756 {
1757 pAdapter = pAdapterNode->pAdapter;
1758 if( pAdapter &&
1759 (( pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
1760 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)))
1761 {
1762 if (pHddCtx->cfg_ini->fhostArpOffload)
1763 {
1764 //Configure ARPOFFLOAD
1765 vstatus = hdd_conf_arp_offload(pAdapter, TRUE);
1766 if (!VOS_IS_STATUS_SUCCESS(vstatus))
1767 {
1768 hddLog(VOS_TRACE_LEVEL_INFO,
1769 FL("Failed to disable ARPOffload Feature %d"), vstatus);
1770 }
1771 }
1772#ifdef WLAN_NS_OFFLOAD
1773 //Configure NSOFFLOAD
1774 if (pHddCtx->cfg_ini->fhostNSOffload)
1775 {
1776 hdd_conf_ns_offload(pAdapter, TRUE);
1777 }
1778#endif
1779#ifdef WLAN_FEATURE_PACKET_FILTERING
1780 /* During suspend, configure MC Addr list filter to the firmware
1781 * function takes care of checking necessary conditions before
1782 * configuring.
1783 */
1784 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
1785#endif
1786 }
1787 vstatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1788 pAdapterNode = pNext;
1789 }
1790 EXIT();
1791}
1792
Jeff Johnson295189b2012-06-20 16:38:30 -07001793static void hdd_PowerStateChangedCB
1794(
1795 v_PVOID_t callbackContext,
1796 tPmcState newState
1797)
1798{
1799 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301800
Jeff Johnson295189b2012-06-20 16:38:30 -07001801 /* if the driver was not in BMPS during early suspend,
1802 * the dynamic DTIM is now updated at Riva */
1803 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
Abhishek Singh0ea13232016-02-12 16:46:10 +05301804 && (pHddCtx->cfg_ini->enableDynamicDTIM ||
1805 pHddCtx->cfg_ini->enableModulatedDTIM)
Jeff Johnson295189b2012-06-20 16:38:30 -07001806 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1807 {
1808 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1809 }
1810 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301811 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1812 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301813 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001814 spin_unlock(&pHddCtx->filter_lock);
1815 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001816 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301818 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001819 else
Mihir Shete793209f2014-01-06 11:01:12 +05301820 {
1821 /* Android framework can send resume request when the WCN chip is
1822 * in IMPS mode. When the chip exits IMPS mode the firmware will
1823 * restore all the registers to the state they were before the chip
1824 * entered IMPS and so our hardware filter settings confgured by the
1825 * resume request will be lost. So reconfigure the filters on detecting
1826 * a change in the power state of the WCN chip.
1827 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301828 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301829 if (IMPS != newState)
1830 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301831 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301832 if (FALSE == pHddCtx->hdd_wlan_suspended)
1833 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301834 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301835 hddLog(VOS_TRACE_LEVEL_INFO,
1836 "Not in IMPS/BMPS and suspended state");
1837 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1838 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301839 else
1840 {
1841 spin_unlock(&pHddCtx->filter_lock);
1842 }
Mihir Shete793209f2014-01-06 11:01:12 +05301843 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301844 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001845}
1846
Jeff Johnson295189b2012-06-20 16:38:30 -07001847void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1848{
1849 v_CONTEXT_t pVosContext;
1850 tHalHandle smeContext;
1851
1852 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1853 if (NULL == pVosContext)
1854 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001855 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001856 return;
1857 }
1858 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1859 if (NULL == smeContext)
1860 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001861 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001862 return;
1863 }
1864
1865 spin_lock_init(&pHddCtx->filter_lock);
1866 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1867 pHddCtx->cfg_ini->nEnableSuspend)
1868 {
1869 pmcRegisterDeviceStateUpdateInd(smeContext,
1870 hdd_PowerStateChangedCB, pHddCtx);
1871 }
1872}
1873
1874void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1875{
1876 v_CONTEXT_t pVosContext;
1877 tHalHandle smeContext;
1878
1879 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1880 if (NULL == pVosContext)
1881 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001882 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001883 return;
1884 }
1885 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1886 if (NULL == smeContext)
1887 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001888 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001889 return;
1890 }
1891
1892 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1893 pHddCtx->cfg_ini->nEnableSuspend)
1894 {
1895 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1896 }
1897}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301898
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301899#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301900void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301901{
1902 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301903 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301904 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1905
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301906 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301907 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301908 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1909 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1910 {
1911 vos_mem_copy(&hddGtkOffloadReqParams,
1912 &pHddStaCtx->gtkOffloadReqParams,
1913 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301914
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301915 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1916 &hddGtkOffloadReqParams, pAdapter->sessionId);
1917 if (eHAL_STATUS_SUCCESS != ret)
1918 {
1919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1920 "%s: sme_SetGTKOffload failed, returned %d",
1921 __func__, ret);
1922 return;
1923 }
1924
1925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1926 "%s: sme_SetGTKOffload successfull", __func__);
1927 }
1928
1929 }
1930 else
1931 {
1932 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1933 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1934 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1935 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1936 {
1937
1938 /* Host driver has previously offloaded GTK rekey */
1939 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301940 wlan_hdd_cfg80211_update_replayCounterCallback,
1941 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301942 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301943
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301944 {
1945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1946 "%s: sme_GetGTKOffload failed, returned %d",
1947 __func__, ret);
1948 return;
1949 }
1950 else
1951 {
1952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1953 "%s: sme_GetGTKOffload successful",
1954 __func__);
1955
1956 /* Sending GTK offload dissable */
1957 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1958 sizeof (tSirGtkOffloadParams));
1959 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1960 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301961 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301962 if (eHAL_STATUS_SUCCESS != ret)
1963 {
1964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1965 "%s: failed to dissable GTK offload, returned %d",
1966 __func__, ret);
1967 return;
1968 }
1969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1970 "%s: successfully dissabled GTK offload request to HAL",
1971 __func__);
1972 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301973 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301974 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301975 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301976}
1977#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001978
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001979void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001980{
1981 hdd_context_t *pHddCtx = NULL;
1982 hdd_adapter_t *pAdapter = NULL;
1983 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1984 VOS_STATUS status;
1985 v_CONTEXT_t pVosContext = NULL;
Mukul Sharma3da767d2017-06-29 18:25:39 +05301986 tPmcState pmc_state;
1987 hdd_adapter_t *first_adapter = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001988
Jeff Johnson295189b2012-06-20 16:38:30 -07001989 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1990
1991 //Get the global VOSS context.
1992 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1993 if(!pVosContext) {
1994 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1995 return;
1996 }
1997
1998 //Get the HDD context.
1999 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
2000
2001 if(!pHddCtx) {
2002 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2003 return;
2004 }
2005
Agarwal Ashish971c2882013-10-30 20:11:12 +05302006 if (pHddCtx->isLogpInProgress)
2007 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002008 hddLog(VOS_TRACE_LEVEL_INFO,
2009 "%s: Ignore resume wlan, LOGP in progress!", __func__);
2010 return;
2011 }
2012
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05302013 if (!pHddCtx->hdd_wlan_suspended)
2014 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05302015 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05302016 "%s: Ignore resume wlan, Already resumed!", __func__);
2017 return;
2018 }
2019
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 pHddCtx->hdd_wlan_suspended = FALSE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05302021 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
Mukul Sharma3da767d2017-06-29 18:25:39 +05302022
2023 /* Get first valid adapter for disable/enable bmps purpose */
2024 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2025 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2026 {
2027 first_adapter = pAdapterNode->pAdapter;
2028 if (first_adapter != NULL)
2029 break;
2030 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2031 pAdapterNode = pNext;
2032 }
2033 pmc_state = pmcGetPmcState(pHddCtx->hHal);
2034 if (BMPS == pmc_state && first_adapter)
2035 {
2036 /* put the device into full power */
2037 hddLog(VOS_TRACE_LEVEL_INFO,
2038 "%s: Disaling bmps during resume", __func__);
2039 wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_ACTIVE);
2040 }
2041
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 /*loop through all adapters. Concurrency */
2043 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2044
2045 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2046 {
2047 pAdapter = pAdapterNode->pAdapter;
2048 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07002049 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07002050 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07002051 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2053 pAdapterNode = pNext;
2054 continue;
2055 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302056
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302057
Jeff Johnson295189b2012-06-20 16:38:30 -07002058#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2059 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
2060 {
2061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
2062 hdd_exit_deep_sleep(pAdapter);
2063 }
2064#endif
2065
2066 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
2067 {
2068 /*Switch back to DTIM 1*/
2069 tSirSetPowerParamsReq powerRequest = { 0 };
2070
2071 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
2072 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07002073 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002074
2075 /*Disabled ModulatedDTIM if enabled on suspend*/
2076 if(pHddCtx->cfg_ini->enableModulatedDTIM)
2077 powerRequest.uDTIMPeriod = 0;
2078
2079 /* Update ignoreDTIM and ListedInterval in CFG with default values */
2080 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
2081 NULL, eANI_BOOLEAN_FALSE);
2082 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
2083 NULL, eANI_BOOLEAN_FALSE);
2084
2085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002086 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08002087 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002088
Mukul Sharma3da767d2017-06-29 18:25:39 +05302089 if (BMPS == pmc_state)
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302090 {
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302091 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
2092 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 }
2094
Gopichand Nakkala0f276812013-02-24 14:45:51 +05302095 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002096 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2097 pAdapterNode = pNext;
2098 }
2099
Mukul Sharma3da767d2017-06-29 18:25:39 +05302100 if (BMPS == pmc_state && first_adapter)
2101 {
2102 /* put the device into full power */
2103 hddLog(VOS_TRACE_LEVEL_INFO,
2104 "%s: Enable bmps during resume", __func__);
2105 /* put the device back into BMPS */
2106 wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_AUTO);
2107 }
2108
Jeff Johnson295189b2012-06-20 16:38:30 -07002109#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2110 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
2111 {
2112 hdd_exit_standby(pHddCtx);
2113 }
2114#endif
2115
Jeff Johnson295189b2012-06-20 16:38:30 -07002116 return;
2117}
2118
Jeff Johnson295189b2012-06-20 16:38:30 -07002119VOS_STATUS hdd_wlan_reset_initialization(void)
2120{
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 v_CONTEXT_t pVosContext = NULL;
2122
2123 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
2124
2125 //Get the global VOSS context.
2126 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2127 if(!pVosContext)
2128 {
2129 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2130 return VOS_STATUS_E_FAILURE;
2131 }
2132
2133 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
2134
2135 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302136 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002137
Jeff Johnson295189b2012-06-20 16:38:30 -07002138 return VOS_STATUS_SUCCESS;
2139}
2140
2141
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002142/*
2143 * Based on the ioctl command recieved by HDD, put WLAN driver
2144 * into the quiet mode. This is the same as the early suspend
2145 * notification that driver used to listen
2146 */
2147void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07002148{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302149 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002150 if (suspend)
2151 hdd_suspend_wlan();
2152 else
2153 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302154 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002155}
2156
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002157static void hdd_ssr_timer_init(void)
2158{
2159 init_timer(&ssr_timer);
2160}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002161
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002162static void hdd_ssr_timer_del(void)
2163{
2164 del_timer(&ssr_timer);
2165 ssr_timer_started = false;
2166}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002167
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002168static void hdd_ssr_timer_cb(unsigned long data)
2169{
2170 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07002171
2172#ifdef WCN_PRONTO
2173 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
2174 wcnss_pronto_log_debug_regs();
2175#endif
2176
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002177 VOS_BUG(0);
2178}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002179
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002180static void hdd_ssr_timer_start(int msec)
2181{
2182 if(ssr_timer_started)
2183 {
2184 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
2185 ,__func__);
2186 }
2187 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
2188 ssr_timer.function = hdd_ssr_timer_cb;
2189 add_timer(&ssr_timer);
2190 ssr_timer_started = true;
2191}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002192
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302193#ifdef FEATURE_WLAN_DIAG_SUPPORT
2194/**
2195 * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state
2196 *
2197 * This Function send send ssr shutdown state diag event
2198 *
2199 * Return: void.
2200 */
2201static void hdd_wlan_ssr_shutdown_event(void)
2202{
2203 WLAN_VOS_DIAG_EVENT_DEF(ssr_shutdown,
2204 struct host_event_wlan_ssr_shutdown);
2205 vos_mem_zero(&ssr_shutdown, sizeof(ssr_shutdown));
2206 ssr_shutdown.status = SSR_SUB_SYSTEM_SHUTDOWN;
2207 WLAN_VOS_DIAG_EVENT_REPORT(&ssr_shutdown,
2208 EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM);
2209}
2210#else
2211static inline void hdd_wlan_ssr_shutdown_event(void)
2212{
2213
2214};
2215#endif
2216
Jeff Johnson295189b2012-06-20 16:38:30 -07002217/* the HDD interface to WLAN driver shutdown,
2218 * the primary shutdown function in SSR
2219 */
2220VOS_STATUS hdd_wlan_shutdown(void)
2221{
2222 VOS_STATUS vosStatus;
2223 v_CONTEXT_t pVosContext = NULL;
2224 hdd_context_t *pHddCtx = NULL;
2225 pVosSchedContext vosSchedContext = NULL;
2226
2227 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
2228
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002229 /* if re-init never happens, then do SSR1 */
2230 hdd_ssr_timer_init();
2231 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
2232
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 /* Get the global VOSS context. */
2234 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2235 if(!pVosContext) {
2236 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2237 return VOS_STATUS_E_FAILURE;
2238 }
2239 /* Get the HDD context. */
2240 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2241 if(!pHddCtx) {
2242 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2243 return VOS_STATUS_E_FAILURE;
2244 }
c_hpothud662a352013-12-26 15:09:12 +05302245
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +05302246 vos_set_snoc_high_freq_voting(false);
c_hpothud662a352013-12-26 15:09:12 +05302247 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +05302248 if ((pHddCtx->cfg_ini->dynSplitscan)&& (VOS_TIMER_STATE_RUNNING ==
2249 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
c_hpothud662a352013-12-26 15:09:12 +05302250 {
2251 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
2252 }
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05302253 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Kapil Gupta137ef892016-12-13 19:38:00 +05302254 vos_flush_work(&pHddCtx->sap_start_work);
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 hdd_reset_all_adapters(pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +05302256
2257 /* set default value of Tcp delack and stop timer */
2258 hdd_set_default_stop_delack_timer(pHddCtx);
2259
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 /* DeRegister with platform driver as client for Suspend/Resume */
2261 vosStatus = hddDeregisterPmOps(pHddCtx);
2262 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2263 {
2264 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
2265 }
2266
2267 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
2268 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2269 {
2270 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
2271 }
2272
2273 /* Disable IMPS/BMPS as we do not want the device to enter any power
2274 * save mode on its own during reset sequence
2275 */
2276 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
2277 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
2278 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
2279
2280 vosSchedContext = get_vos_sched_ctxt();
2281
2282 /* Wakeup all driver threads */
2283 if(TRUE == pHddCtx->isMcThreadSuspended){
2284 complete(&vosSchedContext->ResumeMcEvent);
2285 pHddCtx->isMcThreadSuspended= FALSE;
2286 }
2287 if(TRUE == pHddCtx->isTxThreadSuspended){
2288 complete(&vosSchedContext->ResumeTxEvent);
2289 pHddCtx->isTxThreadSuspended= FALSE;
2290 }
2291 if(TRUE == pHddCtx->isRxThreadSuspended){
2292 complete(&vosSchedContext->ResumeRxEvent);
2293 pHddCtx->isRxThreadSuspended= FALSE;
2294 }
2295 /* Reset the Suspend Variable */
2296 pHddCtx->isWlanSuspended = FALSE;
2297
2298 /* Stop all the threads; we do not want any messages to be a processed,
2299 * any more and the best way to ensure that is to terminate the threads
2300 * gracefully.
2301 */
2302 /* Wait for MC to exit */
2303 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302304 set_bit(MC_SHUTDOWN_EVENT, &vosSchedContext->mcEventFlag);
2305 set_bit(MC_POST_EVENT, &vosSchedContext->mcEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002306 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302307 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002308
2309 /* Wait for TX to exit */
2310 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302311 set_bit(TX_SHUTDOWN_EVENT, &vosSchedContext->txEventFlag);
2312 set_bit(TX_POST_EVENT, &vosSchedContext->txEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002313 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302314 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002315
2316 /* Wait for RX to exit */
2317 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302318 set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->rxEventFlag);
2319 set_bit(RX_POST_EVENT, &vosSchedContext->rxEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002320 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05302321
Mihir Sheteb5425f72013-12-19 09:06:13 +05302322 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002323
2324#ifdef WLAN_BTAMP_FEATURE
2325 vosStatus = WLANBAP_Stop(pVosContext);
2326 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2327 {
2328 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2329 "%s: Failed to stop BAP",__func__);
2330 }
2331#endif //WLAN_BTAMP_FEATURE
2332 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302333 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2334 {
2335 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2336 "%s: Failed to stop wda %d", __func__, vosStatus);
2337 VOS_ASSERT(0);
2338 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002339
2340 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2341 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2342 * on threads being running to process the SYS Stop
2343 */
Kiet Lama72a2322013-11-15 11:18:11 +05302344 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302345 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2346 {
2347 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2348 "%s: Failed to stop sme %d", __func__, vosStatus);
2349 VOS_ASSERT(0);
2350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002351
2352 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2353 /* Stop MAC (PE and HAL) */
2354 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302355 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2356 {
2357 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2358 "%s: Failed to stop mac %d", __func__, vosStatus);
2359 VOS_ASSERT(0);
2360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002361
2362 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2363 /* Stop TL */
2364 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302365 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2366 {
2367 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2368 "%s: Failed to stop TL %d", __func__, vosStatus);
2369 VOS_ASSERT(0);
2370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002371
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002373 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2374 /* Clean up message queues of TX and MC thread */
2375 vos_sched_flush_mc_mqs(vosSchedContext);
2376 vos_sched_flush_tx_mqs(vosSchedContext);
2377 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302378#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2379 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302380 /*Free fw dump mem in case of SSR/Shutdown */
2381 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2382 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302383#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002384
2385 /* Deinit all the TX and MC queues */
2386 vos_sched_deinit_mqs(vosSchedContext);
2387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2388
2389 /* shutdown VOSS */
2390 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302391
2392 /*mac context has already been released in mac_close call
2393 so setting it to NULL in hdd context*/
2394 pHddCtx->hHal = (tHalHandle)NULL;
2395
Jeff Johnson295189b2012-06-20 16:38:30 -07002396 if (free_riva_power_on_lock("wlan"))
2397 {
2398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2399 __func__);
2400 }
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302401 hdd_wlan_ssr_shutdown_event();
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2403 ,__func__);
2404 return VOS_STATUS_SUCCESS;
2405}
2406
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302407int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter)
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302408{
2409 hdd_config_t *config;
2410 int status = VOS_STATUS_SUCCESS;
2411 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2412
2413 config = hdd_ctx->cfg_ini;
2414 if (NULL == config) {
2415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2416 ("cfg_ini is NULL!!"));
2417 return -EINVAL;
2418 }
2419#ifdef DHCP_SERVER_OFFLOAD
2420 /* set dhcp server offload */
2421 if (config->enable_dhcp_srv_offload &&
2422 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302423 vos_event_reset(&adapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +05302424 status = wlan_hdd_set_dhcp_server_offload(adapter, true);
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302425 if (!VOS_IS_STATUS_SUCCESS(status))
2426 {
2427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2428 ("HDD DHCP Server Offload Failed!!"));
2429 return -EINVAL;
2430 }
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302431 status = vos_wait_single_event(&adapter->dhcp_status.vos_event, 2000);
2432 if (!VOS_IS_STATUS_SUCCESS(status) ||
2433 adapter->dhcp_status.dhcp_offload_status)
2434 {
2435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2436 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
2437 adapter->dhcp_status.dhcp_offload_status);
2438 return -EINVAL;
2439 }
2440#ifdef MDNS_OFFLOAD
2441 if (config->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302442 vos_event_reset(&adapter->mdns_status.vos_event);
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302443 status = wlan_hdd_set_mdns_offload(adapter);
2444 if (VOS_IS_STATUS_SUCCESS(status))
2445 {
2446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2447 ("HDD MDNS Server Offload Failed!!"));
2448 return -EINVAL;
2449 }
Anurag Chouhan7e2a9912017-02-09 20:21:40 +05302450 status = vos_wait_single_event(&adapter->
2451 mdns_status.vos_event, 2000);
2452 if (!VOS_IS_STATUS_SUCCESS(status) ||
2453 adapter->mdns_status.mdns_enable_status ||
2454 adapter->mdns_status.mdns_fqdn_status ||
2455 adapter->mdns_status.mdns_resp_status)
2456 {
2457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2458 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
2459 adapter->mdns_status.mdns_enable_status,
2460 adapter->mdns_status.mdns_fqdn_status,
2461 adapter->mdns_status.mdns_resp_status);
2462 return -EINVAL;
2463 }
2464 }
2465#endif /* MDNS_OFFLOAD */
2466 } else {
2467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2468 ("DHCP Disabled ini %d, FW %d"),
2469 config->enable_dhcp_srv_offload,
2470 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
2471 }
2472#endif /* DHCP_SERVER_OFFLOAD */
2473 return status;
2474}
2475
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302476/**
2477 * hdd_ssr_restart_sap() - restart sap on SSR
2478 * @hdd_ctx: hdd context
2479 *
2480 * Return: nothing
2481 */
2482static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx)
2483{
2484 VOS_STATUS status;
2485 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
2486 hdd_adapter_t *adapter;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302487 hdd_hostapd_state_t *hostapd_state;
Jeff Johnson295189b2012-06-20 16:38:30 -07002488
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302489 ENTER();
2490
2491 status = hdd_get_front_adapter (hdd_ctx, &adapter_node);
2492 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
2493 adapter = adapter_node->pAdapter;
2494 if (adapter && adapter->device_mode == WLAN_HDD_SOFTAP) {
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05302495 if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) {
2496 hostapd_state =
2497 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
2498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Restart prev SAP session"));
2499 wlan_hdd_start_sap(adapter);
2500 if (!VOS_IS_STATUS_SUCCESS(
2501 hdd_dhcp_mdns_offload(adapter))) {
2502 vos_event_reset(
2503 &hostapd_state->vosEvent);
2504 hddLog(VOS_TRACE_LEVEL_ERROR,
2505 FL("DHCP/MDNS offload Failed!!"));
2506 if (VOS_STATUS_SUCCESS ==
2507 WLANSAP_StopBss(
2508 hdd_ctx->pvosContext)) {
2509 status = vos_wait_single_event(
2510 &hostapd_state->vosEvent
2511 , 10000);
2512 if (!VOS_IS_STATUS_SUCCESS(
2513 status)) {
2514 hddLog(LOGE, FL("SAP Stop Failed"));
2515 return;
2516 }
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05302517 }
2518 }
2519 }
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302520 }
2521 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
2522 adapter_node = next;
2523 }
2524
2525 EXIT();
2526}
Jeff Johnson295189b2012-06-20 16:38:30 -07002527
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302528#ifdef FEATURE_WLAN_DIAG_SUPPORT
2529/**
2530* hdd_wlan_ssr_reinit_event()- send ssr reinit state
2531*
2532* This Function send send ssr reinit state diag event
2533*
2534* Return: void.
2535*/
2536static void hdd_wlan_ssr_reinit_event(void)
2537{
2538 WLAN_VOS_DIAG_EVENT_DEF(ssr_reinit, struct host_event_wlan_ssr_reinit);
2539 vos_mem_zero(&ssr_reinit, sizeof(ssr_reinit));
2540 ssr_reinit.status = SSR_SUB_SYSTEM_REINIT;
2541 WLAN_VOS_DIAG_EVENT_REPORT(&ssr_reinit,
2542 EVENT_WLAN_SSR_REINIT_SUBSYSTEM);
2543}
2544#else
2545static inline void hdd_wlan_ssr_reinit_event(void)
2546{
2547
2548}
2549#endif
2550
Jeff Johnson295189b2012-06-20 16:38:30 -07002551/* the HDD interface to WLAN driver re-init.
2552 * This is called to initialize/start WLAN driver after a shutdown.
2553 */
2554VOS_STATUS hdd_wlan_re_init(void)
2555{
2556 VOS_STATUS vosStatus;
2557 v_CONTEXT_t pVosContext = NULL;
2558 hdd_context_t *pHddCtx = NULL;
2559 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002560#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2561 int max_retries = 0;
2562#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302563#ifdef HAVE_CBC_DONE
2564 int max_cbc_retries = 0;
2565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002566#ifdef WLAN_BTAMP_FEATURE
2567 hdd_config_t *pConfig = NULL;
2568 WLANBAP_ConfigType btAmpConfig;
2569#endif
2570
Katya Nigam82a93062014-06-04 15:15:36 +05302571 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002572 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302573 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002574
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002575#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2576 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002577 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002578 msleep(1000);
2579 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002580 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002581 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2582 goto err_re_init;
2583 }
2584#endif
2585
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302586#ifdef HAVE_CBC_DONE
2587 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2588 msleep(1000);
2589 }
2590 if (max_cbc_retries >= 20) {
2591 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2592 }
2593#endif
2594
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002595 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2596
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002597 /* The driver should always be initialized in STA mode after SSR */
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302598 if (VOS_STA_SAP_MODE != hdd_get_conparam())
2599 hdd_set_conparam(0);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002600
Katya Nigam82a93062014-06-04 15:15:36 +05302601 dev = wcnss_wlan_get_device();
2602 if (NULL == dev)
2603 {
2604 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2605 goto err_re_init;
2606 }
2607
Jeff Johnson295189b2012-06-20 16:38:30 -07002608 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302609 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002610 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2611 {
2612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2613 goto err_re_init;
2614 }
2615
2616 /* Get the HDD context. */
2617 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2618 if(!pHddCtx)
2619 {
2620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2621 goto err_vosclose;
2622 }
2623
2624 /* Save the hal context in Adapter */
2625 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2626 if ( NULL == pHddCtx->hHal )
2627 {
2628 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2629 goto err_vosclose;
2630 }
2631
2632 /* Set the SME configuration parameters. */
2633 vosStatus = hdd_set_sme_config(pHddCtx);
2634 if ( VOS_STATUS_SUCCESS != vosStatus )
2635 {
2636 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2637 goto err_vosclose;
2638 }
2639
Jeff Johnson295189b2012-06-20 16:38:30 -07002640 vosStatus = vos_preStart( pHddCtx->pvosContext );
2641 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2642 {
2643 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2644 goto err_vosclose;
2645 }
2646
2647 /* In the integrated architecture we update the configuration from
2648 the INI file and from NV before vOSS has been started so that
2649 the final contents are available to send down to the cCPU */
2650 /* Apply the cfg.ini to cfg.dat */
2651 if (FALSE == hdd_update_config_dat(pHddCtx))
2652 {
2653 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2654 goto err_vosclose;
2655 }
2656
2657 /* Set the MAC Address, currently this is used by HAL to add self sta.
2658 * Remove this once self sta is added as part of session open. */
2659 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2660 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2661 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2662 if (!HAL_STATUS_SUCCESS(halStatus))
2663 {
2664 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2665 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2666 goto err_vosclose;
2667 }
2668
2669 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2670 Note: Firmware image will be read and downloaded inside vos_start API */
2671 vosStatus = vos_start( pVosContext );
2672 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2673 {
2674 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +05302675 if (isSsrPanicOnFailure())
2676 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002677 goto err_vosclose;
2678 }
2679
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002680 /* Exchange capability info between Host and FW and also get versioning info from FW */
2681 hdd_exchange_version_and_caps(pHddCtx);
2682
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 vosStatus = hdd_post_voss_start_config( pHddCtx );
2684 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2685 {
2686 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2687 __func__);
2688 goto err_vosstop;
2689 }
2690
Mihir Shete04206452014-11-20 17:50:58 +05302691#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302692 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2693 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2694 {
2695 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2696 __func__);
2697 goto err_vosstop;
2698 }
Mihir Shete04206452014-11-20 17:50:58 +05302699#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302700
Jeff Johnson295189b2012-06-20 16:38:30 -07002701#ifdef WLAN_BTAMP_FEATURE
2702 vosStatus = WLANBAP_Open(pVosContext);
2703 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2706 "%s: Failed to open BAP",__func__);
2707 goto err_vosstop;
2708 }
2709 vosStatus = BSL_Init(pVosContext);
2710 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2711 {
2712 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2713 "%s: Failed to Init BSL",__func__);
2714 goto err_bap_close;
2715 }
2716 vosStatus = WLANBAP_Start(pVosContext);
2717 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2718 {
2719 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2720 "%s: Failed to start TL",__func__);
2721 goto err_bap_close;
2722 }
2723 pConfig = pHddCtx->cfg_ini;
2724 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2725 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2726#endif //WLAN_BTAMP_FEATURE
2727
2728 /* Restart all adapters */
2729 hdd_start_all_adapters(pHddCtx);
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +05302730 pHddCtx->last_scan_reject_session_id = 0xFF;
2731 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +05302732 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +05302733 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002734 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302735 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002736 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302737 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002738 /* Register with platform driver as client for Suspend/Resume */
2739 vosStatus = hddRegisterPmOps(pHddCtx);
2740 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2741 {
2742 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2743 goto err_bap_stop;
2744 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302745
2746#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2747 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2748 (pHddCtx->cfg_ini->enableFWLogging ||
2749 pHddCtx->cfg_ini->enableMgmtLogging ||
2750 pHddCtx->cfg_ini->enableContFWLogging))
2751 {
2752 hdd_init_frame_logging(pHddCtx);
2753 }
2754#endif
2755
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302757 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002758 /* register for riva power on lock */
2759 if (req_riva_power_on_lock("wlan"))
2760 {
2761 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2762 __func__);
2763 goto err_unregister_pmops;
2764 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302765 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002766 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Deepthi Gowri1ca95bb2016-01-13 19:47:53 +05302767
2768 sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame);
2769
Dasari Srinivas421bde82014-06-25 12:01:44 +05302770#ifdef WLAN_FEATURE_EXTSCAN
2771 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2772 wlan_hdd_cfg80211_extscan_callback,
2773 pHddCtx);
2774#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302775
2776#ifdef FEATURE_OEM_DATA_SUPPORT
2777 sme_OemDataRegisterCallback(pHddCtx->hHal,
2778 wlan_hdd_cfg80211_oemdata_callback,
2779 pHddCtx);
2780#endif /* FEATURE_OEM_DATA_SUPPORT */
2781
Jeff Johnson295189b2012-06-20 16:38:30 -07002782 goto success;
2783
2784err_unregister_pmops:
2785 hddDeregisterPmOps(pHddCtx);
2786
2787err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002788#ifdef CONFIG_HAS_EARLYSUSPEND
2789 hdd_unregister_mcast_bcast_filter(pHddCtx);
2790#endif
2791 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002792#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002793 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002794#endif
2795
2796#ifdef WLAN_BTAMP_FEATURE
2797err_bap_close:
2798 WLANBAP_Close(pVosContext);
2799#endif
2800
2801err_vosstop:
2802 vos_stop(pVosContext);
2803
2804err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302805 if(!isSsrPanicOnFailure())
2806 {
2807 /* If we hit this, it means wlan driver is in bad state and needs
2808 * driver unload and load.
2809 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302810 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2811 return VOS_STATUS_E_FAILURE;
2812 }
2813
Jeff Johnson295189b2012-06-20 16:38:30 -07002814 vos_close(pVosContext);
2815 vos_sched_close(pVosContext);
2816 if (pHddCtx)
2817 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002818 /* Unregister the Net Device Notifier */
2819 unregister_netdevice_notifier(&hdd_netdev_notifier);
2820 /* Clean up HDD Nlink Service */
2821 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002822#ifdef WLAN_KD_READY_NOTIFIER
2823 nl_srv_exit(pHddCtx->ptt_pid);
2824#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002825 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002826#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002827 /* Free up dynamically allocated members inside HDD Adapter */
2828 kfree(pHddCtx->cfg_ini);
2829 pHddCtx->cfg_ini= NULL;
2830
Jeff Johnson295189b2012-06-20 16:38:30 -07002831 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302832 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002833 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002834 }
2835 vos_preClose(&pVosContext);
2836
2837#ifdef MEMORY_DEBUG
2838 vos_mem_exit();
2839#endif
2840
2841err_re_init:
2842 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302843 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002844 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002845 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002846 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002847
2848success:
Sen, Devendrade5cfe92017-01-31 18:51:15 +05302849 hdd_wlan_ssr_reinit_event();
Jeff Johnson295189b2012-06-20 16:38:30 -07002850 /* Trigger replay of BTC events */
2851 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05302852
2853 if (pHddCtx->cfg_ini->sap_internal_restart)
2854 hdd_ssr_restart_sap(pHddCtx);
2855
Jeff Johnson295189b2012-06-20 16:38:30 -07002856 return VOS_STATUS_SUCCESS;
2857}