blob: 5a4e8783a0a335e8c9dcc2ad004caf5cdece2844 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
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.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*========================================================================
43
44 \file wlan_hdd_main.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 04/5/09 Shailender Created module.
69 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
70 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
71 ==========================================================================*/
72
73/*--------------------------------------------------------------------------
74 Include Files
75 ------------------------------------------------------------------------*/
76//#include <wlan_qct_driver.h>
77#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070078#include <vos_api.h>
79#include <vos_sched.h>
80#include <vos_power.h>
81#include <linux/etherdevice.h>
82#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#ifdef ANI_BUS_TYPE_PLATFORM
84#include <linux/wcnss_wlan.h>
85#endif //ANI_BUS_TYPE_PLATFORM
86#ifdef ANI_BUS_TYPE_PCI
87#include "wcnss_wlan.h"
88#endif /* ANI_BUS_TYPE_PCI */
89#include <wlan_hdd_tx_rx.h>
90#include <palTimer.h>
91#include <wniApi.h>
92#include <wlan_nlink_srv.h>
93#include <wlan_btc_svc.h>
94#include <wlan_hdd_cfg.h>
95#include <wlan_ptt_sock_svc.h>
96#include <wlan_hdd_wowl.h>
97#include <wlan_hdd_misc.h>
98#include <wlan_hdd_wext.h>
99#ifdef WLAN_BTAMP_FEATURE
100#include <bap_hdd_main.h>
101#include <bapInternal.h>
102#endif // WLAN_BTAMP_FEATURE
103
Jeff Johnson295189b2012-06-20 16:38:30 -0700104#include <linux/wireless.h>
105#include <net/cfg80211.h>
106#include "wlan_hdd_cfg80211.h"
107#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700109int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "sapApi.h"
111#include <linux/semaphore.h>
112#include <mach/subsystem_restart.h>
113#include <wlan_hdd_hostapd.h>
114#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "wlan_hdd_dev_pwr.h"
117#ifdef WLAN_BTAMP_FEATURE
118#include "bap_hdd_misc.h"
119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700120#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700121#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800122#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530123#ifdef FEATURE_WLAN_TDLS
124#include "wlan_hdd_tdls.h"
125#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700126#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700127
128#ifdef MODULE
129#define WLAN_MODULE_NAME module_name(THIS_MODULE)
130#else
131#define WLAN_MODULE_NAME "wlan"
132#endif
133
134#ifdef TIMER_MANAGER
135#define TIMER_MANAGER_STR " +TIMER_MANAGER"
136#else
137#define TIMER_MANAGER_STR ""
138#endif
139
140#ifdef MEMORY_DEBUG
141#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
142#else
143#define MEMORY_DEBUG_STR ""
144#endif
145
146/* the Android framework expects this param even though we don't use it */
147#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700148static char fwpath_buffer[BUF_LEN];
149static struct kparam_string fwpath = {
150 .string = fwpath_buffer,
151 .maxlen = BUF_LEN,
152};
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700153#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700154static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700156
Jeff Johnsone7245742012-09-05 17:12:55 -0700157/*
158 * The rate at which the driver sends RESTART event to supplicant
159 * once the function 'vos_wlanRestart()' is called
160 *
161 */
162#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
163#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700164
165/*
166 * Size of Driver command strings from upper layer
167 */
168#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
169#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
170
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700171/*
172 * Driver miracast parameters 0-Disabled
173 * 1-Source, 2-Sink
174 */
175#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
176#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
177
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800178#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700179static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700180#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700181/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700182static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700183
184//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700185static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
186static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
187static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
188void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800189void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700190
Jeff Johnson295189b2012-06-20 16:38:30 -0700191v_U16_t hdd_select_queue(struct net_device *dev,
192 struct sk_buff *skb);
193
194#ifdef WLAN_FEATURE_PACKET_FILTERING
195static void hdd_set_multicast_list(struct net_device *dev);
196#endif
197
198void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
Amar Singhal4c723bd2013-03-25 18:14:15 -0700199int isWDresetInProgress(void);
Jeff Johnson295189b2012-06-20 16:38:30 -0700200
201extern int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800202#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
203void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
204static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700205static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
206 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
207 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700208static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
209 tANI_U8 *pTargetApBssid,
210 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700212static int hdd_netdev_notifier_call(struct notifier_block * nb,
213 unsigned long state,
214 void *ndev)
215{
216 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700217 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700218 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700219#ifdef WLAN_BTAMP_FEATURE
220 VOS_STATUS status;
221 hdd_context_t *pHddCtx;
222#endif
223
224 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700225 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700226 (strncmp(dev->name, "p2p", 3)))
227 return NOTIFY_DONE;
228
229 if (isWDresetInProgress())
Jeff Johnson295189b2012-06-20 16:38:30 -0700230 return NOTIFY_DONE;
231
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700233 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700234
Jeff Johnson27cee452013-03-27 11:10:24 -0700235 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800237 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700238 VOS_ASSERT(0);
239 return NOTIFY_DONE;
240 }
241
Jeff Johnson27cee452013-03-27 11:10:24 -0700242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
243 if (NULL == pHddCtx)
244 {
245 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
246 VOS_ASSERT(0);
247 return NOTIFY_DONE;
248 }
249
250 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
251 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700252
253 switch (state) {
254 case NETDEV_REGISTER:
255 break;
256
257 case NETDEV_UNREGISTER:
258 break;
259
260 case NETDEV_UP:
261 break;
262
263 case NETDEV_DOWN:
264 break;
265
266 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700267 if(TRUE == pAdapter->isLinkUpSvcNeeded)
268 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700269 break;
270
271 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700272 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 {
274 int result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800275 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +0530276 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800278 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
280 if(!result)
281 {
282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson902c9832012-12-10 14:28:09 -0800283 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700284 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700285 }
286 }
287 else
288 {
289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700290 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700291 }
292#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 status = WLANBAP_StopAmp();
295 if(VOS_STATUS_SUCCESS != status )
296 {
297 pHddCtx->isAmpAllowed = VOS_TRUE;
298 hddLog(VOS_TRACE_LEVEL_FATAL,
299 "%s: Failed to stop AMP", __func__);
300 }
301 else
302 {
303 //a state m/c implementation in PAL is TBD to avoid this delay
304 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700305 if ( pHddCtx->isAmpAllowed )
306 {
307 WLANBAP_DeregisterFromHCI();
308 pHddCtx->isAmpAllowed = VOS_FALSE;
309 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 }
311#endif //WLAN_BTAMP_FEATURE
312 break;
313
314 default:
315 break;
316 }
317
318 return NOTIFY_DONE;
319}
320
321struct notifier_block hdd_netdev_notifier = {
322 .notifier_call = hdd_netdev_notifier_call,
323};
324
325/*---------------------------------------------------------------------------
326 * Function definitions
327 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700328void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
329void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700330//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700331static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700332#ifndef MODULE
333/* current con_mode - used only for statically linked driver
334 * con_mode is changed by userspace to indicate a mode change which will
335 * result in calling the module exit and init functions. The module
336 * exit function will clean up based on the value of con_mode prior to it
337 * being changed by userspace. So curr_con_mode records the current con_mode
338 * for exit when con_mode becomes the next mode for init
339 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700340static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700341#endif
342
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800343/**---------------------------------------------------------------------------
344
345 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
346
347 Called immediately after the cfg.ini is read in order to configure
348 the desired trace levels.
349
350 \param - moduleId - module whose trace level is being configured
351 \param - bitmask - bitmask of log levels to be enabled
352
353 \return - void
354
355 --------------------------------------------------------------------------*/
356static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
357{
358 wpt_tracelevel level;
359
360 /* if the bitmask is the default value, then a bitmask was not
361 specified in cfg.ini, so leave the logging level alone (it
362 will remain at the "compiled in" default value) */
363 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
364 {
365 return;
366 }
367
368 /* a mask was specified. start by disabling all logging */
369 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
370
371 /* now cycle through the bitmask until all "set" bits are serviced */
372 level = VOS_TRACE_LEVEL_FATAL;
373 while (0 != bitmask)
374 {
375 if (bitmask & 1)
376 {
377 vos_trace_setValue(moduleId, level, 1);
378 }
379 level++;
380 bitmask >>= 1;
381 }
382}
383
384
Jeff Johnson295189b2012-06-20 16:38:30 -0700385/**---------------------------------------------------------------------------
386
387 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
388
389 Called immediately after the cfg.ini is read in order to configure
390 the desired trace levels in the WDI.
391
392 \param - moduleId - module whose trace level is being configured
393 \param - bitmask - bitmask of log levels to be enabled
394
395 \return - void
396
397 --------------------------------------------------------------------------*/
398static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
399{
400 wpt_tracelevel level;
401
402 /* if the bitmask is the default value, then a bitmask was not
403 specified in cfg.ini, so leave the logging level alone (it
404 will remain at the "compiled in" default value) */
405 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
406 {
407 return;
408 }
409
410 /* a mask was specified. start by disabling all logging */
411 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
412
413 /* now cycle through the bitmask until all "set" bits are serviced */
414 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
415 while (0 != bitmask)
416 {
417 if (bitmask & 1)
418 {
419 wpalTraceSetLevel(moduleId, level, 1);
420 }
421 level++;
422 bitmask >>= 1;
423 }
424}
Jeff Johnson295189b2012-06-20 16:38:30 -0700425
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530426/*
427 * FUNCTION: wlan_hdd_validate_context
428 * This function is used to check the HDD context
429 */
430int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
431{
432 ENTER();
433
434 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
435 {
436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
437 "%s: HDD context is Null", __func__);
438 return -ENODEV;
439 }
440
441 if (pHddCtx->isLogpInProgress)
442 {
443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
444 "%s: LOGP in Progress. Ignore!!!", __func__);
445 return -EAGAIN;
446 }
447
448 if (pHddCtx->isLoadUnloadInProgress)
449 {
450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
451 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
452 return -EAGAIN;
453 }
454 return 0;
455}
456
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530457void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
458{
459 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
460 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
461 hdd_config_t *cfg_param;
462 eCsrPhyMode phyMode;
463
464 if (NULL == pHddCtx)
465 {
466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
467 "HDD Context is null !!");
468 return ;
469 }
470
471 cfg_param = pHddCtx->cfg_ini;
472
473 if (NULL == cfg_param)
474 {
475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
476 "cfg_params not available !!");
477 return ;
478 }
479
480 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
481
482 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
483 {
484 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
485 (eCSR_DOT11_MODE_11ac == phyMode) ||
486 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
487 {
488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
489 "Setting phymode to 11n!!");
490 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
491 }
492 }
493 else
494 {
495 /*New country Supports 11ac as well resetting value back from .ini*/
496 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
497 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
498 return ;
499 }
500
501 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
502 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
503 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
504 {
505 VOS_STATUS vosStatus;
506
507 // need to issue a disconnect to CSR.
508 INIT_COMPLETION(pAdapter->disconnect_comp_var);
509 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
510 pAdapter->sessionId,
511 eCSR_DISCONNECT_REASON_UNSPECIFIED );
512
513 if (VOS_STATUS_SUCCESS == vosStatus)
514 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
515 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
516
517 }
518}
519
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700520void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
521{
522 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
523 hdd_config_t *cfg_param;
524
525 if (NULL == pHddCtx)
526 {
527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
528 "HDD Context is null !!");
529 return ;
530 }
531
532 cfg_param = pHddCtx->cfg_ini;
533
534 if (NULL == cfg_param)
535 {
536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
537 "cfg_params not available !!");
538 return ;
539 }
540
541 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
542 {
543 /*New country doesn't support DFS */
544 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
545 }
546 else
547 {
548 /*New country Supports DFS as well resetting value back from .ini*/
549 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
550 }
551
552}
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
555{
556 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
557 hdd_priv_data_t priv_data;
558 tANI_U8 *command = NULL;
559 int ret = 0;
560
561 if (NULL == pAdapter)
562 {
563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700564 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700565 ret = -ENODEV;
566 goto exit;
567 }
568
Jeff Johnsone7245742012-09-05 17:12:55 -0700569 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -0700570 {
571 ret = -EINVAL;
572 goto exit;
573 }
574
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -0700575 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
576 {
577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
578 "%s:LOGP in Progress. Ignore!!!", __func__);
579 ret = -EBUSY;
580 goto exit;
581 }
582
Jeff Johnson295189b2012-06-20 16:38:30 -0700583 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
584 {
585 ret = -EFAULT;
586 goto exit;
587 }
588
589 command = kmalloc(priv_data.total_len, GFP_KERNEL);
590 if (!command)
591 {
592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700593 "%s: failed to allocate memory\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700594 ret = -ENOMEM;
595 goto exit;
596 }
597
598 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
599 {
600 ret = -EFAULT;
601 goto exit;
602 }
603
604 if ((SIOCDEVPRIVATE + 1) == cmd)
605 {
606 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
607
608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -0700609 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -0700610
611 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
612 {
613 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
614 sizeof(tSirMacAddr)))
615 {
616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700617 "%s: failed to copy data to user buffer\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 ret = -EFAULT;
619 }
620 }
Amar Singhal0974e402013-02-12 14:27:46 -0800621 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 {
Amar Singhal0974e402013-02-12 14:27:46 -0800623 tANI_U8 *ptr = command ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700624 int ret = 0 ;
Srinivas Girigowdade697412013-02-14 16:31:48 -0800625
Jeff Johnson295189b2012-06-20 16:38:30 -0700626 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -0800627
628 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -0700629 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -0800631 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Jeff Johnson295189b2012-06-20 16:38:30 -0700632 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -0800633 ret = hdd_setBand_helper(dev, ptr);
634 }
Jeff Johnson32d95a32012-09-10 13:15:23 -0700635 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
636 {
637 char *country_code;
638
639 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700640
641 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642 hdd_checkandupdate_phymode(pAdapter, country_code);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700643 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal, NULL, country_code,
Gopichand Nakkalaacd94112013-05-29 21:37:47 +0530644 pAdapter, pHddCtx->pvosContext, eSIR_TRUE);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700645 if( 0 != ret )
646 {
647 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
648 "%s: SME Change Country code fail ret=%d\n",__func__, ret);
649
650 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700651 }
652 /*
653 command should be a string having format
654 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
655 */
Amar Singhal0974e402013-02-12 14:27:46 -0800656 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700657 {
Amar Singhal0974e402013-02-12 14:27:46 -0800658 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700659
660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700661 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -0700662
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -0800663 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700664 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800665 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
666 {
667 int suspend = 0;
668 tANI_U8 *ptr = (tANI_U8*)command + 15;
669
670 suspend = *ptr - '0';
671 hdd_set_wlan_suspend_mode(suspend);
672 }
Srinivas Girigowdade697412013-02-14 16:31:48 -0800673#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
674 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
675 {
676 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700677 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -0800678 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
679 eHalStatus status = eHAL_STATUS_SUCCESS;
680
681 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
682 value = value + 15;
683
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700684 /* Convert the value from ascii to integer */
685 ret = kstrtos8(value, 10, &rssi);
686 if (ret < 0)
687 {
688 /* If the input value is greater than max value of datatype, then also
689 kstrtou8 fails */
690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
691 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
692 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
693 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
694 ret = -EINVAL;
695 goto exit;
696 }
697
Srinivas Girigowdade697412013-02-14 16:31:48 -0800698 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700699
Srinivas Girigowdade697412013-02-14 16:31:48 -0800700 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
701 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
702 {
703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
704 "Neighbor lookup threshold value %d is out of range"
705 " (Min: %d Max: %d)", lookUpThreshold,
706 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
707 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
708 ret = -EINVAL;
709 goto exit;
710 }
711
712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
713 "%s: Received Command to Set Roam trigger"
714 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
715
716 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
717 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
718 if (eHAL_STATUS_SUCCESS != status)
719 {
720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
721 "%s: Failed to set roam trigger, try again", __func__);
722 ret = -EPERM;
723 goto exit;
724 }
725
726 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
727 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
728 }
729 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
730 {
731 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
732 int rssi = (-1) * lookUpThreshold;
733 char extra[32];
734 tANI_U8 len = 0;
735
736 len = snprintf(extra, sizeof(extra), "%s %d", command, rssi);
737 if (copy_to_user(priv_data.buf, &extra, len + 1))
738 {
739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
740 "%s: failed to copy data to user buffer", __func__);
741 ret = -EFAULT;
742 goto exit;
743 }
744 }
745 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
746 {
747 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700748 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700749 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700750
Srinivas Girigowdade697412013-02-14 16:31:48 -0800751 /* input refresh period is in terms of seconds */
752 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
753 value = value + 18;
754 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700755 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800756 if (ret < 0)
757 {
758 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700759 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -0800760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700761 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -0800762 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -0700763 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
764 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -0800765 ret = -EINVAL;
766 goto exit;
767 }
768
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700769 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
770 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -0800771 {
772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700773 "Roam scan period value %d is out of range"
774 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -0700775 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
776 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -0800777 ret = -EINVAL;
778 goto exit;
779 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700780 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -0800781
782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
783 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700784 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800785
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700786 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
787 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800788 }
789 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
790 {
791 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
792 char extra[32];
793 tANI_U8 len = 0;
794
795 len = snprintf(extra, sizeof(extra), "%s %d", "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
796 /* Returned value is in units of seconds */
797 if (copy_to_user(priv_data.buf, &extra, len + 1))
798 {
799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
800 "%s: failed to copy data to user buffer", __func__);
801 ret = -EFAULT;
802 goto exit;
803 }
804 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700805 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
806 {
807 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700808 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700809 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700810
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700811 /* input refresh period is in terms of seconds */
812 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
813 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700814
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700815 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700816 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700817 if (ret < 0)
818 {
819 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700820 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700822 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700823 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700824 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
825 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
826 ret = -EINVAL;
827 goto exit;
828 }
829
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700830 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
831 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
832 {
833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
834 "Neighbor scan results refresh period value %d is out of range"
835 " (Min: %d Max: %d)", roamScanRefreshPeriod,
836 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
837 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
838 ret = -EINVAL;
839 goto exit;
840 }
841 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
842
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
844 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -0700845 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -0700846
847 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
848 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
849 }
850 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
851 {
852 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
853 char extra[32];
854 tANI_U8 len = 0;
855
856 len = snprintf(extra, sizeof(extra), "%s %d", "GETROAMSCANREFRESHPERIOD", (value/1000));
857 /* Returned value is in units of seconds */
858 if (copy_to_user(priv_data.buf, &extra, len + 1))
859 {
860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
861 "%s: failed to copy data to user buffer", __func__);
862 ret = -EFAULT;
863 goto exit;
864 }
865 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700866#ifdef FEATURE_WLAN_LFR
867 /* SETROAMMODE */
868 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
869 {
870 tANI_U8 *value = command;
871 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
872
873 /* Move pointer to ahead of SETROAMMODE<delimiter> */
874 value = value + SIZE_OF_SETROAMMODE + 1;
875
876 /* Convert the value from ascii to integer */
877 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
878 if (ret < 0)
879 {
880 /* If the input value is greater than max value of datatype, then also
881 kstrtou8 fails */
882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
883 "%s: kstrtou8 failed range [%d - %d]", __func__,
884 CFG_LFR_FEATURE_ENABLED_MIN,
885 CFG_LFR_FEATURE_ENABLED_MAX);
886 ret = -EINVAL;
887 goto exit;
888 }
889 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
890 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
891 {
892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
893 "Roam Mode value %d is out of range"
894 " (Min: %d Max: %d)", roamMode,
895 CFG_LFR_FEATURE_ENABLED_MIN,
896 CFG_LFR_FEATURE_ENABLED_MAX);
897 ret = -EINVAL;
898 goto exit;
899 }
900
901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
902 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
903 /*
904 * Note that
905 * SETROAMMODE 0 is to enable LFR while
906 * SETROAMMODE 1 is to disable LFR, but
907 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
908 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
909 */
910 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
911 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
912 else
913 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
914
915 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
916 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
917 }
918 /* GETROAMMODE */
919 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
920 {
921 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
922 char extra[32];
923 tANI_U8 len = 0;
924
925 /*
926 * roamMode value shall be inverted because the sementics is different.
927 */
928 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
929 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
930 else
931 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
932
933 len = snprintf(extra, sizeof(extra), "%s %d", command, roamMode);
934 if (copy_to_user(priv_data.buf, &extra, len + 1))
935 {
936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
937 "%s: failed to copy data to user buffer", __func__);
938 ret = -EFAULT;
939 goto exit;
940 }
941 }
942#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -0800943#endif
944#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
945 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
946 {
947 tANI_U8 *value = command;
948 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
949
950 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
951 value = value + 13;
952 /* Convert the value from ascii to integer */
953 ret = kstrtou8(value, 10, &roamRssiDiff);
954 if (ret < 0)
955 {
956 /* If the input value is greater than max value of datatype, then also
957 kstrtou8 fails */
958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
959 "%s: kstrtou8 failed range [%d - %d]", __func__,
960 CFG_ROAM_RSSI_DIFF_MIN,
961 CFG_ROAM_RSSI_DIFF_MAX);
962 ret = -EINVAL;
963 goto exit;
964 }
965
966 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
967 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
968 {
969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
970 "Roam rssi diff value %d is out of range"
971 " (Min: %d Max: %d)", roamRssiDiff,
972 CFG_ROAM_RSSI_DIFF_MIN,
973 CFG_ROAM_RSSI_DIFF_MAX);
974 ret = -EINVAL;
975 goto exit;
976 }
977
978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
979 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
980
981 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
982 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
983 }
984 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
985 {
986 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
987 char extra[32];
988 tANI_U8 len = 0;
989
990 len = snprintf(extra, sizeof(extra), "%s %d", command, roamRssiDiff);
991 if (copy_to_user(priv_data.buf, &extra, len + 1))
992 {
993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
994 "%s: failed to copy data to user buffer", __func__);
995 ret = -EFAULT;
996 goto exit;
997 }
998 }
999#endif
1000#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
1001 else if (strncmp(command, "GETBAND", 7) == 0)
1002 {
1003 int band = -1;
1004 char extra[32];
1005 tANI_U8 len = 0;
1006 hdd_getBand_helper(pHddCtx, &band);
1007
1008 len = snprintf(extra, sizeof(extra), "%s %d", command, band);
1009 if (copy_to_user(priv_data.buf, &extra, len + 1))
1010 {
1011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1012 "%s: failed to copy data to user buffer", __func__);
1013 ret = -EFAULT;
1014 goto exit;
1015 }
1016 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08001017 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
1018 {
1019 tANI_U8 *value = command;
1020 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1021 tANI_U8 numChannels = 0;
1022 eHalStatus status = eHAL_STATUS_SUCCESS;
1023
1024 status = hdd_parse_channellist(value, ChannelList, &numChannels);
1025 if (eHAL_STATUS_SUCCESS != status)
1026 {
1027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1028 "%s: Failed to parse channel list information", __func__);
1029 ret = -EINVAL;
1030 goto exit;
1031 }
1032
1033 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
1034 {
1035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1036 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
1037 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
1038 ret = -EINVAL;
1039 goto exit;
1040 }
1041 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
1042 numChannels);
1043 if (eHAL_STATUS_SUCCESS != status)
1044 {
1045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1046 "%s: Failed to update channel list information", __func__);
1047 ret = -EINVAL;
1048 goto exit;
1049 }
1050 }
1051 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
1052 {
1053 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1054 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07001055 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001056 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07001057 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001058
1059 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
1060 ChannelList, &numChannels ))
1061 {
1062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1063 "%s: failed to get roam scan channel list", __func__);
1064 ret = -EFAULT;
1065 goto exit;
1066 }
1067 /* output channel list is of the format
1068 [Number of roam scan channels][Channel1][Channel2]... */
1069 /* copy the number of channels in the 0th index */
1070 len = snprintf(extra, sizeof(extra), "%s %d", command, numChannels);
1071 for (j = 0; (j < numChannels); j++)
1072 {
1073 len += snprintf(extra + len, sizeof(extra) - len, " %d", ChannelList[j]);
1074 }
1075
1076 if (copy_to_user(priv_data.buf, &extra, len + 1))
1077 {
1078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1079 "%s: failed to copy data to user buffer", __func__);
1080 ret = -EFAULT;
1081 goto exit;
1082 }
1083 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001084 else if (strncmp(command, "GETCCXMODE", 10) == 0)
1085 {
1086 tANI_BOOLEAN ccxMode = sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal));
1087 char extra[32];
1088 tANI_U8 len = 0;
1089
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07001090 /* Check if the features OKC/CCX/11R are supported simultaneously,
1091 then this operation is not permitted (return FAILURE) */
1092 if (ccxMode &&
1093 hdd_is_okc_mode_enabled(pHddCtx) &&
1094 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
1095 {
1096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1097 "%s: OKC/CCX/11R are supported simultaneously"
1098 " hence this operation is not permitted!", __func__);
1099 ret = -EPERM;
1100 goto exit;
1101 }
1102
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001103 len = snprintf(extra, sizeof(extra), "%s %d", "GETCCXMODE", ccxMode);
1104 if (copy_to_user(priv_data.buf, &extra, len + 1))
1105 {
1106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1107 "%s: failed to copy data to user buffer", __func__);
1108 ret = -EFAULT;
1109 goto exit;
1110 }
1111 }
1112 else if (strncmp(command, "GETOKCMODE", 10) == 0)
1113 {
1114 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
1115 char extra[32];
1116 tANI_U8 len = 0;
1117
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07001118 /* Check if the features OKC/CCX/11R are supported simultaneously,
1119 then this operation is not permitted (return FAILURE) */
1120 if (okcMode &&
1121 sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
1122 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
1123 {
1124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1125 "%s: OKC/CCX/11R are supported simultaneously"
1126 " hence this operation is not permitted!", __func__);
1127 ret = -EPERM;
1128 goto exit;
1129 }
1130
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001131 len = snprintf(extra, sizeof(extra), "%s %d", "GETOKCMODE", okcMode);
1132 if (copy_to_user(priv_data.buf, &extra, len + 1))
1133 {
1134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1135 "%s: failed to copy data to user buffer", __func__);
1136 ret = -EFAULT;
1137 goto exit;
1138 }
1139 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07001140 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001141 {
1142 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
1143 char extra[32];
1144 tANI_U8 len = 0;
1145
1146 len = snprintf(extra, sizeof(extra), "%s %d", "GETFASTROAM", lfrMode);
1147 if (copy_to_user(priv_data.buf, &extra, len + 1))
1148 {
1149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1150 "%s: failed to copy data to user buffer", __func__);
1151 ret = -EFAULT;
1152 goto exit;
1153 }
1154 }
1155 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
1156 {
1157 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
1158 char extra[32];
1159 tANI_U8 len = 0;
1160
1161 len = snprintf(extra, sizeof(extra), "%s %d", "GETFASTTRANSITION", ft);
1162 if (copy_to_user(priv_data.buf, &extra, len + 1))
1163 {
1164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1165 "%s: failed to copy data to user buffer", __func__);
1166 ret = -EFAULT;
1167 goto exit;
1168 }
1169 }
1170 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
1171 {
1172 tANI_U8 *value = command;
1173 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
1174
1175 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
1176 value = value + 26;
1177 /* Convert the value from ascii to integer */
1178 ret = kstrtou8(value, 10, &minTime);
1179 if (ret < 0)
1180 {
1181 /* If the input value is greater than max value of datatype, then also
1182 kstrtou8 fails */
1183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1184 "%s: kstrtou8 failed range [%d - %d]", __func__,
1185 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
1186 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
1187 ret = -EINVAL;
1188 goto exit;
1189 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001190 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
1191 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
1192 {
1193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "scan min channel time value %d is out of range"
1195 " (Min: %d Max: %d)", minTime,
1196 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
1197 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
1198 ret = -EINVAL;
1199 goto exit;
1200 }
1201
1202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1203 "%s: Received Command to change channel min time = %d", __func__, minTime);
1204
1205 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
1206 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
1207 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001208 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
1209 {
1210 tANI_U8 *value = command;
1211 tANI_U8 channel = 0;
1212 tANI_U8 dwellTime = 0;
1213 tANI_U8 bufLen = 0;
1214 tANI_U8 *buf = NULL;
1215 tSirMacAddr targetApBssid;
1216 eHalStatus status = eHAL_STATUS_SUCCESS;
1217 struct ieee80211_channel chan;
1218 tANI_U8 finalLen = 0;
1219 tANI_U8 *finalBuf = NULL;
1220 tANI_U8 temp = 0;
1221 u64 cookie;
1222 hdd_station_ctx_t *pHddStaCtx = NULL;
1223 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1224
1225 /* if not associated, no need to send action frame */
1226 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
1227 {
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
1229 ret = -EINVAL;
1230 goto exit;
1231 }
1232
1233 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
1234 &dwellTime, &buf, &bufLen);
1235 if (eHAL_STATUS_SUCCESS != status)
1236 {
1237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1238 "%s: Failed to parse send action frame data", __func__);
1239 ret = -EINVAL;
1240 goto exit;
1241 }
1242
1243 /* if the target bssid is different from currently associated AP,
1244 then no need to send action frame */
1245 if (VOS_TRUE != vos_mem_compare(targetApBssid,
1246 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
1247 {
1248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
1249 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07001250 vos_mem_free(buf);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001251 goto exit;
1252 }
1253
1254 /* if the channel number is different from operating channel then
1255 no need to send action frame */
1256 if (channel != pHddStaCtx->conn_info.operationChannel)
1257 {
1258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1259 "%s: channel(%d) is different from operating channel(%d)",
1260 __func__, channel, pHddStaCtx->conn_info.operationChannel);
1261 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07001262 vos_mem_free(buf);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001263 goto exit;
1264 }
1265 chan.center_freq = sme_ChnToFreq(channel);
1266
1267 finalLen = bufLen + 24;
1268 finalBuf = vos_mem_malloc(finalLen);
1269 if (NULL == finalBuf)
1270 {
1271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
1272 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07001273 vos_mem_free(buf);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001274 goto exit;
1275 }
1276 vos_mem_zero(finalBuf, finalLen);
1277
1278 /* Fill subtype */
1279 temp = SIR_MAC_MGMT_ACTION << 4;
1280 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
1281
1282 /* Fill type */
1283 temp = SIR_MAC_MGMT_FRAME;
1284 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
1285
1286 /* Fill destination address (bssid of the AP) */
1287 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
1288
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07001289 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001290 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
1291
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07001292 /* Fill BSSID (AP mac address) */
1293 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001294
1295 /* Fill received buffer from 24th address */
1296 vos_mem_copy(finalBuf + 24, buf, bufLen);
1297
Jeff Johnson11c33152013-04-16 17:52:40 -07001298 /* done with the parsed buffer */
1299 vos_mem_free(buf);
1300
Yue Maf49ba872013-08-19 12:04:25 -07001301 wlan_hdd_action( NULL,
1302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1303 &(pAdapter->wdev),
1304#else
1305 dev,
1306#endif
1307 &chan, 0,
1308#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1309 NL80211_CHAN_HT20, 1,
1310#endif
1311 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001312 1, &cookie );
1313 vos_mem_free(finalBuf);
1314 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001315 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
1316 {
1317 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
1318 char extra[32];
1319 tANI_U8 len = 0;
1320
1321 /* value is interms of msec */
1322 len = snprintf(extra, sizeof(extra), "%s %d", "GETROAMSCANCHANNELMINTIME", val);
1323 if (copy_to_user(priv_data.buf, &extra, len + 1))
1324 {
1325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1326 "%s: failed to copy data to user buffer", __func__);
1327 ret = -EFAULT;
1328 goto exit;
1329 }
1330 }
1331 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
1332 {
1333 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07001334 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07001335 tANI_U16 homeAwayTime = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001336
1337 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
1338 value = value + 19;
1339 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07001340 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001341 if (ret < 0)
1342 {
1343 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07001344 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07001346 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001347 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
1348 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
1349 ret = -EINVAL;
1350 goto exit;
1351 }
1352
1353 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
1354 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
1355 {
1356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1357 "lfr mode value %d is out of range"
1358 " (Min: %d Max: %d)", maxTime,
1359 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
1360 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
1361 ret = -EINVAL;
1362 goto exit;
1363 }
1364
1365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1366 "%s: Received Command to change channel max time = %d", __func__, maxTime);
1367
1368 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07001369
1370 /* Home Away Time should be atleast equal to (MaxDwell time + (2*RFS)),
1371 * where RFS is the RF Switching time. It is twice RFS to consider the
1372 * time to go off channel and return to the home channel. */
1373 homeAwayTime = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
1374 if (homeAwayTime < (maxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
1375 {
1376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1377 "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)",
1378 " Hence enforcing home away time to disable (0)",
1379 __func__, homeAwayTime, (maxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
1380 homeAwayTime = 0;
1381 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
1382 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_FALSE);
1383 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001384 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
1385 }
1386 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
1387 {
1388 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
1389 char extra[32];
1390 tANI_U8 len = 0;
1391
1392 /* value is interms of msec */
1393 len = snprintf(extra, sizeof(extra), "%s %d", "GETSCANCHANNELTIME", val);
1394 if (copy_to_user(priv_data.buf, &extra, len + 1))
1395 {
1396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1397 "%s: failed to copy data to user buffer", __func__);
1398 ret = -EFAULT;
1399 goto exit;
1400 }
1401 }
1402 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
1403 {
1404 tANI_U8 *value = command;
1405 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
1406
1407 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
1408 value = value + 16;
1409 /* Convert the value from ascii to integer */
1410 ret = kstrtou16(value, 10, &val);
1411 if (ret < 0)
1412 {
1413 /* If the input value is greater than max value of datatype, then also
1414 kstrtou16 fails */
1415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1416 "%s: kstrtou16 failed range [%d - %d]", __func__,
1417 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
1418 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
1419 ret = -EINVAL;
1420 goto exit;
1421 }
1422
1423 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
1424 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
1425 {
1426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1427 "scan home time value %d is out of range"
1428 " (Min: %d Max: %d)", val,
1429 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
1430 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
1431 ret = -EINVAL;
1432 goto exit;
1433 }
1434
1435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1436 "%s: Received Command to change scan home time = %d", __func__, val);
1437
1438 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
1439 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
1440 }
1441 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
1442 {
1443 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
1444 char extra[32];
1445 tANI_U8 len = 0;
1446
1447 /* value is interms of msec */
1448 len = snprintf(extra, sizeof(extra), "%s %d", "GETSCANHOMETIME", val);
1449 if (copy_to_user(priv_data.buf, &extra, len + 1))
1450 {
1451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1452 "%s: failed to copy data to user buffer", __func__);
1453 ret = -EFAULT;
1454 goto exit;
1455 }
1456 }
1457 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
1458 {
1459 tANI_U8 *value = command;
1460 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
1461
1462 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
1463 value = value + 17;
1464 /* Convert the value from ascii to integer */
1465 ret = kstrtou8(value, 10, &val);
1466 if (ret < 0)
1467 {
1468 /* If the input value is greater than max value of datatype, then also
1469 kstrtou8 fails */
1470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1471 "%s: kstrtou8 failed range [%d - %d]", __func__,
1472 CFG_ROAM_INTRA_BAND_MIN,
1473 CFG_ROAM_INTRA_BAND_MAX);
1474 ret = -EINVAL;
1475 goto exit;
1476 }
1477
1478 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
1479 (val > CFG_ROAM_INTRA_BAND_MAX))
1480 {
1481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1482 "intra band mode value %d is out of range"
1483 " (Min: %d Max: %d)", val,
1484 CFG_ROAM_INTRA_BAND_MIN,
1485 CFG_ROAM_INTRA_BAND_MAX);
1486 ret = -EINVAL;
1487 goto exit;
1488 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1490 "%s: Received Command to change intra band = %d", __func__, val);
1491
1492 pHddCtx->cfg_ini->nRoamIntraBand = val;
1493 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
1494 }
1495 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
1496 {
1497 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
1498 char extra[32];
1499 tANI_U8 len = 0;
1500
1501 /* value is interms of msec */
1502 len = snprintf(extra, sizeof(extra), "%s %d", "GETROAMINTRABAND", val);
1503 if (copy_to_user(priv_data.buf, &extra, len + 1))
1504 {
1505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1506 "%s: failed to copy data to user buffer", __func__);
1507 ret = -EFAULT;
1508 goto exit;
1509 }
1510 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001511 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
1512 {
1513 tANI_U8 *value = command;
1514 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
1515
1516 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
1517 value = value + 15;
1518 /* Convert the value from ascii to integer */
1519 ret = kstrtou8(value, 10, &nProbes);
1520 if (ret < 0)
1521 {
1522 /* If the input value is greater than max value of datatype, then also
1523 kstrtou8 fails */
1524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1525 "%s: kstrtou8 failed range [%d - %d]", __func__,
1526 CFG_ROAM_SCAN_N_PROBES_MIN,
1527 CFG_ROAM_SCAN_N_PROBES_MAX);
1528 ret = -EINVAL;
1529 goto exit;
1530 }
1531
1532 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
1533 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
1534 {
1535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1536 "NProbes value %d is out of range"
1537 " (Min: %d Max: %d)", nProbes,
1538 CFG_ROAM_SCAN_N_PROBES_MIN,
1539 CFG_ROAM_SCAN_N_PROBES_MAX);
1540 ret = -EINVAL;
1541 goto exit;
1542 }
1543
1544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1545 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
1546
1547 pHddCtx->cfg_ini->nProbes = nProbes;
1548 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
1549 }
1550 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
1551 {
1552 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
1553 char extra[32];
1554 tANI_U8 len = 0;
1555
1556 len = snprintf(extra, sizeof(extra), "%s %d", command, val);
1557 if (copy_to_user(priv_data.buf, &extra, len + 1))
1558 {
1559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1560 "%s: failed to copy data to user buffer", __func__);
1561 ret = -EFAULT;
1562 goto exit;
1563 }
1564 }
1565 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
1566 {
1567 tANI_U8 *value = command;
1568 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07001569 tANI_U16 scanChannelMaxTime = 0;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001570
1571 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
1572 /* input value is in units of msec */
1573 value = value + 20;
1574 /* Convert the value from ascii to integer */
1575 ret = kstrtou16(value, 10, &homeAwayTime);
1576 if (ret < 0)
1577 {
1578 /* If the input value is greater than max value of datatype, then also
1579 kstrtou8 fails */
1580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1581 "%s: kstrtou8 failed range [%d - %d]", __func__,
1582 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
1583 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
1584 ret = -EINVAL;
1585 goto exit;
1586 }
1587
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001588 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
1589 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
1590 {
1591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1592 "homeAwayTime value %d is out of range"
1593 " (Min: %d Max: %d)", homeAwayTime,
1594 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
1595 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
1596 ret = -EINVAL;
1597 goto exit;
1598 }
1599
1600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1601 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
1602
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07001603 /* Home Away Time should be atleast equal to (MaxDwell time + (2*RFS)),
1604 * where RFS is the RF Switching time. It is twice RFS to consider the
1605 * time to go off channel and return to the home channel. */
1606 scanChannelMaxTime = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
1607 if (homeAwayTime < (scanChannelMaxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
1608 {
1609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1610 "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)",
1611 " Hence enforcing home away time to disable (0)",
1612 __func__, homeAwayTime, (scanChannelMaxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
1613 homeAwayTime = 0;
1614 }
1615
1616 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
1617 {
1618 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
1619 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
1620 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001621 }
1622 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
1623 {
1624 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
1625 char extra[32];
1626 tANI_U8 len = 0;
1627
1628 len = snprintf(extra, sizeof(extra), "%s %d", command, val);
1629 if (copy_to_user(priv_data.buf, &extra, len + 1))
1630 {
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: failed to copy data to user buffer", __func__);
1633 ret = -EFAULT;
1634 goto exit;
1635 }
1636 }
1637 else if (strncmp(command, "REASSOC", 7) == 0)
1638 {
1639 tANI_U8 *value = command;
1640 tANI_U8 channel = 0;
1641 tSirMacAddr targetApBssid;
1642 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07001643#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
1644 tCsrHandoffRequest handoffInfo;
1645#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001646 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001647 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1648
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001649 /* if not associated, no need to proceed with reassoc */
1650 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
1651 {
1652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
1653 ret = -EINVAL;
1654 goto exit;
1655 }
1656
1657 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
1658 if (eHAL_STATUS_SUCCESS != status)
1659 {
1660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: Failed to parse reassoc command data", __func__);
1662 ret = -EINVAL;
1663 goto exit;
1664 }
1665
1666 /* if the target bssid is same as currently associated AP,
1667 then no need to proceed with reassoc */
1668 if (VOS_TRUE == vos_mem_compare(targetApBssid,
1669 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
1670 {
1671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
1672 ret = -EINVAL;
1673 goto exit;
1674 }
1675
1676 /* Check channel number is a valid channel number */
1677 if(VOS_STATUS_SUCCESS !=
1678 wlan_hdd_validate_operation_channel(pAdapter, channel))
1679 {
1680 hddLog(VOS_TRACE_LEVEL_ERROR,
1681 "%s: Invalid Channel [%d] \n", __func__, channel);
1682 return -EINVAL;
1683 }
1684
1685 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07001686#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
1687 handoffInfo.channel = channel;
1688 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
1689 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
1690#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001691 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001692#endif
1693#ifdef FEATURE_WLAN_LFR
1694 else if (strncmp(command, "SETFASTROAM", 11) == 0)
1695 {
1696 tANI_U8 *value = command;
1697 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
1698
1699 /* Move pointer to ahead of SETFASTROAM<delimiter> */
1700 value = value + 12;
1701 /* Convert the value from ascii to integer */
1702 ret = kstrtou8(value, 10, &lfrMode);
1703 if (ret < 0)
1704 {
1705 /* If the input value is greater than max value of datatype, then also
1706 kstrtou8 fails */
1707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1708 "%s: kstrtou8 failed range [%d - %d]", __func__,
1709 CFG_LFR_FEATURE_ENABLED_MIN,
1710 CFG_LFR_FEATURE_ENABLED_MAX);
1711 ret = -EINVAL;
1712 goto exit;
1713 }
1714
1715 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
1716 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
1717 {
1718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1719 "lfr mode value %d is out of range"
1720 " (Min: %d Max: %d)", lfrMode,
1721 CFG_LFR_FEATURE_ENABLED_MIN,
1722 CFG_LFR_FEATURE_ENABLED_MAX);
1723 ret = -EINVAL;
1724 goto exit;
1725 }
1726
1727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1728 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
1729
1730 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
1731 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
1732 }
1733#endif
1734#ifdef WLAN_FEATURE_VOWIFI_11R
1735 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
1736 {
1737 tANI_U8 *value = command;
1738 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
1739
1740 /* Move pointer to ahead of SETFASTROAM<delimiter> */
1741 value = value + 18;
1742 /* Convert the value from ascii to integer */
1743 ret = kstrtou8(value, 10, &ft);
1744 if (ret < 0)
1745 {
1746 /* If the input value is greater than max value of datatype, then also
1747 kstrtou8 fails */
1748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1749 "%s: kstrtou8 failed range [%d - %d]", __func__,
1750 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
1751 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
1752 ret = -EINVAL;
1753 goto exit;
1754 }
1755
1756 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
1757 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
1758 {
1759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1760 "ft mode value %d is out of range"
1761 " (Min: %d Max: %d)", ft,
1762 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
1763 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
1764 ret = -EINVAL;
1765 goto exit;
1766 }
1767
1768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1769 "%s: Received Command to change ft mode = %d", __func__, ft);
1770
1771 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
1772 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
1773 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05301774
1775 else if (strncmp(command, "FASTREASSOC", 11) == 0)
1776 {
1777 tANI_U8 *value = command;
1778 tSirMacAddr targetApBssid;
1779 tANI_U8 trigger = 0;
1780 eHalStatus status = eHAL_STATUS_SUCCESS;
1781 hdd_station_ctx_t *pHddStaCtx = NULL;
1782 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1783
1784 /* if not associated, no need to proceed with reassoc */
1785 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
1786 {
1787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
1788 ret = -EINVAL;
1789 goto exit;
1790 }
1791
1792 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
1793 if (eHAL_STATUS_SUCCESS != status)
1794 {
1795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1796 "%s: Failed to parse reassoc command data", __func__);
1797 ret = -EINVAL;
1798 goto exit;
1799 }
1800
1801 /* if the target bssid is same as currently associated AP,
1802 then no need to proceed with reassoc */
1803 if (VOS_TRUE == vos_mem_compare(targetApBssid,
1804 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
1805 {
1806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1807 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
1808 __func__);
1809 ret = -EINVAL;
1810 goto exit;
1811 }
1812
1813 /* Proceed with scan/roam */
1814 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
1815 &targetApBssid[0],
1816 (tSmeFastRoamTrigger)(trigger));
1817 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001818#endif
1819#ifdef FEATURE_WLAN_CCX
1820 else if (strncmp(command, "SETCCXMODE", 10) == 0)
1821 {
1822 tANI_U8 *value = command;
1823 tANI_U8 ccxMode = CFG_CCX_FEATURE_ENABLED_DEFAULT;
1824
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07001825 /* Check if the features OKC/CCX/11R are supported simultaneously,
1826 then this operation is not permitted (return FAILURE) */
1827 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
1828 hdd_is_okc_mode_enabled(pHddCtx) &&
1829 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
1830 {
1831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1832 "%s: OKC/CCX/11R are supported simultaneously"
1833 " hence this operation is not permitted!", __func__);
1834 ret = -EPERM;
1835 goto exit;
1836 }
1837
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001838 /* Move pointer to ahead of SETCCXMODE<delimiter> */
1839 value = value + 11;
1840 /* Convert the value from ascii to integer */
1841 ret = kstrtou8(value, 10, &ccxMode);
1842 if (ret < 0)
1843 {
1844 /* If the input value is greater than max value of datatype, then also
1845 kstrtou8 fails */
1846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1847 "%s: kstrtou8 failed range [%d - %d]", __func__,
1848 CFG_CCX_FEATURE_ENABLED_MIN,
1849 CFG_CCX_FEATURE_ENABLED_MAX);
1850 ret = -EINVAL;
1851 goto exit;
1852 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001853 if ((ccxMode < CFG_CCX_FEATURE_ENABLED_MIN) ||
1854 (ccxMode > CFG_CCX_FEATURE_ENABLED_MAX))
1855 {
1856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1857 "Ccx mode value %d is out of range"
1858 " (Min: %d Max: %d)", ccxMode,
1859 CFG_CCX_FEATURE_ENABLED_MIN,
1860 CFG_CCX_FEATURE_ENABLED_MAX);
1861 ret = -EINVAL;
1862 goto exit;
1863 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1865 "%s: Received Command to change ccx mode = %d", __func__, ccxMode);
1866
1867 pHddCtx->cfg_ini->isCcxIniFeatureEnabled = ccxMode;
1868 sme_UpdateIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal), ccxMode);
1869 }
1870#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001871 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
1872 {
1873 tANI_U8 *value = command;
1874 tANI_BOOLEAN roamScanControl = 0;
1875
1876 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
1877 value = value + 19;
1878 /* Convert the value from ascii to integer */
1879 ret = kstrtou8(value, 10, &roamScanControl);
1880 if (ret < 0)
1881 {
1882 /* If the input value is greater than max value of datatype, then also
1883 kstrtou8 fails */
1884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1885 "%s: kstrtou8 failed ", __func__);
1886 ret = -EINVAL;
1887 goto exit;
1888 }
1889
1890 if (0 != roamScanControl)
1891 {
1892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1893 "roam scan control invalid value = %d",
1894 roamScanControl);
1895 ret = -EINVAL;
1896 goto exit;
1897 }
1898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1899 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
1900
1901 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
1902 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001903#ifdef FEATURE_WLAN_OKC
1904 else if (strncmp(command, "SETOKCMODE", 10) == 0)
1905 {
1906 tANI_U8 *value = command;
1907 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
1908
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07001909 /* Check if the features OKC/CCX/11R are supported simultaneously,
1910 then this operation is not permitted (return FAILURE) */
1911 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
1912 hdd_is_okc_mode_enabled(pHddCtx) &&
1913 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
1914 {
1915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1916 "%s: OKC/CCX/11R are supported simultaneously"
1917 " hence this operation is not permitted!", __func__);
1918 ret = -EPERM;
1919 goto exit;
1920 }
1921
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07001922 /* Move pointer to ahead of SETOKCMODE<delimiter> */
1923 value = value + 11;
1924 /* Convert the value from ascii to integer */
1925 ret = kstrtou8(value, 10, &okcMode);
1926 if (ret < 0)
1927 {
1928 /* If the input value is greater than max value of datatype, then also
1929 kstrtou8 fails */
1930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1931 "%s: kstrtou8 failed range [%d - %d]", __func__,
1932 CFG_OKC_FEATURE_ENABLED_MIN,
1933 CFG_OKC_FEATURE_ENABLED_MAX);
1934 ret = -EINVAL;
1935 goto exit;
1936 }
1937
1938 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
1939 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
1940 {
1941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1942 "Okc mode value %d is out of range"
1943 " (Min: %d Max: %d)", okcMode,
1944 CFG_OKC_FEATURE_ENABLED_MIN,
1945 CFG_OKC_FEATURE_ENABLED_MAX);
1946 ret = -EINVAL;
1947 goto exit;
1948 }
1949
1950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1951 "%s: Received Command to change okc mode = %d", __func__, okcMode);
1952
1953 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
1954 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07001955 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
1956 {
1957 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
1958 char extra[32];
1959 tANI_U8 len = 0;
1960
1961 len = snprintf(extra, sizeof(extra), "%s %d", command, roamScanControl);
1962 if (copy_to_user(priv_data.buf, &extra, len + 1))
1963 {
1964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1965 "%s: failed to copy data to user buffer", __func__);
1966 ret = -EFAULT;
1967 goto exit;
1968 }
1969 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08001970#endif
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05301971#ifdef WLAN_FEATURE_PACKET_FILTERING
1972 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
1973 {
1974 tANI_U8 filterType = 0;
1975 tANI_U8 *value = command;
1976
1977 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
1978 value = value + 22;
1979
1980 /* Convert the value from ascii to integer */
1981 ret = kstrtou8(value, 10, &filterType);
1982 if (ret < 0)
1983 {
1984 /* If the input value is greater than max value of datatype,
1985 * then also kstrtou8 fails
1986 */
1987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1988 "%s: kstrtou8 failed range ", __func__);
1989 ret = -EINVAL;
1990 goto exit;
1991 }
1992
1993 if (filterType != 0 && filterType != 1)
1994 {
1995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1996 "%s: Accepted Values are 0 and 1 ", __func__);
1997 ret = -EINVAL;
1998 goto exit;
1999 }
2000 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
2001 pAdapter->sessionId);
2002 }
2003#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05302004 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
2005 {
2006 char *dhcpPhase;
2007 dhcpPhase = command + 12;
2008 if ('1' == *dhcpPhase)
2009 {
2010 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
2011 pAdapter->macAddressCurrent.bytes);
2012 }
2013 else if ('2' == *dhcpPhase)
2014 {
2015 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
2016 pAdapter->macAddressCurrent.bytes);
2017 }
2018 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07002019 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
2020 {
2021 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
2022 }
2023 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
2024 {
2025 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
2026 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05302027 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2028 {
2029 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
2030 char extra[32];
2031 tANI_U8 len = 0;
2032
2033 len = snprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
2034 (int)pCfg->nActiveMaxChnTime);
2035 if (copy_to_user(priv_data.buf, &extra, len + 1))
2036 {
2037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2038 "%s: failed to copy data to user buffer", __func__);
2039 ret = -EFAULT;
2040 goto exit;
2041 }
2042 ret = len;
2043 }
2044 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2045 {
2046 tANI_U8 *value = command;
2047 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
2048 int val = 0, temp;
2049
2050 value = value + 13;
2051 temp = kstrtou32(value, 10, &val);
2052 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2053 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2054 {
2055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2056 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2057 ret = -EFAULT;
2058 goto exit;
2059 }
2060 pCfg->nActiveMaxChnTime = val;
2061 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002062 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
2063 {
2064 tANI_U8 filterType = 0;
2065 tANI_U8 *value;
2066 value = command + 9;
2067
2068 /* Convert the value from ascii to integer */
2069 ret = kstrtou8(value, 10, &filterType);
2070 if (ret < 0)
2071 {
2072 /* If the input value is greater than max value of datatype,
2073 * then also kstrtou8 fails
2074 */
2075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2076 "%s: kstrtou8 failed range ", __func__);
2077 ret = -EINVAL;
2078 goto exit;
2079 }
2080 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
2081 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
2082 {
2083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2084 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
2085 " 2-Sink ", __func__);
2086 ret = -EINVAL;
2087 goto exit;
2088 }
2089 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
2090 pHddCtx->drvr_miracast = filterType;
2091 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
2092 }
Leo Chang614d2072013-08-22 14:59:44 -07002093 else if (strncmp(command, "SETMCRATE", 9) == 0)
2094 {
2095 int rc;
2096 tANI_U8 *value = command;
2097 int targetRate;
2098
2099 /* Only valid for SAP mode */
2100 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
2101 {
2102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2103 "%s: SAP mode is not running", __func__);
2104 ret = -EFAULT;
2105 goto exit;
2106 }
2107
2108 /* Move pointer to ahead of SETMCRATE<delimiter> */
2109 /* input value is in units of hundred kbps */
2110 value = value + 10;
2111 /* Convert the value from ascii to integer, decimal base */
2112 ret = kstrtouint(value, 10, &targetRate);
2113
2114 rc = hdd_hostapd_set_mc_rate(pAdapter, targetRate);
2115 if (rc)
2116 {
2117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2118 "%s: Set MC Rate Fail %d", __func__, rc);
2119 ret = -EFAULT;
2120 goto exit;
2121 }
2122 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002123 else {
2124 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
2125 __func__, command);
2126 }
2127
Jeff Johnson295189b2012-06-20 16:38:30 -07002128 }
2129exit:
2130 if (command)
2131 {
2132 kfree(command);
2133 }
2134 return ret;
2135}
2136
Srinivas Girigowdade697412013-02-14 16:31:48 -08002137#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2138void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
2139{
2140 eCsrBand band = -1;
2141 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
2142 switch (band)
2143 {
2144 case eCSR_BAND_ALL:
2145 *pBand = WLAN_HDD_UI_BAND_AUTO;
2146 break;
2147
2148 case eCSR_BAND_24:
2149 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
2150 break;
2151
2152 case eCSR_BAND_5G:
2153 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
2154 break;
2155
2156 default:
2157 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
2158 *pBand = -1;
2159 break;
2160 }
2161}
2162
2163/**---------------------------------------------------------------------------
2164
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002165 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
2166
2167 This function parses the send action frame data passed in the format
2168 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
2169
Srinivas Girigowda56076852013-08-20 14:00:50 -07002170 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002171 \param - pTargetApBssid Pointer to target Ap bssid
2172 \param - pChannel Pointer to the Target AP channel
2173 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
2174 \param - pBuf Pointer to data
2175 \param - pBufLen Pointer to data length
2176
2177 \return - 0 for success non-zero for failure
2178
2179 --------------------------------------------------------------------------*/
2180VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
2181 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
2182{
2183 tANI_U8 *inPtr = pValue;
2184 tANI_U8 *dataEnd;
2185 int tempInt;
2186 int j = 0;
2187 int i = 0;
2188 int v = 0;
2189 tANI_U8 tempBuf[32];
2190 tANI_U8 tempByte = 0;
2191
2192 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2193 /*no argument after the command*/
2194 if (NULL == inPtr)
2195 {
2196 return -EINVAL;
2197 }
2198
2199 /*no space after the command*/
2200 else if (SPACE_ASCII_VALUE != *inPtr)
2201 {
2202 return -EINVAL;
2203 }
2204
2205 /*removing empty spaces*/
2206 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
2207
2208 /*no argument followed by spaces*/
2209 if ('\0' == *inPtr)
2210 {
2211 return -EINVAL;
2212 }
2213
2214 /*getting the first argument ie the target AP bssid */
2215 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' || inPtr[11] != ':' || inPtr[14] != ':')
2216 {
2217 return -EINVAL;
2218 }
2219 j = sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x", (unsigned int *)&pTargetApBssid[0], (unsigned int *)&pTargetApBssid[1],
2220 (unsigned int *)&pTargetApBssid[2], (unsigned int *)&pTargetApBssid[3],
2221 (unsigned int *)&pTargetApBssid[4], (unsigned int *)&pTargetApBssid[5]);
2222
2223 /* point to the next argument */
2224 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
2225 /*no argument after the command*/
2226 if (NULL == inPtr) return -EINVAL;
2227
2228 /*removing empty spaces*/
2229 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
2230
2231 /*no argument followed by spaces*/
2232 if ('\0' == *inPtr)
2233 {
2234 return -EINVAL;
2235 }
2236
2237 /*getting the next argument ie the channel number */
Jeff Johnson440b9472013-04-16 17:35:57 -07002238 j = sscanf(inPtr, "%32s ", tempBuf);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002239 v = kstrtos32(tempBuf, 10, &tempInt);
2240 if ( v < 0) return -EINVAL;
2241
2242 *pChannel = tempInt;
2243
2244 /* point to the next argument */
2245 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
2246 /*no argument after the command*/
2247 if (NULL == inPtr) return -EINVAL;
2248 /*removing empty spaces*/
2249 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
2250
2251 /*no argument followed by spaces*/
2252 if ('\0' == *inPtr)
2253 {
2254 return -EINVAL;
2255 }
2256
2257 /*getting the next argument ie the dwell time */
Jeff Johnson440b9472013-04-16 17:35:57 -07002258 j = sscanf(inPtr, "%32s ", tempBuf);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002259 v = kstrtos32(tempBuf, 10, &tempInt);
2260 if ( v < 0) return -EINVAL;
2261
2262 *pDwellTime = tempInt;
2263
2264 /* point to the next argument */
2265 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
2266 /*no argument after the command*/
2267 if (NULL == inPtr) return -EINVAL;
2268 /*removing empty spaces*/
2269 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
2270
2271 /*no argument followed by spaces*/
2272 if ('\0' == *inPtr)
2273 {
2274 return -EINVAL;
2275 }
2276
2277 /* find the length of data */
2278 dataEnd = inPtr;
2279 while(('\0' != *dataEnd) )
2280 {
2281 dataEnd++;
2282 ++(*pBufLen);
2283 }
2284 if ( *pBufLen <= 0) return -EINVAL;
2285
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07002286 /* Allocate the number of bytes based on the number of input characters
2287 whether it is even or odd.
2288 if the number of input characters are even, then we need N/2 byte.
2289 if the number of input characters are odd, then we need do (N+1)/2 to
2290 compensate rounding off.
2291 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
2292 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
2293 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002294 if (NULL == *pBuf)
2295 {
2296 hddLog(VOS_TRACE_LEVEL_FATAL,
2297 "%s: vos_mem_alloc failed ", __func__);
2298 return -EINVAL;
2299 }
2300
2301 /* the buffer received from the upper layer is character buffer,
2302 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
2303 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
2304 and f0 in 3rd location */
2305 for (i = 0, j = 0; j < *pBufLen; j += 2)
2306 {
2307 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
2308 (*pBuf)[i++] = tempByte;
2309 }
2310 *pBufLen = i;
2311 return VOS_STATUS_SUCCESS;
2312}
2313
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002314/**---------------------------------------------------------------------------
2315
Srinivas Girigowdade697412013-02-14 16:31:48 -08002316 \brief hdd_parse_channellist() - HDD Parse channel list
2317
2318 This function parses the channel list passed in the format
2319 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07002320 if the Number of channels (N) does not match with the actual number of channels passed
2321 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
2322 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
2323 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
2324 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08002325
2326 \param - pValue Pointer to input channel list
2327 \param - ChannelList Pointer to local output array to record channel list
2328 \param - pNumChannels Pointer to number of roam scan channels
2329
2330 \return - 0 for success non-zero for failure
2331
2332 --------------------------------------------------------------------------*/
2333VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
2334{
2335 tANI_U8 *inPtr = pValue;
2336 int tempInt;
2337 int j = 0;
2338 int v = 0;
2339 char buf[32];
2340
2341 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2342 /*no argument after the command*/
2343 if (NULL == inPtr)
2344 {
2345 return -EINVAL;
2346 }
2347
2348 /*no space after the command*/
2349 else if (SPACE_ASCII_VALUE != *inPtr)
2350 {
2351 return -EINVAL;
2352 }
2353
2354 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07002355 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002356
2357 /*no argument followed by spaces*/
2358 if ('\0' == *inPtr)
2359 {
2360 return -EINVAL;
2361 }
2362
2363 /*getting the first argument ie the number of channels*/
Chilam Ngc4244af2013-04-01 15:37:32 -07002364 sscanf(inPtr, "%32s ", buf);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002365 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07002366 if ((v < 0) ||
2367 (tempInt <= 0) ||
2368 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
2369 {
2370 return -EINVAL;
2371 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002372
2373 *pNumChannels = tempInt;
2374
2375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2376 "Number of channels are: %d", *pNumChannels);
2377
2378 for (j = 0; j < (*pNumChannels); j++)
2379 {
2380 /*inPtr pointing to the beginning of first space after number of channels*/
2381 inPtr = strpbrk( inPtr, " " );
2382 /*no channel list after the number of channels argument*/
2383 if (NULL == inPtr)
2384 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07002385 if (0 != j)
2386 {
2387 *pNumChannels = j;
2388 return VOS_STATUS_SUCCESS;
2389 }
2390 else
2391 {
2392 return -EINVAL;
2393 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002394 }
2395
2396 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07002397 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002398
2399 /*no channel list after the number of channels argument and spaces*/
2400 if ( '\0' == *inPtr )
2401 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07002402 if (0 != j)
2403 {
2404 *pNumChannels = j;
2405 return VOS_STATUS_SUCCESS;
2406 }
2407 else
2408 {
2409 return -EINVAL;
2410 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002411 }
2412
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07002413 sscanf(inPtr, "%32s ", buf);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002414 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07002415 if ((v < 0) ||
2416 (tempInt <= 0) ||
2417 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
2418 {
2419 return -EINVAL;
2420 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002421 pChannelList[j] = tempInt;
2422
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2424 "Channel %d added to preferred channel list",
2425 pChannelList[j] );
2426 }
2427
Srinivas Girigowdade697412013-02-14 16:31:48 -08002428 return VOS_STATUS_SUCCESS;
2429}
2430
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002431
2432/**---------------------------------------------------------------------------
2433
2434 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
2435
2436 This function parses the reasoc command data passed in the format
2437 REASSOC<space><bssid><space><channel>
2438
Srinivas Girigowda56076852013-08-20 14:00:50 -07002439 \param - pValue Pointer to input data
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002440 \param - pTargetApBssid Pointer to target Ap bssid
2441 \param - pChannel Pointer to the Target AP channel
2442
2443 \return - 0 for success non-zero for failure
2444
2445 --------------------------------------------------------------------------*/
2446VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
2447{
2448 tANI_U8 *inPtr = pValue;
2449 int tempInt;
2450 int v = 0;
2451 tANI_U8 tempBuf[32];
2452
2453 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2454 /*no argument after the command*/
2455 if (NULL == inPtr)
2456 {
2457 return -EINVAL;
2458 }
2459
2460 /*no space after the command*/
2461 else if (SPACE_ASCII_VALUE != *inPtr)
2462 {
2463 return -EINVAL;
2464 }
2465
2466 /*removing empty spaces*/
2467 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
2468
2469 /*no argument followed by spaces*/
2470 if ('\0' == *inPtr)
2471 {
2472 return -EINVAL;
2473 }
2474
2475 /*getting the first argument ie the target AP bssid */
2476 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' || inPtr[11] != ':' || inPtr[14] != ':')
2477 {
2478 return -EINVAL;
2479 }
2480 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x", (unsigned int *)&pTargetApBssid[0], (unsigned int *)&pTargetApBssid[1],
2481 (unsigned int *)&pTargetApBssid[2], (unsigned int *)&pTargetApBssid[3],
2482 (unsigned int *)&pTargetApBssid[4], (unsigned int *)&pTargetApBssid[5]);
2483
2484 /* point to the next argument */
2485 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
2486 /*no argument after the command*/
2487 if (NULL == inPtr) return -EINVAL;
2488
2489 /*removing empty spaces*/
2490 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
2491
2492 /*no argument followed by spaces*/
2493 if ('\0' == *inPtr)
2494 {
2495 return -EINVAL;
2496 }
2497
2498 /*getting the next argument ie the channel number */
2499 sscanf(inPtr, "%s ", tempBuf);
2500 v = kstrtos32(tempBuf, 10, &tempInt);
2501 if ( v < 0) return -EINVAL;
2502
2503 *pChannel = tempInt;
2504 return VOS_STATUS_SUCCESS;
2505}
2506
2507#endif
2508
Jeff Johnson295189b2012-06-20 16:38:30 -07002509/**---------------------------------------------------------------------------
2510
2511 \brief hdd_open() - HDD Open function
2512
2513 This is called in response to ifconfig up
2514
2515 \param - dev Pointer to net_device structure
2516
2517 \return - 0 for success non-zero for failure
2518
2519 --------------------------------------------------------------------------*/
2520int hdd_open (struct net_device *dev)
2521{
2522 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2523 hdd_context_t *pHddCtx;
2524 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2525 VOS_STATUS status;
2526 v_BOOL_t in_standby = TRUE;
2527
2528 if (NULL == pAdapter)
2529 {
2530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002531 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 return -ENODEV;
2533 }
2534
2535 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2536 if (NULL == pHddCtx)
2537 {
2538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002539 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002540 return -ENODEV;
2541 }
2542
2543 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2544 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
2545 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07002546 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
2547 {
2548 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302549 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07002550 in_standby = FALSE;
2551 break;
2552 }
2553 else
2554 {
2555 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2556 pAdapterNode = pNext;
2557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 }
2559
2560 if (TRUE == in_standby)
2561 {
2562 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
2563 {
2564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
2565 "wlan out of power save", __func__);
2566 return -EINVAL;
2567 }
2568 }
2569
Jeff Johnson6a81ca42013-04-05 10:37:08 -07002570 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002571 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
2572 {
2573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002574 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002575 /* Enable TX queues only when we are connected */
2576 netif_tx_start_all_queues(dev);
2577 }
2578
2579 return 0;
2580}
2581
2582int hdd_mon_open (struct net_device *dev)
2583{
2584 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2585
2586 if(pAdapter == NULL) {
2587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002588 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002589 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002590 }
2591
2592 netif_start_queue(dev);
2593
2594 return 0;
2595}
2596/**---------------------------------------------------------------------------
2597
2598 \brief hdd_stop() - HDD stop function
2599
2600 This is called in response to ifconfig down
2601
2602 \param - dev Pointer to net_device structure
2603
2604 \return - 0 for success non-zero for failure
2605
2606 --------------------------------------------------------------------------*/
2607
2608int hdd_stop (struct net_device *dev)
2609{
2610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2611 hdd_context_t *pHddCtx;
2612 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2613 VOS_STATUS status;
2614 v_BOOL_t enter_standby = TRUE;
2615
2616 ENTER();
2617
2618 if (NULL == pAdapter)
2619 {
2620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002621 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002622 return -ENODEV;
2623 }
2624
2625 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2626 if (NULL == pHddCtx)
2627 {
2628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002629 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002630 return -ENODEV;
2631 }
2632
Jeff Johnson6a81ca42013-04-05 10:37:08 -07002633 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07002634 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
2635 netif_tx_disable(pAdapter->dev);
2636 netif_carrier_off(pAdapter->dev);
2637
2638
2639 /* SoftAP ifaces should never go in power save mode
2640 making sure same here. */
2641 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
2642 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07002643 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07002644 )
2645 {
2646 /* SoftAP mode, so return from here */
2647 EXIT();
2648 return 0;
2649 }
2650
2651 /* Find if any iface is up then
2652 if any iface is up then can't put device to sleep/ power save mode. */
2653 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2654 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
2655 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07002656 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
2657 {
2658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302659 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07002660 enter_standby = FALSE;
2661 break;
2662 }
2663 else
2664 {
2665 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2666 pAdapterNode = pNext;
2667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 }
2669
2670 if (TRUE == enter_standby)
2671 {
2672 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
2673 "entering standby", __func__);
2674 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
2675 {
2676 /*log and return success*/
2677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
2678 "wlan in power save", __func__);
2679 }
2680 }
2681
2682 EXIT();
2683 return 0;
2684}
2685
2686/**---------------------------------------------------------------------------
2687
2688 \brief hdd_uninit() - HDD uninit function
2689
2690 This is called during the netdev unregister to uninitialize all data
2691associated with the device
2692
2693 \param - dev Pointer to net_device structure
2694
2695 \return - void
2696
2697 --------------------------------------------------------------------------*/
2698static void hdd_uninit (struct net_device *dev)
2699{
2700 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2701
2702 ENTER();
2703
2704 do
2705 {
2706 if (NULL == pAdapter)
2707 {
2708 hddLog(VOS_TRACE_LEVEL_FATAL,
2709 "%s: NULL pAdapter", __func__);
2710 break;
2711 }
2712
2713 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_FATAL,
2716 "%s: Invalid magic", __func__);
2717 break;
2718 }
2719
2720 if (NULL == pAdapter->pHddCtx)
2721 {
2722 hddLog(VOS_TRACE_LEVEL_FATAL,
2723 "%s: NULL pHddCtx", __func__);
2724 break;
2725 }
2726
2727 if (dev != pAdapter->dev)
2728 {
2729 hddLog(VOS_TRACE_LEVEL_FATAL,
2730 "%s: Invalid device reference", __func__);
2731 /* we haven't validated all cases so let this go for now */
2732 }
2733
2734 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
2735
2736 /* after uninit our adapter structure will no longer be valid */
2737 pAdapter->dev = NULL;
2738 pAdapter->magic = 0;
2739 } while (0);
2740
2741 EXIT();
2742}
2743
2744/**---------------------------------------------------------------------------
2745
2746 \brief hdd_release_firmware() -
2747
2748 This function calls the release firmware API to free the firmware buffer.
2749
2750 \param - pFileName Pointer to the File Name.
2751 pCtx - Pointer to the adapter .
2752
2753
2754 \return - 0 for success, non zero for failure
2755
2756 --------------------------------------------------------------------------*/
2757
2758VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
2759{
2760 VOS_STATUS status = VOS_STATUS_SUCCESS;
2761 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
2762 ENTER();
2763
2764
2765 if (!strcmp(WLAN_FW_FILE, pFileName)) {
2766
2767 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
2768
2769 if(pHddCtx->fw) {
2770 release_firmware(pHddCtx->fw);
2771 pHddCtx->fw = NULL;
2772 }
2773 else
2774 status = VOS_STATUS_E_FAILURE;
2775 }
2776 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
2777 if(pHddCtx->nv) {
2778 release_firmware(pHddCtx->nv);
2779 pHddCtx->nv = NULL;
2780 }
2781 else
2782 status = VOS_STATUS_E_FAILURE;
2783
2784 }
2785
2786 EXIT();
2787 return status;
2788}
2789
2790/**---------------------------------------------------------------------------
2791
2792 \brief hdd_request_firmware() -
2793
2794 This function reads the firmware file using the request firmware
2795 API and returns the the firmware data and the firmware file size.
2796
2797 \param - pfileName - Pointer to the file name.
2798 - pCtx - Pointer to the adapter .
2799 - ppfw_data - Pointer to the pointer of the firmware data.
2800 - pSize - Pointer to the file size.
2801
2802 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
2803
2804 --------------------------------------------------------------------------*/
2805
2806
2807VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
2808{
2809 int status;
2810 VOS_STATUS retval = VOS_STATUS_SUCCESS;
2811 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
2812 ENTER();
2813
2814 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
2815
2816 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
2817
2818 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
2819 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
2820 __func__, pfileName);
2821 retval = VOS_STATUS_E_FAILURE;
2822 }
2823
2824 else {
2825 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
2826 *pSize = pHddCtx->fw->size;
2827 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
2828 __func__, *pSize);
2829 }
2830 }
2831 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
2832
2833 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
2834
2835 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
2836 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
2837 __func__, pfileName);
2838 retval = VOS_STATUS_E_FAILURE;
2839 }
2840
2841 else {
2842 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
2843 *pSize = pHddCtx->nv->size;
2844 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
2845 __func__, *pSize);
2846 }
2847 }
2848
2849 EXIT();
2850 return retval;
2851}
2852/**---------------------------------------------------------------------------
2853 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
2854
2855 This is the function invoked by SME to inform the result of a full power
2856 request issued by HDD
2857
2858 \param - callbackcontext - Pointer to cookie
2859 status - result of request
2860
2861 \return - None
2862
2863--------------------------------------------------------------------------*/
2864void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
2865{
2866 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
2867
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002868 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002869 if(&pHddCtx->full_pwr_comp_var)
2870 {
2871 complete(&pHddCtx->full_pwr_comp_var);
2872 }
2873}
2874
2875/**---------------------------------------------------------------------------
2876
2877 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
2878
2879 This is the function invoked by SME to inform the result of BMPS
2880 request issued by HDD
2881
2882 \param - callbackcontext - Pointer to cookie
2883 status - result of request
2884
2885 \return - None
2886
2887--------------------------------------------------------------------------*/
2888void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
2889{
2890
2891 struct completion *completion_var = (struct completion*) callbackContext;
2892
2893 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d\n", status);
2894 if(completion_var != NULL)
2895 {
2896 complete(completion_var);
2897 }
2898}
2899
2900/**---------------------------------------------------------------------------
2901
2902 \brief hdd_get_cfg_file_size() -
2903
2904 This function reads the configuration file using the request firmware
2905 API and returns the configuration file size.
2906
2907 \param - pCtx - Pointer to the adapter .
2908 - pFileName - Pointer to the file name.
2909 - pBufSize - Pointer to the buffer size.
2910
2911 \return - 0 for success, non zero for failure
2912
2913 --------------------------------------------------------------------------*/
2914
2915VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
2916{
2917 int status;
2918 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
2919
2920 ENTER();
2921
2922 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
2923
2924 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
2925 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
2926 status = VOS_STATUS_E_FAILURE;
2927 }
2928 else {
2929 *pBufSize = pHddCtx->fw->size;
2930 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
2931 release_firmware(pHddCtx->fw);
2932 pHddCtx->fw = NULL;
2933 }
2934
2935 EXIT();
2936 return VOS_STATUS_SUCCESS;
2937}
2938
2939/**---------------------------------------------------------------------------
2940
2941 \brief hdd_read_cfg_file() -
2942
2943 This function reads the configuration file using the request firmware
2944 API and returns the cfg data and the buffer size of the configuration file.
2945
2946 \param - pCtx - Pointer to the adapter .
2947 - pFileName - Pointer to the file name.
2948 - pBuffer - Pointer to the data buffer.
2949 - pBufSize - Pointer to the buffer size.
2950
2951 \return - 0 for success, non zero for failure
2952
2953 --------------------------------------------------------------------------*/
2954
2955VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
2956 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
2957{
2958 int status;
2959 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
2960
2961 ENTER();
2962
2963 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
2964
2965 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
2966 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
2967 return VOS_STATUS_E_FAILURE;
2968 }
2969 else {
2970 if(*pBufSize != pHddCtx->fw->size) {
2971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
2972 "file size", __func__);
2973 release_firmware(pHddCtx->fw);
2974 pHddCtx->fw = NULL;
2975 return VOS_STATUS_E_FAILURE;
2976 }
2977 else {
2978 if(pBuffer) {
2979 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
2980 }
2981 release_firmware(pHddCtx->fw);
2982 pHddCtx->fw = NULL;
2983 }
2984 }
2985
2986 EXIT();
2987
2988 return VOS_STATUS_SUCCESS;
2989}
2990
2991/**---------------------------------------------------------------------------
2992
Jeff Johnson295189b2012-06-20 16:38:30 -07002993 \brief hdd_set_mac_address() -
2994
2995 This function sets the user specified mac address using
2996 the command ifconfig wlanX hw ether <mac adress>.
2997
2998 \param - dev - Pointer to the net device.
2999 - addr - Pointer to the sockaddr.
3000 \return - 0 for success, non zero for failure
3001
3002 --------------------------------------------------------------------------*/
3003
3004static int hdd_set_mac_address(struct net_device *dev, void *addr)
3005{
3006 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3007 struct sockaddr *psta_mac_addr = addr;
3008 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
3009
3010 ENTER();
3011
3012 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
3013
3014#ifdef HDD_SESSIONIZE
3015 // set the MAC address though the STA ID CFG.
3016 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
3017 (v_U8_t *)&pAdapter->macAddressCurrent,
3018 sizeof( pAdapter->macAddressCurrent ),
3019 hdd_set_mac_addr_cb, VOS_FALSE );
3020#endif
3021
3022 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3023
3024 EXIT();
3025 return halStatus;
3026}
3027
3028tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
3029{
3030 int i;
3031 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
3032 {
3033 if( 0 == (pHddCtx->cfg_ini->intfAddrMask >> i))
3034 break;
3035 }
3036
3037 if( VOS_MAX_CONCURRENCY_PERSONA == i)
3038 return NULL;
3039
3040 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
3041 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
3042}
3043
3044void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
3045{
3046 int i;
3047 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
3048 {
3049 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
3050 {
3051 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
3052 break;
3053 }
3054 }
3055 return;
3056}
3057
3058#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
3059 static struct net_device_ops wlan_drv_ops = {
3060 .ndo_open = hdd_open,
3061 .ndo_stop = hdd_stop,
3062 .ndo_uninit = hdd_uninit,
3063 .ndo_start_xmit = hdd_hard_start_xmit,
3064 .ndo_tx_timeout = hdd_tx_timeout,
3065 .ndo_get_stats = hdd_stats,
3066 .ndo_do_ioctl = hdd_ioctl,
3067 .ndo_set_mac_address = hdd_set_mac_address,
3068 .ndo_select_queue = hdd_select_queue,
3069#ifdef WLAN_FEATURE_PACKET_FILTERING
3070#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
3071 .ndo_set_rx_mode = hdd_set_multicast_list,
3072#else
3073 .ndo_set_multicast_list = hdd_set_multicast_list,
3074#endif //LINUX_VERSION_CODE
3075#endif
3076 };
Jeff Johnson295189b2012-06-20 16:38:30 -07003077 static struct net_device_ops wlan_mon_drv_ops = {
3078 .ndo_open = hdd_mon_open,
3079 .ndo_stop = hdd_stop,
3080 .ndo_uninit = hdd_uninit,
3081 .ndo_start_xmit = hdd_mon_hard_start_xmit,
3082 .ndo_tx_timeout = hdd_tx_timeout,
3083 .ndo_get_stats = hdd_stats,
3084 .ndo_do_ioctl = hdd_ioctl,
3085 .ndo_set_mac_address = hdd_set_mac_address,
3086 };
Jeff Johnson295189b2012-06-20 16:38:30 -07003087
3088#endif
3089
3090void hdd_set_station_ops( struct net_device *pWlanDev )
3091{
3092#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
3093 pWlanDev->tx_queue_len = NET_DEV_TX_QUEUE_LEN,
3094 pWlanDev->netdev_ops = &wlan_drv_ops;
3095#else
3096 pWlanDev->open = hdd_open;
3097 pWlanDev->stop = hdd_stop;
3098 pWlanDev->uninit = hdd_uninit;
3099 pWlanDev->hard_start_xmit = NULL;
3100 pWlanDev->tx_timeout = hdd_tx_timeout;
3101 pWlanDev->get_stats = hdd_stats;
3102 pWlanDev->do_ioctl = hdd_ioctl;
3103 pWlanDev->tx_queue_len = NET_DEV_TX_QUEUE_LEN;
3104 pWlanDev->set_mac_address = hdd_set_mac_address;
3105#endif
3106}
3107
Jeff Johnsoneed415b2013-01-18 16:11:20 -08003108static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07003109{
3110 struct net_device *pWlanDev = NULL;
3111 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003112 /*
3113 * cfg80211 initialization and registration....
3114 */
3115 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
3116
Jeff Johnson295189b2012-06-20 16:38:30 -07003117 if(pWlanDev != NULL)
3118 {
3119
3120 //Save the pointer to the net_device in the HDD adapter
3121 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
3122
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
3124
3125 pAdapter->dev = pWlanDev;
3126 pAdapter->pHddCtx = pHddCtx;
3127 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3128
3129 init_completion(&pAdapter->session_open_comp_var);
3130 init_completion(&pAdapter->session_close_comp_var);
3131 init_completion(&pAdapter->disconnect_comp_var);
3132 init_completion(&pAdapter->linkup_event_var);
3133 init_completion(&pAdapter->cancel_rem_on_chan_var);
3134 init_completion(&pAdapter->rem_on_chan_ready_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07003135#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3136 init_completion(&pAdapter->offchannel_tx_event);
3137#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003138 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08003139#ifdef FEATURE_WLAN_TDLS
3140 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003141 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08003142 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303143 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08003144#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003145 init_completion(&pHddCtx->mc_sus_event_var);
3146 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05303147 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07003148 init_completion(&pAdapter->ula_complete);
Jeff Johnson295189b2012-06-20 16:38:30 -07003149
Jeff Johnson295189b2012-06-20 16:38:30 -07003150 pAdapter->isLinkUpSvcNeeded = FALSE;
3151 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
3152 //Init the net_device structure
3153 strlcpy(pWlanDev->name, name, IFNAMSIZ);
3154
3155 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
3156 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
3157 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
3158 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
3159
3160 hdd_set_station_ops( pAdapter->dev );
3161
3162 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003163 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
3164 pAdapter->wdev.wiphy = pHddCtx->wiphy;
3165 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07003166 /* set pWlanDev's parent to underlying device */
3167 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
3168 }
3169
3170 return pAdapter;
3171}
3172
3173VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
3174{
3175 struct net_device *pWlanDev = pAdapter->dev;
3176 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
3177 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
3178 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
3179
3180 if( rtnl_lock_held )
3181 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08003182 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07003183 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
3184 {
3185 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
3186 return VOS_STATUS_E_FAILURE;
3187 }
3188 }
3189 if (register_netdevice(pWlanDev))
3190 {
3191 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
3192 return VOS_STATUS_E_FAILURE;
3193 }
3194 }
3195 else
3196 {
3197 if(register_netdev(pWlanDev))
3198 {
3199 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
3200 return VOS_STATUS_E_FAILURE;
3201 }
3202 }
3203 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
3204
3205 return VOS_STATUS_SUCCESS;
3206}
3207
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003208static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07003209{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003210 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003211
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003212 if (NULL == pAdapter)
3213 {
3214 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
3215 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07003216 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003217
3218 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
3219 {
3220 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
3221 return eHAL_STATUS_NOT_INITIALIZED;
3222 }
3223
3224 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3225
3226 /* need to make sure all of our scheduled work has completed.
3227 * This callback is called from MC thread context, so it is safe to
3228 * to call below flush workqueue API from here.
3229 */
3230 flush_scheduled_work();
3231
3232 /* We can be blocked while waiting for scheduled work to be
3233 * flushed, and the adapter structure can potentially be freed, in
3234 * which case the magic will have been reset. So make sure the
3235 * magic is still good, and hence the adapter structure is still
3236 * valid, before signaling completion */
3237 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
3238 {
3239 complete(&pAdapter->session_close_comp_var);
3240 }
3241
Jeff Johnson295189b2012-06-20 16:38:30 -07003242 return eHAL_STATUS_SUCCESS;
3243}
3244
3245VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
3246{
3247 struct net_device *pWlanDev = pAdapter->dev;
3248 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
3249 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
3250 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
3251 VOS_STATUS status = VOS_STATUS_E_FAILURE;
3252 int rc = 0;
3253
3254 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003255 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003256 //Open a SME session for future operation
3257 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07003258 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07003259 if ( !HAL_STATUS_SUCCESS( halStatus ) )
3260 {
3261 hddLog(VOS_TRACE_LEVEL_FATAL,
3262 "sme_OpenSession() failed with status code %08d [x%08lx]",
3263 halStatus, halStatus );
3264 status = VOS_STATUS_E_FAILURE;
3265 goto error_sme_open;
3266 }
3267
3268 //Block on a completion variable. Can't wait forever though.
3269 rc = wait_for_completion_interruptible_timeout(
3270 &pAdapter->session_open_comp_var,
3271 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
3272 if (!rc)
3273 {
3274 hddLog(VOS_TRACE_LEVEL_FATAL,
3275 "Session is not opened within timeout period code %08d", rc );
3276 status = VOS_STATUS_E_FAILURE;
3277 goto error_sme_open;
3278 }
3279
3280 // Register wireless extensions
3281 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
3282 {
3283 hddLog(VOS_TRACE_LEVEL_FATAL,
3284 "hdd_register_wext() failed with status code %08d [x%08lx]",
3285 halStatus, halStatus );
3286 status = VOS_STATUS_E_FAILURE;
3287 goto error_register_wext;
3288 }
3289 //Safe to register the hard_start_xmit function again
3290#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
3291 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
3292#else
3293 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
3294#endif
3295
3296 //Set the Connection State to Not Connected
3297 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
3298
3299 //Set the default operation channel
3300 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
3301
3302 /* Make the default Auth Type as OPEN*/
3303 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3304
3305 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
3306 {
3307 hddLog(VOS_TRACE_LEVEL_FATAL,
3308 "hdd_init_tx_rx() failed with status code %08d [x%08lx]",
3309 status, status );
3310 goto error_init_txrx;
3311 }
3312
3313 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
3314
3315 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
3316 {
3317 hddLog(VOS_TRACE_LEVEL_FATAL,
3318 "hdd_wmm_adapter_init() failed with status code %08d [x%08lx]",
3319 status, status );
3320 goto error_wmm_init;
3321 }
3322
3323 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3324
Gopichand Nakkala4327a152013-03-04 23:22:42 -08003325#ifdef FEATURE_WLAN_TDLS
3326 if(0 != wlan_hdd_tdls_init(pAdapter))
3327 {
3328 status = VOS_STATUS_E_FAILURE;
3329 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
3330 goto error_tdls_init;
3331 }
3332 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
3333#endif
3334
Jeff Johnson295189b2012-06-20 16:38:30 -07003335 return VOS_STATUS_SUCCESS;
3336
Gopichand Nakkala4327a152013-03-04 23:22:42 -08003337#ifdef FEATURE_WLAN_TDLS
3338error_tdls_init:
3339 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3340 hdd_wmm_adapter_close(pAdapter);
3341#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003342error_wmm_init:
3343 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
3344 hdd_deinit_tx_rx(pAdapter);
3345error_init_txrx:
3346 hdd_UnregisterWext(pWlanDev);
3347error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003348 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07003349 {
3350 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003351 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07003352 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003353 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07003354 {
3355 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003356 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07003357 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07003358 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
Jeff Johnson295189b2012-06-20 16:38:30 -07003359 }
3360}
3361error_sme_open:
3362 return status;
3363}
3364
Jeff Johnson295189b2012-06-20 16:38:30 -07003365void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
3366{
3367 hdd_cfg80211_state_t *cfgState;
3368
3369 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
3370
3371 if( NULL != cfgState->buf )
3372 {
3373 int rc;
3374 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
3375 rc = wait_for_completion_interruptible_timeout(
3376 &pAdapter->tx_action_cnf_event,
3377 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
3378 if(!rc)
3379 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08003380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003381 ("ERROR: HDD Wait for Action Confirmation Failed!!\n"));
3382 }
3383 }
3384 return;
3385}
Jeff Johnson295189b2012-06-20 16:38:30 -07003386
3387void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
3388{
3389 ENTER();
3390 switch ( pAdapter->device_mode )
3391 {
3392 case WLAN_HDD_INFRA_STATION:
3393 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07003394 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 {
3396 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
3397 {
3398 hdd_deinit_tx_rx( pAdapter );
3399 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
3400 }
3401
3402 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
3403 {
3404 hdd_wmm_adapter_close( pAdapter );
3405 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3406 }
3407
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08003409#ifdef FEATURE_WLAN_TDLS
3410 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
3411 {
3412 wlan_hdd_tdls_exit(pAdapter);
3413 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
3414 }
3415#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003416
3417 break;
3418 }
3419
3420 case WLAN_HDD_SOFTAP:
3421 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003422 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05303423
3424 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
3425 {
3426 hdd_wmm_adapter_close( pAdapter );
3427 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
3428 }
3429
Jeff Johnson295189b2012-06-20 16:38:30 -07003430 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003431
3432 hdd_unregister_hostapd(pAdapter);
3433 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07003434 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07003435 break;
3436 }
3437
3438 case WLAN_HDD_MONITOR:
3439 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003440 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003441 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
3442 {
3443 hdd_deinit_tx_rx( pAdapter );
3444 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
3445 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003446 if(NULL != pAdapterforTx)
3447 {
3448 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
3449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003450 break;
3451 }
3452
3453
3454 default:
3455 break;
3456 }
3457
3458 EXIT();
3459}
3460
3461void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
3462{
3463 struct net_device *pWlanDev = pAdapter->dev;
3464
3465 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
3466 if( rtnl_held )
3467 {
3468 unregister_netdevice(pWlanDev);
3469 }
3470 else
3471 {
3472 unregister_netdev(pWlanDev);
3473 }
3474 // note that the pAdapter is no longer valid at this point
3475 // since the memory has been reclaimed
3476 }
3477
3478}
3479
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003480void hdd_set_pwrparams(hdd_context_t *pHddCtx)
3481{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303482 VOS_STATUS status;
3483 hdd_adapter_t *pAdapter = NULL;
3484 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003485
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303486 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003487
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303488 /*loop through all adapters.*/
3489 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003490 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303491 pAdapter = pAdapterNode->pAdapter;
3492 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
3493 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003494
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303495 { // we skip this registration for modes other than STA and P2P client modes.
3496 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
3497 pAdapterNode = pNext;
3498 continue;
3499 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003500
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303501 //Apply Dynamic DTIM For P2P
3502 //Only if ignoreDynamicDtimInP2pMode is not set in ini
3503 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
3504 pHddCtx->cfg_ini->enableModulatedDTIM) &&
3505 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
3506 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
3507 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
3508 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
3509 (eConnectionState_Associated ==
3510 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
3511 (pHddCtx->cfg_ini->fIsBmpsEnabled))
3512 {
3513 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003514
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303515 powerRequest.uIgnoreDTIM = 1;
3516 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
3517
3518 if (pHddCtx->cfg_ini->enableModulatedDTIM)
3519 {
3520 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
3521 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
3522 }
3523 else
3524 {
3525 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
3526 }
3527
3528 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
3529 * specified during Enter/Exit BMPS when LCD off*/
3530 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
3531 NULL, eANI_BOOLEAN_FALSE);
3532 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
3533 NULL, eANI_BOOLEAN_FALSE);
3534
3535 /* switch to the DTIM specified in cfg.ini */
3536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3537 "Switch to DTIM %d", powerRequest.uListenInterval);
3538 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
3539 break;
3540
3541 }
3542
3543 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
3544 pAdapterNode = pNext;
3545 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003546}
3547
3548void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
3549{
3550 /*Switch back to DTIM 1*/
3551 tSirSetPowerParamsReq powerRequest = { 0 };
3552
3553 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
3554 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07003555 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08003556
3557 /* Update ignoreDTIM and ListedInterval in CFG with default values */
3558 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
3559 NULL, eANI_BOOLEAN_FALSE);
3560 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
3561 NULL, eANI_BOOLEAN_FALSE);
3562
3563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3564 "Switch to DTIM%d",powerRequest.uListenInterval);
3565 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
3566
3567}
3568
Jeff Johnson295189b2012-06-20 16:38:30 -07003569VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
3570{
3571 VOS_STATUS status = VOS_STATUS_SUCCESS;
3572
3573 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
3574 {
3575 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
3576 }
3577
3578 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
3579 {
3580 sme_StartAutoBmpsTimer(pHddCtx->hHal);
3581 }
3582
3583 if (pHddCtx->cfg_ini->fIsImpsEnabled)
3584 {
3585 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
3586 }
3587
3588 return status;
3589}
3590
3591VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
3592{
3593 hdd_adapter_t *pAdapter = NULL;
3594 eHalStatus halStatus;
3595 VOS_STATUS status = VOS_STATUS_E_INVAL;
3596 v_BOOL_t disableBmps = FALSE;
3597 v_BOOL_t disableImps = FALSE;
3598
3599 switch(session_type)
3600 {
3601 case WLAN_HDD_INFRA_STATION:
3602 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003603 case WLAN_HDD_P2P_CLIENT:
3604 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003605 //Exit BMPS -> Is Sta/P2P Client is already connected
3606 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
3607 if((NULL != pAdapter)&&
3608 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
3609 {
3610 disableBmps = TRUE;
3611 }
3612
3613 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
3614 if((NULL != pAdapter)&&
3615 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
3616 {
3617 disableBmps = TRUE;
3618 }
3619
3620 //Exit both Bmps and Imps incase of Go/SAP Mode
3621 if((WLAN_HDD_SOFTAP == session_type) ||
3622 (WLAN_HDD_P2P_GO == session_type))
3623 {
3624 disableBmps = TRUE;
3625 disableImps = TRUE;
3626 }
3627
3628 if(TRUE == disableImps)
3629 {
3630 if (pHddCtx->cfg_ini->fIsImpsEnabled)
3631 {
3632 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
3633 }
3634 }
3635
3636 if(TRUE == disableBmps)
3637 {
3638 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
3639 {
3640 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
3641
3642 if(eHAL_STATUS_SUCCESS != halStatus)
3643 {
3644 status = VOS_STATUS_E_FAILURE;
3645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save\n", __func__);
3646 VOS_ASSERT(0);
3647 return status;
3648 }
3649 }
3650
3651 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
3652 {
3653 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
3654
3655 if(eHAL_STATUS_SUCCESS != halStatus)
3656 {
3657 status = VOS_STATUS_E_FAILURE;
3658 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer\n", __func__);
3659 VOS_ASSERT(0);
3660 return status;
3661 }
3662 }
3663 }
3664
3665 if((TRUE == disableBmps) ||
3666 (TRUE == disableImps))
3667 {
3668 /* Now, get the chip into Full Power now */
3669 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
3670 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
3671 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
3672
3673 if(halStatus != eHAL_STATUS_SUCCESS)
3674 {
3675 if(halStatus == eHAL_STATUS_PMC_PENDING)
3676 {
3677 //Block on a completion variable. Can't wait forever though
3678 wait_for_completion_interruptible_timeout(
3679 &pHddCtx->full_pwr_comp_var, msecs_to_jiffies(1000));
3680 }
3681 else
3682 {
3683 status = VOS_STATUS_E_FAILURE;
3684 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed\n", __func__);
3685 VOS_ASSERT(0);
3686 return status;
3687 }
3688 }
3689
3690 status = VOS_STATUS_SUCCESS;
3691 }
3692
3693 break;
3694 }
3695 return status;
3696}
3697
3698hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08003699 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07003700 tANI_U8 rtnl_held )
3701{
3702 hdd_adapter_t *pAdapter = NULL;
3703 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
3704 VOS_STATUS status = VOS_STATUS_E_FAILURE;
3705 VOS_STATUS exitbmpsStatus;
3706
3707 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d\n",__func__,iface_name,session_type);
3708
3709 //Disable BMPS incase of Concurrency
3710 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
3711
3712 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
3713 {
3714 //Fail to Exit BMPS
3715 VOS_ASSERT(0);
3716 return NULL;
3717 }
3718
3719 switch(session_type)
3720 {
3721 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07003723 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07003724 {
3725 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
3726
3727 if( NULL == pAdapter )
3728 return NULL;
3729
Jeff Johnsone7245742012-09-05 17:12:55 -07003730 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
3731 NL80211_IFTYPE_P2P_CLIENT:
3732 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07003733
Jeff Johnson295189b2012-06-20 16:38:30 -07003734 pAdapter->device_mode = session_type;
3735
3736 status = hdd_init_station_mode( pAdapter );
3737 if( VOS_STATUS_SUCCESS != status )
3738 goto err_free_netdev;
3739
3740 status = hdd_register_interface( pAdapter, rtnl_held );
3741 if( VOS_STATUS_SUCCESS != status )
3742 {
3743 hdd_deinit_adapter(pHddCtx, pAdapter);
3744 goto err_free_netdev;
3745 }
3746 //Stop the Interface TX queue.
3747 netif_tx_disable(pAdapter->dev);
3748 //netif_tx_disable(pWlanDev);
3749 netif_carrier_off(pAdapter->dev);
3750
3751 break;
3752 }
3753
Jeff Johnson295189b2012-06-20 16:38:30 -07003754 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003755 case WLAN_HDD_SOFTAP:
3756 {
3757 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
3758 if( NULL == pAdapter )
3759 return NULL;
3760
Jeff Johnson295189b2012-06-20 16:38:30 -07003761 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
3762 NL80211_IFTYPE_AP:
3763 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003764 pAdapter->device_mode = session_type;
3765
3766 status = hdd_init_ap_mode(pAdapter);
3767 if( VOS_STATUS_SUCCESS != status )
3768 goto err_free_netdev;
3769
3770 status = hdd_register_hostapd( pAdapter, rtnl_held );
3771 if( VOS_STATUS_SUCCESS != status )
3772 {
3773 hdd_deinit_adapter(pHddCtx, pAdapter);
3774 goto err_free_netdev;
3775 }
3776
3777 netif_tx_disable(pAdapter->dev);
3778 netif_carrier_off(pAdapter->dev);
3779
3780 hdd_set_conparam( 1 );
3781 break;
3782 }
3783 case WLAN_HDD_MONITOR:
3784 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003785 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
3786 if( NULL == pAdapter )
3787 return NULL;
3788
3789 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
3790 pAdapter->device_mode = session_type;
3791 status = hdd_register_interface( pAdapter, rtnl_held );
3792#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
3793 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
3794#else
3795 pAdapter->dev->open = hdd_mon_open;
3796 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
3797#endif
3798 hdd_init_tx_rx( pAdapter );
3799 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
3800 //Set adapter to be used for data tx. It will use either GO or softap.
3801 pAdapter->sessionCtx.monitor.pAdapterForTx =
3802 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07003803 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
3804 {
3805 pAdapter->sessionCtx.monitor.pAdapterForTx =
3806 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
3807 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003808 /* This workqueue will be used to transmit management packet over
3809 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07003810 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
3812 return NULL;
3813 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07003814
Jeff Johnson295189b2012-06-20 16:38:30 -07003815 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
3816 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07003817 }
3818 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07003819 case WLAN_HDD_FTM:
3820 {
3821 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
3822
3823 if( NULL == pAdapter )
3824 return NULL;
3825 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
3826 * message while loading driver in FTM mode. */
3827 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
3828 pAdapter->device_mode = session_type;
3829 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05303830
3831 hdd_init_tx_rx( pAdapter );
3832
3833 //Stop the Interface TX queue.
3834 netif_tx_disable(pAdapter->dev);
3835 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07003836 }
3837 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07003838 default:
3839 {
3840 VOS_ASSERT(0);
3841 return NULL;
3842 }
3843 }
3844
3845
3846 if( VOS_STATUS_SUCCESS == status )
3847 {
3848 //Add it to the hdd's session list.
3849 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
3850 if( NULL == pHddAdapterNode )
3851 {
3852 status = VOS_STATUS_E_NOMEM;
3853 }
3854 else
3855 {
3856 pHddAdapterNode->pAdapter = pAdapter;
3857 status = hdd_add_adapter_back ( pHddCtx,
3858 pHddAdapterNode );
3859 }
3860 }
3861
3862 if( VOS_STATUS_SUCCESS != status )
3863 {
3864 if( NULL != pAdapter )
3865 {
3866 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
3867 pAdapter = NULL;
3868 }
3869 if( NULL != pHddAdapterNode )
3870 {
3871 vos_mem_free( pHddAdapterNode );
3872 }
3873
3874 goto resume_bmps;
3875 }
3876
3877 if(VOS_STATUS_SUCCESS == status)
3878 {
3879 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
3880
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07003881 //Initialize the WoWL service
3882 if(!hdd_init_wowl(pAdapter))
3883 {
3884 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
3885 goto err_free_netdev;
3886 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 return pAdapter;
3889
3890err_free_netdev:
3891 free_netdev(pAdapter->dev);
3892 wlan_hdd_release_intf_addr( pHddCtx,
3893 pAdapter->macAddressCurrent.bytes );
3894
3895resume_bmps:
3896 //If bmps disabled enable it
3897 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
3898 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303899 if (pHddCtx->hdd_wlan_suspended)
3900 {
3901 hdd_set_pwrparams(pHddCtx);
3902 }
3903 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003904 }
3905 return NULL;
3906}
3907
3908VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
3909 tANI_U8 rtnl_held )
3910{
3911 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
3912 VOS_STATUS status;
3913
3914 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
3915 if( VOS_STATUS_SUCCESS != status )
3916 return status;
3917
3918 while ( pCurrent->pAdapter != pAdapter )
3919 {
3920 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
3921 if( VOS_STATUS_SUCCESS != status )
3922 break;
3923
3924 pCurrent = pNext;
3925 }
3926 pAdapterNode = pCurrent;
3927 if( VOS_STATUS_SUCCESS == status )
3928 {
3929 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
3930 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
3931 hdd_remove_adapter( pHddCtx, pAdapterNode );
3932 vos_mem_free( pAdapterNode );
3933
Jeff Johnson295189b2012-06-20 16:38:30 -07003934
3935 /* If there is a single session of STA/P2P client, re-enable BMPS */
3936 if ((!vos_concurrent_sessions_running()) &&
3937 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
3938 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
3939 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303940 if (pHddCtx->hdd_wlan_suspended)
3941 {
3942 hdd_set_pwrparams(pHddCtx);
3943 }
3944 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003945 }
3946
3947 return VOS_STATUS_SUCCESS;
3948 }
3949
3950 return VOS_STATUS_E_FAILURE;
3951}
3952
3953VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
3954{
3955 hdd_adapter_list_node_t *pHddAdapterNode;
3956 VOS_STATUS status;
3957
3958 ENTER();
3959
3960 do
3961 {
3962 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
3963 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
3964 {
3965 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
3966 vos_mem_free( pHddAdapterNode );
3967 }
3968 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
3969
3970 EXIT();
3971
3972 return VOS_STATUS_SUCCESS;
3973}
3974
3975void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
3976{
3977 v_U8_t addIE[1] = {0};
3978
3979 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
3980 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
3981 eANI_BOOLEAN_FALSE) )
3982 {
3983 hddLog(LOGE,
3984 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM\n");
3985 }
3986
3987 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
3988 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
3989 eANI_BOOLEAN_FALSE) )
3990 {
3991 hddLog(LOGE,
3992 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
3993 }
3994
3995 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
3996 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
3997 eANI_BOOLEAN_FALSE) )
3998 {
3999 hddLog(LOGE,
4000 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
4001 }
4002}
4003
4004VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
4005{
4006 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
4007 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4008 union iwreq_data wrqu;
4009
4010 ENTER();
4011
4012 switch(pAdapter->device_mode)
4013 {
4014 case WLAN_HDD_INFRA_STATION:
4015 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07004016 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07004017 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
4018 {
4019 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
4020 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
4021 pAdapter->sessionId,
4022 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
4023 else
4024 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
4025 pAdapter->sessionId,
4026 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4027 //success implies disconnect command got queued up successfully
4028 if(halStatus == eHAL_STATUS_SUCCESS)
4029 {
4030 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
4031 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4032 }
4033 memset(&wrqu, '\0', sizeof(wrqu));
4034 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4035 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
4036 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
4037 }
4038 else
4039 {
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05304040 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004041 }
4042
4043 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
4044 {
4045 INIT_COMPLETION(pAdapter->session_close_comp_var);
4046 if (eHAL_STATUS_SUCCESS ==
4047 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
4048 hdd_smeCloseSessionCallback, pAdapter))
4049 {
4050 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07004051 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004052 &pAdapter->session_close_comp_var,
4053 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
4054 }
4055 }
4056
4057 break;
4058
4059 case WLAN_HDD_SOFTAP:
4060 case WLAN_HDD_P2P_GO:
4061 //Any softap specific cleanup here...
4062 mutex_lock(&pHddCtx->sap_lock);
4063 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
4064 {
4065 VOS_STATUS status;
4066 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4067
4068 //Stop Bss.
4069 status = WLANSAP_StopBss(pHddCtx->pvosContext);
4070 if (VOS_IS_STATUS_SUCCESS(status))
4071 {
4072 hdd_hostapd_state_t *pHostapdState =
4073 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4074
4075 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
4076
4077 if (!VOS_IS_STATUS_SUCCESS(status))
4078 {
4079 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004080 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 }
4082 }
4083 else
4084 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004085 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004086 }
4087 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
4088
4089 if (eHAL_STATUS_FAILURE ==
4090 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
4091 0, NULL, eANI_BOOLEAN_FALSE))
4092 {
4093 hddLog(LOGE,
4094 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004095 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004096 }
4097
4098 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
4099 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
4100 eANI_BOOLEAN_FALSE) )
4101 {
4102 hddLog(LOGE,
4103 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
4104 }
4105
4106 // Reset WNI_CFG_PROBE_RSP Flags
4107 wlan_hdd_reset_prob_rspies(pAdapter);
4108 kfree(pAdapter->sessionCtx.ap.beacon);
4109 pAdapter->sessionCtx.ap.beacon = NULL;
4110 }
4111 mutex_unlock(&pHddCtx->sap_lock);
4112 break;
4113 case WLAN_HDD_MONITOR:
4114 break;
4115 default:
4116 break;
4117 }
4118
4119 EXIT();
4120 return VOS_STATUS_SUCCESS;
4121}
4122
4123VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
4124{
4125 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4126 VOS_STATUS status;
4127 hdd_adapter_t *pAdapter;
4128
4129 ENTER();
4130
4131 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4132
4133 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4134 {
4135 pAdapter = pAdapterNode->pAdapter;
4136 netif_tx_disable(pAdapter->dev);
4137 netif_carrier_off(pAdapter->dev);
4138
4139 hdd_stop_adapter( pHddCtx, pAdapter );
4140
4141 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4142 pAdapterNode = pNext;
4143 }
4144
4145 EXIT();
4146
4147 return VOS_STATUS_SUCCESS;
4148}
4149
4150VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
4151{
4152 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4153 VOS_STATUS status;
4154 hdd_adapter_t *pAdapter;
4155
4156 ENTER();
4157
4158 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4159
4160 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4161 {
4162 pAdapter = pAdapterNode->pAdapter;
4163 netif_tx_disable(pAdapter->dev);
4164 netif_carrier_off(pAdapter->dev);
4165
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07004166 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
4167
Jeff Johnson295189b2012-06-20 16:38:30 -07004168 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05304169 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
4170 {
4171 hdd_wmm_adapter_close( pAdapter );
4172 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
4173 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004174
4175 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4176 pAdapterNode = pNext;
4177 }
4178
4179 EXIT();
4180
4181 return VOS_STATUS_SUCCESS;
4182}
4183
4184VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
4185{
4186 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4187 VOS_STATUS status;
4188 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05304189 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07004190
4191 ENTER();
4192
4193 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4194
4195 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4196 {
4197 pAdapter = pAdapterNode->pAdapter;
4198
4199 switch(pAdapter->device_mode)
4200 {
4201 case WLAN_HDD_INFRA_STATION:
4202 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07004203 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05304204
4205 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
4206
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 hdd_init_station_mode(pAdapter);
4208 /* Open the gates for HDD to receive Wext commands */
4209 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004210 pHddCtx->scan_info.mScanPending = FALSE;
4211 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004212
4213 //Trigger the initial scan
4214 hdd_wlan_initial_scan(pAdapter);
4215
4216 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05304217 if (eConnectionState_Associated == connState ||
4218 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07004219 {
4220 union iwreq_data wrqu;
4221 memset(&wrqu, '\0', sizeof(wrqu));
4222 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4223 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
4224 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07004225 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004226
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 /* indicate disconnected event to nl80211 */
4228 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
4229 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05304231 else if (eConnectionState_Connecting == connState)
4232 {
4233 /*
4234 * Indicate connect failure to supplicant if we were in the
4235 * process of connecting
4236 */
4237 cfg80211_connect_result(pAdapter->dev, NULL,
4238 NULL, 0, NULL, 0,
4239 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
4240 GFP_KERNEL);
4241 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004242 break;
4243
4244 case WLAN_HDD_SOFTAP:
4245 /* softAP can handle SSR */
4246 break;
4247
4248 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07004249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07004251 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07004252 break;
4253
4254 case WLAN_HDD_MONITOR:
4255 /* monitor interface start */
4256 break;
4257 default:
4258 break;
4259 }
4260
4261 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4262 pAdapterNode = pNext;
4263 }
4264
4265 EXIT();
4266
4267 return VOS_STATUS_SUCCESS;
4268}
4269
4270VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
4271{
4272 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4273 hdd_adapter_t *pAdapter;
4274 VOS_STATUS status;
4275 v_U32_t roamId;
4276
4277 ENTER();
4278
4279 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4280
4281 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4282 {
4283 pAdapter = pAdapterNode->pAdapter;
4284
4285 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4286 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
4287 {
4288 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4289 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4290
4291 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
4292 init_completion(&pAdapter->disconnect_comp_var);
4293 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
4294 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4295
4296 wait_for_completion_interruptible_timeout(
4297 &pAdapter->disconnect_comp_var,
4298 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4299
4300 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4301 pHddCtx->isAmpAllowed = VOS_FALSE;
4302 sme_RoamConnect(pHddCtx->hHal,
4303 pAdapter->sessionId, &(pWextState->roamProfile),
4304 &roamId);
4305 }
4306
4307 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4308 pAdapterNode = pNext;
4309 }
4310
4311 EXIT();
4312
4313 return VOS_STATUS_SUCCESS;
4314}
4315
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07004316void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
4317{
4318 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4319 VOS_STATUS status;
4320 hdd_adapter_t *pAdapter;
4321 hdd_station_ctx_t *pHddStaCtx;
4322 hdd_ap_ctx_t *pHddApCtx;
4323 hdd_hostapd_state_t * pHostapdState;
4324 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
4325 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
4326 const char *p2pMode = "DEV";
4327 const char *ccMode = "Standalone";
4328 int n;
4329
4330 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4331 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4332 {
4333 pAdapter = pAdapterNode->pAdapter;
4334 switch (pAdapter->device_mode) {
4335 case WLAN_HDD_INFRA_STATION:
4336 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4337 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
4338 staChannel = pHddStaCtx->conn_info.operationChannel;
4339 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
4340 }
4341 break;
4342 case WLAN_HDD_P2P_CLIENT:
4343 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4344 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
4345 p2pChannel = pHddStaCtx->conn_info.operationChannel;
4346 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
4347 p2pMode = "CLI";
4348 }
4349 break;
4350 case WLAN_HDD_P2P_GO:
4351 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4352 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4353 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
4354 p2pChannel = pHddApCtx->operatingChannel;
4355 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
4356 }
4357 p2pMode = "GO";
4358 break;
4359 case WLAN_HDD_SOFTAP:
4360 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4361 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4362 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
4363 apChannel = pHddApCtx->operatingChannel;
4364 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
4365 }
4366 break;
4367 default:
4368 break;
4369 }
4370 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4371 pAdapterNode = pNext;
4372 }
4373 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
4374 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
4375 }
4376 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
4377 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
4378 if (p2pChannel > 0) {
4379 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
4380 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
4381 }
4382 if (apChannel > 0) {
4383 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
4384 apChannel, MAC_ADDR_ARRAY(apBssid));
4385 }
4386
4387 if (p2pChannel > 0 && apChannel > 0) {
4388 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
4389 }
4390}
4391
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07004392bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07004393{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07004394 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07004395}
4396
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07004397/* Once SSR is disabled then it cannot be set. */
4398void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07004399{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07004400 if (HDD_SSR_DISABLED == isSsrRequired)
4401 return;
4402
Jeff Johnson295189b2012-06-20 16:38:30 -07004403 isSsrRequired = value;
4404}
4405
4406VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
4407 hdd_adapter_list_node_t** ppAdapterNode)
4408{
4409 VOS_STATUS status;
4410 spin_lock(&pHddCtx->hddAdapters.lock);
4411 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
4412 (hdd_list_node_t**) ppAdapterNode );
4413 spin_unlock(&pHddCtx->hddAdapters.lock);
4414 return status;
4415}
4416
4417VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
4418 hdd_adapter_list_node_t* pAdapterNode,
4419 hdd_adapter_list_node_t** pNextAdapterNode)
4420{
4421 VOS_STATUS status;
4422 spin_lock(&pHddCtx->hddAdapters.lock);
4423 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
4424 (hdd_list_node_t*) pAdapterNode,
4425 (hdd_list_node_t**)pNextAdapterNode );
4426
4427 spin_unlock(&pHddCtx->hddAdapters.lock);
4428 return status;
4429}
4430
4431VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
4432 hdd_adapter_list_node_t* pAdapterNode)
4433{
4434 VOS_STATUS status;
4435 spin_lock(&pHddCtx->hddAdapters.lock);
4436 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
4437 &pAdapterNode->node );
4438 spin_unlock(&pHddCtx->hddAdapters.lock);
4439 return status;
4440}
4441
4442VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
4443 hdd_adapter_list_node_t** ppAdapterNode)
4444{
4445 VOS_STATUS status;
4446 spin_lock(&pHddCtx->hddAdapters.lock);
4447 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
4448 (hdd_list_node_t**) ppAdapterNode );
4449 spin_unlock(&pHddCtx->hddAdapters.lock);
4450 return status;
4451}
4452
4453VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
4454 hdd_adapter_list_node_t* pAdapterNode)
4455{
4456 VOS_STATUS status;
4457 spin_lock(&pHddCtx->hddAdapters.lock);
4458 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
4459 (hdd_list_node_t*) pAdapterNode );
4460 spin_unlock(&pHddCtx->hddAdapters.lock);
4461 return status;
4462}
4463
4464VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
4465 hdd_adapter_list_node_t* pAdapterNode)
4466{
4467 VOS_STATUS status;
4468 spin_lock(&pHddCtx->hddAdapters.lock);
4469 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
4470 (hdd_list_node_t*) pAdapterNode );
4471 spin_unlock(&pHddCtx->hddAdapters.lock);
4472 return status;
4473}
4474
4475hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
4476 tSirMacAddr macAddr )
4477{
4478 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4479 hdd_adapter_t *pAdapter;
4480 VOS_STATUS status;
4481
4482 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4483
4484 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4485 {
4486 pAdapter = pAdapterNode->pAdapter;
4487
4488 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
4489 macAddr, sizeof(tSirMacAddr) ) )
4490 {
4491 return pAdapter;
4492 }
4493 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4494 pAdapterNode = pNext;
4495 }
4496
4497 return NULL;
4498
4499}
4500
4501hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
4502{
4503 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4504 hdd_adapter_t *pAdapter;
4505 VOS_STATUS status;
4506
4507 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4508
4509 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4510 {
4511 pAdapter = pAdapterNode->pAdapter;
4512
4513 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
4514 IFNAMSIZ ) )
4515 {
4516 return pAdapter;
4517 }
4518 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4519 pAdapterNode = pNext;
4520 }
4521
4522 return NULL;
4523
4524}
4525
4526hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
4527{
4528 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4529 hdd_adapter_t *pAdapter;
4530 VOS_STATUS status;
4531
4532 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4533
4534 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4535 {
4536 pAdapter = pAdapterNode->pAdapter;
4537
4538 if( pAdapter && (mode == pAdapter->device_mode) )
4539 {
4540 return pAdapter;
4541 }
4542 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4543 pAdapterNode = pNext;
4544 }
4545
4546 return NULL;
4547
4548}
4549
4550//Remove this function later
4551hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
4552{
4553 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4554 hdd_adapter_t *pAdapter;
4555 VOS_STATUS status;
4556
4557 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4558
4559 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4560 {
4561 pAdapter = pAdapterNode->pAdapter;
4562
4563 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
4564 {
4565 return pAdapter;
4566 }
4567
4568 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4569 pAdapterNode = pNext;
4570 }
4571
4572 return NULL;
4573
4574}
4575
Jeff Johnson295189b2012-06-20 16:38:30 -07004576/**---------------------------------------------------------------------------
4577
4578 \brief hdd_set_monitor_tx_adapter() -
4579
4580 This API initializes the adapter to be used while transmitting on monitor
4581 adapter.
4582
4583 \param - pHddCtx - Pointer to the HDD context.
4584 pAdapter - Adapter that will used for TX. This can be NULL.
4585 \return - None.
4586 --------------------------------------------------------------------------*/
4587void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
4588{
4589 hdd_adapter_t *pMonAdapter;
4590
4591 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
4592
4593 if( NULL != pMonAdapter )
4594 {
4595 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
4596 }
4597}
Jeff Johnson295189b2012-06-20 16:38:30 -07004598/**---------------------------------------------------------------------------
4599
4600 \brief hdd_select_queue() -
4601
4602 This API returns the operating channel of the requested device mode
4603
4604 \param - pHddCtx - Pointer to the HDD context.
4605 - mode - Device mode for which operating channel is required
4606 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
4607 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
4608 \return - channel number. "0" id the requested device is not found OR it is not connected.
4609 --------------------------------------------------------------------------*/
4610v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
4611{
4612 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4613 VOS_STATUS status;
4614 hdd_adapter_t *pAdapter;
4615 v_U8_t operatingChannel = 0;
4616
4617 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4618
4619 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4620 {
4621 pAdapter = pAdapterNode->pAdapter;
4622
4623 if( mode == pAdapter->device_mode )
4624 {
4625 switch(pAdapter->device_mode)
4626 {
4627 case WLAN_HDD_INFRA_STATION:
4628 case WLAN_HDD_P2P_CLIENT:
4629 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
4630 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
4631 break;
4632 case WLAN_HDD_SOFTAP:
4633 case WLAN_HDD_P2P_GO:
4634 /*softap connection info */
4635 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
4636 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
4637 break;
4638 default:
4639 break;
4640 }
4641
4642 break; //Found the device of interest. break the loop
4643 }
4644
4645 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4646 pAdapterNode = pNext;
4647 }
4648 return operatingChannel;
4649}
4650
4651#ifdef WLAN_FEATURE_PACKET_FILTERING
4652/**---------------------------------------------------------------------------
4653
4654 \brief hdd_set_multicast_list() -
4655
4656 This used to set the multicast address list.
4657
4658 \param - dev - Pointer to the WLAN device.
4659 - skb - Pointer to OS packet (sk_buff).
4660 \return - success/fail
4661
4662 --------------------------------------------------------------------------*/
4663static void hdd_set_multicast_list(struct net_device *dev)
4664{
4665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07004666 int mc_count;
4667 int i = 0;
4668 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05304669
4670 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 {
4672 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05304673 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004674 return;
4675 }
4676
4677 if (dev->flags & IFF_ALLMULTI)
4678 {
4679 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004680 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05304681 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004682 }
4683 else
4684 {
4685 mc_count = netdev_mc_count(dev);
4686 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004687 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07004688 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
4689 {
4690 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004691 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05304692 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004693 return;
4694 }
4695
Gopichand Nakkala0f276812013-02-24 14:45:51 +05304696 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07004697
4698 netdev_for_each_mc_addr(ha, dev) {
4699 if (i == mc_count)
4700 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05304701 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
4702 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
4703 hddLog(VOS_TRACE_LEVEL_INFO, "\n%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004704 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05304705 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07004706 i++;
4707 }
4708 }
4709 return;
4710}
4711#endif
4712
4713/**---------------------------------------------------------------------------
4714
4715 \brief hdd_select_queue() -
4716
4717 This function is registered with the Linux OS for network
4718 core to decide which queue to use first.
4719
4720 \param - dev - Pointer to the WLAN device.
4721 - skb - Pointer to OS packet (sk_buff).
4722 \return - ac, Queue Index/access category corresponding to UP in IP header
4723
4724 --------------------------------------------------------------------------*/
4725v_U16_t hdd_select_queue(struct net_device *dev,
4726 struct sk_buff *skb)
4727{
4728 return hdd_wmm_select_queue(dev, skb);
4729}
4730
4731
4732/**---------------------------------------------------------------------------
4733
4734 \brief hdd_wlan_initial_scan() -
4735
4736 This function triggers the initial scan
4737
4738 \param - pAdapter - Pointer to the HDD adapter.
4739
4740 --------------------------------------------------------------------------*/
4741void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
4742{
4743 tCsrScanRequest scanReq;
4744 tCsrChannelInfo channelInfo;
4745 eHalStatus halStatus;
4746 unsigned long scanId;
4747 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4748
4749 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
4750 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
4751 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
4752
4753 if(sme_Is11dSupported(pHddCtx->hHal))
4754 {
4755 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
4756 if ( HAL_STATUS_SUCCESS( halStatus ) )
4757 {
4758 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
4759 if( !scanReq.ChannelInfo.ChannelList )
4760 {
4761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
4762 vos_mem_free(channelInfo.ChannelList);
4763 return;
4764 }
4765 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
4766 channelInfo.numOfChannels);
4767 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
4768 vos_mem_free(channelInfo.ChannelList);
4769 }
4770
4771 scanReq.scanType = eSIR_PASSIVE_SCAN;
4772 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
4773 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
4774 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
4775 }
4776 else
4777 {
4778 scanReq.scanType = eSIR_ACTIVE_SCAN;
4779 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
4780 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
4781 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
4782 }
4783
4784 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
4785 if ( !HAL_STATUS_SUCCESS( halStatus ) )
4786 {
4787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
4788 __func__, halStatus );
4789 }
4790
4791 if(sme_Is11dSupported(pHddCtx->hHal))
4792 vos_mem_free(scanReq.ChannelInfo.ChannelList);
4793}
4794
4795struct fullPowerContext
4796{
4797 struct completion completion;
4798 unsigned int magic;
4799};
4800#define POWER_CONTEXT_MAGIC 0x504F5752 //POWR
4801
4802/**---------------------------------------------------------------------------
4803
4804 \brief hdd_full_power_callback() - HDD full power callback function
4805
4806 This is the function invoked by SME to inform the result of a full power
4807 request issued by HDD
4808
4809 \param - callbackcontext - Pointer to cookie
4810 \param - status - result of request
4811
4812 \return - None
4813
4814 --------------------------------------------------------------------------*/
4815static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
4816{
4817 struct fullPowerContext *pContext = callbackContext;
4818
4819 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304820 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004821
4822 if (NULL == callbackContext)
4823 {
4824 hddLog(VOS_TRACE_LEVEL_ERROR,
4825 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004826 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07004827 return;
4828 }
4829
4830 /* there is a race condition that exists between this callback function
4831 and the caller since the caller could time out either before or
4832 while this code is executing. we'll assume the timeout hasn't
4833 occurred, but we'll verify that right before we save our work */
4834
4835 if (POWER_CONTEXT_MAGIC != pContext->magic)
4836 {
4837 /* the caller presumably timed out so there is nothing we can do */
4838 hddLog(VOS_TRACE_LEVEL_WARN,
4839 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004840 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 return;
4842 }
4843
4844 /* the race is on. caller could have timed out immediately after
4845 we verified the magic, but if so, caller will wait a short time
4846 for us to notify the caller, so the context will stay valid */
4847 complete(&pContext->completion);
4848}
4849
4850/**---------------------------------------------------------------------------
4851
4852 \brief hdd_wlan_exit() - HDD WLAN exit function
4853
4854 This is the driver exit point (invoked during rmmod)
4855
4856 \param - pHddCtx - Pointer to the HDD Context
4857
4858 \return - None
4859
4860 --------------------------------------------------------------------------*/
4861void hdd_wlan_exit(hdd_context_t *pHddCtx)
4862{
4863 eHalStatus halStatus;
4864 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
4865 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05304866 struct wiphy *wiphy = pHddCtx->wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 hdd_adapter_t* pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07004868 struct fullPowerContext powerContext;
4869 long lrc;
4870
4871 ENTER();
4872
Jeff Johnson88ba7742013-02-27 14:36:02 -08004873 if (VOS_FTM_MODE != hdd_get_conparam())
4874 {
4875 // Unloading, restart logic is no more required.
4876 wlan_hdd_restart_deinit(pHddCtx);
4877 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004878
Jeff Johnson295189b2012-06-20 16:38:30 -07004879 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07004880 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07004882 {
4883 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
4884 WLAN_HDD_INFRA_STATION);
4885 if (pAdapter == NULL)
4886 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
4887
4888 if (pAdapter != NULL)
4889 {
4890 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
4891 hdd_UnregisterWext(pAdapter->dev);
4892 }
4893 }
4894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004895
Jeff Johnson295189b2012-06-20 16:38:30 -07004896 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08004897 {
4898 wlan_hdd_ftm_close(pHddCtx);
4899 goto free_hdd_ctx;
4900 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004901 //Stop the Interface TX queue.
4902 //netif_tx_disable(pWlanDev);
4903 //netif_carrier_off(pWlanDev);
4904
Jeff Johnson295189b2012-06-20 16:38:30 -07004905 if (VOS_STA_SAP_MODE == hdd_get_conparam())
4906 {
4907 pAdapter = hdd_get_adapter(pHddCtx,
4908 WLAN_HDD_SOFTAP);
4909 }
4910 else
4911 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004912 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07004913 {
4914 pAdapter = hdd_get_adapter(pHddCtx,
4915 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07004916 if (pAdapter == NULL)
4917 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07004918 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 /* DeRegister with platform driver as client for Suspend/Resume */
4921 vosStatus = hddDeregisterPmOps(pHddCtx);
4922 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
4923 {
4924 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
4925 VOS_ASSERT(0);
4926 }
4927
4928 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
4929 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
4930 {
4931 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
4932 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004933
4934 // Cancel any outstanding scan requests. We are about to close all
4935 // of our adapters, but an adapter structure is what SME passes back
4936 // to our callback function. Hence if there are any outstanding scan
4937 // requests then there is a race condition between when the adapter
4938 // is closed and when the callback is invoked. We try to resolve that
4939 // race condition here by canceling any outstanding scans before we
4940 // close the adapters.
4941 // Note that the scans may be cancelled in an asynchronous manner, so
4942 // ideally there needs to be some kind of synchronization. Rather than
4943 // introduce a new synchronization here, we will utilize the fact that
4944 // we are about to Request Full Power, and since that is synchronized,
4945 // the expectation is that by the time Request Full Power has completed,
4946 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07004947 if (NULL != pAdapter)
4948 hdd_abort_mac_scan( pHddCtx, pAdapter->sessionId);
4949 else
4950 hddLog(VOS_TRACE_LEVEL_ERROR,
4951 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004952
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004953 //Stop the traffic monitor timer
4954 if ( VOS_TIMER_STATE_RUNNING ==
4955 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
4956 {
4957 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
4958 }
4959
4960 // Destroy the traffic monitor timer
4961 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
4962 &pHddCtx->tx_rx_trafficTmr)))
4963 {
4964 hddLog(VOS_TRACE_LEVEL_ERROR,
4965 "%s: Cannot deallocate Traffic monitor timer", __func__);
4966 }
4967
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 //Disable IMPS/BMPS as we do not want the device to enter any power
4969 //save mode during shutdown
4970 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
4971 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
4972 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
4973
4974 //Ensure that device is in full power as we will touch H/W during vos_Stop
4975 init_completion(&powerContext.completion);
4976 powerContext.magic = POWER_CONTEXT_MAGIC;
4977
4978 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
4979 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
4980
4981 if (eHAL_STATUS_SUCCESS != halStatus)
4982 {
4983 if (eHAL_STATUS_PMC_PENDING == halStatus)
4984 {
4985 /* request was sent -- wait for the response */
4986 lrc = wait_for_completion_interruptible_timeout(
4987 &powerContext.completion,
4988 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
4989 /* either we have a response or we timed out
4990 either way, first invalidate our magic */
4991 powerContext.magic = 0;
4992 if (lrc <= 0)
4993 {
4994 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004995 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 /* there is a race condition such that the callback
4997 function could be executing at the same time we are. of
4998 primary concern is if the callback function had already
4999 verified the "magic" but hasn't yet set the completion
5000 variable. Since the completion variable is on our
5001 stack, we'll delay just a bit to make sure the data is
5002 still valid if that is the case */
5003 msleep(50);
5004 }
5005 }
5006 else
5007 {
5008 hddLog(VOS_TRACE_LEVEL_ERROR,
5009 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005010 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 VOS_ASSERT(0);
5012 /* continue -- need to clean up as much as possible */
5013 }
5014 }
5015
Yue Ma0d4891e2013-08-06 17:01:45 -07005016 hdd_debugfs_exit(pHddCtx);
5017
Jeff Johnson295189b2012-06-20 16:38:30 -07005018 // Unregister the Net Device Notifier
5019 unregister_netdevice_notifier(&hdd_netdev_notifier);
5020
Jeff Johnson295189b2012-06-20 16:38:30 -07005021 hdd_stop_all_adapters( pHddCtx );
5022
Jeff Johnson295189b2012-06-20 16:38:30 -07005023#ifdef WLAN_BTAMP_FEATURE
5024 vosStatus = WLANBAP_Stop(pVosContext);
5025 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
5026 {
5027 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
5028 "%s: Failed to stop BAP",__func__);
5029 }
5030#endif //WLAN_BTAMP_FEATURE
5031
5032 //Stop all the modules
5033 vosStatus = vos_stop( pVosContext );
5034 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
5035 {
5036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
5037 "%s: Failed to stop VOSS",__func__);
5038 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
5039 }
5040
Jeff Johnson295189b2012-06-20 16:38:30 -07005041 //Assert Deep sleep signal now to put Libra HW in lowest power state
5042 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
5043 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
5044
5045 //Vote off any PMIC voltage supplies
5046 vos_chipPowerDown(NULL, NULL, NULL);
5047
5048 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
5049
Leo Chang59cdc7e2013-07-10 10:08:21 -07005050
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07005052 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005053
5054 //Close the scheduler before calling vos_close to make sure no thread is
5055 // scheduled after the each module close is called i.e after all the data
5056 // structures are freed.
5057 vosStatus = vos_sched_close( pVosContext );
5058 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
5059 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
5060 "%s: Failed to close VOSS Scheduler",__func__);
5061 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
5062 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08005063#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07005064#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
5065 /* Destroy the wake lock */
5066 wake_lock_destroy(&pHddCtx->rx_wake_lock);
5067#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08005068 /* Destroy the wake lock */
5069 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08005070#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005071
5072 //Close VOSS
5073 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
5074 vos_close(pVosContext);
5075
Jeff Johnson295189b2012-06-20 16:38:30 -07005076 //Close Watchdog
5077 if(pHddCtx->cfg_ini->fIsLogpEnabled)
5078 vos_watchdog_close(pVosContext);
5079
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05305080 //Clean up HDD Nlink Service
5081 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07005082#ifdef WLAN_KD_READY_NOTIFIER
5083 nl_srv_exit(pHddCtx->ptt_pid);
5084#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05305085 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07005086#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05305087
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 /* Cancel the vote for XO Core ON.
5089 * This is done here to ensure there is no race condition since MC, TX and WD threads have
5090 * exited at this point
5091 */
5092 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
5093 " when WLAN is turned OFF\n");
5094 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
5095 {
5096 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
5097 " Not returning failure."
5098 " Power consumed will be high\n");
5099 }
5100
5101 hdd_close_all_adapters( pHddCtx );
5102
5103
5104 //Free up dynamically allocated members inside HDD Adapter
5105 kfree(pHddCtx->cfg_ini);
5106 pHddCtx->cfg_ini= NULL;
5107
5108 /* free the power on lock from platform driver */
5109 if (free_riva_power_on_lock("wlan"))
5110 {
5111 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
5112 __func__);
5113 }
5114
Jeff Johnson88ba7742013-02-27 14:36:02 -08005115free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07005116 /* FTM mode, WIPHY did not registered
5117 If un-register here, system crash will happen */
5118 if (VOS_FTM_MODE != hdd_get_conparam())
5119 {
5120 wiphy_unregister(wiphy) ;
5121 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005122 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07005123 if (hdd_is_ssr_required())
5124 {
5125 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07005126 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07005127 msleep(5000);
5128 }
5129 hdd_set_ssr_required (VOS_FALSE);
5130}
5131
5132
5133/**---------------------------------------------------------------------------
5134
5135 \brief hdd_update_config_from_nv() - Function to update the contents of
5136 the running configuration with parameters taken from NV storage
5137
5138 \param - pHddCtx - Pointer to the HDD global context
5139
5140 \return - VOS_STATUS_SUCCESS if successful
5141
5142 --------------------------------------------------------------------------*/
5143static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
5144{
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 v_BOOL_t itemIsValid = VOS_FALSE;
5146 VOS_STATUS status;
5147 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
5148 v_U8_t macLoop;
5149
5150 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
5151 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
5152 if(status != VOS_STATUS_SUCCESS)
5153 {
5154 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed\n ");
5155 return VOS_STATUS_E_FAILURE;
5156 }
5157
5158 if (itemIsValid == VOS_TRUE)
5159 {
5160 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV\n ");
5161 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
5162 VOS_MAX_CONCURRENCY_PERSONA);
5163 if(status != VOS_STATUS_SUCCESS)
5164 {
5165 /* Get MAC from NV fail, not update CFG info
5166 * INI MAC value will be used for MAC setting */
5167 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed\n ");
5168 return VOS_STATUS_E_FAILURE;
5169 }
5170
5171 /* If first MAC is not valid, treat all others are not valid
5172 * Then all MACs will be got from ini file */
5173 if(vos_is_macaddr_zero(&macFromNV[0]))
5174 {
5175 /* MAC address in NV file is not configured yet */
5176 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
5177 return VOS_STATUS_E_INVAL;
5178 }
5179
5180 /* Get MAC address from NV, update CFG info */
5181 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
5182 {
5183 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
5184 {
5185 printk(KERN_ERR "not valid MAC from NV for %d", macLoop);
5186 /* This MAC is not valid, skip it
5187 * This MAC will be got from ini file */
5188 }
5189 else
5190 {
5191 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
5192 (v_U8_t *)&macFromNV[macLoop].bytes[0],
5193 VOS_MAC_ADDR_SIZE);
5194 }
5195 }
5196 }
5197 else
5198 {
5199 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
5200 return VOS_STATUS_E_FAILURE;
5201 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005202
Jeff Johnson295189b2012-06-20 16:38:30 -07005203
5204 return VOS_STATUS_SUCCESS;
5205}
5206
5207/**---------------------------------------------------------------------------
5208
5209 \brief hdd_post_voss_start_config() - HDD post voss start config helper
5210
5211 \param - pAdapter - Pointer to the HDD
5212
5213 \return - None
5214
5215 --------------------------------------------------------------------------*/
5216VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
5217{
5218 eHalStatus halStatus;
5219 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305220 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07005221
Jeff Johnson295189b2012-06-20 16:38:30 -07005222
5223 // Send ready indication to the HDD. This will kick off the MAC
5224 // into a 'running' state and should kick off an initial scan.
5225 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
5226 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5227 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305228 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07005229 "code %08d [x%08x]",__func__, halStatus, halStatus );
5230 return VOS_STATUS_E_FAILURE;
5231 }
5232
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305233 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07005234 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
5235 // And RIVA will crash
5236 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
5237 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305238 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
5239 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
5240
5241
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 return VOS_STATUS_SUCCESS;
5243}
5244
Jeff Johnson295189b2012-06-20 16:38:30 -07005245/* wake lock APIs for HDD */
5246void hdd_prevent_suspend(void)
5247{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08005248#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07005249 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07005250#else
5251 wcnss_prevent_suspend();
5252#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005253}
5254
5255void hdd_allow_suspend(void)
5256{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08005257#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07005259#else
5260 wcnss_allow_suspend();
5261#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005262}
5263
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005264void hdd_allow_suspend_timeout(v_U32_t timeout)
5265{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08005266#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07005267 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005268#else
5269 /* Do nothing as there is no API in wcnss for timeout*/
5270#endif
5271}
5272
Jeff Johnson295189b2012-06-20 16:38:30 -07005273/**---------------------------------------------------------------------------
5274
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005275 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
5276 information between Host and Riva
5277
5278 This function gets reported version of FW
5279 It also finds the version of Riva headers used to compile the host
5280 It compares the above two and prints a warning if they are different
5281 It gets the SW and HW version string
5282 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
5283 indicating the features they support through a bitmap
5284
5285 \param - pHddCtx - Pointer to HDD context
5286
5287 \return - void
5288
5289 --------------------------------------------------------------------------*/
5290
5291void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
5292{
5293
5294 tSirVersionType versionCompiled;
5295 tSirVersionType versionReported;
5296 tSirVersionString versionString;
5297 tANI_U8 fwFeatCapsMsgSupported = 0;
5298 VOS_STATUS vstatus;
5299
5300 /* retrieve and display WCNSS version information */
5301 do {
5302
5303 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
5304 &versionCompiled);
5305 if (!VOS_IS_STATUS_SUCCESS(vstatus))
5306 {
5307 hddLog(VOS_TRACE_LEVEL_FATAL,
5308 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005309 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005310 break;
5311 }
5312
5313 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
5314 &versionReported);
5315 if (!VOS_IS_STATUS_SUCCESS(vstatus))
5316 {
5317 hddLog(VOS_TRACE_LEVEL_FATAL,
5318 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005319 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005320 break;
5321 }
5322
5323 if ((versionCompiled.major != versionReported.major) ||
5324 (versionCompiled.minor != versionReported.minor) ||
5325 (versionCompiled.version != versionReported.version) ||
5326 (versionCompiled.revision != versionReported.revision))
5327 {
5328 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
5329 "Host expected %u.%u.%u.%u\n",
5330 WLAN_MODULE_NAME,
5331 (int)versionReported.major,
5332 (int)versionReported.minor,
5333 (int)versionReported.version,
5334 (int)versionReported.revision,
5335 (int)versionCompiled.major,
5336 (int)versionCompiled.minor,
5337 (int)versionCompiled.version,
5338 (int)versionCompiled.revision);
5339 }
5340 else
5341 {
5342 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
5343 WLAN_MODULE_NAME,
5344 (int)versionReported.major,
5345 (int)versionReported.minor,
5346 (int)versionReported.version,
5347 (int)versionReported.revision);
5348 }
5349
5350 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
5351 versionString,
5352 sizeof(versionString));
5353 if (!VOS_IS_STATUS_SUCCESS(vstatus))
5354 {
5355 hddLog(VOS_TRACE_LEVEL_FATAL,
5356 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005357 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005358 break;
5359 }
5360
5361 pr_info("%s: WCNSS software version %s\n",
5362 WLAN_MODULE_NAME, versionString);
5363
5364 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
5365 versionString,
5366 sizeof(versionString));
5367 if (!VOS_IS_STATUS_SUCCESS(vstatus))
5368 {
5369 hddLog(VOS_TRACE_LEVEL_FATAL,
5370 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005371 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005372 break;
5373 }
5374
5375 pr_info("%s: WCNSS hardware version %s\n",
5376 WLAN_MODULE_NAME, versionString);
5377
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07005378 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
5379 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005380 send the message only if it the riva is 1.1
5381 minor numbers for different riva branches:
5382 0 -> (1.0)Mainline Build
5383 1 -> (1.1)Mainline Build
5384 2->(1.04) Stability Build
5385 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07005386 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005387 ((versionReported.minor>=1) && (versionReported.version>=1)))
5388 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
5389 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07005390
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005391 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08005392 {
5393#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
5394 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
5395 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
5396#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07005397 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
5398 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
5399 {
5400 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
5401 }
5402
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005403 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08005404 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005405
5406 } while (0);
5407
5408}
5409
5410/**---------------------------------------------------------------------------
5411
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05305412 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
5413
5414 \param - pHddCtx - Pointer to the hdd context
5415
5416 \return - true if hardware supports 5GHz
5417
5418 --------------------------------------------------------------------------*/
5419static boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
5420{
5421 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
5422 * then hardware support 5Ghz.
5423 */
5424 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
5425 {
5426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
5427 return true;
5428 }
5429 else
5430 {
5431 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
5432 __func__);
5433 return false;
5434 }
5435}
5436
5437
5438/**---------------------------------------------------------------------------
5439
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 \brief hdd_wlan_startup() - HDD init function
5441
5442 This is the driver startup code executed once a WLAN device has been detected
5443
5444 \param - dev - Pointer to the underlying device
5445
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005446 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07005447
5448 --------------------------------------------------------------------------*/
5449
5450int hdd_wlan_startup(struct device *dev )
5451{
5452 VOS_STATUS status;
5453 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07005454 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 hdd_context_t *pHddCtx = NULL;
5456 v_CONTEXT_t pVosContext= NULL;
5457#ifdef WLAN_BTAMP_FEATURE
5458 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
5459 WLANBAP_ConfigType btAmpConfig;
5460 hdd_config_t *pConfig;
5461#endif
5462 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005463 struct wiphy *wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07005464
5465 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 /*
5467 * cfg80211: wiphy allocation
5468 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305469 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07005470
5471 if(wiphy == NULL)
5472 {
5473 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005474 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 }
5476
5477 pHddCtx = wiphy_priv(wiphy);
5478
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 //Initialize the adapter context to zeros.
5480 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
5481
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 hdd_prevent_suspend();
5484 pHddCtx->isLoadUnloadInProgress = TRUE;
5485
5486 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
5487
5488 /*Get vos context here bcoz vos_open requires it*/
5489 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
5490
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08005491 if(pVosContext == NULL)
5492 {
5493 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
5494 goto err_free_hdd_context;
5495 }
5496
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 //Save the Global VOSS context in adapter context for future.
5498 pHddCtx->pvosContext = pVosContext;
5499
5500 //Save the adapter context in global context for future.
5501 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
5502
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 pHddCtx->parent_dev = dev;
5504
5505 init_completion(&pHddCtx->full_pwr_comp_var);
5506 init_completion(&pHddCtx->standby_comp_var);
5507 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005508 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08005509 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Amar Singhalfddc28c2013-09-05 13:03:40 -07005510 init_completion(&pHddCtx->linux_reg_req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005511
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05305512 spin_lock_init(&pHddCtx->schedScan_lock);
5513
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
5515
5516 // Load all config first as TL config is needed during vos_open
5517 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
5518 if(pHddCtx->cfg_ini == NULL)
5519 {
5520 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
5521 goto err_free_hdd_context;
5522 }
5523
5524 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
5525
5526 // Read and parse the qcom_cfg.ini file
5527 status = hdd_parse_config_ini( pHddCtx );
5528 if ( VOS_STATUS_SUCCESS != status )
5529 {
5530 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
5531 __func__, WLAN_INI_FILE);
5532 goto err_config;
5533 }
5534
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05305535 /* INI has been read, initialise the configuredMcastBcastFilter with
5536 * INI value as this will serve as the default value
5537 */
5538 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
5539 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
5540 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05305541
5542 if (false == hdd_is_5g_supported(pHddCtx))
5543 {
5544 //5Ghz is not supported.
5545 if (1 != pHddCtx->cfg_ini->nBandCapability)
5546 {
5547 hddLog(VOS_TRACE_LEVEL_INFO,
5548 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
5549 pHddCtx->cfg_ini->nBandCapability = 1;
5550 }
5551 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05305552
5553 /* If SNR Monitoring is enabled, FW has to parse all beacons
5554 * for calcaluting and storing the average SNR, so set Nth beacon
5555 * filter to 1 to enable FW to parse all the beaocons
5556 */
5557 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
5558 {
5559 /* The log level is deliberately set to WARN as overriding
5560 * nthBeaconFilter to 1 will increase power cosumption and this
5561 * might just prove helpful to detect the power issue.
5562 */
5563 hddLog(VOS_TRACE_LEVEL_WARN,
5564 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
5565 pHddCtx->cfg_ini->nthBeaconFilter = 1;
5566 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305568 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305570 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -07005571 {
5572 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305573 "%s: wlan_hdd_cfg80211_init return failure", __func__);
5574 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005576
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08005577 // Update VOS trace levels based upon the cfg.ini
5578 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
5579 pHddCtx->cfg_ini->vosTraceEnableBAP);
5580 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
5581 pHddCtx->cfg_ini->vosTraceEnableTL);
5582 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
5583 pHddCtx->cfg_ini->vosTraceEnableWDI);
5584 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
5585 pHddCtx->cfg_ini->vosTraceEnableHDD);
5586 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
5587 pHddCtx->cfg_ini->vosTraceEnableSME);
5588 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
5589 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05305590 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
5591 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08005592 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
5593 pHddCtx->cfg_ini->vosTraceEnableWDA);
5594 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
5595 pHddCtx->cfg_ini->vosTraceEnableSYS);
5596 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
5597 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08005598 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
5599 pHddCtx->cfg_ini->vosTraceEnableSAP);
5600 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
5601 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08005602
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 // Update WDI trace levels based upon the cfg.ini
5604 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
5605 pHddCtx->cfg_ini->wdiTraceEnableDAL);
5606 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
5607 pHddCtx->cfg_ini->wdiTraceEnableCTL);
5608 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
5609 pHddCtx->cfg_ini->wdiTraceEnableDAT);
5610 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
5611 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07005612
Jeff Johnson88ba7742013-02-27 14:36:02 -08005613 if (VOS_FTM_MODE == hdd_get_conparam())
5614 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
5616 {
5617 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
5618 goto err_free_hdd_context;
5619 }
5620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
5621 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08005622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005623
Jeff Johnson88ba7742013-02-27 14:36:02 -08005624 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 if(pHddCtx->cfg_ini->fIsLogpEnabled)
5626 {
5627 status = vos_watchdog_open(pVosContext,
5628 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
5629
5630 if(!VOS_IS_STATUS_SUCCESS( status ))
5631 {
5632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305633 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07005634 }
5635 }
5636
5637 pHddCtx->isLogpInProgress = FALSE;
5638 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
5639
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
5641 if(!VOS_IS_STATUS_SUCCESS(status))
5642 {
5643 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07005645 }
5646
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 status = vos_open( &pVosContext, 0);
5648 if ( !VOS_IS_STATUS_SUCCESS( status ))
5649 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08005650 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
5651 goto err_clkvote;
Jeff Johnson295189b2012-06-20 16:38:30 -07005652 }
5653
Jeff Johnson295189b2012-06-20 16:38:30 -07005654 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
5655
5656 if ( NULL == pHddCtx->hHal )
5657 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08005658 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 goto err_vosclose;
5660 }
5661
Jeff Johnsonbc676b42013-02-14 16:04:08 -08005662 status = vos_preStart( pHddCtx->pvosContext );
5663 if ( !VOS_IS_STATUS_SUCCESS( status ) )
5664 {
5665 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
5666 goto err_vosclose;
5667 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005668
Jeff Johnsonbc676b42013-02-14 16:04:08 -08005669 /* Note that the vos_preStart() sequence triggers the cfg download.
5670 The cfg download must occur before we update the SME config
5671 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 status = hdd_set_sme_config( pHddCtx );
5673
5674 if ( VOS_STATUS_SUCCESS != status )
5675 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08005676 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
5677 goto err_vosclose;
5678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005679
5680 //Initialize the WMM module
5681 status = hdd_wmm_init(pHddCtx);
5682 if (!VOS_IS_STATUS_SUCCESS(status))
5683 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005684 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 goto err_vosclose;
5686 }
5687
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 /* In the integrated architecture we update the configuration from
5689 the INI file and from NV before vOSS has been started so that
5690 the final contents are available to send down to the cCPU */
5691
5692 // Apply the cfg.ini to cfg.dat
5693 if (FALSE == hdd_update_config_dat(pHddCtx))
5694 {
5695 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
5696 goto err_vosclose;
5697 }
5698
5699 // Apply the NV to cfg.dat
5700 /* Prima Update MAC address only at here */
5701 if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
5702 {
5703#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
5704 /* There was not a valid set of MAC Addresses in NV. See if the
5705 default addresses were modified by the cfg.ini settings. If so,
5706 we'll use them, but if not, we'll autogenerate a set of MAC
5707 addresses based upon the device serial number */
5708
5709 static const v_MACADDR_t default_address =
5710 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
5711 unsigned int serialno;
5712 int i;
5713
5714 serialno = wcnss_get_serial_number();
5715 if ((0 != serialno) &&
5716 (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
5717 sizeof(default_address))))
5718 {
5719 /* cfg.ini has the default address, invoke autogen logic */
5720
5721 /* MAC address has 3 bytes of OUI so we have a maximum of 3
5722 bytes of the serial number that can be used to generate
5723 the other 3 bytes of the MAC address. Mask off all but
5724 the lower 3 bytes (this will also make sure we don't
5725 overflow in the next step) */
5726 serialno &= 0x00FFFFFF;
5727
5728 /* we need a unique address for each session */
5729 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
5730
5731 /* autogen all addresses */
5732 for (i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5733 {
5734 /* start with the entire default address */
5735 pHddCtx->cfg_ini->intfMacAddr[i] = default_address;
5736 /* then replace the lower 3 bytes */
5737 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
5738 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
5739 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
5740
5741 serialno++;
5742 }
5743
5744 pr_info("wlan: Invalid MAC addresses in NV, autogenerated "
5745 MAC_ADDRESS_STR,
5746 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
5747 }
5748 else
5749#endif //WLAN_AUTOGEN_MACADDR_FEATURE
5750 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08005751 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 "%s: Invalid MAC address in NV, using MAC from ini file "
5753 MAC_ADDRESS_STR, __func__,
5754 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
5755 }
5756 }
5757 {
5758 eHalStatus halStatus;
5759 // Set the MAC Address
5760 // Currently this is used by HAL to add self sta. Remove this once self sta is added as part of session open.
5761 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
5762 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
5763 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
5764
5765 if (!HAL_STATUS_SUCCESS( halStatus ))
5766 {
5767 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
5768 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Madan Mohan Koyyalamudib8b126b2012-11-15 17:37:30 -08005769 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 }
5771 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005772
5773 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
5774 Note: Firmware image will be read and downloaded inside vos_start API */
5775 status = vos_start( pHddCtx->pvosContext );
5776 if ( !VOS_IS_STATUS_SUCCESS( status ) )
5777 {
5778 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
5779 goto err_vosclose;
5780 }
5781
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07005782 /* Exchange capability info between Host and FW and also get versioning info from FW */
5783 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005784
5785 status = hdd_post_voss_start_config( pHddCtx );
5786 if ( !VOS_IS_STATUS_SUCCESS( status ) )
5787 {
5788 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
5789 __func__);
5790 goto err_vosstop;
5791 }
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305792 wlan_hdd_cfg80211_update_reg_info( wiphy );
5793
5794 /* registration of wiphy dev with cfg80211 */
5795 if (0 > wlan_hdd_cfg80211_register(wiphy))
5796 {
5797 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5798 goto err_vosstop;
5799 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005800
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 if (VOS_STA_SAP_MODE == hdd_get_conparam())
5802 {
5803 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
5804 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
5805 }
5806 else
5807 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
5809 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
5810 if (pAdapter != NULL)
5811 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05305812 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05305814 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
5815 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
5816 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07005817
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05305818 /* Generate the P2P Device Address. This consists of the device's
5819 * primary MAC address with the locally administered bit set.
5820 */
5821 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07005822 }
5823 else
5824 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05305825 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
5826 if (p2p_dev_addr != NULL)
5827 {
5828 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
5829 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
5830 }
5831 else
5832 {
5833 hddLog(VOS_TRACE_LEVEL_FATAL,
5834 "%s: Failed to allocate mac_address for p2p_device",
5835 __func__);
5836 goto err_close_adapter;
5837 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005839
5840 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
5841 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
5842 if ( NULL == pP2pAdapter )
5843 {
5844 hddLog(VOS_TRACE_LEVEL_FATAL,
5845 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005846 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07005847 goto err_close_adapter;
5848 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005849 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005851
5852 if( pAdapter == NULL )
5853 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08005854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
5855 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005857
Jeff Johnson295189b2012-06-20 16:38:30 -07005858#ifdef WLAN_BTAMP_FEATURE
5859 vStatus = WLANBAP_Open(pVosContext);
5860 if(!VOS_IS_STATUS_SUCCESS(vStatus))
5861 {
5862 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
5863 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07005864 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 }
5866
5867 vStatus = BSL_Init(pVosContext);
5868 if(!VOS_IS_STATUS_SUCCESS(vStatus))
5869 {
5870 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
5871 "%s: Failed to Init BSL",__func__);
5872 goto err_bap_close;
5873 }
5874 vStatus = WLANBAP_Start(pVosContext);
5875 if (!VOS_IS_STATUS_SUCCESS(vStatus))
5876 {
5877 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
5878 "%s: Failed to start TL",__func__);
5879 goto err_bap_close;
5880 }
5881
5882 pConfig = pHddCtx->cfg_ini;
5883 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
5884 status = WLANBAP_SetConfig(&btAmpConfig);
5885
5886#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07005887
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07005888#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
5889 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
5890 {
5891 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
5892 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
5893 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
5894 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
5895 }
5896#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005897#ifdef FEATURE_WLAN_SCAN_PNO
5898 /*SME must send channel update configuration to RIVA*/
5899 sme_UpdateChannelConfig(pHddCtx->hHal);
5900#endif
5901
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 /* Register with platform driver as client for Suspend/Resume */
5903 status = hddRegisterPmOps(pHddCtx);
5904 if ( !VOS_IS_STATUS_SUCCESS( status ) )
5905 {
5906 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
5907#ifdef WLAN_BTAMP_FEATURE
5908 goto err_bap_stop;
5909#else
Jeff Johnsone7245742012-09-05 17:12:55 -07005910 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07005911#endif //WLAN_BTAMP_FEATURE
5912 }
5913
Yue Ma0d4891e2013-08-06 17:01:45 -07005914 /* Open debugfs interface */
5915 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
5916 {
5917 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
5918 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07005919 }
5920
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 /* Register TM level change handler function to the platform */
5922 status = hddDevTmRegisterNotifyCallback(pHddCtx);
5923 if ( !VOS_IS_STATUS_SUCCESS( status ) )
5924 {
5925 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
5926 goto err_unregister_pmops;
5927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005928
5929 /* register for riva power on lock to platform driver */
5930 if (req_riva_power_on_lock("wlan"))
5931 {
5932 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
5933 __func__);
5934 goto err_unregister_pmops;
5935 }
5936
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 // register net device notifier for device change notification
5938 ret = register_netdevice_notifier(&hdd_netdev_notifier);
5939
5940 if(ret < 0)
5941 {
5942 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
5943 goto err_free_power_on_lock;
5944 }
5945
5946 //Initialize the nlink service
5947 if(nl_srv_init() != 0)
5948 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305949 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 goto err_reg_netdev;
5951 }
5952
5953 //Initialize the BTC service
5954 if(btc_activate_service(pHddCtx) != 0)
5955 {
5956 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
5957 goto err_nl_srv;
5958 }
5959
5960#ifdef PTT_SOCK_SVC_ENABLE
5961 //Initialize the PTT service
5962 if(ptt_sock_activate_svc(pHddCtx) != 0)
5963 {
5964 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
5965 goto err_nl_srv;
5966 }
5967#endif
5968
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07005971 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07005972 /* Action frame registered in one adapter which will
5973 * applicable to all interfaces
5974 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07005975 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005977
5978 mutex_init(&pHddCtx->sap_lock);
5979
5980 pHddCtx->isLoadUnloadInProgress = FALSE;
5981
Sameer Thalappil50dc0092013-02-19 17:23:33 -08005982#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07005983#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
5984 /* Initialize the wake lcok */
5985 wake_lock_init(&pHddCtx->rx_wake_lock,
5986 WAKE_LOCK_SUSPEND,
5987 "qcom_rx_wakelock");
5988#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08005989 /* Initialize the wake lcok */
5990 wake_lock_init(&pHddCtx->sap_wake_lock,
5991 WAKE_LOCK_SUSPEND,
5992 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08005993#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07005994
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005995 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
5996 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005997
5998 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
5999 hdd_allow_suspend();
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05306000
Jeff Johnsone7245742012-09-05 17:12:55 -07006001 // Initialize the restart logic
6002 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05306003
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07006004 //Register the traffic monitor timer now
6005 if ( pHddCtx->cfg_ini->dynSplitscan)
6006 {
6007 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
6008 VOS_TIMER_TYPE_SW,
6009 hdd_tx_rx_pkt_cnt_stat_timer_handler,
6010 (void *)pHddCtx);
6011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 goto success;
6013
6014err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07006015#ifdef WLAN_KD_READY_NOTIFIER
6016 nl_srv_exit(pHddCtx->ptt_pid);
6017#else
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07006019#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07006020err_reg_netdev:
6021 unregister_netdevice_notifier(&hdd_netdev_notifier);
6022
6023err_free_power_on_lock:
6024 free_riva_power_on_lock("wlan");
6025
6026err_unregister_pmops:
6027 hddDevTmUnregisterNotifyCallback(pHddCtx);
6028 hddDeregisterPmOps(pHddCtx);
6029
Yue Ma0d4891e2013-08-06 17:01:45 -07006030 hdd_debugfs_exit(pHddCtx);
6031
Jeff Johnson295189b2012-06-20 16:38:30 -07006032#ifdef WLAN_BTAMP_FEATURE
6033err_bap_stop:
6034 WLANBAP_Stop(pVosContext);
6035#endif
6036
6037#ifdef WLAN_BTAMP_FEATURE
6038err_bap_close:
6039 WLANBAP_Close(pVosContext);
6040#endif
6041
Jeff Johnson295189b2012-06-20 16:38:30 -07006042err_close_adapter:
6043 hdd_close_all_adapters( pHddCtx );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306044 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07006045
6046err_vosstop:
6047 vos_stop(pVosContext);
6048
6049err_vosclose:
6050 status = vos_sched_close( pVosContext );
6051 if (!VOS_IS_STATUS_SUCCESS(status)) {
6052 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
6053 "%s: Failed to close VOSS Scheduler", __func__);
6054 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
6055 }
6056 vos_close(pVosContext );
6057
Jeff Johnson295189b2012-06-20 16:38:30 -07006058err_clkvote:
Jeff Johnsonbc676b42013-02-14 16:04:08 -08006059 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006060
6061err_wdclose:
6062 if(pHddCtx->cfg_ini->fIsLogpEnabled)
6063 vos_watchdog_close(pVosContext);
6064
Jeff Johnson295189b2012-06-20 16:38:30 -07006065err_config:
6066 kfree(pHddCtx->cfg_ini);
6067 pHddCtx->cfg_ini= NULL;
6068
6069err_free_hdd_context:
6070 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 wiphy_free(wiphy) ;
6072 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 VOS_BUG(1);
6074
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08006075 if (hdd_is_ssr_required())
6076 {
6077 /* WDI timeout had happened during load, so SSR is needed here */
6078 subsystem_restart("wcnss");
6079 msleep(5000);
6080 }
6081 hdd_set_ssr_required (VOS_FALSE);
6082
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006083 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006084
6085success:
6086 EXIT();
6087 return 0;
6088}
6089
6090/**---------------------------------------------------------------------------
6091
Jeff Johnson32d95a32012-09-10 13:15:23 -07006092 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07006093
Jeff Johnson32d95a32012-09-10 13:15:23 -07006094 This is the driver entry point - called in different timeline depending
6095 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07006096
6097 \param - None
6098
6099 \return - 0 for success, non zero for failure
6100
6101 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07006102static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006103{
6104 VOS_STATUS status;
6105 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 struct device *dev = NULL;
6107 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07006108#ifdef HAVE_WCNSS_CAL_DOWNLOAD
6109 int max_retries = 0;
6110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006111
Gopichand Nakkalad0774962013-05-24 11:32:21 +05306112#ifdef WCONN_TRACE_KMSG_LOG_BUFF
6113 vos_wconn_trace_init();
6114#endif
6115
Jeff Johnson295189b2012-06-20 16:38:30 -07006116 ENTER();
6117
Sameer Thalappil50dc0092013-02-19 17:23:33 -08006118#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07006120#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006121
6122 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
6123 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
6124
6125 //Power Up Libra WLAN card first if not already powered up
6126 status = vos_chipPowerUp(NULL,NULL,NULL);
6127 if (!VOS_IS_STATUS_SUCCESS(status))
6128 {
6129 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
6130 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05306131#ifdef WLAN_OPEN_SOURCE
6132 wake_lock_destroy(&wlan_wake_lock);
6133#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006134 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006135 }
6136
Jeff Johnson295189b2012-06-20 16:38:30 -07006137#ifdef ANI_BUS_TYPE_PCI
6138
6139 dev = wcnss_wlan_get_device();
6140
6141#endif // ANI_BUS_TYPE_PCI
6142
6143#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07006144
6145#ifdef HAVE_WCNSS_CAL_DOWNLOAD
6146 /* wait until WCNSS driver downloads NV */
6147 while (!wcnss_device_ready() && 5 >= ++max_retries) {
6148 msleep(1000);
6149 }
6150 if (max_retries >= 5) {
6151 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05306152#ifdef WLAN_OPEN_SOURCE
6153 wake_lock_destroy(&wlan_wake_lock);
6154#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07006155 return -ENODEV;
6156 }
6157#endif
6158
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 dev = wcnss_wlan_get_device();
6160#endif // ANI_BUS_TYPE_PLATFORM
6161
6162
6163 do {
6164 if (NULL == dev) {
6165 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
6166 ret_status = -1;
6167 break;
6168 }
6169
6170#ifdef MEMORY_DEBUG
6171 vos_mem_init();
6172#endif
6173
6174#ifdef TIMER_MANAGER
6175 vos_timer_manager_init();
6176#endif
6177
6178 /* Preopen VOSS so that it is ready to start at least SAL */
6179 status = vos_preOpen(&pVosContext);
6180
6181 if (!VOS_IS_STATUS_SUCCESS(status))
6182 {
6183 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
6184 ret_status = -1;
6185 break;
6186 }
6187
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006188#ifndef MODULE
6189 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
6190 */
6191 hdd_set_conparam((v_UINT_t)con_mode);
6192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006193
6194 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08006195 if (hdd_wlan_startup(dev))
6196 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08006198 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 vos_preClose( &pVosContext );
6200 ret_status = -1;
6201 break;
6202 }
6203
6204 /* Cancel the vote for XO Core ON
6205 * This is done here for safety purposes in case we re-initialize without turning
6206 * it OFF in any error scenario.
6207 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07006208 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07006210 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
6212 {
6213 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
6214 " Power consumed will be high\n");
6215 }
6216 } while (0);
6217
6218 if (0 != ret_status)
6219 {
6220 //Assert Deep sleep signal now to put Libra HW in lowest power state
6221 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
6222 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
6223
6224 //Vote off any PMIC voltage supplies
6225 vos_chipPowerDown(NULL, NULL, NULL);
6226#ifdef TIMER_MANAGER
6227 vos_timer_exit();
6228#endif
6229#ifdef MEMORY_DEBUG
6230 vos_mem_exit();
6231#endif
6232
Sameer Thalappil50dc0092013-02-19 17:23:33 -08006233#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07006235#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
6237 }
6238 else
6239 {
6240 //Send WLAN UP indication to Nlink Service
6241 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
6242
6243 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 }
6245
6246 EXIT();
6247
6248 return ret_status;
6249}
6250
Jeff Johnson32d95a32012-09-10 13:15:23 -07006251/**---------------------------------------------------------------------------
6252
6253 \brief hdd_module_init() - Init Function
6254
6255 This is the driver entry point (invoked when module is loaded using insmod)
6256
6257 \param - None
6258
6259 \return - 0 for success, non zero for failure
6260
6261 --------------------------------------------------------------------------*/
6262#ifdef MODULE
6263static int __init hdd_module_init ( void)
6264{
6265 return hdd_driver_init();
6266}
Jeff Johnson32d95a32012-09-10 13:15:23 -07006267#else /* #ifdef MODULE */
6268static int __init hdd_module_init ( void)
6269{
6270 /* Driver initialization is delayed to fwpath_changed_handler */
6271 return 0;
6272}
Jeff Johnson32d95a32012-09-10 13:15:23 -07006273#endif /* #ifdef MODULE */
6274
Jeff Johnson295189b2012-06-20 16:38:30 -07006275
6276/**---------------------------------------------------------------------------
6277
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006278 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07006279
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006280 This is the driver exit point (invoked when module is unloaded using rmmod
6281 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07006282
6283 \param - None
6284
6285 \return - None
6286
6287 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006288static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006289{
6290 hdd_context_t *pHddCtx = NULL;
6291 v_CONTEXT_t pVosContext = NULL;
Sameer Thalappil451ebb92013-06-28 15:49:58 -07006292 int retry = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006293
6294 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
6295
6296 //Get the global vos context
6297 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
6298
6299 if(!pVosContext)
6300 {
6301 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
6302 goto done;
6303 }
6304
6305 //Get the HDD context.
6306 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
6307
6308 if(!pHddCtx)
6309 {
6310 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
6311 }
6312 else
6313 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07006314 while(isWDresetInProgress()) {
6315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6316 "%s:SSR in Progress; block rmmod for 1 second!!!", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07006317 msleep(1000);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07006318
6319 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
6320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6321 "%s:SSR never completed, fatal error", __func__);
6322 VOS_BUG(0);
6323 }
6324 }
6325
Jeff Johnson295189b2012-06-20 16:38:30 -07006326
6327 pHddCtx->isLoadUnloadInProgress = TRUE;
6328 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
6329
6330 //Do all the cleanup before deregistering the driver
6331 hdd_wlan_exit(pHddCtx);
6332 }
6333
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 vos_preClose( &pVosContext );
6335
6336#ifdef TIMER_MANAGER
6337 vos_timer_exit();
6338#endif
6339#ifdef MEMORY_DEBUG
6340 vos_mem_exit();
6341#endif
6342
Gopichand Nakkalad0774962013-05-24 11:32:21 +05306343#ifdef WCONN_TRACE_KMSG_LOG_BUFF
6344 vos_wconn_trace_exit();
6345#endif
6346
Jeff Johnson295189b2012-06-20 16:38:30 -07006347done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08006348#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07006350#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
6352}
6353
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006354/**---------------------------------------------------------------------------
6355
6356 \brief hdd_module_exit() - Exit function
6357
6358 This is the driver exit point (invoked when module is unloaded using rmmod)
6359
6360 \param - None
6361
6362 \return - None
6363
6364 --------------------------------------------------------------------------*/
6365static void __exit hdd_module_exit(void)
6366{
6367 hdd_driver_exit();
6368}
6369
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006370#ifdef MODULE
6371static int fwpath_changed_handler(const char *kmessage,
6372 struct kernel_param *kp)
6373{
Jeff Johnson76052702013-04-16 13:55:05 -07006374 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006375}
6376
6377static int con_mode_handler(const char *kmessage,
6378 struct kernel_param *kp)
6379{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07006380 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006381}
6382#else /* #ifdef MODULE */
6383/**---------------------------------------------------------------------------
6384
Jeff Johnson76052702013-04-16 13:55:05 -07006385 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006386
Jeff Johnson76052702013-04-16 13:55:05 -07006387 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006388 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07006389 - invoked when module parameter fwpath is modified from userspace to signal
6390 initializing the WLAN driver or when con_mode is modified from userspace
6391 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006392
6393 \return - 0 for success, non zero for failure
6394
6395 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07006396static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006397{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07006398 int ret_status;
6399
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006400 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07006401 ret_status = hdd_driver_init();
6402 wlan_hdd_inited = ret_status ? 0 : 1;
6403 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006404 }
6405
6406 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07006407
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006408 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07006409
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07006410 ret_status = hdd_driver_init();
6411 wlan_hdd_inited = ret_status ? 0 : 1;
6412 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07006413}
6414
Jeff Johnson295189b2012-06-20 16:38:30 -07006415/**---------------------------------------------------------------------------
6416
Jeff Johnson76052702013-04-16 13:55:05 -07006417 \brief fwpath_changed_handler() - Handler Function
6418
6419 Handle changes to the fwpath parameter
6420
6421 \return - 0 for success, non zero for failure
6422
6423 --------------------------------------------------------------------------*/
6424static int fwpath_changed_handler(const char *kmessage,
6425 struct kernel_param *kp)
6426{
6427 int ret;
6428
6429 ret = param_set_copystring(kmessage, kp);
6430 if (0 == ret)
6431 ret = kickstart_driver();
6432 return ret;
6433}
6434
6435/**---------------------------------------------------------------------------
6436
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006437 \brief con_mode_handler() -
6438
6439 Handler function for module param con_mode when it is changed by userspace
6440 Dynamically linked - do nothing
6441 Statically linked - exit and init driver, as in rmmod and insmod
6442
Jeff Johnson76052702013-04-16 13:55:05 -07006443 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006444
Jeff Johnson76052702013-04-16 13:55:05 -07006445 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006446
6447 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07006448static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006449{
Jeff Johnson76052702013-04-16 13:55:05 -07006450 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006451
Jeff Johnson76052702013-04-16 13:55:05 -07006452 ret = param_set_int(kmessage, kp);
6453 if (0 == ret)
6454 ret = kickstart_driver();
6455 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006456}
6457#endif /* #ifdef MODULE */
6458
6459/**---------------------------------------------------------------------------
6460
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 \brief hdd_get_conparam() -
6462
6463 This is the driver exit point (invoked when module is unloaded using rmmod)
6464
6465 \param - None
6466
6467 \return - tVOS_CON_MODE
6468
6469 --------------------------------------------------------------------------*/
6470tVOS_CON_MODE hdd_get_conparam ( void )
6471{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006472#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006474#else
6475 return (tVOS_CON_MODE)curr_con_mode;
6476#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006477}
6478void hdd_set_conparam ( v_UINT_t newParam )
6479{
6480 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006481#ifndef MODULE
6482 curr_con_mode = con_mode;
6483#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006484}
6485/**---------------------------------------------------------------------------
6486
6487 \brief hdd_softap_sta_deauth() - function
6488
6489 This to take counter measure to handle deauth req from HDD
6490
6491 \param - pAdapter - Pointer to the HDD
6492
6493 \param - enable - boolean value
6494
6495 \return - None
6496
6497 --------------------------------------------------------------------------*/
6498
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006499VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07006500{
Jeff Johnson295189b2012-06-20 16:38:30 -07006501 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006502 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07006503
6504 ENTER();
6505
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07006506 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
6507 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07006508
6509 //Ignore request to deauth bcmc station
6510 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006511 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07006512
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006513 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07006514
6515 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006516 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07006517}
6518
6519/**---------------------------------------------------------------------------
6520
6521 \brief hdd_softap_sta_disassoc() - function
6522
6523 This to take counter measure to handle deauth req from HDD
6524
6525 \param - pAdapter - Pointer to the HDD
6526
6527 \param - enable - boolean value
6528
6529 \return - None
6530
6531 --------------------------------------------------------------------------*/
6532
6533void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
6534{
6535 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
6536
6537 ENTER();
6538
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306539 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07006540
6541 //Ignore request to disassoc bcmc station
6542 if( pDestMacAddress[0] & 0x1 )
6543 return;
6544
6545 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
6546}
6547
6548void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
6549{
6550 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
6551
6552 ENTER();
6553
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306554 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07006555
6556 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
6557}
6558
Jeff Johnson295189b2012-06-20 16:38:30 -07006559/**---------------------------------------------------------------------------
6560 *
6561 * \brief hdd_get__concurrency_mode() -
6562 *
6563 *
6564 * \param - None
6565 *
6566 * \return - CONCURRENCY MODE
6567 *
6568 * --------------------------------------------------------------------------*/
6569tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
6570{
6571 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
6572 hdd_context_t *pHddCtx;
6573
6574 if (NULL != pVosContext)
6575 {
6576 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
6577 if (NULL != pHddCtx)
6578 {
6579 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
6580 }
6581 }
6582
6583 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006584 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 return VOS_STA;
6586}
6587
6588/* Decide whether to allow/not the apps power collapse.
6589 * Allow apps power collapse if we are in connected state.
6590 * if not, allow only if we are in IMPS */
6591v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
6592{
6593 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08006594 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08006595 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006596 hdd_config_t *pConfig = pHddCtx->cfg_ini;
6597 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6598 hdd_adapter_t *pAdapter = NULL;
6599 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08006600 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006601
Jeff Johnson295189b2012-06-20 16:38:30 -07006602 if (VOS_STA_SAP_MODE == hdd_get_conparam())
6603 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006604
Yathish9f22e662012-12-10 14:21:35 -08006605 concurrent_state = hdd_get_concurrency_mode();
6606
6607#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
6608 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
6609 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
6610 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
6611 return TRUE;
6612#endif
6613
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 /*loop through all adapters. TBD fix for Concurrency */
6615 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6616 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6617 {
6618 pAdapter = pAdapterNode->pAdapter;
6619 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
6620 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6621 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08006622 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08006624 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08006625 (eANI_BOOLEAN_TRUE == scanRspPending) ||
6626 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08006628 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08006629 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
6630 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 return FALSE;
6632 }
6633 }
6634 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6635 pAdapterNode = pNext;
6636 }
6637 return TRUE;
6638}
6639
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08006640/* Decides whether to send suspend notification to Riva
6641 * if any adapter is in BMPS; then it is required */
6642v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
6643{
6644 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
6645 hdd_config_t *pConfig = pHddCtx->cfg_ini;
6646
6647 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
6648 {
6649 return TRUE;
6650 }
6651 return FALSE;
6652}
6653
Jeff Johnson295189b2012-06-20 16:38:30 -07006654void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
6655{
6656 switch(mode)
6657 {
Chilam Ngc4244af2013-04-01 15:37:32 -07006658 case VOS_STA_MODE:
6659 case VOS_P2P_CLIENT_MODE:
6660 case VOS_P2P_GO_MODE:
6661 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07006662 pHddCtx->concurrency_mode |= (1 << mode);
6663 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07006664 break;
6665 default:
6666 break;
6667
6668 }
6669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
6670 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
6671}
6672
6673
6674void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
6675{
6676 switch(mode)
6677 {
Chilam Ngc4244af2013-04-01 15:37:32 -07006678 case VOS_STA_MODE:
6679 case VOS_P2P_CLIENT_MODE:
6680 case VOS_P2P_GO_MODE:
6681 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006682 pHddCtx->no_of_sessions[mode]--;
6683 if (!(pHddCtx->no_of_sessions[mode]))
6684 pHddCtx->concurrency_mode &= (~(1 << mode));
6685 break;
6686 default:
6687 break;
6688 }
6689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
6690 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
6691}
6692
Jeff Johnsone7245742012-09-05 17:12:55 -07006693/**---------------------------------------------------------------------------
6694 *
6695 * \brief wlan_hdd_restart_init
6696 *
6697 * This function initalizes restart timer/flag. An internal function.
6698 *
6699 * \param - pHddCtx
6700 *
6701 * \return - None
6702 *
6703 * --------------------------------------------------------------------------*/
6704
6705static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
6706{
6707 /* Initialize */
6708 pHddCtx->hdd_restart_retries = 0;
6709 atomic_set(&pHddCtx->isRestartInProgress, 0);
6710 vos_timer_init(&pHddCtx->hdd_restart_timer,
6711 VOS_TIMER_TYPE_SW,
6712 wlan_hdd_restart_timer_cb,
6713 pHddCtx);
6714}
6715/**---------------------------------------------------------------------------
6716 *
6717 * \brief wlan_hdd_restart_deinit
6718 *
6719 * This function cleans up the resources used. An internal function.
6720 *
6721 * \param - pHddCtx
6722 *
6723 * \return - None
6724 *
6725 * --------------------------------------------------------------------------*/
6726
6727static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
6728{
6729
6730 VOS_STATUS vos_status;
6731 /* Block any further calls */
6732 atomic_set(&pHddCtx->isRestartInProgress, 1);
6733 /* Cleanup */
6734 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
6735 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07006736 hddLog(LOGW, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07006737 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
6738 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07006739 hddLog(LOGW, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07006740
6741}
6742
6743/**---------------------------------------------------------------------------
6744 *
6745 * \brief wlan_hdd_framework_restart
6746 *
6747 * This function uses a cfg80211 API to start a framework initiated WLAN
6748 * driver module unload/load.
6749 *
6750 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
6751 *
6752 *
6753 * \param - pHddCtx
6754 *
6755 * \return - VOS_STATUS_SUCCESS: Success
6756 * VOS_STATUS_E_EMPTY: Adapter is Empty
6757 * VOS_STATUS_E_NOMEM: No memory
6758
6759 * --------------------------------------------------------------------------*/
6760
6761static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
6762{
6763 VOS_STATUS status = VOS_STATUS_SUCCESS;
6764 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07006765 int len = (sizeof (struct ieee80211_mgmt));
6766 struct ieee80211_mgmt *mgmt = NULL;
6767
6768 /* Prepare the DEAUTH managment frame with reason code */
6769 mgmt = kzalloc(len, GFP_KERNEL);
6770 if(mgmt == NULL)
6771 {
6772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6773 "%s: memory allocation failed (%d bytes)", __func__, len);
6774 return VOS_STATUS_E_NOMEM;
6775 }
6776 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07006777
6778 /* Iterate over all adapters/devices */
6779 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6780 do
6781 {
6782 if( (status == VOS_STATUS_SUCCESS) &&
6783 pAdapterNode &&
6784 pAdapterNode->pAdapter)
6785 {
6786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6787 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
6788 pAdapterNode->pAdapter->dev->name,
6789 pAdapterNode->pAdapter->device_mode,
6790 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07006791 /*
6792 * CFG80211 event to restart the driver
6793 *
6794 * 'cfg80211_send_unprot_deauth' sends a
6795 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
6796 * of SME(Linux Kernel) state machine.
6797 *
6798 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
6799 * the driver.
6800 *
6801 */
6802
6803 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07006804 }
6805 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6806 pAdapterNode = pNext;
6807 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
6808
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07006809
6810 /* Free the allocated management frame */
6811 kfree(mgmt);
6812
Jeff Johnsone7245742012-09-05 17:12:55 -07006813 /* Retry until we unload or reach max count */
6814 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
6815 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
6816
6817 return status;
6818
6819}
6820/**---------------------------------------------------------------------------
6821 *
6822 * \brief wlan_hdd_restart_timer_cb
6823 *
6824 * Restart timer callback. An internal function.
6825 *
6826 * \param - User data:
6827 *
6828 * \return - None
6829 *
6830 * --------------------------------------------------------------------------*/
6831
6832void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
6833{
6834 hdd_context_t *pHddCtx = usrDataForCallback;
6835 wlan_hdd_framework_restart(pHddCtx);
6836 return;
6837
6838}
6839
6840
6841/**---------------------------------------------------------------------------
6842 *
6843 * \brief wlan_hdd_restart_driver
6844 *
6845 * This function sends an event to supplicant to restart the WLAN driver.
6846 *
6847 * This function is called from vos_wlanRestart.
6848 *
6849 * \param - pHddCtx
6850 *
6851 * \return - VOS_STATUS_SUCCESS: Success
6852 * VOS_STATUS_E_EMPTY: Adapter is Empty
6853 * VOS_STATUS_E_ALREADY: Request already in progress
6854
6855 * --------------------------------------------------------------------------*/
6856VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
6857{
6858 VOS_STATUS status = VOS_STATUS_SUCCESS;
6859
6860 /* A tight check to make sure reentrancy */
6861 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
6862 {
6863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6864 "%s: WLAN restart is already in progress", __func__);
6865
6866 return VOS_STATUS_E_ALREADY;
6867 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07006868 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08006869#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07006870 wcnss_reset_intr();
6871#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07006872
Jeff Johnsone7245742012-09-05 17:12:55 -07006873 return status;
6874}
6875
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07006876/*
6877 * API to find if there is any STA or P2P-Client is connected
6878 */
6879VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
6880{
6881 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
6882}
Jeff Johnsone7245742012-09-05 17:12:55 -07006883
Jeff Johnson295189b2012-06-20 16:38:30 -07006884//Register the module init/exit functions
6885module_init(hdd_module_init);
6886module_exit(hdd_module_exit);
6887
6888MODULE_LICENSE("Dual BSD/GPL");
6889MODULE_AUTHOR("Qualcomm Atheros, Inc.");
6890MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
6891
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07006892module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
6893 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07006894
Jeff Johnson76052702013-04-16 13:55:05 -07006895module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07006896 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);