blob: a61b3c18e44eec75f3c1ce7da9f6d8dba83a84a5 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singh37471cd2016-01-05 17:09:57 +05302 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=============================================================================
29* wlan_hdd_early_suspend.c
30*
31* \brief power management functions
32*
33* Description
Jeff Johnson295189b2012-06-20 16:38:30 -070034*
35==============================================================================**/
36/* $HEADER$ */
37
38/**-----------------------------------------------------------------------------
39* Include files
40* ----------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42#include <linux/pm.h>
43#include <linux/wait.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070044#include <wlan_hdd_includes.h>
45#include <wlan_qct_driver.h>
46#include <linux/wakelock.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48#include "halTypes.h"
49#include "sme_Api.h"
50#include <vos_api.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070051#include <vos_sched.h>
52#include <macInitApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <wlan_qct_sys.h>
54#include <wlan_btc_svc.h>
55#include <wlan_nlink_common.h>
56#include <wlan_hdd_main.h>
57#include <wlan_hdd_assoc.h>
58#include <wlan_hdd_dev_pwr.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070059#include <wlan_nlink_srv.h>
60#include <wlan_hdd_misc.h>
Amar Singhald08ce752014-03-21 16:28:27 -070061#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062
Jeff Johnson295189b2012-06-20 16:38:30 -070063#include <linux/semaphore.h>
64#include <wlan_hdd_hostapd.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include "cfgApi.h"
Siddharth Bhal7bd19932015-03-03 16:54:36 +053066#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067
68#ifdef WLAN_BTAMP_FEATURE
69#include "bapApi.h"
70#include "bap_hdd_main.h"
71#include "bap_hdd_misc.h"
72#endif
73
Jeff Johnsone7245742012-09-05 17:12:55 -070074#include <linux/wcnss_wlan.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070075#include <linux/inetdevice.h>
76#include <wlan_hdd_cfg.h>
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053077#include <wlan_hdd_cfg80211.h>
Gopichand Nakkala746a9452013-06-11 12:45:54 +053078#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070079/**-----------------------------------------------------------------------------
80* Preprocessor definitions and constants
81* ----------------------------------------------------------------------------*/
82
83/**-----------------------------------------------------------------------------
84* Type declarations
85* ----------------------------------------------------------------------------*/
86
87/**-----------------------------------------------------------------------------
88* Function and variables declarations
89* ----------------------------------------------------------------------------*/
90#include "wlan_hdd_power.h"
91#include "wlan_hdd_packet_filtering.h"
92
Sameer Thalappile5637f42013-08-07 15:46:55 -070093#define HDD_SSR_BRING_UP_TIME 180000
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +053094#define NS_DEFAULT_SLOT_INDEX 4
95#define NS_EXTENDED_SLOT_INDEX 18
Jeff Johnson295189b2012-06-20 16:38:30 -070096
97static eHalStatus g_full_pwr_status;
98static eHalStatus g_standby_status;
99
100extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103extern struct notifier_block hdd_netdev_notifier;
Jeff Johnson295189b2012-06-20 16:38:30 -0700104extern tVOS_CON_MODE hdd_get_conparam ( void );
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -0700106static struct timer_list ssr_timer;
107static bool ssr_timer_started;
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
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
492 hdd_wlan_initial_scan(pHddCtx);
493
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 }
Srinivas Girigowdad26a8072016-10-19 20:26:42 +0530878 read_unlock_bh(&in6_dev->lock);
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530879
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530880 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530881 for (i =0; i < slot_index; i++)
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530882 {
883 if (selfIPv6AddrValid[i])
884 {
885 //Filling up the request structure
886 /* Filling the selfIPv6Addr with solicited address
887 * A Solicited-Node multicast address is created by
888 * taking the last 24 bits of a unicast or anycast
889 * address and appending them to the prefix
890 *
891 * FF02:0000:0000:0000:0000:0001:FFXX:XX
892 *
893 * here XX is the unicast/anycast bits
894 */
895 offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF;
896 offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02;
897 offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01;
898 offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF;
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530899 offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] =
900 selfIPv6Addr[i][13];
901 offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] =
902 selfIPv6Addr[i][14];
903 offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] =
904 selfIPv6Addr[i][15];
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530905 offLoadRequest.nsOffloadInfo.slotIdx = i;
906
907 vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530908 selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530909 vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
910 &pAdapter->macAddressCurrent.bytes,
911 sizeof(tANI_U8)*SIR_MAC_ADDR_LEN);
912
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530913 offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] =
914 SIR_IPV6_ADDR_VALID;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530915 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
916 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +0530917 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
918 SIR_OFFLOAD_ENABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530919
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530920 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530921 FL("configuredMcastBcastFilter: %d"
922 "NSOffload Slot = %d"),
923 pHddCtx->configuredMcastBcastFilter, i);
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530924
Kiet Lamc8e1eb52013-10-24 00:30:49 +0530925 if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)
Amar Singhald08ce752014-03-21 16:28:27 -0700926 && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST ==
927 pHddCtx->sus_res_mcastbcast_filter) ||
928 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
929 pHddCtx->sus_res_mcastbcast_filter)) &&
930 (!WDA_IS_MCAST_FLT_ENABLE_IN_FW ||
931 (WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
932 !(pHddCtx->cfg_ini->fEnableMCAddrList))))
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530933 {
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530934 offLoadRequest.enableOrDisable =
Amar Singhald08ce752014-03-21 16:28:27 -0700935 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
Madan Mohan Koyyalamudibadffe72013-09-11 13:09:14 +0530936 }
Abhishek Singh937ec542016-01-05 18:03:14 +0530937 hdd_wlan_offload_event(
938 SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE,
939 SIR_OFFLOAD_ENABLE);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +0530940 hddLog(VOS_TRACE_LEVEL_INFO,
941 FL("offload: NS filter programmed %d"),
942 offLoadRequest.enableOrDisable);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530943 vos_mem_copy(&offLoadRequest.params.hostIpv6Addr,
944 &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0],
945 sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN);
946
947 hddLog (VOS_TRACE_LEVEL_INFO,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530948 FL("Setting NSOffload with solicitedIp: %pI6,"
949 "targetIp: %pI6"),
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530950 offLoadRequest.nsOffloadInfo.selfIPv6Addr,
951 offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]);
952
953 //Configure the Firmware with this
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530954 returnStatus = sme_SetHostOffload(halHandle,
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530955 pAdapter->sessionId, &offLoadRequest);
956 if(eHAL_STATUS_SUCCESS != returnStatus)
957 {
958 hddLog(VOS_TRACE_LEVEL_ERROR,
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530959 FL("Failed to enable HostOffload feature with"
960 " status: %d"), returnStatus);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530961 }
962 vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
963 }
964 }
965 }
966 else
967 {
968 hddLog(VOS_TRACE_LEVEL_ERROR,
969 FL("IPv6 dev does not exist. Failed to request NSOffload"));
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530970 goto end;
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530971 }
972 }
973 else
974 {
975 //Disable NSOffload
976 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
977 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
978 offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +0530979 hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
980 SIR_OFFLOAD_DISABLE);
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530981
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530982 for (i = 0; i < slot_index; i++)
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530983 {
c_hpothu86feba52014-10-28 15:51:18 +0530984 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530985 offLoadRequest.nsOffloadInfo.slotIdx = i;
986 if (eHAL_STATUS_SUCCESS !=
Vinay Krishna Eranna911a3b82014-01-07 12:20:51 +0530987 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
988 pAdapter->sessionId, &offLoadRequest))
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530989 {
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable"
991 " %d Slot"), i);
Vinay Krishna Erannab29c6142014-01-07 12:20:51 +0530992 }
993 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +0530994 }
Hardik Kantilal Patele1760e12014-01-21 15:57:21 +0530995end:
996 while (slot > 0 && selfIPv6Addr[--slot])
997 {
998 vos_mem_free(selfIPv6Addr[slot]);
999 }
1000 if (selfIPv6Addr)
1001 {
1002 vos_mem_free(selfIPv6Addr);
1003 }
1004 if (selfIPv6AddrValid)
1005 {
1006 vos_mem_free(selfIPv6AddrValid);
1007 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301008 EXIT();
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301009 return;
1010}
1011#endif
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301012
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301013void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301014{
1015 hdd_adapter_t* pAdapter =
1016 container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
1017 hdd_context_t *pHddCtx;
1018 int status;
1019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301020 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301021 if (NULL == pAdapter)
1022 {
1023 hddLog(LOGE, FL("Adapter is invalid"));
1024 return;
1025 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301026 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1027 status = wlan_hdd_validate_context(pHddCtx);
1028 if (0 != status)
1029 {
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301030 return;
1031 }
1032
1033 if ((eConnectionState_Associated ==
1034 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)
Deepthi Gowri5933f402014-01-23 17:48:24 +05301035 && (pHddCtx->hdd_wlan_suspended))
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301036 {
1037 // This invocation being part of the IPv4 registration callback,
1038 // we are passing second parameter as 2 to avoid registration
1039 // of IPv4 notifier again.
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301040 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1041 if (pHddCtx->cfg_ini->fhostArpOffload)
1042 {
1043 hdd_conf_arp_offload(pAdapter, 2);
1044 }
1045 else
1046 {
1047 hddLog(VOS_TRACE_LEVEL_INFO,
1048 FL("offload: arp offload ini is disabled in host"));
1049 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301050 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301051 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301052}
1053
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301054void hdd_ipv4_notifier_work_queue(struct work_struct *work)
1055{
1056 vos_ssr_protect(__func__);
1057 __hdd_ipv4_notifier_work_queue(work);
1058 vos_ssr_unprotect(__func__);
1059}
1060
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301061int __wlan_hdd_ipv4_changed(struct notifier_block *nb,
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301062 unsigned long data, void *arg)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301063{
1064 struct in_ifaddr *ifa = (struct in_ifaddr *)arg;
1065 struct in_ifaddr **ifap = NULL;
1066 struct in_device *in_dev;
1067
1068 struct net_device *ndev = ifa->ifa_dev->dev;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301069 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301070 hdd_context_t *pHddCtx;
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301071 VOS_STATUS vos_status;
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05301072 int status;
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05301073
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301074 ENTER();
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301075 pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier);
1076 status = wlan_hdd_validate_context(pHddCtx);
1077 if (0 != status)
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301078 {
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301079 return NOTIFY_DONE;
1080 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301081
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301082 vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
1083 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status)
1084 {
1085 if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev &&
1086 (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1087 pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
1088 {
Abhishek Singhe0bc0992016-05-20 17:58:18 +05301089
1090 if (eConnectionState_Associated ==
1091 WLAN_HDD_GET_STATION_CTX_PTR
1092 (pAdapterNode->pAdapter)->conn_info.connState)
1093 sme_dhcp_done_ind(pHddCtx->hHal,
1094 pAdapterNode->pAdapter->sessionId);
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301095 if ((pHddCtx->cfg_ini->nEnableSuspend !=
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301096 WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301097 || (!pHddCtx->cfg_ini->fhostArpOffload))
1098 {
1099 hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"),
1100 pHddCtx->cfg_ini->nEnableSuspend,
1101 pHddCtx->cfg_ini->fhostArpOffload);
1102 return NOTIFY_DONE;
1103 }
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05301104
Vinay Krishna Eranna55029602015-02-06 15:43:35 +05301105 if ((in_dev =
1106 __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL)
1107 {
1108 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
1109 ifap = &ifa->ifa_next)
1110 {
1111 if (!strcmp(pAdapterNode->pAdapter->dev->name,
1112 ifa->ifa_label))
1113 {
1114 break; /* found */
1115 }
1116 }
1117 }
1118 if(ifa && ifa->ifa_local)
1119 {
1120 schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue);
1121 }
1122 break;
1123 }
1124 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
1125 pAdapterNode = pNext;
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301126 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301127 EXIT();
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301128 return NOTIFY_DONE;
1129}
1130
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +05301131int wlan_hdd_ipv4_changed(struct notifier_block *nb,
1132 unsigned long data, void *arg)
1133{
1134 int ret;
1135 vos_ssr_protect(__func__);
1136 ret = __wlan_hdd_ipv4_changed( nb, data, arg);
1137 vos_ssr_unprotect(__func__);
1138 return ret;
1139}
1140
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301141/**----------------------------------------------------------------------------
1142
1143 \brief hdd_conf_arp_offload() - Configure ARP offload
1144
1145 Called during SUSPEND to configure the ARP offload (MC BC filter) which
1146 reduces power consumption.
1147
1148 \param - pAdapter -Adapter context for which ARP offload is to be configured
1149 \param - fenable - 0 - disable.
1150 1 - enable. (with IPv4 notifier registration)
1151 2 - enable. (without IPv4 notifier registration)
1152
1153 \return -
1154 VOS_STATUS_SUCCESS - on successful operation
1155 VOS_STATUS_E_FAILURE - on failure of operation
1156-----------------------------------------------------------------------------*/
1157VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001158{
1159 struct in_ifaddr **ifap = NULL;
1160 struct in_ifaddr *ifa = NULL;
1161 struct in_device *in_dev;
1162 int i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 tSirHostOffloadReq offLoadRequest;
Yathish9f22e662012-12-10 14:21:35 -08001164 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001165
Sushant Kaushik87787972015-09-11 16:05:00 +05301166 hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001167
Jeff Johnson295189b2012-06-20 16:38:30 -07001168 if(fenable)
1169 {
1170 if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL)
1171 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301172 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 ifap = &ifa->ifa_next)
1174 {
1175 if (!strcmp(pAdapter->dev->name, ifa->ifa_label))
1176 {
1177 break; /* found */
1178 }
1179 }
1180 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 if(ifa && ifa->ifa_local)
1182 {
1183 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
1184 offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
Abhishek Singh937ec542016-01-05 18:03:14 +05301185 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1186 SIR_OFFLOAD_ENABLE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001187
Arif Hussain6d2a3322013-11-17 19:50:10 -08001188 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001189
Amar Singhald53568e2013-09-26 11:03:45 -07001190 if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1191 pHddCtx->sus_res_mcastbcast_filter) ||
1192 (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
1193 pHddCtx->sus_res_mcastbcast_filter)) &&
1194 (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07001195 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301196 offLoadRequest.enableOrDisable =
Amar Singhald53568e2013-09-26 11:03:45 -07001197 SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
1198 hddLog(VOS_TRACE_LEVEL_INFO,
1199 "offload: inside arp offload conditional check");
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 }
Abhishek Singh937ec542016-01-05 18:03:14 +05301201 hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE,
1202 SIR_OFFLOAD_ENABLE);
Amar Singhald53568e2013-09-26 11:03:45 -07001203
1204 hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d",
1205 offLoadRequest.enableOrDisable);
1206
Jeff Johnson295189b2012-06-20 16:38:30 -07001207 //converting u32 to IPV4 address
1208 for(i = 0 ; i < 4; i++)
1209 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301210 offLoadRequest.params.hostIpv4Addr[i] =
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 (ifa->ifa_local >> (i*8) ) & 0xFF ;
1212 }
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301213 hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001214 offLoadRequest.params.hostIpv4Addr[0],
1215 offLoadRequest.params.hostIpv4Addr[1],
1216 offLoadRequest.params.hostIpv4Addr[2],
1217 offLoadRequest.params.hostIpv4Addr[3]);
1218
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301219 if (eHAL_STATUS_SUCCESS !=
1220 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1221 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001222 {
1223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001224 "feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 return VOS_STATUS_E_FAILURE;
1226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 }
1228 else
1229 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301230 hddLog(VOS_TRACE_LEVEL_WARN, FL("IP Address is not assigned"));
Agarwal Ashish971c2882013-10-30 20:11:12 +05301231 return VOS_STATUS_E_AGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301233
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05301234 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001235 }
1236 else
1237 {
1238 vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
1239 offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
1240 offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
Abhishek Singh937ec542016-01-05 18:03:14 +05301241 hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
1242 SIR_OFFLOAD_DISABLE);
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301243 if (eHAL_STATUS_SUCCESS !=
1244 sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1245 pAdapter->sessionId, &offLoadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07001246 {
1247 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001248 "offload feature", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001249 return VOS_STATUS_E_FAILURE;
1250 }
1251 return VOS_STATUS_SUCCESS;
1252 }
1253}
1254
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301255/*
1256 * This function is called before setting mcbc filters
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301257 * to modify filter value considering Different Offloads
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301258*/
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301259void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301260 tANI_U8 *pMcBcFilter)
1261{
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301262 if (NULL == pHddCtx)
1263 {
1264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed"));
1265 return;
1266 }
1267
1268 *pMcBcFilter = pHddCtx->configuredMcastBcastFilter;
1269 if (pHddCtx->cfg_ini->fhostArpOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301270 {
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301271 /* ARP offload is enabled, do not block bcast packets at RXP
1272 * Will be using Bitmasking to reset the filter. As we have
1273 * disable Broadcast filtering, Anding with the negation
1274 * of Broadcast BIT
1275 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301276 hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301277 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301278 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301279
1280#ifdef WLAN_NS_OFFLOAD
1281 if (pHddCtx->cfg_ini->fhostNSOffload)
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301282 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301283 /* NS offload is enabled, do not block mcast packets at RXP
1284 * Will be using Bitmasking to reset the filter. As we have
1285 * disable Multicast filtering, Anding with the negation
1286 * of Multicast BIT
1287 */
Agarwal Ashishff451a32015-07-28 01:01:29 +05301288 hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled"));
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301289 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301290 }
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301291#endif
1292
Amar Singhald08ce752014-03-21 16:28:27 -07001293 if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1294 {
1295 *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1296 }
1297
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301298 pHddCtx->configuredMcastBcastFilter = *pMcBcFilter;
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301299}
1300
Jeff Johnson295189b2012-06-20 16:38:30 -07001301void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter)
1302{
1303 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001304 tpSirWlanSetRxpFilters wlanRxpFilterParam =
1305 vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
Agarwal Ashishff451a32015-07-28 01:01:29 +05301306 if (NULL == wlanRxpFilterParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001307 {
1308 hddLog(VOS_TRACE_LEVEL_FATAL,
1309 "%s: vos_mem_alloc failed ", __func__);
1310 return;
1311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001312 hddLog(VOS_TRACE_LEVEL_INFO,
1313 "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301314 if (TRUE == setfilter)
1315 {
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301316 hdd_mcbc_filter_modification(pHddCtx,
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301317 &wlanRxpFilterParam->configuredMcstBcstFilterSetting);
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301318 }
1319 else
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301320 {
1321 /*Use the current configured value to clear*/
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301322 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05301323 pHddCtx->configuredMcastBcastFilter;
1324 }
Gopichand Nakkalab8ddf462013-02-20 18:53:50 +05301325
Jeff Johnson295189b2012-06-20 16:38:30 -07001326 wlanRxpFilterParam->setMcstBcstFilter = setfilter;
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam);
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301328
1329 if (setfilter && (eHAL_STATUS_SUCCESS == halStatus))
Agarwal Ashishff451a32015-07-28 01:01:29 +05301330 {
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301331 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Agarwal Ashishff451a32015-07-28 01:01:29 +05301332 }
Masti, Narayanraddibdc261d2015-01-22 15:59:49 +05301333
1334 hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to"
1335 "lower mac with status %d"
1336 "configuredMcstBcstFilterSetting = %d"
1337 "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ?
1338 "Failed" : "Success", halStatus,
1339 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
1340 wlanRxpFilterParam->setMcstBcstFilter);
1341
Chilam Ngc4244af2013-04-01 15:37:32 -07001342 if (eHAL_STATUS_SUCCESS != halStatus)
1343 vos_mem_free(wlanRxpFilterParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001344}
1345
mukul sharmae4abd892016-11-24 22:03:31 +05301346/*
1347 * Enable/Disable McAddrList cfg item in fwr.
1348 */
1349eHalStatus hdd_set_mc_list_cfg_item(hdd_context_t* pHddCtx,
1350 bool value)
1351{
1352 eHalStatus ret_val;
1353
1354 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST,
1355 value, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1356 {
1357 ret_val = eHAL_STATUS_FAILURE;
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301358 hddLog(LOGE,
1359 FL("offload: can't pass WNI_CFG_ENABLE_MC_ADDR_LIST to CCM"));
mukul sharmae4abd892016-11-24 22:03:31 +05301360 return ret_val;
1361 }
1362
1363 ret_val = sme_update_cfg_int_param(pHddCtx->hHal,
1364 WNI_CFG_ENABLE_MC_ADDR_LIST);
1365 if (!HAL_STATUS_SUCCESS(ret_val))
1366 {
1367 hddLog(VOS_TRACE_LEVEL_ERROR,
1368 FL("Failed to toggle MC_ADDR_LIST_INI %d "),
1369 ret_val);
1370 return ret_val;
1371 }
1372 /* cache the value configured in fwr */
1373 pHddCtx->mc_list_cfg_in_fwr = value;
mukul sharmae4abd892016-11-24 22:03:31 +05301374 return eHAL_STATUS_SUCCESS;
1375}
1376
1377bool is_mc_list_cfg_disable_required(hdd_context_t* pHddCtx)
1378{
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301379 hddLog(VOS_TRACE_LEVEL_INFO,
1380 FL("offload: fEnableMCList %d sus_res_mcbc_filter %d mc_list_in_fwr %d"),
1381 pHddCtx->cfg_ini->fEnableMCAddrList,
1382 pHddCtx->sus_res_mcastbcast_filter,
1383 pHddCtx->mc_list_cfg_in_fwr);
1384
mukul sharmae4abd892016-11-24 22:03:31 +05301385 /*
1386 * If MCAddrList is enabled in ini and MCBC filter is set to
1387 * Either Filter None or Filter all BC then, Fwr need to push
1388 * all MC to host. This can be achieved by disabling cfg MCAddrList
1389 * in fwr. As in driver load, firmware have this value to 1 we
1390 * need to set it to 0. Same needs to be reverted on resume.
1391 */
1392 if (pHddCtx->cfg_ini->fEnableMCAddrList &&
1393 WDA_IS_MCAST_FLT_ENABLE_IN_FW &&
1394 ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)&&
1395 ((HDD_MCASTBCASTFILTER_FILTER_NONE ==
1396 pHddCtx->sus_res_mcastbcast_filter) ||
1397 (HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
1398 pHddCtx->sus_res_mcastbcast_filter)))
1399 )
1400 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301401 hddLog(VOS_TRACE_LEVEL_INFO,
1402 FL("offload: cfg ini need to disable in fwr"));
mukul sharmae4abd892016-11-24 22:03:31 +05301403 return true;
1404 }
1405 else
1406 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301407 hddLog(VOS_TRACE_LEVEL_INFO,
1408 FL("offload: cfg ini disable not needed "));
mukul sharmae4abd892016-11-24 22:03:31 +05301409 return false;
1410 }
1411}
1412
1413/**
1414 * hdd_mc_addr_list_cfg_config() - To set mc list cfg configuration in fwr
1415 * @pHddCtx: hdd context handle
1416 * @action: true to disable MCAddrList in fwr to get all MC pkt to host
1417 * false to set ini value of MCAddrList in fwr if it was toggled
1418 * Return: none
1419 *
1420 * Ensure Below API is invoked always post modification
1421 * of sus_res_mcastbcast_filter.
1422 */
1423void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action)
1424{
1425 if (action)
1426 {
1427 /* check host need to disable mc list ini in fwr */
1428 if (is_mc_list_cfg_disable_required(pHddCtx))
1429 {
1430 /*
1431 * Yes Host should disable the mc list in fwr
1432 * But Ensure host might already disable it
1433 * This can happen when user issue set/clear MCBC
1434 * ioctl with 2 to 0 or vice versa.
1435 */
1436 if (pHddCtx->cfg_ini->fEnableMCAddrList ==
1437 pHddCtx->mc_list_cfg_in_fwr)
1438 {
1439 hdd_set_mc_list_cfg_item(pHddCtx,
1440 !pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301441 hddLog(VOS_TRACE_LEVEL_INFO,
1442 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1443 !pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301444 }
1445 }
1446 else
1447 {
1448 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1449 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1450 pHddCtx->mc_list_cfg_in_fwr)
1451 {
1452 hdd_set_mc_list_cfg_item(pHddCtx,
1453 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301454 hddLog(VOS_TRACE_LEVEL_INFO,
1455 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1456 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301457 }
1458 }
1459 }
1460 else
1461 {
1462 /* Host toggled mc list ini in fwr previosuly, set to ini value */
1463 if (pHddCtx->cfg_ini->fEnableMCAddrList !=
1464 pHddCtx->mc_list_cfg_in_fwr)
1465 {
1466 hdd_set_mc_list_cfg_item(pHddCtx,
1467 pHddCtx->cfg_ini->fEnableMCAddrList);
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301468 hddLog(VOS_TRACE_LEVEL_INFO,
1469 FL("offload: setting mc_list_cfg_in_fwr: %d"),
1470 pHddCtx->cfg_ini->fEnableMCAddrList);
mukul sharmae4abd892016-11-24 22:03:31 +05301471 }
1472 }
1473}
1474
Jeff Johnson295189b2012-06-20 16:38:30 -07001475static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx,
1476 hdd_adapter_t *pAdapter)
1477{
1478 eHalStatus halStatus = eHAL_STATUS_FAILURE;
1479 tpSirWlanSuspendParam wlanSuspendParam =
1480 vos_mem_malloc(sizeof(tSirWlanSuspendParam));
1481
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301482 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001483 if(NULL == wlanSuspendParam)
1484 {
1485 hddLog(VOS_TRACE_LEVEL_FATAL,
1486 "%s: vos_mem_alloc failed ", __func__);
1487 return;
1488 }
1489
Amar Singhald53568e2013-09-26 11:03:45 -07001490 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001491 "%s: send wlan suspend indication", __func__);
1492
1493 if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER))
1494 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301495 //Configure supported OffLoads
1496 hdd_conf_hostoffload(pAdapter, TRUE);
1497 wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter;
Sushant Kaushik439d4c72014-05-12 16:39:51 +05301498 hddLog(VOS_TRACE_LEVEL_INFO,
1499 FL("saving configuredMcastBcastFilterSetting = %d"),
1500 wlanSuspendParam->configuredMcstBcstFilterSetting);
Jeff Johnson295189b2012-06-20 16:38:30 -07001501#ifdef WLAN_FEATURE_PACKET_FILTERING
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301502 /* During suspend, configure MC Addr list filter to the firmware
1503 * function takes care of checking necessary conditions before
1504 * configuring.
1505 */
1506 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001507#endif
Amar Singhald08ce752014-03-21 16:28:27 -07001508
1509 if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW)
1510 {
1511
1512 hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set ");
1513 pHddCtx->configuredMcastBcastFilter &=
1514 ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST);
1515 }
1516
1517 wlanSuspendParam->configuredMcstBcstFilterSetting =
1518 pHddCtx->configuredMcastBcastFilter;
mukul sharmae4abd892016-11-24 22:03:31 +05301519
1520 /* mc add list cfg item configuration in fwr */
1521 hdd_mc_addr_list_cfg_config(pHddCtx, true);
1522
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 }
1524
1525 halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam);
1526 if(eHAL_STATUS_SUCCESS == halStatus)
1527 {
1528 pHddCtx->hdd_mcastbcast_filter_set = TRUE;
Chilam Ngc4244af2013-04-01 15:37:32 -07001529 } else {
c_hpothuffdb5272013-10-02 16:42:35 +05301530 hddLog(VOS_TRACE_LEVEL_ERROR,
1531 FL("sme_ConfigureSuspendInd returned failure %d"), halStatus);
Chilam Ngc4244af2013-04-01 15:37:32 -07001532 vos_mem_free(wlanSuspendParam);
Jeff Johnson295189b2012-06-20 16:38:30 -07001533 }
1534}
1535
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301536static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07001537{
Chilam Ngc4244af2013-04-01 15:37:32 -07001538 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Yathish9f22e662012-12-10 14:21:35 -08001539 hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam Ngc4244af2013-04-01 15:37:32 -07001540 tpSirWlanResumeParam wlanResumeParam;
Jeff Johnson295189b2012-06-20 16:38:30 -07001541
Gopichand Nakkala0f276812013-02-24 14:45:51 +05301542 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 "%s: send wlan resume indication", __func__);
1544
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301545 wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam));
1546
1547 if (NULL == wlanResumeParam)
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 {
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301549 hddLog(VOS_TRACE_LEVEL_FATAL,
1550 "%s: memory allocation failed for wlanResumeParam ", __func__);
1551 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001553
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301554 //Disable supported OffLoads
1555 hdd_conf_hostoffload(pAdapter, FALSE);
1556
1557 wlanResumeParam->configuredMcstBcstFilterSetting =
1558 pHddCtx->configuredMcastBcastFilter;
1559 halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam);
1560 if (eHAL_STATUS_SUCCESS != halStatus)
1561 {
c_hpothuffdb5272013-10-02 16:42:35 +05301562 hddLog(VOS_TRACE_LEVEL_ERROR,
1563 "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301564 vos_mem_free(wlanResumeParam);
1565 }
1566
1567 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
mukul sharmae4abd892016-11-24 22:03:31 +05301568 /* mc add list cfg item configuration in fwr */
1569 hdd_mc_addr_list_cfg_config(pHddCtx, false);
Madan Mohan Koyyalamudia6d7eab2013-09-25 10:21:22 +05301570
Amar Singhalf8ba2b82013-12-02 12:54:38 -08001571 if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
1572 pHddCtx->configuredMcastBcastFilter =
1573 pHddCtx->sus_res_mcastbcast_filter;
1574 pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
1575 }
Amar Singhald53568e2013-09-26 11:03:45 -07001576
1577 hddLog(VOS_TRACE_LEVEL_INFO,
1578 "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
1579 hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
1580 pHddCtx->configuredMcastBcastFilter);
Amar Singhal49fdfd52013-08-13 13:25:12 -07001581
Chilam Ngc4244af2013-04-01 15:37:32 -07001582
madan mohan koyyalamudibfd9cef2013-07-01 18:39:37 +05301583#ifdef WLAN_FEATURE_PACKET_FILTERING
1584 /* Filer was applied during suspend inditication
1585 * clear it when we resume.
1586 */
1587 wlan_hdd_set_mc_addr_list(pAdapter, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001588#endif
1589}
Jeff Johnson295189b2012-06-20 16:38:30 -07001590
Jeff Johnson295189b2012-06-20 16:38:30 -07001591//Suspend routine registered with Android OS
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001592void hdd_suspend_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001593{
1594 hdd_context_t *pHddCtx = NULL;
1595 v_CONTEXT_t pVosContext = NULL;
1596
Jeff Johnson295189b2012-06-20 16:38:30 -07001597 VOS_STATUS status;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301598 hdd_adapter_t *pAdapter = NULL;
1599 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301600 bool hdd_enter_bmps = FALSE;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001601
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__);
1603
1604 //Get the global VOSS context.
1605 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1606 if(!pVosContext) {
1607 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1608 return;
1609 }
1610
1611 //Get the HDD context.
1612 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1613
1614 if(!pHddCtx) {
1615 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1616 return;
1617 }
1618
1619 if (pHddCtx->isLogpInProgress) {
1620 hddLog(VOS_TRACE_LEVEL_ERROR,
1621 "%s: Ignore suspend wlan, LOGP in progress!", __func__);
1622 return;
1623 }
1624
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301625 if (pHddCtx->hdd_wlan_suspended)
1626 {
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05301627 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301628 "%s: Ignore suspend wlan, Already suspended!", __func__);
1629 return;
1630 }
1631
Mahesh A Saptasagar0ea15c22014-10-28 15:26:57 +05301632 pHddCtx->hdd_wlan_suspended = TRUE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301633 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301634 hdd_set_pwrparams(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001635 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1636 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1637 {
1638 pAdapter = pAdapterNode->pAdapter;
1639 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001640 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001641 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
1642
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001643 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1645 pAdapterNode = pNext;
1646 continue;
1647 }
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301648 /* Avoid multiple enter/exit BMPS in this while loop using
1649 * hdd_enter_bmps flag
1650 */
1651 if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal)))
1652 {
1653 hdd_enter_bmps = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001654
madan mohan koyyalamudi459d6e72013-07-09 23:36:00 +05301655 /* If device was already in BMPS, and dynamic DTIM is set,
1656 * exit(set the device to full power) and enter BMPS again
1657 * to reflect new DTIM value */
1658 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
1659
1660 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
1661
1662 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1663 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001664#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1665 if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1666 {
1667 //stop the interface before putting the chip to standby
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301668 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 netif_tx_disable(pAdapter->dev);
1670 netif_carrier_off(pAdapter->dev);
1671 }
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301672 else if (pHddCtx->cfg_ini->nEnableSuspend ==
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 WLAN_MAP_SUSPEND_TO_DEEP_SLEEP)
1674 {
1675 //Execute deep sleep procedure
1676 hdd_enter_deep_sleep(pHddCtx, pAdapter);
1677 }
1678#endif
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301679
1680 /*Suspend notification sent down to driver*/
1681 hdd_conf_suspend_ind(pHddCtx, pAdapter);
1682
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05301683 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1684 pAdapterNode = pNext;
1685 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301686
Jeff Johnson295189b2012-06-20 16:38:30 -07001687#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
1688 if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY)
1689 {
1690 hdd_enter_standby(pHddCtx);
1691 }
1692#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001693
1694 return;
1695}
1696
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301697/**
1698 * @brief hdd_ReConfigSuspendDataClearedDuringRoaming() - Reconfigure the
1699 * suspend related data which was cleared during roaming in FWR.
1700 */
1701void hdd_ReConfigSuspendDataClearedDuringRoaming(hdd_context_t *pHddCtx)
1702
1703{
1704 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
1705 hdd_adapter_t *pAdapter;
1706 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1707
1708 ENTER();
1709
1710 spin_lock(&pHddCtx->filter_lock);
1711 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
1712 spin_unlock(&pHddCtx->filter_lock);
1713
1714 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
1715 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Not able to set mcast/bcast filter "));
1717
1718 vstatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1719 //No need to configure GTK Offload from here because it might possible
1720 //cfg80211_set_rekey_data might not yet came, anyway GTK offload will
1721 //be handled as part of cfg80211_set_rekey_data processing.
1722 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vstatus )
1723 {
1724 pAdapter = pAdapterNode->pAdapter;
1725 if( pAdapter &&
1726 (( pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
1727 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)))
1728 {
1729 if (pHddCtx->cfg_ini->fhostArpOffload)
1730 {
1731 //Configure ARPOFFLOAD
1732 vstatus = hdd_conf_arp_offload(pAdapter, TRUE);
1733 if (!VOS_IS_STATUS_SUCCESS(vstatus))
1734 {
1735 hddLog(VOS_TRACE_LEVEL_INFO,
1736 FL("Failed to disable ARPOffload Feature %d"), vstatus);
1737 }
1738 }
1739#ifdef WLAN_NS_OFFLOAD
1740 //Configure NSOFFLOAD
1741 if (pHddCtx->cfg_ini->fhostNSOffload)
1742 {
1743 hdd_conf_ns_offload(pAdapter, TRUE);
1744 }
1745#endif
1746#ifdef WLAN_FEATURE_PACKET_FILTERING
1747 /* During suspend, configure MC Addr list filter to the firmware
1748 * function takes care of checking necessary conditions before
1749 * configuring.
1750 */
1751 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
1752#endif
1753 }
1754 vstatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1755 pAdapterNode = pNext;
1756 }
1757 EXIT();
1758}
1759
Jeff Johnson295189b2012-06-20 16:38:30 -07001760static void hdd_PowerStateChangedCB
1761(
1762 v_PVOID_t callbackContext,
1763 tPmcState newState
1764)
1765{
1766 hdd_context_t *pHddCtx = callbackContext;
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301767
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 /* if the driver was not in BMPS during early suspend,
1769 * the dynamic DTIM is now updated at Riva */
1770 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended
Abhishek Singh0ea13232016-02-12 16:46:10 +05301771 && (pHddCtx->cfg_ini->enableDynamicDTIM ||
1772 pHddCtx->cfg_ini->enableModulatedDTIM)
Jeff Johnson295189b2012-06-20 16:38:30 -07001773 && (pHddCtx->hdd_ignore_dtim_enabled == FALSE))
1774 {
1775 pHddCtx->hdd_ignore_dtim_enabled = TRUE;
1776 }
1777 spin_lock(&pHddCtx->filter_lock);
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301778 if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended)
1779 {
Mukul Sharma75ee8aa2016-12-01 14:28:10 +05301780 check_and_set_suspend_resume_mcbc_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001781 spin_unlock(&pHddCtx->filter_lock);
1782 hdd_conf_mcastbcast_filter(pHddCtx, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 if(pHddCtx->hdd_mcastbcast_filter_set != TRUE)
1784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__);
Mukul Sharmabb94ece2014-04-04 21:22:15 +05301785 }
Amar Singhal49fdfd52013-08-13 13:25:12 -07001786 else
Mihir Shete793209f2014-01-06 11:01:12 +05301787 {
1788 /* Android framework can send resume request when the WCN chip is
1789 * in IMPS mode. When the chip exits IMPS mode the firmware will
1790 * restore all the registers to the state they were before the chip
1791 * entered IMPS and so our hardware filter settings confgured by the
1792 * resume request will be lost. So reconfigure the filters on detecting
1793 * a change in the power state of the WCN chip.
1794 */
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301795 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301796 if (IMPS != newState)
1797 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301798 spin_lock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301799 if (FALSE == pHddCtx->hdd_wlan_suspended)
1800 {
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301801 spin_unlock(&pHddCtx->filter_lock);
Mihir Shete793209f2014-01-06 11:01:12 +05301802 hddLog(VOS_TRACE_LEVEL_INFO,
1803 "Not in IMPS/BMPS and suspended state");
1804 hdd_conf_mcastbcast_filter(pHddCtx, FALSE);
1805 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301806 else
1807 {
1808 spin_unlock(&pHddCtx->filter_lock);
1809 }
Mihir Shete793209f2014-01-06 11:01:12 +05301810 }
Agarwal Ashish469b1e52014-01-17 09:13:10 +05301811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001812}
1813
Jeff Johnson295189b2012-06-20 16:38:30 -07001814void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx)
1815{
1816 v_CONTEXT_t pVosContext;
1817 tHalHandle smeContext;
1818
1819 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1820 if (NULL == pVosContext)
1821 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001822 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 return;
1824 }
1825 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1826 if (NULL == smeContext)
1827 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001828 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001829 return;
1830 }
1831
1832 spin_lock_init(&pHddCtx->filter_lock);
1833 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1834 pHddCtx->cfg_ini->nEnableSuspend)
1835 {
1836 pmcRegisterDeviceStateUpdateInd(smeContext,
1837 hdd_PowerStateChangedCB, pHddCtx);
1838 }
1839}
1840
1841void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx)
1842{
1843 v_CONTEXT_t pVosContext;
1844 tHalHandle smeContext;
1845
1846 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1847 if (NULL == pVosContext)
1848 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001849 hddLog(LOGE, "%s: Invalid pContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001850 return;
1851 }
1852 smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext);
1853 if (NULL == smeContext)
1854 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001855 hddLog(LOGE, "%s: Invalid smeContext", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001856 return;
1857 }
1858
1859 if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER ==
1860 pHddCtx->cfg_ini->nEnableSuspend)
1861 {
1862 pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB);
1863 }
1864}
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301865
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301866#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301867void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301868{
1869 eHalStatus ret;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301870 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301871 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1872
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301873 if(fenable)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301874 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301875 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1876 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags ))
1877 {
1878 vos_mem_copy(&hddGtkOffloadReqParams,
1879 &pHddStaCtx->gtkOffloadReqParams,
1880 sizeof (tSirGtkOffloadParams));
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301881
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301882 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
1883 &hddGtkOffloadReqParams, pAdapter->sessionId);
1884 if (eHAL_STATUS_SUCCESS != ret)
1885 {
1886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1887 "%s: sme_SetGTKOffload failed, returned %d",
1888 __func__, ret);
1889 return;
1890 }
1891
1892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1893 "%s: sme_SetGTKOffload successfull", __func__);
1894 }
1895
1896 }
1897 else
1898 {
1899 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1900 (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId,
1901 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) &&
1902 (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags))
1903 {
1904
1905 /* Host driver has previously offloaded GTK rekey */
1906 ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301907 wlan_hdd_cfg80211_update_replayCounterCallback,
1908 pAdapter, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301909 if (eHAL_STATUS_SUCCESS != ret)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301910
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301911 {
1912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1913 "%s: sme_GetGTKOffload failed, returned %d",
1914 __func__, ret);
1915 return;
1916 }
1917 else
1918 {
1919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1920 "%s: sme_GetGTKOffload successful",
1921 __func__);
1922
1923 /* Sending GTK offload dissable */
1924 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
1925 sizeof (tSirGtkOffloadParams));
1926 hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1927 ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05301928 &hddGtkOffloadReqParams, pAdapter->sessionId);
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301929 if (eHAL_STATUS_SUCCESS != ret)
1930 {
1931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1932 "%s: failed to dissable GTK offload, returned %d",
1933 __func__, ret);
1934 return;
1935 }
1936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1937 "%s: successfully dissabled GTK offload request to HAL",
1938 __func__);
1939 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301940 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301941 }
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05301942 return;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05301943}
1944#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001945
Sameer Thalappil45931fb2013-02-01 11:18:05 -08001946void hdd_resume_wlan(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07001947{
1948 hdd_context_t *pHddCtx = NULL;
1949 hdd_adapter_t *pAdapter = NULL;
1950 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1951 VOS_STATUS status;
1952 v_CONTEXT_t pVosContext = NULL;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08001953
Jeff Johnson295189b2012-06-20 16:38:30 -07001954 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__);
1955
1956 //Get the global VOSS context.
1957 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
1958 if(!pVosContext) {
1959 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
1960 return;
1961 }
1962
1963 //Get the HDD context.
1964 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
1965
1966 if(!pHddCtx) {
1967 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
1968 return;
1969 }
1970
Agarwal Ashish971c2882013-10-30 20:11:12 +05301971 if (pHddCtx->isLogpInProgress)
1972 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 hddLog(VOS_TRACE_LEVEL_INFO,
1974 "%s: Ignore resume wlan, LOGP in progress!", __func__);
1975 return;
1976 }
1977
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301978 if (!pHddCtx->hdd_wlan_suspended)
1979 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05301980 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar2ee1ad02015-01-12 16:05:47 +05301981 "%s: Ignore resume wlan, Already resumed!", __func__);
1982 return;
1983 }
1984
Jeff Johnson295189b2012-06-20 16:38:30 -07001985 pHddCtx->hdd_wlan_suspended = FALSE;
Abhishek Singh37471cd2016-01-05 17:09:57 +05301986 hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 /*loop through all adapters. Concurrency */
1988 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1989
1990 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1991 {
1992 pAdapter = pAdapterNode->pAdapter;
1993 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001994 && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Madan Mohan Koyyalamudi802d7582012-10-31 14:19:40 -07001996 { // we skip this registration for modes other than STA, SAP and P2P client modes.
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1998 pAdapterNode = pNext;
1999 continue;
2000 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302001
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05302002
Jeff Johnson295189b2012-06-20 16:38:30 -07002003#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2004 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP)
2005 {
2006 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__);
2007 hdd_exit_deep_sleep(pAdapter);
2008 }
2009#endif
2010
2011 if(pHddCtx->hdd_ignore_dtim_enabled == TRUE)
2012 {
2013 /*Switch back to DTIM 1*/
2014 tSirSetPowerParamsReq powerRequest = { 0 };
2015
2016 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
2017 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07002018 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002019
2020 /*Disabled ModulatedDTIM if enabled on suspend*/
2021 if(pHddCtx->cfg_ini->enableModulatedDTIM)
2022 powerRequest.uDTIMPeriod = 0;
2023
2024 /* Update ignoreDTIM and ListedInterval in CFG with default values */
2025 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
2026 NULL, eANI_BOOLEAN_FALSE);
2027 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
2028 NULL, eANI_BOOLEAN_FALSE);
2029
2030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002031 "Switch to DTIM%d",powerRequest.uListenInterval);
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08002032 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002033
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302034 if (BMPS == pmcGetPmcState(pHddCtx->hHal))
2035 {
2036 /* put the device into full power */
2037 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002038
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302039 /* put the device back into BMPS */
2040 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
Jeff Johnson295189b2012-06-20 16:38:30 -07002041
Madan Mohan Koyyalamudi69b34182013-01-16 08:51:40 +05302042 pHddCtx->hdd_ignore_dtim_enabled = FALSE;
2043 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002044 }
2045
Gopichand Nakkala0f276812013-02-24 14:45:51 +05302046 hdd_conf_resume_ind(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002047 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2048 pAdapterNode = pNext;
2049 }
2050
2051#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP
2052 if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY)
2053 {
2054 hdd_exit_standby(pHddCtx);
2055 }
2056#endif
2057
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 return;
2059}
2060
Jeff Johnson295189b2012-06-20 16:38:30 -07002061VOS_STATUS hdd_wlan_reset_initialization(void)
2062{
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 v_CONTEXT_t pVosContext = NULL;
2064
2065 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__);
2066
2067 //Get the global VOSS context.
2068 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2069 if(!pVosContext)
2070 {
2071 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2072 return VOS_STATUS_E_FAILURE;
2073 }
2074
2075 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
2076
2077 // Prevent the phone from going to sleep
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302078 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002079
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 return VOS_STATUS_SUCCESS;
2081}
2082
2083
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002084/*
2085 * Based on the ioctl command recieved by HDD, put WLAN driver
2086 * into the quiet mode. This is the same as the early suspend
2087 * notification that driver used to listen
2088 */
2089void hdd_set_wlan_suspend_mode(bool suspend)
Jeff Johnson295189b2012-06-20 16:38:30 -07002090{
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302091 vos_ssr_protect(__func__);
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002092 if (suspend)
2093 hdd_suspend_wlan();
2094 else
2095 hdd_resume_wlan();
Sandeep Puligilla308288f2014-06-05 22:21:46 +05302096 vos_ssr_unprotect(__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002097}
2098
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002099static void hdd_ssr_timer_init(void)
2100{
2101 init_timer(&ssr_timer);
2102}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002103
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002104static void hdd_ssr_timer_del(void)
2105{
2106 del_timer(&ssr_timer);
2107 ssr_timer_started = false;
2108}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002109
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002110static void hdd_ssr_timer_cb(unsigned long data)
2111{
2112 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
Sameer Thalappile5637f42013-08-07 15:46:55 -07002113
2114#ifdef WCN_PRONTO
2115 if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
2116 wcnss_pronto_log_debug_regs();
2117#endif
2118
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002119 VOS_BUG(0);
2120}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002121
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002122static void hdd_ssr_timer_start(int msec)
2123{
2124 if(ssr_timer_started)
2125 {
2126 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running"
2127 ,__func__);
2128 }
2129 ssr_timer.expires = jiffies + msecs_to_jiffies(msec);
2130 ssr_timer.function = hdd_ssr_timer_cb;
2131 add_timer(&ssr_timer);
2132 ssr_timer_started = true;
2133}
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002134
Jeff Johnson295189b2012-06-20 16:38:30 -07002135/* the HDD interface to WLAN driver shutdown,
2136 * the primary shutdown function in SSR
2137 */
2138VOS_STATUS hdd_wlan_shutdown(void)
2139{
2140 VOS_STATUS vosStatus;
2141 v_CONTEXT_t pVosContext = NULL;
2142 hdd_context_t *pHddCtx = NULL;
2143 pVosSchedContext vosSchedContext = NULL;
2144
2145 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__);
2146
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002147 /* if re-init never happens, then do SSR1 */
2148 hdd_ssr_timer_init();
2149 hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME);
2150
Jeff Johnson295189b2012-06-20 16:38:30 -07002151 /* Get the global VOSS context. */
2152 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
2153 if(!pVosContext) {
2154 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
2155 return VOS_STATUS_E_FAILURE;
2156 }
2157 /* Get the HDD context. */
2158 pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2159 if(!pHddCtx) {
2160 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2161 return VOS_STATUS_E_FAILURE;
2162 }
c_hpothud662a352013-12-26 15:09:12 +05302163
2164 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +05302165 if ((pHddCtx->cfg_ini->dynSplitscan)&& (VOS_TIMER_STATE_RUNNING ==
2166 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
c_hpothud662a352013-12-26 15:09:12 +05302167 {
2168 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
2169 }
2170
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05302171 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Kapil Gupta137ef892016-12-13 19:38:00 +05302172 vos_flush_work(&pHddCtx->sap_start_work);
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 hdd_reset_all_adapters(pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +05302174
2175 /* set default value of Tcp delack and stop timer */
2176 hdd_set_default_stop_delack_timer(pHddCtx);
2177
Jeff Johnson295189b2012-06-20 16:38:30 -07002178 /* DeRegister with platform driver as client for Suspend/Resume */
2179 vosStatus = hddDeregisterPmOps(pHddCtx);
2180 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2181 {
2182 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
2183 }
2184
2185 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
2186 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2187 {
2188 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
2189 }
2190
2191 /* Disable IMPS/BMPS as we do not want the device to enter any power
2192 * save mode on its own during reset sequence
2193 */
2194 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
2195 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
2196 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
2197
2198 vosSchedContext = get_vos_sched_ctxt();
2199
2200 /* Wakeup all driver threads */
2201 if(TRUE == pHddCtx->isMcThreadSuspended){
2202 complete(&vosSchedContext->ResumeMcEvent);
2203 pHddCtx->isMcThreadSuspended= FALSE;
2204 }
2205 if(TRUE == pHddCtx->isTxThreadSuspended){
2206 complete(&vosSchedContext->ResumeTxEvent);
2207 pHddCtx->isTxThreadSuspended= FALSE;
2208 }
2209 if(TRUE == pHddCtx->isRxThreadSuspended){
2210 complete(&vosSchedContext->ResumeRxEvent);
2211 pHddCtx->isRxThreadSuspended= FALSE;
2212 }
2213 /* Reset the Suspend Variable */
2214 pHddCtx->isWlanSuspended = FALSE;
2215
2216 /* Stop all the threads; we do not want any messages to be a processed,
2217 * any more and the best way to ensure that is to terminate the threads
2218 * gracefully.
2219 */
2220 /* Wait for MC to exit */
2221 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302222 set_bit(MC_SHUTDOWN_EVENT, &vosSchedContext->mcEventFlag);
2223 set_bit(MC_POST_EVENT, &vosSchedContext->mcEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002224 wake_up_interruptible(&vosSchedContext->mcWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302225 wait_for_completion(&vosSchedContext->McShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002226
2227 /* Wait for TX to exit */
2228 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302229 set_bit(TX_SHUTDOWN_EVENT, &vosSchedContext->txEventFlag);
2230 set_bit(TX_POST_EVENT, &vosSchedContext->txEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 wake_up_interruptible(&vosSchedContext->txWaitQueue);
Mihir Sheteb5425f72013-12-19 09:06:13 +05302232 wait_for_completion(&vosSchedContext->TxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002233
2234 /* Wait for RX to exit */
2235 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__);
Mahesh A Saptasagar8b42b272016-02-24 16:22:45 +05302236 set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->rxEventFlag);
2237 set_bit(RX_POST_EVENT, &vosSchedContext->rxEventFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002238 wake_up_interruptible(&vosSchedContext->rxWaitQueue);
c_hpothuffdb5272013-10-02 16:42:35 +05302239
Mihir Sheteb5425f72013-12-19 09:06:13 +05302240 wait_for_completion(&vosSchedContext->RxShutdown);
Jeff Johnson295189b2012-06-20 16:38:30 -07002241
2242#ifdef WLAN_BTAMP_FEATURE
2243 vosStatus = WLANBAP_Stop(pVosContext);
2244 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2245 {
2246 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2247 "%s: Failed to stop BAP",__func__);
2248 }
2249#endif //WLAN_BTAMP_FEATURE
2250 vosStatus = vos_wda_shutdown(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302251 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2252 {
2253 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2254 "%s: Failed to stop wda %d", __func__, vosStatus);
2255 VOS_ASSERT(0);
2256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002257
2258 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__);
2259 /* Stop SME - Cannot invoke vos_stop as vos_stop relies
2260 * on threads being running to process the SYS Stop
2261 */
Kiet Lama72a2322013-11-15 11:18:11 +05302262 vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302263 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2264 {
2265 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2266 "%s: Failed to stop sme %d", __func__, vosStatus);
2267 VOS_ASSERT(0);
2268 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002269
2270 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__);
2271 /* Stop MAC (PE and HAL) */
2272 vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET);
c_hpothuffdb5272013-10-02 16:42:35 +05302273 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2274 {
2275 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2276 "%s: Failed to stop mac %d", __func__, vosStatus);
2277 VOS_ASSERT(0);
2278 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002279
2280 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__);
2281 /* Stop TL */
2282 vosStatus = WLANTL_Stop(pVosContext);
c_hpothuffdb5272013-10-02 16:42:35 +05302283 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2284 {
2285 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2286 "%s: Failed to stop TL %d", __func__, vosStatus);
2287 VOS_ASSERT(0);
2288 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002289
Jeff Johnson295189b2012-06-20 16:38:30 -07002290 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002291 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__);
2292 /* Clean up message queues of TX and MC thread */
2293 vos_sched_flush_mc_mqs(vosSchedContext);
2294 vos_sched_flush_tx_mqs(vosSchedContext);
2295 vos_sched_flush_rx_mqs(vosSchedContext);
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302296#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2297 wlan_logging_flush_pkt_queue();
c_manjeecfd1efb2015-09-25 19:32:34 +05302298 /*Free fw dump mem in case of SSR/Shutdown */
2299 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
2300 wlan_free_fwr_mem_dump_buffer();
Siddharth Bhal7bd19932015-03-03 16:54:36 +05302301#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002302
2303 /* Deinit all the TX and MC queues */
2304 vos_sched_deinit_mqs(vosSchedContext);
2305 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__);
2306
2307 /* shutdown VOSS */
2308 vos_shutdown(pVosContext);
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05302309
2310 /*mac context has already been released in mac_close call
2311 so setting it to NULL in hdd context*/
2312 pHddCtx->hHal = (tHalHandle)NULL;
2313
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 if (free_riva_power_on_lock("wlan"))
2315 {
2316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
2317 __func__);
2318 }
2319 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete"
2320 ,__func__);
2321 return VOS_STATUS_SUCCESS;
2322}
2323
2324
2325
2326/* the HDD interface to WLAN driver re-init.
2327 * This is called to initialize/start WLAN driver after a shutdown.
2328 */
2329VOS_STATUS hdd_wlan_re_init(void)
2330{
2331 VOS_STATUS vosStatus;
2332 v_CONTEXT_t pVosContext = NULL;
2333 hdd_context_t *pHddCtx = NULL;
2334 eHalStatus halStatus;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002335#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2336 int max_retries = 0;
2337#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302338#ifdef HAVE_CBC_DONE
2339 int max_cbc_retries = 0;
2340#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002341#ifdef WLAN_BTAMP_FEATURE
2342 hdd_config_t *pConfig = NULL;
2343 WLANBAP_ConfigType btAmpConfig;
2344#endif
2345
Katya Nigam82a93062014-06-04 15:15:36 +05302346 struct device *dev = NULL;
Madan Mohan Koyyalamudib0e70642012-10-11 12:20:22 -07002347 hdd_ssr_timer_del();
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302348 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002349
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002350#ifdef HAVE_WCNSS_CAL_DOWNLOAD
2351 /* wait until WCNSS driver downloads NV */
Yue Ma120f9ff2014-02-26 14:53:31 -08002352 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002353 msleep(1000);
2354 }
Yue Ma120f9ff2014-02-26 14:53:31 -08002355 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07002356 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
2357 goto err_re_init;
2358 }
2359#endif
2360
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05302361#ifdef HAVE_CBC_DONE
2362 while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) {
2363 msleep(1000);
2364 }
2365 if (max_cbc_retries >= 20) {
2366 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
2367 }
2368#endif
2369
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002370 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE);
2371
Sameer Thalappil5d7a33f2013-01-30 08:36:16 -08002372 /* The driver should always be initialized in STA mode after SSR */
2373 hdd_set_conparam(0);
2374
Katya Nigam82a93062014-06-04 15:15:36 +05302375 dev = wcnss_wlan_get_device();
2376 if (NULL == dev)
2377 {
2378 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__);
2379 goto err_re_init;
2380 }
2381
Jeff Johnson295189b2012-06-20 16:38:30 -07002382 /* Re-open VOSS, it is a re-open b'se control transport was never closed. */
Katya Nigam82a93062014-06-04 15:15:36 +05302383 vosStatus = vos_open(&pVosContext, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002384 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2385 {
2386 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__);
2387 goto err_re_init;
2388 }
2389
2390 /* Get the HDD context. */
2391 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
2392 if(!pHddCtx)
2393 {
2394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
2395 goto err_vosclose;
2396 }
2397
2398 /* Save the hal context in Adapter */
2399 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
2400 if ( NULL == pHddCtx->hHal )
2401 {
2402 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__);
2403 goto err_vosclose;
2404 }
2405
2406 /* Set the SME configuration parameters. */
2407 vosStatus = hdd_set_sme_config(pHddCtx);
2408 if ( VOS_STATUS_SUCCESS != vosStatus )
2409 {
2410 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__);
2411 goto err_vosclose;
2412 }
2413
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 vosStatus = vos_preStart( pHddCtx->pvosContext );
2415 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2416 {
2417 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__);
2418 goto err_vosclose;
2419 }
2420
2421 /* In the integrated architecture we update the configuration from
2422 the INI file and from NV before vOSS has been started so that
2423 the final contents are available to send down to the cCPU */
2424 /* Apply the cfg.ini to cfg.dat */
2425 if (FALSE == hdd_update_config_dat(pHddCtx))
2426 {
2427 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
2428 goto err_vosclose;
2429 }
2430
2431 /* Set the MAC Address, currently this is used by HAL to add self sta.
2432 * Remove this once self sta is added as part of session open. */
2433 halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID,
2434 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
2435 sizeof(pHddCtx->cfg_ini->intfMacAddr[0]));
2436 if (!HAL_STATUS_SUCCESS(halStatus))
2437 {
2438 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
2439 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus);
2440 goto err_vosclose;
2441 }
2442
2443 /* Start VOSS which starts up the SME/MAC/HAL modules and everything else
2444 Note: Firmware image will be read and downloaded inside vos_start API */
2445 vosStatus = vos_start( pVosContext );
2446 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2447 {
2448 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +05302449 if (isSsrPanicOnFailure())
2450 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07002451 goto err_vosclose;
2452 }
2453
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07002454 /* Exchange capability info between Host and FW and also get versioning info from FW */
2455 hdd_exchange_version_and_caps(pHddCtx);
2456
Jeff Johnson295189b2012-06-20 16:38:30 -07002457 vosStatus = hdd_post_voss_start_config( pHddCtx );
2458 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2459 {
2460 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
2461 __func__);
2462 goto err_vosstop;
2463 }
2464
Mihir Shete04206452014-11-20 17:50:58 +05302465#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302466 vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT);
2467 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2468 {
2469 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
2470 __func__);
2471 goto err_vosstop;
2472 }
Mihir Shete04206452014-11-20 17:50:58 +05302473#endif
Agarwal Ashish6db9d532014-09-30 18:19:10 +05302474
Jeff Johnson295189b2012-06-20 16:38:30 -07002475#ifdef WLAN_BTAMP_FEATURE
2476 vosStatus = WLANBAP_Open(pVosContext);
2477 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2478 {
2479 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2480 "%s: Failed to open BAP",__func__);
2481 goto err_vosstop;
2482 }
2483 vosStatus = BSL_Init(pVosContext);
2484 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2485 {
2486 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2487 "%s: Failed to Init BSL",__func__);
2488 goto err_bap_close;
2489 }
2490 vosStatus = WLANBAP_Start(pVosContext);
2491 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2492 {
2493 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2494 "%s: Failed to start TL",__func__);
2495 goto err_bap_close;
2496 }
2497 pConfig = pHddCtx->cfg_ini;
2498 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
2499 vosStatus = WLANBAP_SetConfig(&btAmpConfig);
2500#endif //WLAN_BTAMP_FEATURE
2501
2502 /* Restart all adapters */
2503 hdd_start_all_adapters(pHddCtx);
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +05302504 pHddCtx->last_scan_reject_session_id = 0xFF;
2505 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +05302506 pHddCtx->last_scan_reject_timestamp = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002507 pHddCtx->hdd_mcastbcast_filter_set = FALSE;
Anand N Sunkad0cbc27a2014-09-18 12:58:18 +05302508 pHddCtx->btCoexModeSet = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 hdd_register_mcast_bcast_filter(pHddCtx);
Agarwal Ashish4b87f922014-06-18 03:03:21 +05302510 wlan_hdd_tdls_init(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 /* Register with platform driver as client for Suspend/Resume */
2512 vosStatus = hddRegisterPmOps(pHddCtx);
2513 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2514 {
2515 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
2516 goto err_bap_stop;
2517 }
Hanumantha Reddy Pothulab7dd9972015-07-01 12:24:57 +05302518
2519#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
2520 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
2521 (pHddCtx->cfg_ini->enableFWLogging ||
2522 pHddCtx->cfg_ini->enableMgmtLogging ||
2523 pHddCtx->cfg_ini->enableContFWLogging))
2524 {
2525 hdd_init_frame_logging(pHddCtx);
2526 }
2527#endif
2528
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302530 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Jeff Johnson295189b2012-06-20 16:38:30 -07002531 /* register for riva power on lock */
2532 if (req_riva_power_on_lock("wlan"))
2533 {
2534 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
2535 __func__);
2536 goto err_unregister_pmops;
2537 }
Gupta, Kapil7c34b322015-09-30 13:12:35 +05302538 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002539 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Deepthi Gowri1ca95bb2016-01-13 19:47:53 +05302540
2541 sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame);
2542
Dasari Srinivas421bde82014-06-25 12:01:44 +05302543#ifdef WLAN_FEATURE_EXTSCAN
2544 sme_EXTScanRegisterCallback(pHddCtx->hHal,
2545 wlan_hdd_cfg80211_extscan_callback,
2546 pHddCtx);
2547#endif /* WLAN_FEATURE_EXTSCAN */
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +05302548
2549#ifdef FEATURE_OEM_DATA_SUPPORT
2550 sme_OemDataRegisterCallback(pHddCtx->hHal,
2551 wlan_hdd_cfg80211_oemdata_callback,
2552 pHddCtx);
2553#endif /* FEATURE_OEM_DATA_SUPPORT */
2554
Jeff Johnson295189b2012-06-20 16:38:30 -07002555 goto success;
2556
2557err_unregister_pmops:
2558 hddDeregisterPmOps(pHddCtx);
2559
2560err_bap_stop:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002561#ifdef CONFIG_HAS_EARLYSUSPEND
2562 hdd_unregister_mcast_bcast_filter(pHddCtx);
2563#endif
2564 hdd_close_all_adapters(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002565#ifdef WLAN_BTAMP_FEATURE
Jeff Johnson32d95a32012-09-10 13:15:23 -07002566 WLANBAP_Stop(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002567#endif
2568
2569#ifdef WLAN_BTAMP_FEATURE
2570err_bap_close:
2571 WLANBAP_Close(pVosContext);
2572#endif
2573
2574err_vosstop:
2575 vos_stop(pVosContext);
2576
2577err_vosclose:
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302578 if(!isSsrPanicOnFailure())
2579 {
2580 /* If we hit this, it means wlan driver is in bad state and needs
2581 * driver unload and load.
2582 */
Pradeep Kumar Goudagunta22d8e4d2014-07-17 15:03:51 +05302583 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
2584 return VOS_STATUS_E_FAILURE;
2585 }
2586
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 vos_close(pVosContext);
2588 vos_sched_close(pVosContext);
2589 if (pHddCtx)
2590 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002591 /* Unregister the Net Device Notifier */
2592 unregister_netdevice_notifier(&hdd_netdev_notifier);
2593 /* Clean up HDD Nlink Service */
2594 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07002595#ifdef WLAN_KD_READY_NOTIFIER
2596 nl_srv_exit(pHddCtx->ptt_pid);
2597#else
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07002599#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07002600 /* Free up dynamically allocated members inside HDD Adapter */
2601 kfree(pHddCtx->cfg_ini);
2602 pHddCtx->cfg_ini= NULL;
2603
Jeff Johnson295189b2012-06-20 16:38:30 -07002604 wiphy_unregister(pHddCtx->wiphy);
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05302605 hdd_wlan_free_wiphy_channels(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002606 wiphy_free(pHddCtx->wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 }
2608 vos_preClose(&pVosContext);
2609
2610#ifdef MEMORY_DEBUG
2611 vos_mem_exit();
2612#endif
2613
2614err_re_init:
2615 /* Allow the phone to go to sleep */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302616 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
Sameer Thalappil9ab2fe52013-10-22 12:50:24 -07002617 vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07002618 VOS_BUG(0);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002619 return -EPERM;
Jeff Johnson295189b2012-06-20 16:38:30 -07002620
2621success:
2622 /* Trigger replay of BTC events */
2623 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
2624 return VOS_STATUS_SUCCESS;
2625}