blob: 14a513c06876f3fa0f0a7f756de8bb7137cf1d18 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar8b373292014-01-08 20:36:55 -08002 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
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>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700112#include <linux/ctype.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include <mach/subsystem_restart.h>
114#include <wlan_hdd_hostapd.h>
115#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700117#include "wlan_hdd_dev_pwr.h"
118#ifdef WLAN_BTAMP_FEATURE
119#include "bap_hdd_misc.h"
120#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700121#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700122#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800123#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530124#ifdef FEATURE_WLAN_TDLS
125#include "wlan_hdd_tdls.h"
126#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700127#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129#ifdef MODULE
130#define WLAN_MODULE_NAME module_name(THIS_MODULE)
131#else
132#define WLAN_MODULE_NAME "wlan"
133#endif
134
135#ifdef TIMER_MANAGER
136#define TIMER_MANAGER_STR " +TIMER_MANAGER"
137#else
138#define TIMER_MANAGER_STR ""
139#endif
140
141#ifdef MEMORY_DEBUG
142#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
143#else
144#define MEMORY_DEBUG_STR ""
145#endif
146
147/* the Android framework expects this param even though we don't use it */
148#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700149static char fwpath_buffer[BUF_LEN];
150static struct kparam_string fwpath = {
151 .string = fwpath_buffer,
152 .maxlen = BUF_LEN,
153};
Arif Hussain66559122013-11-21 10:11:40 -0800154
155static char *country_code;
156static int enable_11d = -1;
157static int enable_dfs_chan_scan = -1;
158
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700159#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700160static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700161#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700162
Jeff Johnsone7245742012-09-05 17:12:55 -0700163/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800164 * spinlock for synchronizing asynchronous request/response
165 * (full description of use in wlan_hdd_main.h)
166 */
167DEFINE_SPINLOCK(hdd_context_lock);
168
169/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700170 * The rate at which the driver sends RESTART event to supplicant
171 * once the function 'vos_wlanRestart()' is called
172 *
173 */
174#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
175#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700176
177/*
178 * Size of Driver command strings from upper layer
179 */
180#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
181#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
182
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700183#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
184#define TID_MIN_VALUE 0
185#define TID_MAX_VALUE 15
186static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
187 tAniTrafStrmMetrics* pTsmMetrics);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -0800188static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
189 tCsrCcxBeaconReq *pCcxBcnReq);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
191
Srinivas Girigowda4081bb12014-01-06 17:12:58 -0800192#define WLAN_PRIV_DATA_MAX_LEN 4096
193
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700194/*
195 * Driver miracast parameters 0-Disabled
196 * 1-Source, 2-Sink
197 */
198#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
199#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
200
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800201#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700202static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700205static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700206
207//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700208static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
209static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
210static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
211void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800212void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700213
Jeff Johnson295189b2012-06-20 16:38:30 -0700214v_U16_t hdd_select_queue(struct net_device *dev,
215 struct sk_buff *skb);
216
217#ifdef WLAN_FEATURE_PACKET_FILTERING
218static void hdd_set_multicast_list(struct net_device *dev);
219#endif
220
221void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
Amar Singhal4c723bd2013-03-25 18:14:15 -0700222int isWDresetInProgress(void);
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224extern int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
Amar Singhal0a402232013-10-11 20:57:16 -0700225
Srinivas Girigowdade697412013-02-14 16:31:48 -0800226#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
227void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
228static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700229static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
230 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
231 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700232static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
233 tANI_U8 *pTargetApBssid,
234 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800235#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
237VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
238#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
239
Jeff Johnson295189b2012-06-20 16:38:30 -0700240static int hdd_netdev_notifier_call(struct notifier_block * nb,
241 unsigned long state,
242 void *ndev)
243{
244 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700245 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700246 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700247#ifdef WLAN_BTAMP_FEATURE
248 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700249#endif
250
251 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700252 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700253 (strncmp(dev->name, "p2p", 3)))
254 return NOTIFY_DONE;
255
256 if (isWDresetInProgress())
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 return NOTIFY_DONE;
258
Jeff Johnson295189b2012-06-20 16:38:30 -0700259 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700260 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700261
Jeff Johnson27cee452013-03-27 11:10:24 -0700262 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800264 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 VOS_ASSERT(0);
266 return NOTIFY_DONE;
267 }
268
Jeff Johnson27cee452013-03-27 11:10:24 -0700269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
270 if (NULL == pHddCtx)
271 {
272 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
273 VOS_ASSERT(0);
274 return NOTIFY_DONE;
275 }
276
277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
278 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
280 switch (state) {
281 case NETDEV_REGISTER:
282 break;
283
284 case NETDEV_UNREGISTER:
285 break;
286
287 case NETDEV_UP:
288 break;
289
290 case NETDEV_DOWN:
291 break;
292
293 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700294 if(TRUE == pAdapter->isLinkUpSvcNeeded)
295 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700296 break;
297
298 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700299 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700300 {
301 int result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800302 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +0530303 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800305 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
307 if(!result)
308 {
309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson902c9832012-12-10 14:28:09 -0800310 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700311 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 }
313 }
314 else
315 {
316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700317 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 }
319#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 status = WLANBAP_StopAmp();
322 if(VOS_STATUS_SUCCESS != status )
323 {
324 pHddCtx->isAmpAllowed = VOS_TRUE;
325 hddLog(VOS_TRACE_LEVEL_FATAL,
326 "%s: Failed to stop AMP", __func__);
327 }
328 else
329 {
330 //a state m/c implementation in PAL is TBD to avoid this delay
331 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700332 if ( pHddCtx->isAmpAllowed )
333 {
334 WLANBAP_DeregisterFromHCI();
335 pHddCtx->isAmpAllowed = VOS_FALSE;
336 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 }
338#endif //WLAN_BTAMP_FEATURE
339 break;
340
341 default:
342 break;
343 }
344
345 return NOTIFY_DONE;
346}
347
348struct notifier_block hdd_netdev_notifier = {
349 .notifier_call = hdd_netdev_notifier_call,
350};
351
352/*---------------------------------------------------------------------------
353 * Function definitions
354 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700355void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
356void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700357//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700358static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700359#ifndef MODULE
360/* current con_mode - used only for statically linked driver
361 * con_mode is changed by userspace to indicate a mode change which will
362 * result in calling the module exit and init functions. The module
363 * exit function will clean up based on the value of con_mode prior to it
364 * being changed by userspace. So curr_con_mode records the current con_mode
365 * for exit when con_mode becomes the next mode for init
366 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700367static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700368#endif
369
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800370/**---------------------------------------------------------------------------
371
372 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
373
374 Called immediately after the cfg.ini is read in order to configure
375 the desired trace levels.
376
377 \param - moduleId - module whose trace level is being configured
378 \param - bitmask - bitmask of log levels to be enabled
379
380 \return - void
381
382 --------------------------------------------------------------------------*/
383static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
384{
385 wpt_tracelevel level;
386
387 /* if the bitmask is the default value, then a bitmask was not
388 specified in cfg.ini, so leave the logging level alone (it
389 will remain at the "compiled in" default value) */
390 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
391 {
392 return;
393 }
394
395 /* a mask was specified. start by disabling all logging */
396 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
397
398 /* now cycle through the bitmask until all "set" bits are serviced */
399 level = VOS_TRACE_LEVEL_FATAL;
400 while (0 != bitmask)
401 {
402 if (bitmask & 1)
403 {
404 vos_trace_setValue(moduleId, level, 1);
405 }
406 level++;
407 bitmask >>= 1;
408 }
409}
410
411
Jeff Johnson295189b2012-06-20 16:38:30 -0700412/**---------------------------------------------------------------------------
413
414 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
415
416 Called immediately after the cfg.ini is read in order to configure
417 the desired trace levels in the WDI.
418
419 \param - moduleId - module whose trace level is being configured
420 \param - bitmask - bitmask of log levels to be enabled
421
422 \return - void
423
424 --------------------------------------------------------------------------*/
425static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
426{
427 wpt_tracelevel level;
428
429 /* if the bitmask is the default value, then a bitmask was not
430 specified in cfg.ini, so leave the logging level alone (it
431 will remain at the "compiled in" default value) */
432 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
433 {
434 return;
435 }
436
437 /* a mask was specified. start by disabling all logging */
438 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
439
440 /* now cycle through the bitmask until all "set" bits are serviced */
441 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
442 while (0 != bitmask)
443 {
444 if (bitmask & 1)
445 {
446 wpalTraceSetLevel(moduleId, level, 1);
447 }
448 level++;
449 bitmask >>= 1;
450 }
451}
Jeff Johnson295189b2012-06-20 16:38:30 -0700452
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530453/*
454 * FUNCTION: wlan_hdd_validate_context
455 * This function is used to check the HDD context
456 */
457int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
458{
459 ENTER();
460
461 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
462 {
463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
464 "%s: HDD context is Null", __func__);
465 return -ENODEV;
466 }
467
468 if (pHddCtx->isLogpInProgress)
469 {
470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
471 "%s: LOGP in Progress. Ignore!!!", __func__);
472 return -EAGAIN;
473 }
474
475 if (pHddCtx->isLoadUnloadInProgress)
476 {
477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
478 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
479 return -EAGAIN;
480 }
481 return 0;
482}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700483#ifdef CONFIG_ENABLE_LINUX_REG
484void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
485{
486 hdd_adapter_t *pAdapter = NULL;
487 hdd_station_ctx_t *pHddStaCtx = NULL;
488 eCsrPhyMode phyMode;
489 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530490
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700491 if (NULL == pHddCtx)
492 {
493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
494 "HDD Context is null !!");
495 return ;
496 }
497
498 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
499 if (NULL == pAdapter)
500 {
501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
502 "pAdapter is null !!");
503 return ;
504 }
505
506 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
507 if (NULL == pHddStaCtx)
508 {
509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
510 "pHddStaCtx is null !!");
511 return ;
512 }
513
514 cfg_param = pHddCtx->cfg_ini;
515 if (NULL == cfg_param)
516 {
517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
518 "cfg_params not available !!");
519 return ;
520 }
521
522 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
523
524 if (!pHddCtx->isVHT80Allowed)
525 {
526 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
527 (eCSR_DOT11_MODE_11ac == phyMode) ||
528 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
529 {
530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
531 "Setting phymode to 11n!!");
532 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
533 }
534 }
535 else
536 {
537 /*New country Supports 11ac as well resetting value back from .ini*/
538 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
539 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
540 return ;
541 }
542
543 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
544 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
545 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
546 {
547 VOS_STATUS vosStatus;
548
549 // need to issue a disconnect to CSR.
550 INIT_COMPLETION(pAdapter->disconnect_comp_var);
551 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
552 pAdapter->sessionId,
553 eCSR_DISCONNECT_REASON_UNSPECIFIED );
554
555 if (VOS_STATUS_SUCCESS == vosStatus)
556 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
557 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
558
559 }
560}
561#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530562void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
563{
564 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
565 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
566 hdd_config_t *cfg_param;
567 eCsrPhyMode phyMode;
568
569 if (NULL == pHddCtx)
570 {
571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
572 "HDD Context is null !!");
573 return ;
574 }
575
576 cfg_param = pHddCtx->cfg_ini;
577
578 if (NULL == cfg_param)
579 {
580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
581 "cfg_params not available !!");
582 return ;
583 }
584
585 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
586
587 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
588 {
589 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
590 (eCSR_DOT11_MODE_11ac == phyMode) ||
591 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
594 "Setting phymode to 11n!!");
595 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
596 }
597 }
598 else
599 {
600 /*New country Supports 11ac as well resetting value back from .ini*/
601 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
602 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
603 return ;
604 }
605
606 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
607 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
608 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
609 {
610 VOS_STATUS vosStatus;
611
612 // need to issue a disconnect to CSR.
613 INIT_COMPLETION(pAdapter->disconnect_comp_var);
614 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
615 pAdapter->sessionId,
616 eCSR_DISCONNECT_REASON_UNSPECIFIED );
617
618 if (VOS_STATUS_SUCCESS == vosStatus)
619 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
620 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
621
622 }
623}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700624#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530625
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700626void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
627{
628 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
629 hdd_config_t *cfg_param;
630
631 if (NULL == pHddCtx)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
634 "HDD Context is null !!");
635 return ;
636 }
637
638 cfg_param = pHddCtx->cfg_ini;
639
640 if (NULL == cfg_param)
641 {
642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
643 "cfg_params not available !!");
644 return ;
645 }
646
647 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
648 {
649 /*New country doesn't support DFS */
650 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
651 }
652 else
653 {
654 /*New country Supports DFS as well resetting value back from .ini*/
655 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
656 }
657
658}
659
Rajeev79dbe4c2013-10-05 11:03:42 +0530660#ifdef FEATURE_WLAN_BATCH_SCAN
661
662/**---------------------------------------------------------------------------
663
664 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
665 input string
666
667 This function extracts assigned integer from string in below format:
668 "STRING=10" : extracts integer 10 from this string
669
670 \param - pInPtr Pointer to input string
671 \param - base Base for string to int conversion(10 for decimal 16 for hex)
672 \param - pOutPtr Pointer to variable in which extracted integer needs to be
673 assigned
674 \param - pLastArg to tell whether it is last arguement in input string or
675 not
676
677 \return - NULL for failure cases
678 pointer to next arguement in input string for success cases
679 --------------------------------------------------------------------------*/
680static tANI_U8 *
681hdd_extract_assigned_int_from_str
682(
683 tANI_U8 *pInPtr,
684 tANI_U8 base,
685 tANI_U32 *pOutPtr,
686 tANI_U8 *pLastArg
687)
688{
689 int tempInt;
690 int v = 0;
691 char buf[32];
692 int val = 0;
693 *pLastArg = FALSE;
694
695 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
696 if (NULL == pInPtr)
697 {
698 return NULL;
699 }
700
701 pInPtr++;
702
703 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
704
705 val = sscanf(pInPtr, "%32s ", buf);
706 if (val < 0 && val > strlen(pInPtr))
707 {
708 return NULL;
709 }
710 pInPtr += val;
711 v = kstrtos32(buf, base, &tempInt);
712 if (v < 0)
713 {
714 return NULL;
715 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800716 if (tempInt < 0)
717 {
718 tempInt = 0;
719 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530720 *pOutPtr = tempInt;
721
722 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
723 if (NULL == pInPtr)
724 {
725 *pLastArg = TRUE;
726 return NULL;
727 }
728 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
729
730 return pInPtr;
731}
732
733/**---------------------------------------------------------------------------
734
735 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
736 input string
737
738 This function extracts assigned character from string in below format:
739 "STRING=A" : extracts char 'A' from this string
740
741 \param - pInPtr Pointer to input string
742 \param - pOutPtr Pointer to variable in which extracted char needs to be
743 assigned
744 \param - pLastArg to tell whether it is last arguement in input string or
745 not
746
747 \return - NULL for failure cases
748 pointer to next arguement in input string for success cases
749 --------------------------------------------------------------------------*/
750static tANI_U8 *
751hdd_extract_assigned_char_from_str
752(
753 tANI_U8 *pInPtr,
754 tANI_U8 *pOutPtr,
755 tANI_U8 *pLastArg
756)
757{
758 *pLastArg = FALSE;
759
760 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
761 if (NULL == pInPtr)
762 {
763 return NULL;
764 }
765
766 pInPtr++;
767
768 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
769
770 *pOutPtr = *pInPtr;
771
772 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
773 if (NULL == pInPtr)
774 {
775 *pLastArg = TRUE;
776 return NULL;
777 }
778 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
779
780 return pInPtr;
781}
782
783
784/**---------------------------------------------------------------------------
785
786 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
787
788 This function parses set batch scan command in below format:
789 WLS_BATCHING_SET <space> followed by below arguements
790 "SCANFREQ=XX" : Optional defaults to 30 sec
791 "MSCAN=XX" : Required number of scans to attempt to batch
792 "BESTN=XX" : Best Network (RSSI) defaults to 16
793 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
794 A. implies only 5 GHz , B. implies only 2.4GHz
795 "RTT=X" : optional defaults to 0
796 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
797 error
798
799 For example input commands:
800 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
801 translated into set batch scan with following parameters:
802 a) Frequence 60 seconds
803 b) Batch 10 scans together
804 c) Best RSSI to be 20
805 d) 5GHz band only
806 e) RTT is equal to 0
807
808 \param - pValue Pointer to input channel list
809 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
810
811 \return - 0 for success non-zero for failure
812
813 --------------------------------------------------------------------------*/
814static int
815hdd_parse_set_batchscan_command
816(
817 tANI_U8 *pValue,
818 tSirSetBatchScanReq *pHddSetBatchScanReq
819)
820{
821 tANI_U8 *inPtr = pValue;
822 tANI_U8 val = 0;
823 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800824 tANI_U32 nScanFreq;
825 tANI_U32 nMscan;
826 tANI_U32 nBestN;
827 tANI_U8 ucRfBand;
828 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800829 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530830
831 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800832 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
833 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
834 nRtt = 0;
835 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530836
837 /*go to space after WLS_BATCHING_SET command*/
838 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
839 /*no argument after the command*/
840 if (NULL == inPtr)
841 {
842 return -EINVAL;
843 }
844
845 /*no space after the command*/
846 else if (SPACE_ASCII_VALUE != *inPtr)
847 {
848 return -EINVAL;
849 }
850
851 /*removing empty spaces*/
852 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
853
854 /*no argument followed by spaces*/
855 if ('\0' == *inPtr)
856 {
857 return -EINVAL;
858 }
859
860 /*check and parse SCANFREQ*/
861 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
862 {
863 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800864 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800865
Rajeev Kumarc933d982013-11-18 20:04:20 -0800866 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800867 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800868 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800869 }
870
Rajeev79dbe4c2013-10-05 11:03:42 +0530871 if ( (NULL == inPtr) || (TRUE == lastArg))
872 {
873 return -EINVAL;
874 }
875 }
876
877 /*check and parse MSCAN*/
878 if ((strncmp(inPtr, "MSCAN", 5) == 0))
879 {
880 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800881 &nMscan, &lastArg);
882
883 if (0 == nMscan)
884 {
885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
886 "invalid MSCAN=%d", nMscan);
887 return -EINVAL;
888 }
889
Rajeev79dbe4c2013-10-05 11:03:42 +0530890 if (TRUE == lastArg)
891 {
892 goto done;
893 }
894 else if (NULL == inPtr)
895 {
896 return -EINVAL;
897 }
898 }
899 else
900 {
901 return -EINVAL;
902 }
903
904 /*check and parse BESTN*/
905 if ((strncmp(inPtr, "BESTN", 5) == 0))
906 {
907 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800908 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800909
Rajeev Kumarc933d982013-11-18 20:04:20 -0800910 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800911 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800912 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800913 }
914
Rajeev79dbe4c2013-10-05 11:03:42 +0530915 if (TRUE == lastArg)
916 {
917 goto done;
918 }
919 else if (NULL == inPtr)
920 {
921 return -EINVAL;
922 }
923 }
924
925 /*check and parse CHANNEL*/
926 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
927 {
928 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800929
Rajeev79dbe4c2013-10-05 11:03:42 +0530930 if (('A' == val) || ('a' == val))
931 {
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800932 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530933 }
934 else if (('B' == val) || ('b' == val))
935 {
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800936 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530937 }
938 else
939 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800940 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
941 }
942
943 if (TRUE == lastArg)
944 {
945 goto done;
946 }
947 else if (NULL == inPtr)
948 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530949 return -EINVAL;
950 }
951 }
952
953 /*check and parse RTT*/
954 if ((strncmp(inPtr, "RTT", 3) == 0))
955 {
956 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800957 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 if (TRUE == lastArg)
959 {
960 goto done;
961 }
962 if (NULL == inPtr)
963 {
964 return -EINVAL;
965 }
966 }
967
968
969done:
970
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800971 pHddSetBatchScanReq->scanFrequency = nScanFreq;
972 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
973 pHddSetBatchScanReq->bestNetwork = nBestN;
974 pHddSetBatchScanReq->rfBand = ucRfBand;
975 pHddSetBatchScanReq->rtt = nRtt;
976
Rajeev79dbe4c2013-10-05 11:03:42 +0530977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
978 "Received WLS_BATCHING_SET with SCANFREQ=%d "
979 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
980 pHddSetBatchScanReq->scanFrequency,
981 pHddSetBatchScanReq->numberOfScansToBatch,
982 pHddSetBatchScanReq->bestNetwork,
983 pHddSetBatchScanReq->rfBand,
984 pHddSetBatchScanReq->rtt);
985
986 return 0;
987}/*End of hdd_parse_set_batchscan_command*/
988
989/**---------------------------------------------------------------------------
990
991 \brief hdd_set_batch_scan_req_callback () - This function is called after
992 receiving set batch scan response from FW and it saves set batch scan
993 response data FW to HDD context and sets the completion event on
994 which hdd_ioctl is waiting
995
996 \param - callbackContext Pointer to HDD adapter
997 \param - pRsp Pointer to set batch scan response data received from FW
998
999 \return - nothing
1000
1001 --------------------------------------------------------------------------*/
1002static void hdd_set_batch_scan_req_callback
1003(
1004 void *callbackContext,
1005 tSirSetBatchScanRsp *pRsp
1006)
1007{
1008 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1009 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1010
1011 /*sanity check*/
1012 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1013 {
1014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1015 "%s: Invalid pAdapter magic", __func__);
1016 VOS_ASSERT(0);
1017 return;
1018 }
1019 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1020
1021 /*save set batch scan response*/
1022 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1023
1024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1025 "Received set batch scan rsp from FW with nScansToBatch=%d",
1026 pHddSetBatchScanRsp->nScansToBatch);
1027
1028 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1029 complete(&pAdapter->hdd_set_batch_scan_req_var);
1030
1031 return;
1032}/*End of hdd_set_batch_scan_req_callback*/
1033
1034
1035/**---------------------------------------------------------------------------
1036
1037 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1038 info in hdd batch scan response queue
1039
1040 \param - pAdapter Pointer to hdd adapter
1041 \param - pAPMetaInfo Pointer to access point meta info
1042 \param - scanId scan ID of batch scan response
1043 \param - isLastAp tells whether AP is last AP in batch scan response or not
1044
1045 \return - nothing
1046
1047 --------------------------------------------------------------------------*/
1048static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1049 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1050{
1051 tHddBatchScanRsp *pHead;
1052 tHddBatchScanRsp *pNode;
1053 tHddBatchScanRsp *pPrev;
1054 tHddBatchScanRsp *pTemp;
1055 tANI_U8 ssidLen;
1056
1057 /*head of hdd batch scan response queue*/
1058 pHead = pAdapter->pBatchScanRsp;
1059
1060 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1061 if (NULL == pNode)
1062 {
1063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1064 "%s: Could not allocate memory", __func__);
1065 VOS_ASSERT(0);
1066 return;
1067 }
1068
1069 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1070 sizeof(pNode->ApInfo.bssid));
1071 ssidLen = strlen(pApMetaInfo->ssid);
1072 if (SIR_MAX_SSID_SIZE < ssidLen)
1073 {
1074 /*invalid scan result*/
1075 vos_mem_free(pNode);
1076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1077 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1078 return;
1079 }
1080 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1081 /*null terminate ssid*/
1082 pNode->ApInfo.ssid[ssidLen] = '\0';
1083 pNode->ApInfo.ch = pApMetaInfo->ch;
1084 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1085 pNode->ApInfo.age = pApMetaInfo->timestamp;
1086 pNode->ApInfo.batchId = scanId;
1087 pNode->ApInfo.isLastAp = isLastAp;
1088
1089 pNode->pNext = NULL;
1090 if (NULL == pHead)
1091 {
1092 pAdapter->pBatchScanRsp = pNode;
1093 }
1094 else
1095 {
1096 pTemp = pHead;
1097 while (NULL != pTemp)
1098 {
1099 pPrev = pTemp;
1100 pTemp = pTemp->pNext;
1101 }
1102 pPrev->pNext = pNode;
1103 }
1104
1105 return;
1106}/*End of hdd_populate_batch_scan_rsp_queue*/
1107
1108/**---------------------------------------------------------------------------
1109
1110 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1111 receiving batch scan response indication from FW. It saves get batch scan
1112 response data in HDD batch scan response queue. This callback sets the
1113 completion event on which hdd_ioctl is waiting only after getting complete
1114 batch scan response data from FW
1115
1116 \param - callbackContext Pointer to HDD adapter
1117 \param - pRsp Pointer to get batch scan response data received from FW
1118
1119 \return - nothing
1120
1121 --------------------------------------------------------------------------*/
1122static void hdd_batch_scan_result_ind_callback
1123(
1124 void *callbackContext,
1125 void *pRsp
1126)
1127{
1128 v_BOOL_t isLastAp;
1129 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001130 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301131 tANI_U32 numberScanList;
1132 tANI_U32 nextScanListOffset;
1133 tANI_U32 nextApMetaInfoOffset;
1134 hdd_adapter_t* pAdapter;
1135 tpSirBatchScanList pScanList;
1136 tpSirBatchScanNetworkInfo pApMetaInfo;
1137 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1138 tSirSetBatchScanReq *pReq;
1139
1140 pAdapter = (hdd_adapter_t *)callbackContext;
1141 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001142 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301143 {
1144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1145 "%s: Invalid pAdapter magic", __func__);
1146 VOS_ASSERT(0);
1147 return;
1148 }
1149
1150 /*initialize locals*/
1151 pReq = &pAdapter->hddSetBatchScanReq;
1152 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1153 isLastAp = FALSE;
1154 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001155 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301156 numberScanList = 0;
1157 nextScanListOffset = 0;
1158 nextApMetaInfoOffset = 0;
1159 pScanList = NULL;
1160 pApMetaInfo = NULL;
1161
1162 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1163 {
1164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1165 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1166 isLastAp = TRUE;
1167 goto done;
1168 }
1169
1170 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1172 "Batch scan rsp: numberScalList %d", numberScanList);
1173
1174 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1175 {
1176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1177 "%s: numberScanList %d", __func__, numberScanList);
1178 isLastAp = TRUE;
1179 goto done;
1180 }
1181
1182 while (numberScanList)
1183 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001184 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301185 nextScanListOffset);
1186 if (NULL == pScanList)
1187 {
1188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1189 "%s: pScanList is %p", __func__, pScanList);
1190 isLastAp = TRUE;
1191 goto done;
1192 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001193 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001195 "Batch scan rsp: numApMetaInfo %d scanId %d",
1196 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301197
1198 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1202 isLastAp = TRUE;
1203 goto done;
1204 }
1205
Rajeev Kumarce651e42013-10-21 18:57:15 -07001206 /*Initialize next AP meta info offset for next scan list*/
1207 nextApMetaInfoOffset = 0;
1208
Rajeev79dbe4c2013-10-05 11:03:42 +05301209 while (numApMetaInfo)
1210 {
1211 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1212 nextApMetaInfoOffset);
1213 if (NULL == pApMetaInfo)
1214 {
1215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1216 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1217 isLastAp = TRUE;
1218 goto done;
1219 }
1220 /*calculate AP age*/
1221 pApMetaInfo->timestamp =
1222 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1223
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001225 "%s: bssId "MAC_ADDRESS_STR
1226 " ch %d rssi %d timestamp %d", __func__,
1227 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1228 pApMetaInfo->ch, pApMetaInfo->rssi,
1229 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301230
1231 /*mark last AP in batch scan response*/
1232 if ((TRUE == pBatchScanRsp->isLastResult) &&
1233 (1 == numberScanList) && (1 == numApMetaInfo))
1234 {
1235 isLastAp = TRUE;
1236 }
1237
1238 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1239 /*store batch scan repsonse in hdd queue*/
1240 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1241 pScanList->scanId, isLastAp);
1242 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1243
1244 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1245 numApMetaInfo--;
1246 }
1247
Rajeev Kumarce651e42013-10-21 18:57:15 -07001248 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1249 + (sizeof(tSirBatchScanNetworkInfo)
1250 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301251 numberScanList--;
1252 }
1253
1254done:
1255
1256 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1257 requested from hdd_ioctl*/
1258 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1259 (TRUE == isLastAp))
1260 {
1261 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1262 complete(&pAdapter->hdd_get_batch_scan_req_var);
1263 }
1264
1265 return;
1266}/*End of hdd_batch_scan_result_ind_callback*/
1267
1268/**---------------------------------------------------------------------------
1269
1270 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1271 response as per batch scan FR request format by putting proper markers
1272
1273 \param - pDest pointer to destination buffer
1274 \param - cur_len current length
1275 \param - tot_len total remaining size which can be written to user space
1276 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1277 \param - pAdapter Pointer to HDD adapter
1278
1279 \return - ret no of characters written
1280
1281 --------------------------------------------------------------------------*/
1282static tANI_U32
1283hdd_format_batch_scan_rsp
1284(
1285 tANI_U8 *pDest,
1286 tANI_U32 cur_len,
1287 tANI_U32 tot_len,
1288 tHddBatchScanRsp *pApMetaInfo,
1289 hdd_adapter_t* pAdapter
1290)
1291{
1292 tANI_U32 ret = 0;
1293 tANI_U32 rem_len = 0;
1294 tANI_U8 temp_len = 0;
1295 tANI_U8 temp_total_len = 0;
1296 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1297 tANI_U8 *pTemp = temp;
1298
1299 /*Batch scan reponse needs to be returned to user space in
1300 following format:
1301 "scancount=X\n" where X is the number of scans in current batch
1302 batch
1303 "trunc\n" optional present if current scan truncated
1304 "bssid=XX:XX:XX:XX:XX:XX\n"
1305 "ssid=XXXX\n"
1306 "freq=X\n" frequency in Mhz
1307 "level=XX\n"
1308 "age=X\n" ms
1309 "dist=X\n" cm (-1 if not available)
1310 "errror=X\n" (-1if not available)
1311 "====\n" (end of ap marker)
1312 "####\n" (end of scan marker)
1313 "----\n" (end of results)*/
1314 /*send scan result in above format to user space based on
1315 available length*/
1316 /*The GET response may have more data than the driver can return in its
1317 buffer. In that case the buffer should be filled to the nearest complete
1318 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1319 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1320 The final buffer should end with "----\n"*/
1321
1322 /*sanity*/
1323 if (cur_len > tot_len)
1324 {
1325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1326 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1327 return 0;
1328 }
1329 else
1330 {
1331 rem_len = (tot_len - cur_len);
1332 }
1333
1334 /*end scan marker*/
1335 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1336 {
1337 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1338 pTemp += temp_len;
1339 temp_total_len += temp_len;
1340 }
1341
1342 /*bssid*/
1343 temp_len = snprintf(pTemp, sizeof(temp),
1344 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1345 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1346 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1347 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1348 pTemp += temp_len;
1349 temp_total_len += temp_len;
1350
1351 /*ssid*/
1352 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1353 pApMetaInfo->ApInfo.ssid);
1354 pTemp += temp_len;
1355 temp_total_len += temp_len;
1356
1357 /*freq*/
1358 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001359 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301360 pTemp += temp_len;
1361 temp_total_len += temp_len;
1362
1363 /*level*/
1364 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1365 pApMetaInfo->ApInfo.rssi);
1366 pTemp += temp_len;
1367 temp_total_len += temp_len;
1368
1369 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001370 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301371 pApMetaInfo->ApInfo.age);
1372 pTemp += temp_len;
1373 temp_total_len += temp_len;
1374
1375 /*dist*/
1376 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1377 pTemp += temp_len;
1378 temp_total_len += temp_len;
1379
1380 /*error*/
1381 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1382 pTemp += temp_len;
1383 temp_total_len += temp_len;
1384
1385 /*end AP marker*/
1386 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1387 pTemp += temp_len;
1388 temp_total_len += temp_len;
1389
1390 /*last AP in batch scan response*/
1391 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1392 {
1393 /*end scan marker*/
1394 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1395 pTemp += temp_len;
1396 temp_total_len += temp_len;
1397
1398 /*end batch scan result marker*/
1399 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1400 pTemp += temp_len;
1401 temp_total_len += temp_len;
Rajeev Kumarb20d8c82013-11-18 20:04:20 -08001402
1403 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301404 }
1405
1406 if (temp_total_len < rem_len)
1407 {
1408 ret = temp_total_len + 1;
1409 strlcpy(pDest, temp, ret);
1410 pAdapter->isTruncated = FALSE;
1411 }
1412 else
1413 {
1414 pAdapter->isTruncated = TRUE;
1415 if (rem_len >= strlen("%%%%"))
1416 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001417 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301418 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001419 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301420 {
1421 ret = 0;
1422 }
1423 }
1424
1425 return ret;
1426
1427}/*End of hdd_format_batch_scan_rsp*/
1428
1429/**---------------------------------------------------------------------------
1430
1431 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1432 buffer starting with head of hdd batch scan response queue
1433
1434 \param - pAdapter Pointer to HDD adapter
1435 \param - pDest Pointer to user data buffer
1436 \param - cur_len current offset in user buffer
1437 \param - rem_len remaining no of bytes in user buffer
1438
1439 \return - number of bytes written in user buffer
1440
1441 --------------------------------------------------------------------------*/
1442
1443tANI_U32 hdd_populate_user_batch_scan_rsp
1444(
1445 hdd_adapter_t* pAdapter,
1446 tANI_U8 *pDest,
1447 tANI_U32 cur_len,
1448 tANI_U32 rem_len
1449)
1450{
1451 tHddBatchScanRsp *pHead;
1452 tHddBatchScanRsp *pPrev;
1453 tANI_U32 len;
1454
Rajeev79dbe4c2013-10-05 11:03:42 +05301455 pAdapter->isTruncated = FALSE;
1456
1457 /*head of hdd batch scan response queue*/
1458 pHead = pAdapter->pBatchScanRsp;
1459 while (pHead)
1460 {
1461 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1462 pAdapter);
1463 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001464 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301465 cur_len += len;
1466 if(TRUE == pAdapter->isTruncated)
1467 {
1468 /*result is truncated return rest of scan rsp in next req*/
1469 cur_len = rem_len;
1470 break;
1471 }
1472 pPrev = pHead;
1473 pHead = pHead->pNext;
1474 pAdapter->pBatchScanRsp = pHead;
1475 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1476 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001477 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301478 }
1479
1480 return cur_len;
1481}/*End of hdd_populate_user_batch_scan_rsp*/
1482
1483/**---------------------------------------------------------------------------
1484
1485 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1486 scan response data from HDD queue to user space
1487 It does following in detail:
1488 a) if HDD has enough data in its queue then it 1st copies data to user
1489 space and then send get batch scan indication message to FW. In this
1490 case it does not wait on any event and batch scan response data will
1491 be populated in HDD response queue in MC thread context after receiving
1492 indication from FW
1493 b) else send get batch scan indication message to FW and wait on an event
1494 which will be set once HDD receives complete batch scan response from
1495 FW and then this function returns batch scan response to user space
1496
1497 \param - pAdapter Pointer to HDD adapter
1498 \param - pPrivData Pointer to priv_data
1499
1500 \return - 0 for success -EFAULT for failure
1501
1502 --------------------------------------------------------------------------*/
1503
1504int hdd_return_batch_scan_rsp_to_user
1505(
1506 hdd_adapter_t* pAdapter,
1507 hdd_priv_data_t *pPrivData,
1508 tANI_U8 *command
1509)
1510{
1511 tANI_U8 *pDest;
1512 tANI_U32 count = 0;
1513 tANI_U32 len = 0;
1514 tANI_U32 cur_len = 0;
1515 tANI_U32 rem_len = 0;
1516 eHalStatus halStatus;
1517 unsigned long rc;
1518 tSirTriggerBatchScanResultInd *pReq;
1519
1520 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1521 pReq->param = 0;/*batch scan client*/
1522 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1523 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1524
1525 cur_len = pPrivData->used_len;
1526 if (pPrivData->total_len > pPrivData->used_len)
1527 {
1528 rem_len = pPrivData->total_len - pPrivData->used_len;
1529 }
1530 else
1531 {
1532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1533 "%s: Invalid user data buffer total_len %d used_len %d",
1534 __func__, pPrivData->total_len, pPrivData->used_len);
1535 return -EFAULT;
1536 }
1537
1538 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1539 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1540 cur_len, rem_len);
1541 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1542
1543 /*enough scan result available in cache to return to user space or
1544 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001545 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301546 {
1547 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1548 halStatus = sme_TriggerBatchScanResultInd(
1549 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1550 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1551 pAdapter);
1552 if ( eHAL_STATUS_SUCCESS == halStatus )
1553 {
1554 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1555 {
1556 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1557 rc = wait_for_completion_timeout(
1558 &pAdapter->hdd_get_batch_scan_req_var,
1559 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1560 if (0 == rc)
1561 {
1562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1563 "%s: Timeout waiting to fetch batch scan rsp from fw",
1564 __func__);
1565 return -EFAULT;
1566 }
1567 }
1568
1569 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001570 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301571 pDest += len;
1572 cur_len += len;
1573
1574 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1575 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1576 cur_len, rem_len);
1577 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1578
1579 count = 0;
1580 len = (len - pPrivData->used_len);
1581 pDest = (command + pPrivData->used_len);
1582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001583 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301584 while(count < len)
1585 {
1586 printk("%c", *(pDest + count));
1587 count++;
1588 }
1589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1590 "%s: copy %d data to user buffer", __func__, len);
1591 if (copy_to_user(pPrivData->buf, pDest, len))
1592 {
1593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1594 "%s: failed to copy data to user buffer", __func__);
1595 return -EFAULT;
1596 }
1597 }
1598 else
1599 {
1600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1601 "sme_GetBatchScanScan returned failure halStatus %d",
1602 halStatus);
1603 return -EINVAL;
1604 }
1605 }
1606 else
1607 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301608 count = 0;
1609 len = (len - pPrivData->used_len);
1610 pDest = (command + pPrivData->used_len);
1611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001612 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301613 while(count < len)
1614 {
1615 printk("%c", *(pDest + count));
1616 count++;
1617 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1619 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301620 if (copy_to_user(pPrivData->buf, pDest, len))
1621 {
1622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1623 "%s: failed to copy data to user buffer", __func__);
1624 return -EFAULT;
1625 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301626 }
1627
1628 return 0;
1629} /*End of hdd_return_batch_scan_rsp_to_user*/
1630
Rajeev Kumar8b373292014-01-08 20:36:55 -08001631
1632/**---------------------------------------------------------------------------
1633
1634 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1635 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1636 WLS_BATCHING VERSION
1637 WLS_BATCHING SET
1638 WLS_BATCHING GET
1639 WLS_BATCHING STOP
1640
1641 \param - pAdapter Pointer to HDD adapter
1642 \param - pPrivdata Pointer to priv_data
1643 \param - command Pointer to command
1644
1645 \return - 0 for success -EFAULT for failure
1646
1647 --------------------------------------------------------------------------*/
1648
1649int hdd_handle_batch_scan_ioctl
1650(
1651 hdd_adapter_t *pAdapter,
1652 hdd_priv_data_t *pPrivdata,
1653 tANI_U8 *command
1654)
1655{
1656 int ret = 0;
1657
1658 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1659 {
1660 char extra[32];
1661 tANI_U8 len = 0;
1662 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1663
1664 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1665 {
1666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1667 "%s: Batch scan feature is not supported by FW", __func__);
1668 ret = -EINVAL;
1669 goto exit;
1670 }
1671
1672 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1673 version);
1674 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1675 {
1676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1677 "%s: failed to copy data to user buffer", __func__);
1678 ret = -EFAULT;
1679 goto exit;
1680 }
1681 ret = HDD_BATCH_SCAN_VERSION;
1682 }
1683 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1684 {
1685 int status;
1686 tANI_U8 *value = (command + 16);
1687 eHalStatus halStatus;
1688 unsigned long rc;
1689 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1690 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1691
1692 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1693 {
1694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1695 "%s: Batch scan feature is not supported by FW", __func__);
1696 ret = -EINVAL;
1697 goto exit;
1698 }
1699
1700 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1701 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1702 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1703 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1704 {
1705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1706 "Received WLS_BATCHING SET command in invalid mode %d "
1707 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
1708 pAdapter->device_mode);
1709 ret = -EINVAL;
1710 goto exit;
1711 }
1712
1713 status = hdd_parse_set_batchscan_command(value, pReq);
1714 if (status)
1715 {
1716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1717 "Invalid WLS_BATCHING SET command");
1718 ret = -EINVAL;
1719 goto exit;
1720 }
1721
1722
1723 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1724 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1725 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1726 pAdapter);
1727
1728 if ( eHAL_STATUS_SUCCESS == halStatus )
1729 {
1730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1731 "sme_SetBatchScanReq returned success halStatus %d",
1732 halStatus);
1733 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1734 {
1735 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1736 rc = wait_for_completion_timeout(
1737 &pAdapter->hdd_set_batch_scan_req_var,
1738 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1739 if (0 == rc)
1740 {
1741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1742 "%s: Timeout waiting for set batch scan to complete",
1743 __func__);
1744 ret = -EINVAL;
1745 goto exit;
1746 }
1747 }
1748 if ( !pRsp->nScansToBatch )
1749 {
1750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1751 "%s: Received set batch scan failure response from FW",
1752 __func__);
1753 ret = -EINVAL;
1754 goto exit;
1755 }
1756 /*As per the Batch Scan Framework API we should return the MIN of
1757 either MSCAN or the max # of scans firmware can cache*/
1758 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
1759
1760 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1761
1762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1763 "%s: request MSCAN %d response MSCAN %d ret %d",
1764 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
1765 }
1766 else
1767 {
1768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1769 "sme_SetBatchScanReq returned failure halStatus %d",
1770 halStatus);
1771 ret = -EINVAL;
1772 goto exit;
1773 }
1774 }
1775 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1776 {
1777 eHalStatus halStatus;
1778 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1779 pInd->param = 0;
1780
1781 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1782 {
1783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1784 "%s: Batch scan feature is not supported by FW", __func__);
1785 ret = -EINVAL;
1786 goto exit;
1787 }
1788
1789 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1790 {
1791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1792 "Batch scan is not yet enabled batch scan state %d",
1793 pAdapter->batchScanState);
1794 ret = -EINVAL;
1795 goto exit;
1796 }
1797
1798 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1799
1800 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1801 pAdapter->sessionId);
1802 if ( eHAL_STATUS_SUCCESS == halStatus )
1803 {
1804 ret = 0;
1805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1806 "sme_StopBatchScanInd returned success halStatus %d",
1807 halStatus);
1808 }
1809 else
1810 {
1811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1812 "sme_StopBatchScanInd returned failure halStatus %d",
1813 halStatus);
1814 ret = -EINVAL;
1815 goto exit;
1816 }
1817 }
1818 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1819 {
1820 tANI_U32 remain_len;
1821
1822 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1823 {
1824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1825 "%s: Batch scan feature is not supported by FW", __func__);
1826 ret = -EINVAL;
1827 goto exit;
1828 }
1829
1830 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1831 {
1832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1833 "Batch scan is not yet enabled could not return results"
1834 "Batch Scan state %d",
1835 pAdapter->batchScanState);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839
1840 pPrivdata->used_len = 16;
1841 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1842 if (remain_len < pPrivdata->total_len)
1843 {
1844 /*Clear previous batch scan response data if any*/
1845 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1846 }
1847 else
1848 {
1849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1850 "Invalid total length from user space can't fetch batch"
1851 " scan response total_len %d used_len %d remain len %d",
1852 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1853 ret = -EINVAL;
1854 goto exit;
1855 }
1856 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1857 }
1858
1859exit:
1860
1861 return ret;
1862}
1863
1864
Rajeev79dbe4c2013-10-05 11:03:42 +05301865#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1866
Jeff Johnson295189b2012-06-20 16:38:30 -07001867int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1868{
1869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1870 hdd_priv_data_t priv_data;
1871 tANI_U8 *command = NULL;
1872 int ret = 0;
1873
1874 if (NULL == pAdapter)
1875 {
1876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001877 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 ret = -ENODEV;
1879 goto exit;
1880 }
1881
Jeff Johnsone7245742012-09-05 17:12:55 -07001882 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -07001883 {
1884 ret = -EINVAL;
1885 goto exit;
1886 }
1887
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001888 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1889 {
1890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1891 "%s:LOGP in Progress. Ignore!!!", __func__);
1892 ret = -EBUSY;
1893 goto exit;
1894 }
1895
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
1897 {
1898 ret = -EFAULT;
1899 goto exit;
1900 }
1901
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08001902 if (priv_data.total_len <= 0 ||
1903 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001904 {
1905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1906 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1907 priv_data.total_len);
1908 ret = -EINVAL;
1909 goto exit;
1910 }
1911
1912 /* Allocate +1 for '\0' */
1913 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 if (!command)
1915 {
1916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001917 "%s: failed to allocate memory\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001918 ret = -ENOMEM;
1919 goto exit;
1920 }
1921
1922 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1923 {
1924 ret = -EFAULT;
1925 goto exit;
1926 }
1927
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001928 /* Making sure the command is NUL-terminated */
1929 command[priv_data.total_len] = '\0';
1930
Jeff Johnson295189b2012-06-20 16:38:30 -07001931 if ((SIOCDEVPRIVATE + 1) == cmd)
1932 {
1933 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1934
1935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07001936 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07001937
1938 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
1939 {
1940 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
1941 sizeof(tSirMacAddr)))
1942 {
1943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001944 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001945 ret = -EFAULT;
1946 }
1947 }
Amar Singhal0974e402013-02-12 14:27:46 -08001948 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 {
Amar Singhal0974e402013-02-12 14:27:46 -08001950 tANI_U8 *ptr = command ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 int ret = 0 ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001952
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001954
1955 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08001958 "%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 -07001959 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001960 ret = hdd_setBand_helper(dev, ptr);
1961 }
Kiet Lamf040f472013-11-20 21:15:23 +05301962 else if(strncmp(command, "SETWMMPS", 8) == 0)
1963 {
1964 tANI_U8 *ptr = command;
1965 ret = hdd_wmmps_helper(pAdapter, ptr);
1966 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001967 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
1968 {
1969 char *country_code;
1970
1971 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001972
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001973 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001974 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07001975#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05301976 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07001977#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001978 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
1979 (void *)(tSmeChangeCountryCallback)
1980 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05301981 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001982 if (eHAL_STATUS_SUCCESS == ret)
1983 {
1984 ret = wait_for_completion_interruptible_timeout(
1985 &pAdapter->change_country_code,
1986 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
1987 if (0 >= ret)
1988 {
1989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out",
1990 __func__);
1991 }
1992 }
1993 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07001994 {
1995 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001996 "%s: SME Change Country code fail ret=%d", __func__, ret);
1997 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001998 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001999
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002000 }
2001 /*
2002 command should be a string having format
2003 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2004 */
Amar Singhal0974e402013-02-12 14:27:46 -08002005 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002006 {
Amar Singhal0974e402013-02-12 14:27:46 -08002007 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002008
2009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002010 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002011
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002012 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002013 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002014 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2015 {
2016 int suspend = 0;
2017 tANI_U8 *ptr = (tANI_U8*)command + 15;
2018
2019 suspend = *ptr - '0';
2020 hdd_set_wlan_suspend_mode(suspend);
2021 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002022#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2023 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2024 {
2025 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002026 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002027 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2028 eHalStatus status = eHAL_STATUS_SUCCESS;
2029
2030 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2031 value = value + 15;
2032
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002033 /* Convert the value from ascii to integer */
2034 ret = kstrtos8(value, 10, &rssi);
2035 if (ret < 0)
2036 {
2037 /* If the input value is greater than max value of datatype, then also
2038 kstrtou8 fails */
2039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2040 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002041 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002042 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2043 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2044 ret = -EINVAL;
2045 goto exit;
2046 }
2047
Srinivas Girigowdade697412013-02-14 16:31:48 -08002048 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002049
Srinivas Girigowdade697412013-02-14 16:31:48 -08002050 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2051 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2052 {
2053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2054 "Neighbor lookup threshold value %d is out of range"
2055 " (Min: %d Max: %d)", lookUpThreshold,
2056 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2057 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2058 ret = -EINVAL;
2059 goto exit;
2060 }
2061
2062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2063 "%s: Received Command to Set Roam trigger"
2064 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2065
2066 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2067 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2068 if (eHAL_STATUS_SUCCESS != status)
2069 {
2070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2071 "%s: Failed to set roam trigger, try again", __func__);
2072 ret = -EPERM;
2073 goto exit;
2074 }
2075
2076 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2077 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2078 }
2079 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2080 {
2081 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2082 int rssi = (-1) * lookUpThreshold;
2083 char extra[32];
2084 tANI_U8 len = 0;
2085
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002086 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002087 if (copy_to_user(priv_data.buf, &extra, len + 1))
2088 {
2089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2090 "%s: failed to copy data to user buffer", __func__);
2091 ret = -EFAULT;
2092 goto exit;
2093 }
2094 }
2095 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2096 {
2097 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002098 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002099 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002100
Srinivas Girigowdade697412013-02-14 16:31:48 -08002101 /* input refresh period is in terms of seconds */
2102 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2103 value = value + 18;
2104 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002105 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002106 if (ret < 0)
2107 {
2108 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002109 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002111 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002112 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002113 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2114 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002115 ret = -EINVAL;
2116 goto exit;
2117 }
2118
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002119 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2120 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002121 {
2122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002123 "Roam scan period value %d is out of range"
2124 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002125 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2126 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002127 ret = -EINVAL;
2128 goto exit;
2129 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002130 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002131
2132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2133 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002134 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002135
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002136 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2137 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002138 }
2139 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2140 {
2141 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2142 char extra[32];
2143 tANI_U8 len = 0;
2144
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002145 len = scnprintf(extra, sizeof(extra), "%s %d",
2146 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002147 /* Returned value is in units of seconds */
2148 if (copy_to_user(priv_data.buf, &extra, len + 1))
2149 {
2150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2151 "%s: failed to copy data to user buffer", __func__);
2152 ret = -EFAULT;
2153 goto exit;
2154 }
2155 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002156 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2157 {
2158 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002159 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002160 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002161
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002162 /* input refresh period is in terms of seconds */
2163 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2164 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002165
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002166 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002167 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002168 if (ret < 0)
2169 {
2170 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002171 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002173 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002174 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002175 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2176 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2177 ret = -EINVAL;
2178 goto exit;
2179 }
2180
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002181 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2182 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2183 {
2184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2185 "Neighbor scan results refresh period value %d is out of range"
2186 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2187 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2188 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2189 ret = -EINVAL;
2190 goto exit;
2191 }
2192 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2193
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2195 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002196 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002197
2198 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2199 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2200 }
2201 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2202 {
2203 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2204 char extra[32];
2205 tANI_U8 len = 0;
2206
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002207 len = scnprintf(extra, sizeof(extra), "%s %d",
2208 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002209 /* Returned value is in units of seconds */
2210 if (copy_to_user(priv_data.buf, &extra, len + 1))
2211 {
2212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2213 "%s: failed to copy data to user buffer", __func__);
2214 ret = -EFAULT;
2215 goto exit;
2216 }
2217 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002218#ifdef FEATURE_WLAN_LFR
2219 /* SETROAMMODE */
2220 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2221 {
2222 tANI_U8 *value = command;
2223 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2224
2225 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2226 value = value + SIZE_OF_SETROAMMODE + 1;
2227
2228 /* Convert the value from ascii to integer */
2229 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2230 if (ret < 0)
2231 {
2232 /* If the input value is greater than max value of datatype, then also
2233 kstrtou8 fails */
2234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2235 "%s: kstrtou8 failed range [%d - %d]", __func__,
2236 CFG_LFR_FEATURE_ENABLED_MIN,
2237 CFG_LFR_FEATURE_ENABLED_MAX);
2238 ret = -EINVAL;
2239 goto exit;
2240 }
2241 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2242 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2243 {
2244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2245 "Roam Mode value %d is out of range"
2246 " (Min: %d Max: %d)", roamMode,
2247 CFG_LFR_FEATURE_ENABLED_MIN,
2248 CFG_LFR_FEATURE_ENABLED_MAX);
2249 ret = -EINVAL;
2250 goto exit;
2251 }
2252
2253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2254 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2255 /*
2256 * Note that
2257 * SETROAMMODE 0 is to enable LFR while
2258 * SETROAMMODE 1 is to disable LFR, but
2259 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2260 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2261 */
2262 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2263 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2264 else
2265 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2266
2267 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2268 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2269 }
2270 /* GETROAMMODE */
2271 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2272 {
2273 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2274 char extra[32];
2275 tANI_U8 len = 0;
2276
2277 /*
2278 * roamMode value shall be inverted because the sementics is different.
2279 */
2280 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2281 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2282 else
2283 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2284
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002285 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002286 if (copy_to_user(priv_data.buf, &extra, len + 1))
2287 {
2288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2289 "%s: failed to copy data to user buffer", __func__);
2290 ret = -EFAULT;
2291 goto exit;
2292 }
2293 }
2294#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002295#endif
2296#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2297 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2298 {
2299 tANI_U8 *value = command;
2300 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2301
2302 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2303 value = value + 13;
2304 /* Convert the value from ascii to integer */
2305 ret = kstrtou8(value, 10, &roamRssiDiff);
2306 if (ret < 0)
2307 {
2308 /* If the input value is greater than max value of datatype, then also
2309 kstrtou8 fails */
2310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2311 "%s: kstrtou8 failed range [%d - %d]", __func__,
2312 CFG_ROAM_RSSI_DIFF_MIN,
2313 CFG_ROAM_RSSI_DIFF_MAX);
2314 ret = -EINVAL;
2315 goto exit;
2316 }
2317
2318 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2319 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2320 {
2321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2322 "Roam rssi diff value %d is out of range"
2323 " (Min: %d Max: %d)", roamRssiDiff,
2324 CFG_ROAM_RSSI_DIFF_MIN,
2325 CFG_ROAM_RSSI_DIFF_MAX);
2326 ret = -EINVAL;
2327 goto exit;
2328 }
2329
2330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2331 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2332
2333 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2334 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2335 }
2336 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2337 {
2338 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2339 char extra[32];
2340 tANI_U8 len = 0;
2341
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002342 len = scnprintf(extra, sizeof(extra), "%s %d",
2343 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002344 if (copy_to_user(priv_data.buf, &extra, len + 1))
2345 {
2346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2347 "%s: failed to copy data to user buffer", __func__);
2348 ret = -EFAULT;
2349 goto exit;
2350 }
2351 }
2352#endif
2353#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2354 else if (strncmp(command, "GETBAND", 7) == 0)
2355 {
2356 int band = -1;
2357 char extra[32];
2358 tANI_U8 len = 0;
2359 hdd_getBand_helper(pHddCtx, &band);
2360
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002361 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002362 if (copy_to_user(priv_data.buf, &extra, len + 1))
2363 {
2364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2365 "%s: failed to copy data to user buffer", __func__);
2366 ret = -EFAULT;
2367 goto exit;
2368 }
2369 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002370 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2371 {
2372 tANI_U8 *value = command;
2373 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2374 tANI_U8 numChannels = 0;
2375 eHalStatus status = eHAL_STATUS_SUCCESS;
2376
2377 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2378 if (eHAL_STATUS_SUCCESS != status)
2379 {
2380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2381 "%s: Failed to parse channel list information", __func__);
2382 ret = -EINVAL;
2383 goto exit;
2384 }
2385
2386 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2387 {
2388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2389 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2390 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2391 ret = -EINVAL;
2392 goto exit;
2393 }
2394 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2395 numChannels);
2396 if (eHAL_STATUS_SUCCESS != status)
2397 {
2398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2399 "%s: Failed to update channel list information", __func__);
2400 ret = -EINVAL;
2401 goto exit;
2402 }
2403 }
2404 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2405 {
2406 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2407 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002408 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002409 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002410 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002411
2412 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2413 ChannelList, &numChannels ))
2414 {
2415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2416 "%s: failed to get roam scan channel list", __func__);
2417 ret = -EFAULT;
2418 goto exit;
2419 }
2420 /* output channel list is of the format
2421 [Number of roam scan channels][Channel1][Channel2]... */
2422 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002423 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002424 for (j = 0; (j < numChannels); j++)
2425 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002426 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2427 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002428 }
2429
2430 if (copy_to_user(priv_data.buf, &extra, len + 1))
2431 {
2432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2433 "%s: failed to copy data to user buffer", __func__);
2434 ret = -EFAULT;
2435 goto exit;
2436 }
2437 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002438 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2439 {
2440 tANI_BOOLEAN ccxMode = sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2441 char extra[32];
2442 tANI_U8 len = 0;
2443
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002444 /* Check if the features OKC/CCX/11R are supported simultaneously,
2445 then this operation is not permitted (return FAILURE) */
2446 if (ccxMode &&
2447 hdd_is_okc_mode_enabled(pHddCtx) &&
2448 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2449 {
2450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2451 "%s: OKC/CCX/11R are supported simultaneously"
2452 " hence this operation is not permitted!", __func__);
2453 ret = -EPERM;
2454 goto exit;
2455 }
2456
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002457 len = scnprintf(extra, sizeof(extra), "%s %d",
2458 "GETCCXMODE", ccxMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002459 if (copy_to_user(priv_data.buf, &extra, len + 1))
2460 {
2461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2462 "%s: failed to copy data to user buffer", __func__);
2463 ret = -EFAULT;
2464 goto exit;
2465 }
2466 }
2467 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2468 {
2469 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2470 char extra[32];
2471 tANI_U8 len = 0;
2472
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002473 /* Check if the features OKC/CCX/11R are supported simultaneously,
2474 then this operation is not permitted (return FAILURE) */
2475 if (okcMode &&
2476 sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
2477 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2478 {
2479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2480 "%s: OKC/CCX/11R are supported simultaneously"
2481 " hence this operation is not permitted!", __func__);
2482 ret = -EPERM;
2483 goto exit;
2484 }
2485
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002486 len = scnprintf(extra, sizeof(extra), "%s %d",
2487 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002488 if (copy_to_user(priv_data.buf, &extra, len + 1))
2489 {
2490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2491 "%s: failed to copy data to user buffer", __func__);
2492 ret = -EFAULT;
2493 goto exit;
2494 }
2495 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002497 {
2498 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2499 char extra[32];
2500 tANI_U8 len = 0;
2501
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002502 len = scnprintf(extra, sizeof(extra), "%s %d",
2503 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002504 if (copy_to_user(priv_data.buf, &extra, len + 1))
2505 {
2506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2507 "%s: failed to copy data to user buffer", __func__);
2508 ret = -EFAULT;
2509 goto exit;
2510 }
2511 }
2512 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2513 {
2514 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2515 char extra[32];
2516 tANI_U8 len = 0;
2517
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002518 len = scnprintf(extra, sizeof(extra), "%s %d",
2519 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002520 if (copy_to_user(priv_data.buf, &extra, len + 1))
2521 {
2522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2523 "%s: failed to copy data to user buffer", __func__);
2524 ret = -EFAULT;
2525 goto exit;
2526 }
2527 }
2528 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2529 {
2530 tANI_U8 *value = command;
2531 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2532
2533 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2534 value = value + 26;
2535 /* Convert the value from ascii to integer */
2536 ret = kstrtou8(value, 10, &minTime);
2537 if (ret < 0)
2538 {
2539 /* If the input value is greater than max value of datatype, then also
2540 kstrtou8 fails */
2541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2542 "%s: kstrtou8 failed range [%d - %d]", __func__,
2543 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2544 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2545 ret = -EINVAL;
2546 goto exit;
2547 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002548 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2549 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2550 {
2551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2552 "scan min channel time value %d is out of range"
2553 " (Min: %d Max: %d)", minTime,
2554 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2555 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2556 ret = -EINVAL;
2557 goto exit;
2558 }
2559
2560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2561 "%s: Received Command to change channel min time = %d", __func__, minTime);
2562
2563 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2564 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2565 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002566 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2567 {
2568 tANI_U8 *value = command;
2569 tANI_U8 channel = 0;
2570 tANI_U8 dwellTime = 0;
2571 tANI_U8 bufLen = 0;
2572 tANI_U8 *buf = NULL;
2573 tSirMacAddr targetApBssid;
2574 eHalStatus status = eHAL_STATUS_SUCCESS;
2575 struct ieee80211_channel chan;
2576 tANI_U8 finalLen = 0;
2577 tANI_U8 *finalBuf = NULL;
2578 tANI_U8 temp = 0;
2579 u64 cookie;
2580 hdd_station_ctx_t *pHddStaCtx = NULL;
2581 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2582
2583 /* if not associated, no need to send action frame */
2584 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2585 {
2586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2587 ret = -EINVAL;
2588 goto exit;
2589 }
2590
2591 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2592 &dwellTime, &buf, &bufLen);
2593 if (eHAL_STATUS_SUCCESS != status)
2594 {
2595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2596 "%s: Failed to parse send action frame data", __func__);
2597 ret = -EINVAL;
2598 goto exit;
2599 }
2600
2601 /* if the target bssid is different from currently associated AP,
2602 then no need to send action frame */
2603 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2604 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2605 {
2606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2607 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002608 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002609 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002610 goto exit;
2611 }
2612
2613 /* if the channel number is different from operating channel then
2614 no need to send action frame */
2615 if (channel != pHddStaCtx->conn_info.operationChannel)
2616 {
2617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2618 "%s: channel(%d) is different from operating channel(%d)",
2619 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2620 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002621 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002622 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002623 goto exit;
2624 }
2625 chan.center_freq = sme_ChnToFreq(channel);
2626
2627 finalLen = bufLen + 24;
2628 finalBuf = vos_mem_malloc(finalLen);
2629 if (NULL == finalBuf)
2630 {
2631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2632 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002633 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002634 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002635 goto exit;
2636 }
2637 vos_mem_zero(finalBuf, finalLen);
2638
2639 /* Fill subtype */
2640 temp = SIR_MAC_MGMT_ACTION << 4;
2641 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2642
2643 /* Fill type */
2644 temp = SIR_MAC_MGMT_FRAME;
2645 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2646
2647 /* Fill destination address (bssid of the AP) */
2648 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2649
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002650 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002651 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2652
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002653 /* Fill BSSID (AP mac address) */
2654 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002655
2656 /* Fill received buffer from 24th address */
2657 vos_mem_copy(finalBuf + 24, buf, bufLen);
2658
Jeff Johnson11c33152013-04-16 17:52:40 -07002659 /* done with the parsed buffer */
2660 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002661 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002662
Yue Maf49ba872013-08-19 12:04:25 -07002663 wlan_hdd_action( NULL,
2664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2665 &(pAdapter->wdev),
2666#else
2667 dev,
2668#endif
2669 &chan, 0,
2670#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2671 NL80211_CHAN_HT20, 1,
2672#endif
2673 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002674 1, &cookie );
2675 vos_mem_free(finalBuf);
2676 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002677 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2678 {
2679 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2680 char extra[32];
2681 tANI_U8 len = 0;
2682
2683 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002684 len = scnprintf(extra, sizeof(extra), "%s %d",
2685 "GETROAMSCANCHANNELMINTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002686 if (copy_to_user(priv_data.buf, &extra, len + 1))
2687 {
2688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2689 "%s: failed to copy data to user buffer", __func__);
2690 ret = -EFAULT;
2691 goto exit;
2692 }
2693 }
2694 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2695 {
2696 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002697 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002698
2699 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2700 value = value + 19;
2701 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002702 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002703 if (ret < 0)
2704 {
2705 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002706 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002708 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002709 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2710 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2711 ret = -EINVAL;
2712 goto exit;
2713 }
2714
2715 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2716 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2717 {
2718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2719 "lfr mode value %d is out of range"
2720 " (Min: %d Max: %d)", maxTime,
2721 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2722 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2723 ret = -EINVAL;
2724 goto exit;
2725 }
2726
2727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2728 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2729
2730 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2731 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2732 }
2733 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2734 {
2735 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2736 char extra[32];
2737 tANI_U8 len = 0;
2738
2739 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002740 len = scnprintf(extra, sizeof(extra), "%s %d",
2741 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002742 if (copy_to_user(priv_data.buf, &extra, len + 1))
2743 {
2744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2745 "%s: failed to copy data to user buffer", __func__);
2746 ret = -EFAULT;
2747 goto exit;
2748 }
2749 }
2750 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2751 {
2752 tANI_U8 *value = command;
2753 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2754
2755 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2756 value = value + 16;
2757 /* Convert the value from ascii to integer */
2758 ret = kstrtou16(value, 10, &val);
2759 if (ret < 0)
2760 {
2761 /* If the input value is greater than max value of datatype, then also
2762 kstrtou16 fails */
2763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2764 "%s: kstrtou16 failed range [%d - %d]", __func__,
2765 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2766 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2767 ret = -EINVAL;
2768 goto exit;
2769 }
2770
2771 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2772 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2773 {
2774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2775 "scan home time value %d is out of range"
2776 " (Min: %d Max: %d)", val,
2777 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2778 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2779 ret = -EINVAL;
2780 goto exit;
2781 }
2782
2783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2784 "%s: Received Command to change scan home time = %d", __func__, val);
2785
2786 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2787 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2788 }
2789 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2790 {
2791 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2792 char extra[32];
2793 tANI_U8 len = 0;
2794
2795 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002796 len = scnprintf(extra, sizeof(extra), "%s %d",
2797 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002798 if (copy_to_user(priv_data.buf, &extra, len + 1))
2799 {
2800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2801 "%s: failed to copy data to user buffer", __func__);
2802 ret = -EFAULT;
2803 goto exit;
2804 }
2805 }
2806 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2807 {
2808 tANI_U8 *value = command;
2809 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2810
2811 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2812 value = value + 17;
2813 /* Convert the value from ascii to integer */
2814 ret = kstrtou8(value, 10, &val);
2815 if (ret < 0)
2816 {
2817 /* If the input value is greater than max value of datatype, then also
2818 kstrtou8 fails */
2819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2820 "%s: kstrtou8 failed range [%d - %d]", __func__,
2821 CFG_ROAM_INTRA_BAND_MIN,
2822 CFG_ROAM_INTRA_BAND_MAX);
2823 ret = -EINVAL;
2824 goto exit;
2825 }
2826
2827 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2828 (val > CFG_ROAM_INTRA_BAND_MAX))
2829 {
2830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2831 "intra band mode value %d is out of range"
2832 " (Min: %d Max: %d)", val,
2833 CFG_ROAM_INTRA_BAND_MIN,
2834 CFG_ROAM_INTRA_BAND_MAX);
2835 ret = -EINVAL;
2836 goto exit;
2837 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2839 "%s: Received Command to change intra band = %d", __func__, val);
2840
2841 pHddCtx->cfg_ini->nRoamIntraBand = val;
2842 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2843 }
2844 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2845 {
2846 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2847 char extra[32];
2848 tANI_U8 len = 0;
2849
2850 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002851 len = scnprintf(extra, sizeof(extra), "%s %d",
2852 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002853 if (copy_to_user(priv_data.buf, &extra, len + 1))
2854 {
2855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: failed to copy data to user buffer", __func__);
2857 ret = -EFAULT;
2858 goto exit;
2859 }
2860 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002861 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2862 {
2863 tANI_U8 *value = command;
2864 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2865
2866 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2867 value = value + 15;
2868 /* Convert the value from ascii to integer */
2869 ret = kstrtou8(value, 10, &nProbes);
2870 if (ret < 0)
2871 {
2872 /* If the input value is greater than max value of datatype, then also
2873 kstrtou8 fails */
2874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2875 "%s: kstrtou8 failed range [%d - %d]", __func__,
2876 CFG_ROAM_SCAN_N_PROBES_MIN,
2877 CFG_ROAM_SCAN_N_PROBES_MAX);
2878 ret = -EINVAL;
2879 goto exit;
2880 }
2881
2882 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2883 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2884 {
2885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2886 "NProbes value %d is out of range"
2887 " (Min: %d Max: %d)", nProbes,
2888 CFG_ROAM_SCAN_N_PROBES_MIN,
2889 CFG_ROAM_SCAN_N_PROBES_MAX);
2890 ret = -EINVAL;
2891 goto exit;
2892 }
2893
2894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2895 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
2896
2897 pHddCtx->cfg_ini->nProbes = nProbes;
2898 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
2899 }
2900 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
2901 {
2902 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
2903 char extra[32];
2904 tANI_U8 len = 0;
2905
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002906 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002907 if (copy_to_user(priv_data.buf, &extra, len + 1))
2908 {
2909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2910 "%s: failed to copy data to user buffer", __func__);
2911 ret = -EFAULT;
2912 goto exit;
2913 }
2914 }
2915 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
2916 {
2917 tANI_U8 *value = command;
2918 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
2919
2920 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
2921 /* input value is in units of msec */
2922 value = value + 20;
2923 /* Convert the value from ascii to integer */
2924 ret = kstrtou16(value, 10, &homeAwayTime);
2925 if (ret < 0)
2926 {
2927 /* If the input value is greater than max value of datatype, then also
2928 kstrtou8 fails */
2929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2930 "%s: kstrtou8 failed range [%d - %d]", __func__,
2931 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2932 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2933 ret = -EINVAL;
2934 goto exit;
2935 }
2936
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002937 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
2938 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
2939 {
2940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2941 "homeAwayTime value %d is out of range"
2942 " (Min: %d Max: %d)", homeAwayTime,
2943 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2944 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2945 ret = -EINVAL;
2946 goto exit;
2947 }
2948
2949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2950 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07002951 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
2952 {
2953 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
2954 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
2955 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002956 }
2957 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
2958 {
2959 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
2960 char extra[32];
2961 tANI_U8 len = 0;
2962
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002963 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002964 if (copy_to_user(priv_data.buf, &extra, len + 1))
2965 {
2966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2967 "%s: failed to copy data to user buffer", __func__);
2968 ret = -EFAULT;
2969 goto exit;
2970 }
2971 }
2972 else if (strncmp(command, "REASSOC", 7) == 0)
2973 {
2974 tANI_U8 *value = command;
2975 tANI_U8 channel = 0;
2976 tSirMacAddr targetApBssid;
2977 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07002978#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
2979 tCsrHandoffRequest handoffInfo;
2980#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002981 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002982 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2983
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002984 /* if not associated, no need to proceed with reassoc */
2985 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2986 {
2987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2988 ret = -EINVAL;
2989 goto exit;
2990 }
2991
2992 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
2993 if (eHAL_STATUS_SUCCESS != status)
2994 {
2995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2996 "%s: Failed to parse reassoc command data", __func__);
2997 ret = -EINVAL;
2998 goto exit;
2999 }
3000
3001 /* if the target bssid is same as currently associated AP,
3002 then no need to proceed with reassoc */
3003 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3004 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3005 {
3006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3007 ret = -EINVAL;
3008 goto exit;
3009 }
3010
3011 /* Check channel number is a valid channel number */
3012 if(VOS_STATUS_SUCCESS !=
3013 wlan_hdd_validate_operation_channel(pAdapter, channel))
3014 {
3015 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003016 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003017 return -EINVAL;
3018 }
3019
3020 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003021#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3022 handoffInfo.channel = channel;
3023 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3024 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3025#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003026 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003027 else if (strncmp(command, "SETWESMODE", 10) == 0)
3028 {
3029 tANI_U8 *value = command;
3030 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3031
3032 /* Move pointer to ahead of SETWESMODE<delimiter> */
3033 value = value + 11;
3034 /* Convert the value from ascii to integer */
3035 ret = kstrtou8(value, 10, &wesMode);
3036 if (ret < 0)
3037 {
3038 /* If the input value is greater than max value of datatype, then also
3039 kstrtou8 fails */
3040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3041 "%s: kstrtou8 failed range [%d - %d]", __func__,
3042 CFG_ENABLE_WES_MODE_NAME_MIN,
3043 CFG_ENABLE_WES_MODE_NAME_MAX);
3044 ret = -EINVAL;
3045 goto exit;
3046 }
3047
3048 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3049 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3050 {
3051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3052 "WES Mode value %d is out of range"
3053 " (Min: %d Max: %d)", wesMode,
3054 CFG_ENABLE_WES_MODE_NAME_MIN,
3055 CFG_ENABLE_WES_MODE_NAME_MAX);
3056 ret = -EINVAL;
3057 goto exit;
3058 }
3059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3060 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3061
3062 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3063 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3064 }
3065 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3066 {
3067 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3068 char extra[32];
3069 tANI_U8 len = 0;
3070
Arif Hussain826d9412013-11-12 16:44:54 -08003071 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003072 if (copy_to_user(priv_data.buf, &extra, len + 1))
3073 {
3074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3075 "%s: failed to copy data to user buffer", __func__);
3076 ret = -EFAULT;
3077 goto exit;
3078 }
3079 }
3080#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_CCX || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003081#ifdef FEATURE_WLAN_LFR
3082 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3083 {
3084 tANI_U8 *value = command;
3085 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3086
3087 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3088 value = value + 12;
3089 /* Convert the value from ascii to integer */
3090 ret = kstrtou8(value, 10, &lfrMode);
3091 if (ret < 0)
3092 {
3093 /* If the input value is greater than max value of datatype, then also
3094 kstrtou8 fails */
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3096 "%s: kstrtou8 failed range [%d - %d]", __func__,
3097 CFG_LFR_FEATURE_ENABLED_MIN,
3098 CFG_LFR_FEATURE_ENABLED_MAX);
3099 ret = -EINVAL;
3100 goto exit;
3101 }
3102
3103 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3104 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3105 {
3106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3107 "lfr mode value %d is out of range"
3108 " (Min: %d Max: %d)", lfrMode,
3109 CFG_LFR_FEATURE_ENABLED_MIN,
3110 CFG_LFR_FEATURE_ENABLED_MAX);
3111 ret = -EINVAL;
3112 goto exit;
3113 }
3114
3115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3116 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3117
3118 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3119 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3120 }
3121#endif
3122#ifdef WLAN_FEATURE_VOWIFI_11R
3123 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3124 {
3125 tANI_U8 *value = command;
3126 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3127
3128 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3129 value = value + 18;
3130 /* Convert the value from ascii to integer */
3131 ret = kstrtou8(value, 10, &ft);
3132 if (ret < 0)
3133 {
3134 /* If the input value is greater than max value of datatype, then also
3135 kstrtou8 fails */
3136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3137 "%s: kstrtou8 failed range [%d - %d]", __func__,
3138 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3139 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3140 ret = -EINVAL;
3141 goto exit;
3142 }
3143
3144 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3145 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3146 {
3147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3148 "ft mode value %d is out of range"
3149 " (Min: %d Max: %d)", ft,
3150 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3151 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3152 ret = -EINVAL;
3153 goto exit;
3154 }
3155
3156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3157 "%s: Received Command to change ft mode = %d", __func__, ft);
3158
3159 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3160 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3161 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303162
3163 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3164 {
3165 tANI_U8 *value = command;
3166 tSirMacAddr targetApBssid;
3167 tANI_U8 trigger = 0;
3168 eHalStatus status = eHAL_STATUS_SUCCESS;
3169 hdd_station_ctx_t *pHddStaCtx = NULL;
3170 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3171
3172 /* if not associated, no need to proceed with reassoc */
3173 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3174 {
3175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3176 ret = -EINVAL;
3177 goto exit;
3178 }
3179
3180 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3181 if (eHAL_STATUS_SUCCESS != status)
3182 {
3183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3184 "%s: Failed to parse reassoc command data", __func__);
3185 ret = -EINVAL;
3186 goto exit;
3187 }
3188
3189 /* if the target bssid is same as currently associated AP,
3190 then no need to proceed with reassoc */
3191 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3192 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3193 {
3194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3195 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3196 __func__);
3197 ret = -EINVAL;
3198 goto exit;
3199 }
3200
3201 /* Proceed with scan/roam */
3202 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3203 &targetApBssid[0],
3204 (tSmeFastRoamTrigger)(trigger));
3205 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003206#endif
3207#ifdef FEATURE_WLAN_CCX
3208 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3209 {
3210 tANI_U8 *value = command;
3211 tANI_U8 ccxMode = CFG_CCX_FEATURE_ENABLED_DEFAULT;
3212
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003213 /* Check if the features OKC/CCX/11R are supported simultaneously,
3214 then this operation is not permitted (return FAILURE) */
3215 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
3216 hdd_is_okc_mode_enabled(pHddCtx) &&
3217 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3218 {
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
3220 "%s: OKC/CCX/11R are supported simultaneously"
3221 " hence this operation is not permitted!", __func__);
3222 ret = -EPERM;
3223 goto exit;
3224 }
3225
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003226 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3227 value = value + 11;
3228 /* Convert the value from ascii to integer */
3229 ret = kstrtou8(value, 10, &ccxMode);
3230 if (ret < 0)
3231 {
3232 /* If the input value is greater than max value of datatype, then also
3233 kstrtou8 fails */
3234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3235 "%s: kstrtou8 failed range [%d - %d]", __func__,
3236 CFG_CCX_FEATURE_ENABLED_MIN,
3237 CFG_CCX_FEATURE_ENABLED_MAX);
3238 ret = -EINVAL;
3239 goto exit;
3240 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003241 if ((ccxMode < CFG_CCX_FEATURE_ENABLED_MIN) ||
3242 (ccxMode > CFG_CCX_FEATURE_ENABLED_MAX))
3243 {
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3245 "Ccx mode value %d is out of range"
3246 " (Min: %d Max: %d)", ccxMode,
3247 CFG_CCX_FEATURE_ENABLED_MIN,
3248 CFG_CCX_FEATURE_ENABLED_MAX);
3249 ret = -EINVAL;
3250 goto exit;
3251 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3253 "%s: Received Command to change ccx mode = %d", __func__, ccxMode);
3254
3255 pHddCtx->cfg_ini->isCcxIniFeatureEnabled = ccxMode;
3256 sme_UpdateIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal), ccxMode);
3257 }
3258#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003259 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3260 {
3261 tANI_U8 *value = command;
3262 tANI_BOOLEAN roamScanControl = 0;
3263
3264 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3265 value = value + 19;
3266 /* Convert the value from ascii to integer */
3267 ret = kstrtou8(value, 10, &roamScanControl);
3268 if (ret < 0)
3269 {
3270 /* If the input value is greater than max value of datatype, then also
3271 kstrtou8 fails */
3272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3273 "%s: kstrtou8 failed ", __func__);
3274 ret = -EINVAL;
3275 goto exit;
3276 }
3277
3278 if (0 != roamScanControl)
3279 {
3280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "roam scan control invalid value = %d",
3282 roamScanControl);
3283 ret = -EINVAL;
3284 goto exit;
3285 }
3286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3287 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3288
3289 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3290 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003291#ifdef FEATURE_WLAN_OKC
3292 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3293 {
3294 tANI_U8 *value = command;
3295 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3296
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003297 /* Check if the features OKC/CCX/11R are supported simultaneously,
3298 then this operation is not permitted (return FAILURE) */
3299 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
3300 hdd_is_okc_mode_enabled(pHddCtx) &&
3301 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
3304 "%s: OKC/CCX/11R are supported simultaneously"
3305 " hence this operation is not permitted!", __func__);
3306 ret = -EPERM;
3307 goto exit;
3308 }
3309
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003310 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3311 value = value + 11;
3312 /* Convert the value from ascii to integer */
3313 ret = kstrtou8(value, 10, &okcMode);
3314 if (ret < 0)
3315 {
3316 /* If the input value is greater than max value of datatype, then also
3317 kstrtou8 fails */
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3319 "%s: kstrtou8 failed range [%d - %d]", __func__,
3320 CFG_OKC_FEATURE_ENABLED_MIN,
3321 CFG_OKC_FEATURE_ENABLED_MAX);
3322 ret = -EINVAL;
3323 goto exit;
3324 }
3325
3326 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3327 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3328 {
3329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3330 "Okc mode value %d is out of range"
3331 " (Min: %d Max: %d)", okcMode,
3332 CFG_OKC_FEATURE_ENABLED_MIN,
3333 CFG_OKC_FEATURE_ENABLED_MAX);
3334 ret = -EINVAL;
3335 goto exit;
3336 }
3337
3338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3339 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3340
3341 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3342 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003343#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003344 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3345 {
3346 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3347 char extra[32];
3348 tANI_U8 len = 0;
3349
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003350 len = scnprintf(extra, sizeof(extra), "%s %d",
3351 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003352 if (copy_to_user(priv_data.buf, &extra, len + 1))
3353 {
3354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3355 "%s: failed to copy data to user buffer", __func__);
3356 ret = -EFAULT;
3357 goto exit;
3358 }
3359 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303360#ifdef WLAN_FEATURE_PACKET_FILTERING
3361 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3362 {
3363 tANI_U8 filterType = 0;
3364 tANI_U8 *value = command;
3365
3366 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3367 value = value + 22;
3368
3369 /* Convert the value from ascii to integer */
3370 ret = kstrtou8(value, 10, &filterType);
3371 if (ret < 0)
3372 {
3373 /* If the input value is greater than max value of datatype,
3374 * then also kstrtou8 fails
3375 */
3376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3377 "%s: kstrtou8 failed range ", __func__);
3378 ret = -EINVAL;
3379 goto exit;
3380 }
3381
3382 if (filterType != 0 && filterType != 1)
3383 {
3384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3385 "%s: Accepted Values are 0 and 1 ", __func__);
3386 ret = -EINVAL;
3387 goto exit;
3388 }
3389 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3390 pAdapter->sessionId);
3391 }
3392#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303393 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3394 {
3395 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303396 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303397 if ('1' == *dhcpPhase)
3398 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3400 FL("BTCOEXMODE %d"), *dhcpPhase);
3401
3402 pHddCtx->btCoexModeSet = TRUE;
3403
3404 /* Firmware failing to process DHCP START/STOP indications.
3405 * So, for now commentig below code, once issue is resolved,
3406 * follwing will be uncommented.
3407 */
3408 #if 0
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303409 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3410 pAdapter->macAddressCurrent.bytes);
c_hpothu9b781ba2013-12-30 20:57:45 +05303411 #endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303412 }
3413 else if ('2' == *dhcpPhase)
3414 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3416 FL("BTCOEXMODE %d"), *dhcpPhase);
3417
3418 pHddCtx->btCoexModeSet = FALSE;
3419
3420 /* Firmware failing to process DHCP START/STOP indications.
3421 * So, for now commentig below code, once issue is resolved,
3422 * follwing will be uncommented.
3423 */
3424 #if 0
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303425 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3426 pAdapter->macAddressCurrent.bytes);
c_hpothu9b781ba2013-12-30 20:57:45 +05303427 #endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303428 }
3429 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003430 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3431 {
3432 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
3433 }
3434 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3435 {
3436 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
3437 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303438 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3439 {
3440 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3441 char extra[32];
3442 tANI_U8 len = 0;
3443
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003444 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303445 (int)pCfg->nActiveMaxChnTime);
3446 if (copy_to_user(priv_data.buf, &extra, len + 1))
3447 {
3448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3449 "%s: failed to copy data to user buffer", __func__);
3450 ret = -EFAULT;
3451 goto exit;
3452 }
3453 ret = len;
3454 }
3455 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3456 {
3457 tANI_U8 *value = command;
3458 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3459 int val = 0, temp;
3460
3461 value = value + 13;
3462 temp = kstrtou32(value, 10, &val);
3463 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3464 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3465 {
3466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3467 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3468 ret = -EFAULT;
3469 goto exit;
3470 }
3471 pCfg->nActiveMaxChnTime = val;
3472 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003473 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3474 {
3475 tANI_U8 filterType = 0;
3476 tANI_U8 *value;
3477 value = command + 9;
3478
3479 /* Convert the value from ascii to integer */
3480 ret = kstrtou8(value, 10, &filterType);
3481 if (ret < 0)
3482 {
3483 /* If the input value is greater than max value of datatype,
3484 * then also kstrtou8 fails
3485 */
3486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3487 "%s: kstrtou8 failed range ", __func__);
3488 ret = -EINVAL;
3489 goto exit;
3490 }
3491 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3492 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3493 {
3494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3495 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3496 " 2-Sink ", __func__);
3497 ret = -EINVAL;
3498 goto exit;
3499 }
3500 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3501 pHddCtx->drvr_miracast = filterType;
3502 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3503 }
Leo Chang614d2072013-08-22 14:59:44 -07003504 else if (strncmp(command, "SETMCRATE", 9) == 0)
3505 {
Leo Chang614d2072013-08-22 14:59:44 -07003506 tANI_U8 *value = command;
3507 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003508 tSirRateUpdateInd *rateUpdate;
3509 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003510
3511 /* Only valid for SAP mode */
3512 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3513 {
3514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3515 "%s: SAP mode is not running", __func__);
3516 ret = -EFAULT;
3517 goto exit;
3518 }
3519
3520 /* Move pointer to ahead of SETMCRATE<delimiter> */
3521 /* input value is in units of hundred kbps */
3522 value = value + 10;
3523 /* Convert the value from ascii to integer, decimal base */
3524 ret = kstrtouint(value, 10, &targetRate);
3525
Leo Chang1f98cbd2013-10-17 15:03:52 -07003526 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3527 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003528 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003529 hddLog(VOS_TRACE_LEVEL_ERROR,
3530 "%s: SETMCRATE indication alloc fail", __func__);
3531 ret = -EFAULT;
3532 goto exit;
3533 }
3534 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3535
3536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3537 "MC Target rate %d", targetRate);
3538 /* Ignore unicast */
3539 rateUpdate->ucastDataRate = -1;
3540 rateUpdate->mcastDataRate24GHz = targetRate;
3541 rateUpdate->mcastDataRate5GHz = targetRate;
3542 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3543 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3544 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3545 if (eHAL_STATUS_SUCCESS != status)
3546 {
3547 hddLog(VOS_TRACE_LEVEL_ERROR,
3548 "%s: SET_MC_RATE failed", __func__);
3549 vos_mem_free(rateUpdate);
3550 ret = -EFAULT;
3551 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003552 }
3553 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303554#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003555 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303556 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003557 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303558 }
3559#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003560#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
3561 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3562 {
3563 tANI_U8 *value = command;
3564 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3565 tANI_U8 numChannels = 0;
3566 eHalStatus status = eHAL_STATUS_SUCCESS;
3567
3568 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3569 if (eHAL_STATUS_SUCCESS != status)
3570 {
3571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3572 "%s: Failed to parse channel list information", __func__);
3573 ret = -EINVAL;
3574 goto exit;
3575 }
3576
3577 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3578 {
3579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3580 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3581 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3582 ret = -EINVAL;
3583 goto exit;
3584 }
3585 status = sme_SetCcxRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
3586 ChannelList,
3587 numChannels);
3588 if (eHAL_STATUS_SUCCESS != status)
3589 {
3590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3591 "%s: Failed to update channel list information", __func__);
3592 ret = -EINVAL;
3593 goto exit;
3594 }
3595 }
3596 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3597 {
3598 tANI_U8 *value = command;
3599 char extra[128] = {0};
3600 int len = 0;
3601 tANI_U8 tid = 0;
3602 hdd_station_ctx_t *pHddStaCtx = NULL;
3603 tAniTrafStrmMetrics tsmMetrics;
3604 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3605
3606 /* if not associated, return error */
3607 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3608 {
3609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3610 ret = -EINVAL;
3611 goto exit;
3612 }
3613
3614 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3615 value = value + 12;
3616 /* Convert the value from ascii to integer */
3617 ret = kstrtou8(value, 10, &tid);
3618 if (ret < 0)
3619 {
3620 /* If the input value is greater than max value of datatype, then also
3621 kstrtou8 fails */
3622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3623 "%s: kstrtou8 failed range [%d - %d]", __func__,
3624 TID_MIN_VALUE,
3625 TID_MAX_VALUE);
3626 ret = -EINVAL;
3627 goto exit;
3628 }
3629
3630 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3631 {
3632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3633 "tid value %d is out of range"
3634 " (Min: %d Max: %d)", tid,
3635 TID_MIN_VALUE,
3636 TID_MAX_VALUE);
3637 ret = -EINVAL;
3638 goto exit;
3639 }
3640
3641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3642 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3643
3644 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3645 {
3646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3647 "%s: failed to get tsm stats", __func__);
3648 ret = -EFAULT;
3649 goto exit;
3650 }
3651
3652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3653 "UplinkPktQueueDly(%d)\n"
3654 "UplinkPktQueueDlyHist[0](%d)\n"
3655 "UplinkPktQueueDlyHist[1](%d)\n"
3656 "UplinkPktQueueDlyHist[2](%d)\n"
3657 "UplinkPktQueueDlyHist[3](%d)\n"
3658 "UplinkPktTxDly(%lu)\n"
3659 "UplinkPktLoss(%d)\n"
3660 "UplinkPktCount(%d)\n"
3661 "RoamingCount(%d)\n"
3662 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3663 tsmMetrics.UplinkPktQueueDlyHist[0],
3664 tsmMetrics.UplinkPktQueueDlyHist[1],
3665 tsmMetrics.UplinkPktQueueDlyHist[2],
3666 tsmMetrics.UplinkPktQueueDlyHist[3],
3667 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3668 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3669
3670 /* Output TSM stats is of the format
3671 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3672 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003673 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003674 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3675 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3676 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3677 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3678 tsmMetrics.RoamingDly);
3679
3680 if (copy_to_user(priv_data.buf, &extra, len + 1))
3681 {
3682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3683 "%s: failed to copy data to user buffer", __func__);
3684 ret = -EFAULT;
3685 goto exit;
3686 }
3687 }
3688 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3689 {
3690 tANI_U8 *value = command;
3691 tANI_U8 *cckmIe = NULL;
3692 tANI_U8 cckmIeLen = 0;
3693 eHalStatus status = eHAL_STATUS_SUCCESS;
3694
3695 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3696 if (eHAL_STATUS_SUCCESS != status)
3697 {
3698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3699 "%s: Failed to parse cckm ie data", __func__);
3700 ret = -EINVAL;
3701 goto exit;
3702 }
3703
3704 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3705 {
3706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3707 "%s: CCKM Ie input length is more than max[%d]", __func__,
3708 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003709 vos_mem_free(cckmIe);
3710 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003711 ret = -EINVAL;
3712 goto exit;
3713 }
3714 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003715 vos_mem_free(cckmIe);
3716 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003717 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003718 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3719 {
3720 tANI_U8 *value = command;
3721 tCsrCcxBeaconReq ccxBcnReq;
3722 eHalStatus status = eHAL_STATUS_SUCCESS;
3723 status = hdd_parse_ccx_beacon_req(value, &ccxBcnReq);
3724 if (eHAL_STATUS_SUCCESS != status)
3725 {
3726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3727 "%s: Failed to parse ccx beacon req", __func__);
3728 ret = -EINVAL;
3729 goto exit;
3730 }
3731
3732 sme_SetCcxBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &ccxBcnReq);
3733 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003734#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003735 else {
3736 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3737 __func__, command);
3738 }
3739
Jeff Johnson295189b2012-06-20 16:38:30 -07003740 }
3741exit:
3742 if (command)
3743 {
3744 kfree(command);
3745 }
3746 return ret;
3747}
3748
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003749
3750
3751#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003752/**---------------------------------------------------------------------------
3753
3754 \brief hdd_parse_ccx_beacon_req() - Parse ccx beacon request
3755
3756 This function parses the ccx beacon request passed in the format
3757 CCXBEACONREQ<space><Number of fields><space><Measurement token>
3758 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
3759 <space>Scan Mode N<space>Meas Duration N
3760 if the Number of bcn req fields (N) does not match with the actual number of fields passed
3761 then take N.
3762 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
3763 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
3764 This function does not take care of removing duplicate channels from the list
3765
3766 \param - pValue Pointer to data
3767 \param - pCcxBcnReq output pointer to store parsed ie information
3768
3769 \return - 0 for success non-zero for failure
3770
3771 --------------------------------------------------------------------------*/
3772static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
3773 tCsrCcxBeaconReq *pCcxBcnReq)
3774{
3775 tANI_U8 *inPtr = pValue;
3776 int tempInt = 0;
3777 int j = 0, i = 0, v = 0;
3778 char buf[32];
3779
3780 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
3781 /*no argument after the command*/
3782 if (NULL == inPtr)
3783 {
3784 return -EINVAL;
3785 }
3786 /*no space after the command*/
3787 else if (SPACE_ASCII_VALUE != *inPtr)
3788 {
3789 return -EINVAL;
3790 }
3791
3792 /*removing empty spaces*/
3793 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3794
3795 /*no argument followed by spaces*/
3796 if ('\0' == *inPtr) return -EINVAL;
3797
3798 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003799 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003800 if (1 != v) return -EINVAL;
3801
3802 v = kstrtos32(buf, 10, &tempInt);
3803 if ( v < 0) return -EINVAL;
3804
3805 pCcxBcnReq->numBcnReqIe = tempInt;
3806
3807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
3808 "Number of Bcn Req Ie fields(%d)", pCcxBcnReq->numBcnReqIe);
3809
3810 for (j = 0; j < (pCcxBcnReq->numBcnReqIe); j++)
3811 {
3812 for (i = 0; i < 4; i++)
3813 {
3814 /*inPtr pointing to the beginning of first space after number of ie fields*/
3815 inPtr = strpbrk( inPtr, " " );
3816 /*no ie data after the number of ie fields argument*/
3817 if (NULL == inPtr) return -EINVAL;
3818
3819 /*removing empty space*/
3820 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3821
3822 /*no ie data after the number of ie fields argument and spaces*/
3823 if ( '\0' == *inPtr ) return -EINVAL;
3824
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003825 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003826 if (1 != v) return -EINVAL;
3827
3828 v = kstrtos32(buf, 10, &tempInt);
3829 if (v < 0) return -EINVAL;
3830
3831 switch (i)
3832 {
3833 case 0: /* Measurement token */
3834 if (tempInt <= 0)
3835 {
3836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3837 "Invalid Measurement Token(%d)", tempInt);
3838 return -EINVAL;
3839 }
3840 pCcxBcnReq->bcnReq[j].measurementToken = tempInt;
3841 break;
3842
3843 case 1: /* Channel number */
3844 if ((tempInt <= 0) ||
3845 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
3846 {
3847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3848 "Invalid Channel Number(%d)", tempInt);
3849 return -EINVAL;
3850 }
3851 pCcxBcnReq->bcnReq[j].channel = tempInt;
3852 break;
3853
3854 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003855 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003856 {
3857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3858 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
3859 return -EINVAL;
3860 }
3861 pCcxBcnReq->bcnReq[j].scanMode= tempInt;
3862 break;
3863
3864 case 3: /* Measurement duration */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003865 if (((tempInt <= 0) && (pCcxBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
3866 ((tempInt < 0) && (pCcxBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003867 {
3868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3869 "Invalid Measurement Duration(%d)", tempInt);
3870 return -EINVAL;
3871 }
3872 pCcxBcnReq->bcnReq[j].measurementDuration = tempInt;
3873 break;
3874 }
3875 }
3876 }
3877
3878 for (j = 0; j < pCcxBcnReq->numBcnReqIe; j++)
3879 {
3880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3881 "Index(%d) Measurement Token(%lu)Channel(%lu) Scan Mode(%lu) Measurement Duration(%lu)\n",
3882 j,
3883 pCcxBcnReq->bcnReq[j].measurementToken,
3884 pCcxBcnReq->bcnReq[j].channel,
3885 pCcxBcnReq->bcnReq[j].scanMode,
3886 pCcxBcnReq->bcnReq[j].measurementDuration);
3887 }
3888
3889 return VOS_STATUS_SUCCESS;
3890}
3891
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003892static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
3893{
3894 struct statsContext *pStatsContext = NULL;
3895 hdd_adapter_t *pAdapter = NULL;
3896
3897 if (NULL == pContext)
3898 {
3899 hddLog(VOS_TRACE_LEVEL_ERROR,
3900 "%s: Bad param, pContext [%p]",
3901 __func__, pContext);
3902 return;
3903 }
3904
Jeff Johnson72a40512013-12-19 10:14:15 -08003905 /* there is a race condition that exists between this callback
3906 function and the caller since the caller could time out either
3907 before or while this code is executing. we use a spinlock to
3908 serialize these actions */
3909 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003910
3911 pStatsContext = pContext;
3912 pAdapter = pStatsContext->pAdapter;
3913 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
3914 {
3915 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08003916 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003917 hddLog(VOS_TRACE_LEVEL_WARN,
3918 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3919 __func__, pAdapter, pStatsContext->magic);
3920 return;
3921 }
3922
Jeff Johnson72a40512013-12-19 10:14:15 -08003923 /* context is valid so caller is still waiting */
3924
3925 /* paranoia: invalidate the magic */
3926 pStatsContext->magic = 0;
3927
3928 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003929 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
3930 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
3931 tsmMetrics.UplinkPktQueueDlyHist,
3932 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
3933 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
3934 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
3935 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
3936 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
3937 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
3938 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
3939
Jeff Johnson72a40512013-12-19 10:14:15 -08003940 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003941 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08003942
3943 /* serialization is complete */
3944 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003945}
3946
3947
3948
3949static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
3950 tAniTrafStrmMetrics* pTsmMetrics)
3951{
3952 hdd_station_ctx_t *pHddStaCtx = NULL;
3953 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08003954 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003955 long lrc;
3956 struct statsContext context;
3957 hdd_context_t *pHddCtx = NULL;
3958
3959 if (NULL == pAdapter)
3960 {
3961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
3962 return VOS_STATUS_E_FAULT;
3963 }
3964
3965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3966 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3967
3968 /* we are connected prepare our callback context */
3969 init_completion(&context.completion);
3970 context.pAdapter = pAdapter;
3971 context.magic = STATS_CONTEXT_MAGIC;
3972
3973 /* query tsm stats */
3974 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
3975 pHddStaCtx->conn_info.staId[ 0 ],
3976 pHddStaCtx->conn_info.bssId,
3977 &context, pHddCtx->pvosContext, tid);
3978
3979 if (eHAL_STATUS_SUCCESS != hstatus)
3980 {
Jeff Johnson72a40512013-12-19 10:14:15 -08003981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
3982 __func__);
3983 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003984 }
3985 else
3986 {
3987 /* request was sent -- wait for the response */
3988 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3989 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003990 if (lrc <= 0)
3991 {
3992 hddLog(VOS_TRACE_LEVEL_ERROR,
3993 "%s: SME %s while retrieving statistics",
3994 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08003995 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003996 }
3997 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003998
Jeff Johnson72a40512013-12-19 10:14:15 -08003999 /* either we never sent a request, we sent a request and received a
4000 response or we sent a request and timed out. if we never sent a
4001 request or if we sent a request and got a response, we want to
4002 clear the magic out of paranoia. if we timed out there is a
4003 race condition such that the callback function could be
4004 executing at the same time we are. of primary concern is if the
4005 callback function had already verified the "magic" but had not
4006 yet set the completion variable when a timeout occurred. we
4007 serialize these activities by invalidating the magic while
4008 holding a shared spinlock which will cause us to block if the
4009 callback is currently executing */
4010 spin_lock(&hdd_context_lock);
4011 context.magic = 0;
4012 spin_unlock(&hdd_context_lock);
4013
4014 if (VOS_STATUS_SUCCESS == vstatus)
4015 {
4016 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4017 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4018 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4019 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4020 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4021 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4022 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4023 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4024 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4025 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4026 }
4027 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004028}
4029#endif /*FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4030
Srinivas Girigowdade697412013-02-14 16:31:48 -08004031#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
4032void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4033{
4034 eCsrBand band = -1;
4035 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4036 switch (band)
4037 {
4038 case eCSR_BAND_ALL:
4039 *pBand = WLAN_HDD_UI_BAND_AUTO;
4040 break;
4041
4042 case eCSR_BAND_24:
4043 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4044 break;
4045
4046 case eCSR_BAND_5G:
4047 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4048 break;
4049
4050 default:
4051 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4052 *pBand = -1;
4053 break;
4054 }
4055}
4056
4057/**---------------------------------------------------------------------------
4058
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004059 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4060
4061 This function parses the send action frame data passed in the format
4062 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4063
Srinivas Girigowda56076852013-08-20 14:00:50 -07004064 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004065 \param - pTargetApBssid Pointer to target Ap bssid
4066 \param - pChannel Pointer to the Target AP channel
4067 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4068 \param - pBuf Pointer to data
4069 \param - pBufLen Pointer to data length
4070
4071 \return - 0 for success non-zero for failure
4072
4073 --------------------------------------------------------------------------*/
4074VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4075 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4076{
4077 tANI_U8 *inPtr = pValue;
4078 tANI_U8 *dataEnd;
4079 int tempInt;
4080 int j = 0;
4081 int i = 0;
4082 int v = 0;
4083 tANI_U8 tempBuf[32];
4084 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004085 /* 12 hexa decimal digits, 5 ':' and '\0' */
4086 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004087
4088 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4089 /*no argument after the command*/
4090 if (NULL == inPtr)
4091 {
4092 return -EINVAL;
4093 }
4094
4095 /*no space after the command*/
4096 else if (SPACE_ASCII_VALUE != *inPtr)
4097 {
4098 return -EINVAL;
4099 }
4100
4101 /*removing empty spaces*/
4102 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4103
4104 /*no argument followed by spaces*/
4105 if ('\0' == *inPtr)
4106 {
4107 return -EINVAL;
4108 }
4109
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004110 v = sscanf(inPtr, "%17s", macAddress);
4111 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004112 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4114 "Invalid MAC address or All hex inputs are not read (%d)", v);
4115 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004116 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004117
4118 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4119 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4120 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4121 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4122 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4123 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004124
4125 /* point to the next argument */
4126 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4127 /*no argument after the command*/
4128 if (NULL == inPtr) return -EINVAL;
4129
4130 /*removing empty spaces*/
4131 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4132
4133 /*no argument followed by spaces*/
4134 if ('\0' == *inPtr)
4135 {
4136 return -EINVAL;
4137 }
4138
4139 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004140 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004141 if (1 != v) return -EINVAL;
4142
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004143 v = kstrtos32(tempBuf, 10, &tempInt);
Kiet Lambe150c22013-11-21 16:30:32 +05304144 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
4145 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004146
4147 *pChannel = tempInt;
4148
4149 /* point to the next argument */
4150 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4151 /*no argument after the command*/
4152 if (NULL == inPtr) return -EINVAL;
4153 /*removing empty spaces*/
4154 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4155
4156 /*no argument followed by spaces*/
4157 if ('\0' == *inPtr)
4158 {
4159 return -EINVAL;
4160 }
4161
4162 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004163 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004164 if (1 != v) return -EINVAL;
4165
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004166 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004167 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004168
4169 *pDwellTime = tempInt;
4170
4171 /* point to the next argument */
4172 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4173 /*no argument after the command*/
4174 if (NULL == inPtr) return -EINVAL;
4175 /*removing empty spaces*/
4176 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4177
4178 /*no argument followed by spaces*/
4179 if ('\0' == *inPtr)
4180 {
4181 return -EINVAL;
4182 }
4183
4184 /* find the length of data */
4185 dataEnd = inPtr;
4186 while(('\0' != *dataEnd) )
4187 {
4188 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004189 }
Kiet Lambe150c22013-11-21 16:30:32 +05304190 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004191 if ( *pBufLen <= 0) return -EINVAL;
4192
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004193 /* Allocate the number of bytes based on the number of input characters
4194 whether it is even or odd.
4195 if the number of input characters are even, then we need N/2 byte.
4196 if the number of input characters are odd, then we need do (N+1)/2 to
4197 compensate rounding off.
4198 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4199 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4200 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004201 if (NULL == *pBuf)
4202 {
4203 hddLog(VOS_TRACE_LEVEL_FATAL,
4204 "%s: vos_mem_alloc failed ", __func__);
4205 return -EINVAL;
4206 }
4207
4208 /* the buffer received from the upper layer is character buffer,
4209 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4210 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4211 and f0 in 3rd location */
4212 for (i = 0, j = 0; j < *pBufLen; j += 2)
4213 {
Kiet Lambe150c22013-11-21 16:30:32 +05304214 if( j+1 == *pBufLen)
4215 {
4216 tempByte = hdd_parse_hex(inPtr[j]);
4217 }
4218 else
4219 {
4220 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4221 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004222 (*pBuf)[i++] = tempByte;
4223 }
4224 *pBufLen = i;
4225 return VOS_STATUS_SUCCESS;
4226}
4227
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004228/**---------------------------------------------------------------------------
4229
Srinivas Girigowdade697412013-02-14 16:31:48 -08004230 \brief hdd_parse_channellist() - HDD Parse channel list
4231
4232 This function parses the channel list passed in the format
4233 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004234 if the Number of channels (N) does not match with the actual number of channels passed
4235 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4236 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4237 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4238 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004239
4240 \param - pValue Pointer to input channel list
4241 \param - ChannelList Pointer to local output array to record channel list
4242 \param - pNumChannels Pointer to number of roam scan channels
4243
4244 \return - 0 for success non-zero for failure
4245
4246 --------------------------------------------------------------------------*/
4247VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4248{
4249 tANI_U8 *inPtr = pValue;
4250 int tempInt;
4251 int j = 0;
4252 int v = 0;
4253 char buf[32];
4254
4255 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4256 /*no argument after the command*/
4257 if (NULL == inPtr)
4258 {
4259 return -EINVAL;
4260 }
4261
4262 /*no space after the command*/
4263 else if (SPACE_ASCII_VALUE != *inPtr)
4264 {
4265 return -EINVAL;
4266 }
4267
4268 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004269 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004270
4271 /*no argument followed by spaces*/
4272 if ('\0' == *inPtr)
4273 {
4274 return -EINVAL;
4275 }
4276
4277 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004278 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004279 if (1 != v) return -EINVAL;
4280
Srinivas Girigowdade697412013-02-14 16:31:48 -08004281 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004282 if ((v < 0) ||
4283 (tempInt <= 0) ||
4284 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4285 {
4286 return -EINVAL;
4287 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004288
4289 *pNumChannels = tempInt;
4290
4291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4292 "Number of channels are: %d", *pNumChannels);
4293
4294 for (j = 0; j < (*pNumChannels); j++)
4295 {
4296 /*inPtr pointing to the beginning of first space after number of channels*/
4297 inPtr = strpbrk( inPtr, " " );
4298 /*no channel list after the number of channels argument*/
4299 if (NULL == inPtr)
4300 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004301 if (0 != j)
4302 {
4303 *pNumChannels = j;
4304 return VOS_STATUS_SUCCESS;
4305 }
4306 else
4307 {
4308 return -EINVAL;
4309 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004310 }
4311
4312 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004313 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004314
4315 /*no channel list after the number of channels argument and spaces*/
4316 if ( '\0' == *inPtr )
4317 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004318 if (0 != j)
4319 {
4320 *pNumChannels = j;
4321 return VOS_STATUS_SUCCESS;
4322 }
4323 else
4324 {
4325 return -EINVAL;
4326 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004327 }
4328
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004329 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004330 if (1 != v) return -EINVAL;
4331
Srinivas Girigowdade697412013-02-14 16:31:48 -08004332 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004333 if ((v < 0) ||
4334 (tempInt <= 0) ||
4335 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4336 {
4337 return -EINVAL;
4338 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004339 pChannelList[j] = tempInt;
4340
4341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4342 "Channel %d added to preferred channel list",
4343 pChannelList[j] );
4344 }
4345
Srinivas Girigowdade697412013-02-14 16:31:48 -08004346 return VOS_STATUS_SUCCESS;
4347}
4348
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004349
4350/**---------------------------------------------------------------------------
4351
4352 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4353
4354 This function parses the reasoc command data passed in the format
4355 REASSOC<space><bssid><space><channel>
4356
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004357 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004358 \param - pTargetApBssid Pointer to target Ap bssid
4359 \param - pChannel Pointer to the Target AP channel
4360
4361 \return - 0 for success non-zero for failure
4362
4363 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004364VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4365 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004366{
4367 tANI_U8 *inPtr = pValue;
4368 int tempInt;
4369 int v = 0;
4370 tANI_U8 tempBuf[32];
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004371 /* 12 hexa decimal digits, 5 ':' and '\0' */
4372 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004373
4374 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4375 /*no argument after the command*/
4376 if (NULL == inPtr)
4377 {
4378 return -EINVAL;
4379 }
4380
4381 /*no space after the command*/
4382 else if (SPACE_ASCII_VALUE != *inPtr)
4383 {
4384 return -EINVAL;
4385 }
4386
4387 /*removing empty spaces*/
4388 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4389
4390 /*no argument followed by spaces*/
4391 if ('\0' == *inPtr)
4392 {
4393 return -EINVAL;
4394 }
4395
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004396 v = sscanf(inPtr, "%17s", macAddress);
4397 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004398 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4400 "Invalid MAC address or All hex inputs are not read (%d)", v);
4401 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004402 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004403
4404 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4405 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4406 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4407 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4408 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4409 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004410
4411 /* point to the next argument */
4412 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4413 /*no argument after the command*/
4414 if (NULL == inPtr) return -EINVAL;
4415
4416 /*removing empty spaces*/
4417 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4418
4419 /*no argument followed by spaces*/
4420 if ('\0' == *inPtr)
4421 {
4422 return -EINVAL;
4423 }
4424
4425 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004426 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004427 if (1 != v) return -EINVAL;
4428
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004429 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004430 if ((v < 0) ||
4431 (tempInt <= 0) ||
4432 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4433 {
4434 return -EINVAL;
4435 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004436
4437 *pChannel = tempInt;
4438 return VOS_STATUS_SUCCESS;
4439}
4440
4441#endif
4442
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004443#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
4444/**---------------------------------------------------------------------------
4445
4446 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4447
4448 This function parses the SETCCKM IE command
4449 SETCCKMIE<space><ie data>
4450
4451 \param - pValue Pointer to input data
4452 \param - pCckmIe Pointer to output cckm Ie
4453 \param - pCckmIeLen Pointer to output cckm ie length
4454
4455 \return - 0 for success non-zero for failure
4456
4457 --------------------------------------------------------------------------*/
4458VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4459 tANI_U8 *pCckmIeLen)
4460{
4461 tANI_U8 *inPtr = pValue;
4462 tANI_U8 *dataEnd;
4463 int j = 0;
4464 int i = 0;
4465 tANI_U8 tempByte = 0;
4466
4467 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4468 /*no argument after the command*/
4469 if (NULL == inPtr)
4470 {
4471 return -EINVAL;
4472 }
4473
4474 /*no space after the command*/
4475 else if (SPACE_ASCII_VALUE != *inPtr)
4476 {
4477 return -EINVAL;
4478 }
4479
4480 /*removing empty spaces*/
4481 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4482
4483 /*no argument followed by spaces*/
4484 if ('\0' == *inPtr)
4485 {
4486 return -EINVAL;
4487 }
4488
4489 /* find the length of data */
4490 dataEnd = inPtr;
4491 while(('\0' != *dataEnd) )
4492 {
4493 dataEnd++;
4494 ++(*pCckmIeLen);
4495 }
4496 if ( *pCckmIeLen <= 0) return -EINVAL;
4497
4498 /* Allocate the number of bytes based on the number of input characters
4499 whether it is even or odd.
4500 if the number of input characters are even, then we need N/2 byte.
4501 if the number of input characters are odd, then we need do (N+1)/2 to
4502 compensate rounding off.
4503 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4504 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4505 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4506 if (NULL == *pCckmIe)
4507 {
4508 hddLog(VOS_TRACE_LEVEL_FATAL,
4509 "%s: vos_mem_alloc failed ", __func__);
4510 return -EINVAL;
4511 }
4512 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4513 /* the buffer received from the upper layer is character buffer,
4514 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4515 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4516 and f0 in 3rd location */
4517 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4518 {
4519 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4520 (*pCckmIe)[i++] = tempByte;
4521 }
4522 *pCckmIeLen = i;
4523
4524 return VOS_STATUS_SUCCESS;
4525}
4526#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4527
Jeff Johnson295189b2012-06-20 16:38:30 -07004528/**---------------------------------------------------------------------------
4529
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004530 \brief hdd_is_valid_mac_address() - Validate MAC address
4531
4532 This function validates whether the given MAC address is valid or not
4533 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4534 where X is the hexa decimal digit character and separated by ':'
4535 This algorithm works even if MAC address is not separated by ':'
4536
4537 This code checks given input string mac contains exactly 12 hexadecimal digits.
4538 and a separator colon : appears in the input string only after
4539 an even number of hex digits.
4540
4541 \param - pMacAddr pointer to the input MAC address
4542 \return - 1 for valid and 0 for invalid
4543
4544 --------------------------------------------------------------------------*/
4545
4546v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4547{
4548 int xdigit = 0;
4549 int separator = 0;
4550 while (*pMacAddr)
4551 {
4552 if (isxdigit(*pMacAddr))
4553 {
4554 xdigit++;
4555 }
4556 else if (':' == *pMacAddr)
4557 {
4558 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4559 break;
4560
4561 ++separator;
4562 }
4563 else
4564 {
4565 separator = -1;
4566 /* Invalid MAC found */
4567 return 0;
4568 }
4569 ++pMacAddr;
4570 }
4571 return (xdigit == 12 && (separator == 5 || separator == 0));
4572}
4573
4574/**---------------------------------------------------------------------------
4575
Jeff Johnson295189b2012-06-20 16:38:30 -07004576 \brief hdd_open() - HDD Open function
4577
4578 This is called in response to ifconfig up
4579
4580 \param - dev Pointer to net_device structure
4581
4582 \return - 0 for success non-zero for failure
4583
4584 --------------------------------------------------------------------------*/
4585int hdd_open (struct net_device *dev)
4586{
4587 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4588 hdd_context_t *pHddCtx;
4589 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4590 VOS_STATUS status;
4591 v_BOOL_t in_standby = TRUE;
4592
4593 if (NULL == pAdapter)
4594 {
4595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004596 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 return -ENODEV;
4598 }
4599
4600 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4601 if (NULL == pHddCtx)
4602 {
4603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004604 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004605 return -ENODEV;
4606 }
4607
4608 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4609 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4610 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004611 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4612 {
4613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304614 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004615 in_standby = FALSE;
4616 break;
4617 }
4618 else
4619 {
4620 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4621 pAdapterNode = pNext;
4622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004623 }
4624
4625 if (TRUE == in_standby)
4626 {
4627 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4628 {
4629 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4630 "wlan out of power save", __func__);
4631 return -EINVAL;
4632 }
4633 }
4634
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004635 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004636 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4637 {
4638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004639 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004640 /* Enable TX queues only when we are connected */
4641 netif_tx_start_all_queues(dev);
4642 }
4643
4644 return 0;
4645}
4646
4647int hdd_mon_open (struct net_device *dev)
4648{
4649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4650
4651 if(pAdapter == NULL) {
4652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004653 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004654 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004655 }
4656
4657 netif_start_queue(dev);
4658
4659 return 0;
4660}
4661/**---------------------------------------------------------------------------
4662
4663 \brief hdd_stop() - HDD stop function
4664
4665 This is called in response to ifconfig down
4666
4667 \param - dev Pointer to net_device structure
4668
4669 \return - 0 for success non-zero for failure
4670
4671 --------------------------------------------------------------------------*/
4672
4673int hdd_stop (struct net_device *dev)
4674{
4675 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4676 hdd_context_t *pHddCtx;
4677 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4678 VOS_STATUS status;
4679 v_BOOL_t enter_standby = TRUE;
4680
4681 ENTER();
4682
4683 if (NULL == pAdapter)
4684 {
4685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004686 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004687 return -ENODEV;
4688 }
4689
4690 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4691 if (NULL == pHddCtx)
4692 {
4693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004694 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 return -ENODEV;
4696 }
4697
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004698 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4700 netif_tx_disable(pAdapter->dev);
4701 netif_carrier_off(pAdapter->dev);
4702
4703
4704 /* SoftAP ifaces should never go in power save mode
4705 making sure same here. */
4706 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4707 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004708 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004709 )
4710 {
4711 /* SoftAP mode, so return from here */
4712 EXIT();
4713 return 0;
4714 }
4715
4716 /* Find if any iface is up then
4717 if any iface is up then can't put device to sleep/ power save mode. */
4718 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4719 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4720 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004721 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4722 {
4723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304724 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004725 enter_standby = FALSE;
4726 break;
4727 }
4728 else
4729 {
4730 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4731 pAdapterNode = pNext;
4732 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004733 }
4734
4735 if (TRUE == enter_standby)
4736 {
4737 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
4738 "entering standby", __func__);
4739 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
4740 {
4741 /*log and return success*/
4742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
4743 "wlan in power save", __func__);
4744 }
4745 }
4746
4747 EXIT();
4748 return 0;
4749}
4750
4751/**---------------------------------------------------------------------------
4752
4753 \brief hdd_uninit() - HDD uninit function
4754
4755 This is called during the netdev unregister to uninitialize all data
4756associated with the device
4757
4758 \param - dev Pointer to net_device structure
4759
4760 \return - void
4761
4762 --------------------------------------------------------------------------*/
4763static void hdd_uninit (struct net_device *dev)
4764{
4765 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4766
4767 ENTER();
4768
4769 do
4770 {
4771 if (NULL == pAdapter)
4772 {
4773 hddLog(VOS_TRACE_LEVEL_FATAL,
4774 "%s: NULL pAdapter", __func__);
4775 break;
4776 }
4777
4778 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
4779 {
4780 hddLog(VOS_TRACE_LEVEL_FATAL,
4781 "%s: Invalid magic", __func__);
4782 break;
4783 }
4784
4785 if (NULL == pAdapter->pHddCtx)
4786 {
4787 hddLog(VOS_TRACE_LEVEL_FATAL,
4788 "%s: NULL pHddCtx", __func__);
4789 break;
4790 }
4791
4792 if (dev != pAdapter->dev)
4793 {
4794 hddLog(VOS_TRACE_LEVEL_FATAL,
4795 "%s: Invalid device reference", __func__);
4796 /* we haven't validated all cases so let this go for now */
4797 }
4798
4799 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
4800
4801 /* after uninit our adapter structure will no longer be valid */
4802 pAdapter->dev = NULL;
4803 pAdapter->magic = 0;
4804 } while (0);
4805
4806 EXIT();
4807}
4808
4809/**---------------------------------------------------------------------------
4810
4811 \brief hdd_release_firmware() -
4812
4813 This function calls the release firmware API to free the firmware buffer.
4814
4815 \param - pFileName Pointer to the File Name.
4816 pCtx - Pointer to the adapter .
4817
4818
4819 \return - 0 for success, non zero for failure
4820
4821 --------------------------------------------------------------------------*/
4822
4823VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
4824{
4825 VOS_STATUS status = VOS_STATUS_SUCCESS;
4826 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4827 ENTER();
4828
4829
4830 if (!strcmp(WLAN_FW_FILE, pFileName)) {
4831
4832 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
4833
4834 if(pHddCtx->fw) {
4835 release_firmware(pHddCtx->fw);
4836 pHddCtx->fw = NULL;
4837 }
4838 else
4839 status = VOS_STATUS_E_FAILURE;
4840 }
4841 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
4842 if(pHddCtx->nv) {
4843 release_firmware(pHddCtx->nv);
4844 pHddCtx->nv = NULL;
4845 }
4846 else
4847 status = VOS_STATUS_E_FAILURE;
4848
4849 }
4850
4851 EXIT();
4852 return status;
4853}
4854
4855/**---------------------------------------------------------------------------
4856
4857 \brief hdd_request_firmware() -
4858
4859 This function reads the firmware file using the request firmware
4860 API and returns the the firmware data and the firmware file size.
4861
4862 \param - pfileName - Pointer to the file name.
4863 - pCtx - Pointer to the adapter .
4864 - ppfw_data - Pointer to the pointer of the firmware data.
4865 - pSize - Pointer to the file size.
4866
4867 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
4868
4869 --------------------------------------------------------------------------*/
4870
4871
4872VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
4873{
4874 int status;
4875 VOS_STATUS retval = VOS_STATUS_SUCCESS;
4876 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4877 ENTER();
4878
4879 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
4880
4881 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
4882
4883 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4884 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
4885 __func__, pfileName);
4886 retval = VOS_STATUS_E_FAILURE;
4887 }
4888
4889 else {
4890 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
4891 *pSize = pHddCtx->fw->size;
4892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
4893 __func__, *pSize);
4894 }
4895 }
4896 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
4897
4898 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
4899
4900 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
4901 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
4902 __func__, pfileName);
4903 retval = VOS_STATUS_E_FAILURE;
4904 }
4905
4906 else {
4907 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
4908 *pSize = pHddCtx->nv->size;
4909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
4910 __func__, *pSize);
4911 }
4912 }
4913
4914 EXIT();
4915 return retval;
4916}
4917/**---------------------------------------------------------------------------
4918 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
4919
4920 This is the function invoked by SME to inform the result of a full power
4921 request issued by HDD
4922
4923 \param - callbackcontext - Pointer to cookie
4924 status - result of request
4925
4926 \return - None
4927
4928--------------------------------------------------------------------------*/
4929void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
4930{
4931 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
4932
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004933 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004934 if(&pHddCtx->full_pwr_comp_var)
4935 {
4936 complete(&pHddCtx->full_pwr_comp_var);
4937 }
4938}
4939
4940/**---------------------------------------------------------------------------
4941
4942 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
4943
4944 This is the function invoked by SME to inform the result of BMPS
4945 request issued by HDD
4946
4947 \param - callbackcontext - Pointer to cookie
4948 status - result of request
4949
4950 \return - None
4951
4952--------------------------------------------------------------------------*/
4953void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
4954{
4955
4956 struct completion *completion_var = (struct completion*) callbackContext;
4957
Arif Hussain6d2a3322013-11-17 19:50:10 -08004958 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 if(completion_var != NULL)
4960 {
4961 complete(completion_var);
4962 }
4963}
4964
4965/**---------------------------------------------------------------------------
4966
4967 \brief hdd_get_cfg_file_size() -
4968
4969 This function reads the configuration file using the request firmware
4970 API and returns the configuration file size.
4971
4972 \param - pCtx - Pointer to the adapter .
4973 - pFileName - Pointer to the file name.
4974 - pBufSize - Pointer to the buffer size.
4975
4976 \return - 0 for success, non zero for failure
4977
4978 --------------------------------------------------------------------------*/
4979
4980VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
4981{
4982 int status;
4983 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4984
4985 ENTER();
4986
4987 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
4988
4989 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4990 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
4991 status = VOS_STATUS_E_FAILURE;
4992 }
4993 else {
4994 *pBufSize = pHddCtx->fw->size;
4995 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
4996 release_firmware(pHddCtx->fw);
4997 pHddCtx->fw = NULL;
4998 }
4999
5000 EXIT();
5001 return VOS_STATUS_SUCCESS;
5002}
5003
5004/**---------------------------------------------------------------------------
5005
5006 \brief hdd_read_cfg_file() -
5007
5008 This function reads the configuration file using the request firmware
5009 API and returns the cfg data and the buffer size of the configuration file.
5010
5011 \param - pCtx - Pointer to the adapter .
5012 - pFileName - Pointer to the file name.
5013 - pBuffer - Pointer to the data buffer.
5014 - pBufSize - Pointer to the buffer size.
5015
5016 \return - 0 for success, non zero for failure
5017
5018 --------------------------------------------------------------------------*/
5019
5020VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5021 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5022{
5023 int status;
5024 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5025
5026 ENTER();
5027
5028 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5029
5030 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5031 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5032 return VOS_STATUS_E_FAILURE;
5033 }
5034 else {
5035 if(*pBufSize != pHddCtx->fw->size) {
5036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5037 "file size", __func__);
5038 release_firmware(pHddCtx->fw);
5039 pHddCtx->fw = NULL;
5040 return VOS_STATUS_E_FAILURE;
5041 }
5042 else {
5043 if(pBuffer) {
5044 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5045 }
5046 release_firmware(pHddCtx->fw);
5047 pHddCtx->fw = NULL;
5048 }
5049 }
5050
5051 EXIT();
5052
5053 return VOS_STATUS_SUCCESS;
5054}
5055
5056/**---------------------------------------------------------------------------
5057
Jeff Johnson295189b2012-06-20 16:38:30 -07005058 \brief hdd_set_mac_address() -
5059
5060 This function sets the user specified mac address using
5061 the command ifconfig wlanX hw ether <mac adress>.
5062
5063 \param - dev - Pointer to the net device.
5064 - addr - Pointer to the sockaddr.
5065 \return - 0 for success, non zero for failure
5066
5067 --------------------------------------------------------------------------*/
5068
5069static int hdd_set_mac_address(struct net_device *dev, void *addr)
5070{
5071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5072 struct sockaddr *psta_mac_addr = addr;
5073 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5074
5075 ENTER();
5076
5077 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5078
5079#ifdef HDD_SESSIONIZE
5080 // set the MAC address though the STA ID CFG.
5081 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5082 (v_U8_t *)&pAdapter->macAddressCurrent,
5083 sizeof( pAdapter->macAddressCurrent ),
5084 hdd_set_mac_addr_cb, VOS_FALSE );
5085#endif
5086
5087 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5088
5089 EXIT();
5090 return halStatus;
5091}
5092
5093tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5094{
5095 int i;
5096 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5097 {
5098 if( 0 == (pHddCtx->cfg_ini->intfAddrMask >> i))
5099 break;
5100 }
5101
5102 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5103 return NULL;
5104
5105 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5106 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5107}
5108
5109void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5110{
5111 int i;
5112 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5113 {
5114 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5115 {
5116 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5117 break;
5118 }
5119 }
5120 return;
5121}
5122
5123#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5124 static struct net_device_ops wlan_drv_ops = {
5125 .ndo_open = hdd_open,
5126 .ndo_stop = hdd_stop,
5127 .ndo_uninit = hdd_uninit,
5128 .ndo_start_xmit = hdd_hard_start_xmit,
5129 .ndo_tx_timeout = hdd_tx_timeout,
5130 .ndo_get_stats = hdd_stats,
5131 .ndo_do_ioctl = hdd_ioctl,
5132 .ndo_set_mac_address = hdd_set_mac_address,
5133 .ndo_select_queue = hdd_select_queue,
5134#ifdef WLAN_FEATURE_PACKET_FILTERING
5135#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5136 .ndo_set_rx_mode = hdd_set_multicast_list,
5137#else
5138 .ndo_set_multicast_list = hdd_set_multicast_list,
5139#endif //LINUX_VERSION_CODE
5140#endif
5141 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 static struct net_device_ops wlan_mon_drv_ops = {
5143 .ndo_open = hdd_mon_open,
5144 .ndo_stop = hdd_stop,
5145 .ndo_uninit = hdd_uninit,
5146 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5147 .ndo_tx_timeout = hdd_tx_timeout,
5148 .ndo_get_stats = hdd_stats,
5149 .ndo_do_ioctl = hdd_ioctl,
5150 .ndo_set_mac_address = hdd_set_mac_address,
5151 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005152
5153#endif
5154
5155void hdd_set_station_ops( struct net_device *pWlanDev )
5156{
5157#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005158 pWlanDev->netdev_ops = &wlan_drv_ops;
5159#else
5160 pWlanDev->open = hdd_open;
5161 pWlanDev->stop = hdd_stop;
5162 pWlanDev->uninit = hdd_uninit;
5163 pWlanDev->hard_start_xmit = NULL;
5164 pWlanDev->tx_timeout = hdd_tx_timeout;
5165 pWlanDev->get_stats = hdd_stats;
5166 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005167 pWlanDev->set_mac_address = hdd_set_mac_address;
5168#endif
5169}
5170
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005171static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005172{
5173 struct net_device *pWlanDev = NULL;
5174 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 /*
5176 * cfg80211 initialization and registration....
5177 */
5178 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5179
Jeff Johnson295189b2012-06-20 16:38:30 -07005180 if(pWlanDev != NULL)
5181 {
5182
5183 //Save the pointer to the net_device in the HDD adapter
5184 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5185
Jeff Johnson295189b2012-06-20 16:38:30 -07005186 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5187
5188 pAdapter->dev = pWlanDev;
5189 pAdapter->pHddCtx = pHddCtx;
5190 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5191
5192 init_completion(&pAdapter->session_open_comp_var);
5193 init_completion(&pAdapter->session_close_comp_var);
5194 init_completion(&pAdapter->disconnect_comp_var);
5195 init_completion(&pAdapter->linkup_event_var);
5196 init_completion(&pAdapter->cancel_rem_on_chan_var);
5197 init_completion(&pAdapter->rem_on_chan_ready_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07005198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5199 init_completion(&pAdapter->offchannel_tx_event);
5200#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005202#ifdef FEATURE_WLAN_TDLS
5203 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005204 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005205 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305206 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005207#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 init_completion(&pHddCtx->mc_sus_event_var);
5209 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305210 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005211 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005212 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005213
Rajeev79dbe4c2013-10-05 11:03:42 +05305214#ifdef FEATURE_WLAN_BATCH_SCAN
5215 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5216 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5217 pAdapter->pBatchScanRsp = NULL;
5218 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005219 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Rajeev Kumarb20d8c82013-11-18 20:04:20 -08005220 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305221 mutex_init(&pAdapter->hdd_batch_scan_lock);
5222#endif
5223
Jeff Johnson295189b2012-06-20 16:38:30 -07005224 pAdapter->isLinkUpSvcNeeded = FALSE;
5225 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5226 //Init the net_device structure
5227 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5228
5229 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5230 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5231 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5232 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5233
5234 hdd_set_station_ops( pAdapter->dev );
5235
5236 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005237 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5238 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5239 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005240 /* set pWlanDev's parent to underlying device */
5241 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5242 }
5243
5244 return pAdapter;
5245}
5246
5247VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5248{
5249 struct net_device *pWlanDev = pAdapter->dev;
5250 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5251 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5252 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5253
5254 if( rtnl_lock_held )
5255 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005256 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5258 {
5259 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5260 return VOS_STATUS_E_FAILURE;
5261 }
5262 }
5263 if (register_netdevice(pWlanDev))
5264 {
5265 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5266 return VOS_STATUS_E_FAILURE;
5267 }
5268 }
5269 else
5270 {
5271 if(register_netdev(pWlanDev))
5272 {
5273 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5274 return VOS_STATUS_E_FAILURE;
5275 }
5276 }
5277 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5278
5279 return VOS_STATUS_SUCCESS;
5280}
5281
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005282static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005283{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005284 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005285
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005286 if (NULL == pAdapter)
5287 {
5288 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5289 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005290 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005291
5292 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5293 {
5294 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5295 return eHAL_STATUS_NOT_INITIALIZED;
5296 }
5297
5298 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5299
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005300#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005301 /* need to make sure all of our scheduled work has completed.
5302 * This callback is called from MC thread context, so it is safe to
5303 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005304 *
5305 * Even though this is called from MC thread context, if there is a faulty
5306 * work item in the system, that can hang this call forever. So flushing
5307 * this global work queue is not safe; and now we make sure that
5308 * individual work queues are stopped correctly. But the cancel work queue
5309 * is a GPL only API, so the proprietary version of the driver would still
5310 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005311 */
5312 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005313#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005314
5315 /* We can be blocked while waiting for scheduled work to be
5316 * flushed, and the adapter structure can potentially be freed, in
5317 * which case the magic will have been reset. So make sure the
5318 * magic is still good, and hence the adapter structure is still
5319 * valid, before signaling completion */
5320 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5321 {
5322 complete(&pAdapter->session_close_comp_var);
5323 }
5324
Jeff Johnson295189b2012-06-20 16:38:30 -07005325 return eHAL_STATUS_SUCCESS;
5326}
5327
5328VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5329{
5330 struct net_device *pWlanDev = pAdapter->dev;
5331 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5332 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5333 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5334 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5335 int rc = 0;
5336
5337 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005338 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005339 //Open a SME session for future operation
5340 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005341 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005342 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5343 {
5344 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005345 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 halStatus, halStatus );
5347 status = VOS_STATUS_E_FAILURE;
5348 goto error_sme_open;
5349 }
5350
5351 //Block on a completion variable. Can't wait forever though.
5352 rc = wait_for_completion_interruptible_timeout(
5353 &pAdapter->session_open_comp_var,
5354 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
5355 if (!rc)
5356 {
5357 hddLog(VOS_TRACE_LEVEL_FATAL,
5358 "Session is not opened within timeout period code %08d", rc );
5359 status = VOS_STATUS_E_FAILURE;
5360 goto error_sme_open;
5361 }
5362
5363 // Register wireless extensions
5364 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5365 {
5366 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005367 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005368 halStatus, halStatus );
5369 status = VOS_STATUS_E_FAILURE;
5370 goto error_register_wext;
5371 }
5372 //Safe to register the hard_start_xmit function again
5373#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5374 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5375#else
5376 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5377#endif
5378
5379 //Set the Connection State to Not Connected
5380 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5381
5382 //Set the default operation channel
5383 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5384
5385 /* Make the default Auth Type as OPEN*/
5386 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5387
5388 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5389 {
5390 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005391 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 status, status );
5393 goto error_init_txrx;
5394 }
5395
5396 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5397
5398 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5399 {
5400 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005401 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005402 status, status );
5403 goto error_wmm_init;
5404 }
5405
5406 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5407
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005408#ifdef FEATURE_WLAN_TDLS
5409 if(0 != wlan_hdd_tdls_init(pAdapter))
5410 {
5411 status = VOS_STATUS_E_FAILURE;
5412 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5413 goto error_tdls_init;
5414 }
5415 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5416#endif
5417
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 return VOS_STATUS_SUCCESS;
5419
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005420#ifdef FEATURE_WLAN_TDLS
5421error_tdls_init:
5422 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5423 hdd_wmm_adapter_close(pAdapter);
5424#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005425error_wmm_init:
5426 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5427 hdd_deinit_tx_rx(pAdapter);
5428error_init_txrx:
5429 hdd_UnregisterWext(pWlanDev);
5430error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005431 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 {
5433 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005434 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005436 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 {
5438 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005439 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005441 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 }
5443}
5444error_sme_open:
5445 return status;
5446}
5447
Jeff Johnson295189b2012-06-20 16:38:30 -07005448void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5449{
5450 hdd_cfg80211_state_t *cfgState;
5451
5452 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5453
5454 if( NULL != cfgState->buf )
5455 {
5456 int rc;
5457 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5458 rc = wait_for_completion_interruptible_timeout(
5459 &pAdapter->tx_action_cnf_event,
5460 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
5461 if(!rc)
5462 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005464 ("ERROR: HDD Wait for Action Confirmation Failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 }
5466 }
5467 return;
5468}
Jeff Johnson295189b2012-06-20 16:38:30 -07005469
5470void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5471{
5472 ENTER();
5473 switch ( pAdapter->device_mode )
5474 {
5475 case WLAN_HDD_INFRA_STATION:
5476 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005477 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 {
5479 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5480 {
5481 hdd_deinit_tx_rx( pAdapter );
5482 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5483 }
5484
5485 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5486 {
5487 hdd_wmm_adapter_close( pAdapter );
5488 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5489 }
5490
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005492#ifdef FEATURE_WLAN_TDLS
5493 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5494 {
5495 wlan_hdd_tdls_exit(pAdapter);
5496 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5497 }
5498#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005499
5500 break;
5501 }
5502
5503 case WLAN_HDD_SOFTAP:
5504 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005505 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305506
5507 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5508 {
5509 hdd_wmm_adapter_close( pAdapter );
5510 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5511 }
5512
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005514
5515 hdd_unregister_hostapd(pAdapter);
5516 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 break;
5519 }
5520
5521 case WLAN_HDD_MONITOR:
5522 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5525 {
5526 hdd_deinit_tx_rx( pAdapter );
5527 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 if(NULL != pAdapterforTx)
5530 {
5531 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 break;
5534 }
5535
5536
5537 default:
5538 break;
5539 }
5540
5541 EXIT();
5542}
5543
5544void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5545{
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305546 struct net_device *pWlanDev;
5547
5548 ENTER();
5549 if (NULL == pAdapter)
5550 {
5551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5552 "%s: HDD adapter is Null", __func__);
5553 return;
5554 }
5555
5556 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005557
Rajeev79dbe4c2013-10-05 11:03:42 +05305558#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305559 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5560 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005561 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305562 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5563 )
5564 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005565 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305566 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005567 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5568 {
5569 hdd_deinit_batch_scan(pAdapter);
5570 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305571 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005572 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305573#endif
5574
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5576 if( rtnl_held )
5577 {
5578 unregister_netdevice(pWlanDev);
5579 }
5580 else
5581 {
5582 unregister_netdev(pWlanDev);
5583 }
5584 // note that the pAdapter is no longer valid at this point
5585 // since the memory has been reclaimed
5586 }
5587
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305588 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005589}
5590
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005591void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5592{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305593 VOS_STATUS status;
5594 hdd_adapter_t *pAdapter = NULL;
5595 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005596
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305597 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005598
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305599 /*loop through all adapters.*/
5600 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005601 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305602 pAdapter = pAdapterNode->pAdapter;
5603 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5604 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005605
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305606 { // we skip this registration for modes other than STA and P2P client modes.
5607 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5608 pAdapterNode = pNext;
5609 continue;
5610 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005611
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305612 //Apply Dynamic DTIM For P2P
5613 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5614 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5615 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5616 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5617 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5618 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5619 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5620 (eConnectionState_Associated ==
5621 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5622 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5623 {
5624 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005625
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305626 powerRequest.uIgnoreDTIM = 1;
5627 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5628
5629 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5630 {
5631 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5632 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5633 }
5634 else
5635 {
5636 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5637 }
5638
5639 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5640 * specified during Enter/Exit BMPS when LCD off*/
5641 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5642 NULL, eANI_BOOLEAN_FALSE);
5643 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5644 NULL, eANI_BOOLEAN_FALSE);
5645
5646 /* switch to the DTIM specified in cfg.ini */
5647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5648 "Switch to DTIM %d", powerRequest.uListenInterval);
5649 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5650 break;
5651
5652 }
5653
5654 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5655 pAdapterNode = pNext;
5656 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005657}
5658
5659void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5660{
5661 /*Switch back to DTIM 1*/
5662 tSirSetPowerParamsReq powerRequest = { 0 };
5663
5664 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5665 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005666 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005667
5668 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5669 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5670 NULL, eANI_BOOLEAN_FALSE);
5671 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5672 NULL, eANI_BOOLEAN_FALSE);
5673
5674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5675 "Switch to DTIM%d",powerRequest.uListenInterval);
5676 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5677
5678}
5679
Jeff Johnson295189b2012-06-20 16:38:30 -07005680VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5681{
5682 VOS_STATUS status = VOS_STATUS_SUCCESS;
5683
5684 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5685 {
5686 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5687 }
5688
5689 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5690 {
5691 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5692 }
5693
5694 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5695 {
5696 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5697 }
5698
5699 return status;
5700}
5701
5702VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5703{
5704 hdd_adapter_t *pAdapter = NULL;
5705 eHalStatus halStatus;
5706 VOS_STATUS status = VOS_STATUS_E_INVAL;
5707 v_BOOL_t disableBmps = FALSE;
5708 v_BOOL_t disableImps = FALSE;
5709
5710 switch(session_type)
5711 {
5712 case WLAN_HDD_INFRA_STATION:
5713 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 case WLAN_HDD_P2P_CLIENT:
5715 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005716 //Exit BMPS -> Is Sta/P2P Client is already connected
5717 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5718 if((NULL != pAdapter)&&
5719 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5720 {
5721 disableBmps = TRUE;
5722 }
5723
5724 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
5725 if((NULL != pAdapter)&&
5726 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5727 {
5728 disableBmps = TRUE;
5729 }
5730
5731 //Exit both Bmps and Imps incase of Go/SAP Mode
5732 if((WLAN_HDD_SOFTAP == session_type) ||
5733 (WLAN_HDD_P2P_GO == session_type))
5734 {
5735 disableBmps = TRUE;
5736 disableImps = TRUE;
5737 }
5738
5739 if(TRUE == disableImps)
5740 {
5741 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5742 {
5743 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5744 }
5745 }
5746
5747 if(TRUE == disableBmps)
5748 {
5749 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5750 {
5751 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5752
5753 if(eHAL_STATUS_SUCCESS != halStatus)
5754 {
5755 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005756 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 VOS_ASSERT(0);
5758 return status;
5759 }
5760 }
5761
5762 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5763 {
5764 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
5765
5766 if(eHAL_STATUS_SUCCESS != halStatus)
5767 {
5768 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005769 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 VOS_ASSERT(0);
5771 return status;
5772 }
5773 }
5774 }
5775
5776 if((TRUE == disableBmps) ||
5777 (TRUE == disableImps))
5778 {
5779 /* Now, get the chip into Full Power now */
5780 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
5781 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
5782 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
5783
5784 if(halStatus != eHAL_STATUS_SUCCESS)
5785 {
5786 if(halStatus == eHAL_STATUS_PMC_PENDING)
5787 {
5788 //Block on a completion variable. Can't wait forever though
5789 wait_for_completion_interruptible_timeout(
5790 &pHddCtx->full_pwr_comp_var, msecs_to_jiffies(1000));
5791 }
5792 else
5793 {
5794 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005795 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005796 VOS_ASSERT(0);
5797 return status;
5798 }
5799 }
5800
5801 status = VOS_STATUS_SUCCESS;
5802 }
5803
5804 break;
5805 }
5806 return status;
5807}
5808
5809hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005810 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 tANI_U8 rtnl_held )
5812{
5813 hdd_adapter_t *pAdapter = NULL;
5814 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
5815 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5816 VOS_STATUS exitbmpsStatus;
5817
Arif Hussain6d2a3322013-11-17 19:50:10 -08005818 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005819
5820 //Disable BMPS incase of Concurrency
5821 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
5822
5823 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
5824 {
5825 //Fail to Exit BMPS
5826 VOS_ASSERT(0);
5827 return NULL;
5828 }
5829
5830 switch(session_type)
5831 {
5832 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005834 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 {
5836 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5837
5838 if( NULL == pAdapter )
5839 return NULL;
5840
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305841#ifdef FEATURE_WLAN_TDLS
5842 /* A Mutex Lock is introduced while changing/initializing the mode to
5843 * protect the concurrent access for the Adapters by TDLS module.
5844 */
5845 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
5846 {
5847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5848 "%s: unable to lock list", __func__);
5849 return NULL;
5850 }
5851#endif
5852
Jeff Johnsone7245742012-09-05 17:12:55 -07005853 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
5854 NL80211_IFTYPE_P2P_CLIENT:
5855 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07005856
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305858#ifdef FEATURE_WLAN_TDLS
5859 mutex_unlock(&pHddCtx->tdls_lock);
5860#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05305861
5862 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 if( VOS_STATUS_SUCCESS != status )
5864 goto err_free_netdev;
5865
5866 status = hdd_register_interface( pAdapter, rtnl_held );
5867 if( VOS_STATUS_SUCCESS != status )
5868 {
5869 hdd_deinit_adapter(pHddCtx, pAdapter);
5870 goto err_free_netdev;
5871 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305872
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05305873 // Workqueue which gets scheduled in IPv4 notification callback.
5874 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
5875
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305876#ifdef WLAN_NS_OFFLOAD
5877 // Workqueue which gets scheduled in IPv6 notification callback.
5878 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
5879#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 //Stop the Interface TX queue.
5881 netif_tx_disable(pAdapter->dev);
5882 //netif_tx_disable(pWlanDev);
5883 netif_carrier_off(pAdapter->dev);
5884
5885 break;
5886 }
5887
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 case WLAN_HDD_SOFTAP:
5890 {
5891 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
5892 if( NULL == pAdapter )
5893 return NULL;
5894
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
5896 NL80211_IFTYPE_AP:
5897 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 pAdapter->device_mode = session_type;
5899
5900 status = hdd_init_ap_mode(pAdapter);
5901 if( VOS_STATUS_SUCCESS != status )
5902 goto err_free_netdev;
5903
5904 status = hdd_register_hostapd( pAdapter, rtnl_held );
5905 if( VOS_STATUS_SUCCESS != status )
5906 {
5907 hdd_deinit_adapter(pHddCtx, pAdapter);
5908 goto err_free_netdev;
5909 }
5910
5911 netif_tx_disable(pAdapter->dev);
5912 netif_carrier_off(pAdapter->dev);
5913
5914 hdd_set_conparam( 1 );
5915 break;
5916 }
5917 case WLAN_HDD_MONITOR:
5918 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5920 if( NULL == pAdapter )
5921 return NULL;
5922
5923 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
5924 pAdapter->device_mode = session_type;
5925 status = hdd_register_interface( pAdapter, rtnl_held );
5926#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
5927 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
5928#else
5929 pAdapter->dev->open = hdd_mon_open;
5930 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
5931#endif
5932 hdd_init_tx_rx( pAdapter );
5933 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5934 //Set adapter to be used for data tx. It will use either GO or softap.
5935 pAdapter->sessionCtx.monitor.pAdapterForTx =
5936 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
5938 {
5939 pAdapter->sessionCtx.monitor.pAdapterForTx =
5940 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
5941 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005942 /* This workqueue will be used to transmit management packet over
5943 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005944 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
5945 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
5946 return NULL;
5947 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07005948
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
5950 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 }
5952 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 case WLAN_HDD_FTM:
5954 {
5955 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5956
5957 if( NULL == pAdapter )
5958 return NULL;
5959 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
5960 * message while loading driver in FTM mode. */
5961 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
5962 pAdapter->device_mode = session_type;
5963 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05305964
5965 hdd_init_tx_rx( pAdapter );
5966
5967 //Stop the Interface TX queue.
5968 netif_tx_disable(pAdapter->dev);
5969 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 }
5971 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 default:
5973 {
5974 VOS_ASSERT(0);
5975 return NULL;
5976 }
5977 }
5978
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 if( VOS_STATUS_SUCCESS == status )
5980 {
5981 //Add it to the hdd's session list.
5982 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
5983 if( NULL == pHddAdapterNode )
5984 {
5985 status = VOS_STATUS_E_NOMEM;
5986 }
5987 else
5988 {
5989 pHddAdapterNode->pAdapter = pAdapter;
5990 status = hdd_add_adapter_back ( pHddCtx,
5991 pHddAdapterNode );
5992 }
5993 }
5994
5995 if( VOS_STATUS_SUCCESS != status )
5996 {
5997 if( NULL != pAdapter )
5998 {
5999 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6000 pAdapter = NULL;
6001 }
6002 if( NULL != pHddAdapterNode )
6003 {
6004 vos_mem_free( pHddAdapterNode );
6005 }
6006
6007 goto resume_bmps;
6008 }
6009
6010 if(VOS_STATUS_SUCCESS == status)
6011 {
6012 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6013
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006014 //Initialize the WoWL service
6015 if(!hdd_init_wowl(pAdapter))
6016 {
6017 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6018 goto err_free_netdev;
6019 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 return pAdapter;
6022
6023err_free_netdev:
6024 free_netdev(pAdapter->dev);
6025 wlan_hdd_release_intf_addr( pHddCtx,
6026 pAdapter->macAddressCurrent.bytes );
6027
6028resume_bmps:
6029 //If bmps disabled enable it
6030 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6031 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306032 if (pHddCtx->hdd_wlan_suspended)
6033 {
6034 hdd_set_pwrparams(pHddCtx);
6035 }
6036 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 }
6038 return NULL;
6039}
6040
6041VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6042 tANI_U8 rtnl_held )
6043{
6044 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6045 VOS_STATUS status;
6046
6047 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6048 if( VOS_STATUS_SUCCESS != status )
6049 return status;
6050
6051 while ( pCurrent->pAdapter != pAdapter )
6052 {
6053 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6054 if( VOS_STATUS_SUCCESS != status )
6055 break;
6056
6057 pCurrent = pNext;
6058 }
6059 pAdapterNode = pCurrent;
6060 if( VOS_STATUS_SUCCESS == status )
6061 {
6062 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6063 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306064
6065#ifdef FEATURE_WLAN_TDLS
6066
6067 /* A Mutex Lock is introduced while changing/initializing the mode to
6068 * protect the concurrent access for the Adapters by TDLS module.
6069 */
6070 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
6071 {
6072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6073 "%s: unable to lock list", __func__);
6074 return VOS_STATUS_E_FAILURE;
6075 }
6076#endif
6077
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 hdd_remove_adapter( pHddCtx, pAdapterNode );
6079 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006080 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006081
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306082#ifdef FEATURE_WLAN_TDLS
6083 mutex_unlock(&pHddCtx->tdls_lock);
6084#endif
6085
Jeff Johnson295189b2012-06-20 16:38:30 -07006086
6087 /* If there is a single session of STA/P2P client, re-enable BMPS */
6088 if ((!vos_concurrent_sessions_running()) &&
6089 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6090 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6091 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306092 if (pHddCtx->hdd_wlan_suspended)
6093 {
6094 hdd_set_pwrparams(pHddCtx);
6095 }
6096 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 }
6098
6099 return VOS_STATUS_SUCCESS;
6100 }
6101
6102 return VOS_STATUS_E_FAILURE;
6103}
6104
6105VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6106{
6107 hdd_adapter_list_node_t *pHddAdapterNode;
6108 VOS_STATUS status;
6109
6110 ENTER();
6111
6112 do
6113 {
6114 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6115 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6116 {
6117 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6118 vos_mem_free( pHddAdapterNode );
6119 }
6120 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6121
6122 EXIT();
6123
6124 return VOS_STATUS_SUCCESS;
6125}
6126
6127void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6128{
6129 v_U8_t addIE[1] = {0};
6130
6131 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6132 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6133 eANI_BOOLEAN_FALSE) )
6134 {
6135 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006136 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 }
6138
6139 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6140 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6141 eANI_BOOLEAN_FALSE) )
6142 {
6143 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006144 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006145 }
6146
6147 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6148 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6149 eANI_BOOLEAN_FALSE) )
6150 {
6151 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006152 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 }
6154}
6155
6156VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6157{
6158 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6159 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6160 union iwreq_data wrqu;
6161
6162 ENTER();
6163
6164 switch(pAdapter->device_mode)
6165 {
6166 case WLAN_HDD_INFRA_STATION:
6167 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006168 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6170 {
6171 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6172 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6173 pAdapter->sessionId,
6174 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6175 else
6176 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6177 pAdapter->sessionId,
6178 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6179 //success implies disconnect command got queued up successfully
6180 if(halStatus == eHAL_STATUS_SUCCESS)
6181 {
6182 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
6183 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6184 }
6185 memset(&wrqu, '\0', sizeof(wrqu));
6186 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6187 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6188 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6189 }
6190 else
6191 {
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05306192 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306194#ifdef WLAN_OPEN_SOURCE
6195#ifdef WLAN_NS_OFFLOAD
6196 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6197#endif
6198#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006199
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306200#ifdef WLAN_OPEN_SOURCE
6201 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6202#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6204 {
6205 INIT_COMPLETION(pAdapter->session_close_comp_var);
6206 if (eHAL_STATUS_SUCCESS ==
6207 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6208 hdd_smeCloseSessionCallback, pAdapter))
6209 {
6210 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006211 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 &pAdapter->session_close_comp_var,
6213 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
6214 }
6215 }
6216
6217 break;
6218
6219 case WLAN_HDD_SOFTAP:
6220 case WLAN_HDD_P2P_GO:
6221 //Any softap specific cleanup here...
6222 mutex_lock(&pHddCtx->sap_lock);
6223 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6224 {
6225 VOS_STATUS status;
6226 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6227
6228 //Stop Bss.
6229 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6230 if (VOS_IS_STATUS_SUCCESS(status))
6231 {
6232 hdd_hostapd_state_t *pHostapdState =
6233 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6234
6235 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6236
6237 if (!VOS_IS_STATUS_SUCCESS(status))
6238 {
6239 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006240 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 }
6242 }
6243 else
6244 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006245 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 }
6247 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6248
6249 if (eHAL_STATUS_FAILURE ==
6250 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6251 0, NULL, eANI_BOOLEAN_FALSE))
6252 {
6253 hddLog(LOGE,
6254 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006255 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 }
6257
6258 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6259 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6260 eANI_BOOLEAN_FALSE) )
6261 {
6262 hddLog(LOGE,
6263 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6264 }
6265
6266 // Reset WNI_CFG_PROBE_RSP Flags
6267 wlan_hdd_reset_prob_rspies(pAdapter);
6268 kfree(pAdapter->sessionCtx.ap.beacon);
6269 pAdapter->sessionCtx.ap.beacon = NULL;
6270 }
6271 mutex_unlock(&pHddCtx->sap_lock);
6272 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006273
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006275#ifdef WLAN_OPEN_SOURCE
6276 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6277#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006279
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 default:
6281 break;
6282 }
6283
6284 EXIT();
6285 return VOS_STATUS_SUCCESS;
6286}
6287
6288VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6289{
6290 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6291 VOS_STATUS status;
6292 hdd_adapter_t *pAdapter;
6293
6294 ENTER();
6295
6296 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6297
6298 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6299 {
6300 pAdapter = pAdapterNode->pAdapter;
6301 netif_tx_disable(pAdapter->dev);
6302 netif_carrier_off(pAdapter->dev);
6303
6304 hdd_stop_adapter( pHddCtx, pAdapter );
6305
6306 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6307 pAdapterNode = pNext;
6308 }
6309
6310 EXIT();
6311
6312 return VOS_STATUS_SUCCESS;
6313}
6314
Rajeev Kumarf999e582014-01-09 17:33:29 -08006315
6316#ifdef FEATURE_WLAN_BATCH_SCAN
6317/**---------------------------------------------------------------------------
6318
6319 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6320 structures
6321
6322 \param - pAdapter Pointer to HDD adapter
6323
6324 \return - None
6325
6326 --------------------------------------------------------------------------*/
6327void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6328{
6329 tHddBatchScanRsp *pNode;
6330 tHddBatchScanRsp *pPrev;
6331
6332 if (pAdapter)
6333 {
6334 pNode = pAdapter->pBatchScanRsp;
6335 while (pNode)
6336 {
6337 pPrev = pNode;
6338 pNode = pNode->pNext;
6339 vos_mem_free((v_VOID_t * )pPrev);
6340 }
6341 pAdapter->pBatchScanRsp = NULL;
6342 }
6343
6344 pAdapter->pBatchScanRsp = NULL;
6345 pAdapter->numScanList = 0;
6346 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6347 pAdapter->prev_batch_id = 0;
6348
6349 return;
6350}
6351#endif
6352
6353
Jeff Johnson295189b2012-06-20 16:38:30 -07006354VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6355{
6356 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6357 VOS_STATUS status;
6358 hdd_adapter_t *pAdapter;
6359
6360 ENTER();
6361
6362 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6363
6364 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6365 {
6366 pAdapter = pAdapterNode->pAdapter;
6367 netif_tx_disable(pAdapter->dev);
6368 netif_carrier_off(pAdapter->dev);
6369
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006370 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6371
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306373 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6374 {
6375 hdd_wmm_adapter_close( pAdapter );
6376 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6377 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006378
Rajeev Kumarf999e582014-01-09 17:33:29 -08006379#ifdef FEATURE_WLAN_BATCH_SCAN
6380 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6381 {
6382 hdd_deinit_batch_scan(pAdapter);
6383 }
6384#endif
6385
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6387 pAdapterNode = pNext;
6388 }
6389
6390 EXIT();
6391
6392 return VOS_STATUS_SUCCESS;
6393}
6394
6395VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6396{
6397 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6398 VOS_STATUS status;
6399 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306400 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006401
6402 ENTER();
6403
6404 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6405
6406 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6407 {
6408 pAdapter = pAdapterNode->pAdapter;
6409
6410 switch(pAdapter->device_mode)
6411 {
6412 case WLAN_HDD_INFRA_STATION:
6413 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006414 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306415
6416 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6417
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 hdd_init_station_mode(pAdapter);
6419 /* Open the gates for HDD to receive Wext commands */
6420 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006421 pHddCtx->scan_info.mScanPending = FALSE;
6422 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006423
6424 //Trigger the initial scan
6425 hdd_wlan_initial_scan(pAdapter);
6426
6427 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306428 if (eConnectionState_Associated == connState ||
6429 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 {
6431 union iwreq_data wrqu;
6432 memset(&wrqu, '\0', sizeof(wrqu));
6433 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6434 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6435 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006436 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006437
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 /* indicate disconnected event to nl80211 */
6439 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6440 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306442 else if (eConnectionState_Connecting == connState)
6443 {
6444 /*
6445 * Indicate connect failure to supplicant if we were in the
6446 * process of connecting
6447 */
6448 cfg80211_connect_result(pAdapter->dev, NULL,
6449 NULL, 0, NULL, 0,
6450 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6451 GFP_KERNEL);
6452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 break;
6454
6455 case WLAN_HDD_SOFTAP:
6456 /* softAP can handle SSR */
6457 break;
6458
6459 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006462 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006463 break;
6464
6465 case WLAN_HDD_MONITOR:
6466 /* monitor interface start */
6467 break;
6468 default:
6469 break;
6470 }
6471
6472 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6473 pAdapterNode = pNext;
6474 }
6475
6476 EXIT();
6477
6478 return VOS_STATUS_SUCCESS;
6479}
6480
6481VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6482{
6483 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6484 hdd_adapter_t *pAdapter;
6485 VOS_STATUS status;
6486 v_U32_t roamId;
6487
6488 ENTER();
6489
6490 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6491
6492 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6493 {
6494 pAdapter = pAdapterNode->pAdapter;
6495
6496 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6497 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6498 {
6499 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6500 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6501
6502 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6503 init_completion(&pAdapter->disconnect_comp_var);
6504 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6505 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6506
6507 wait_for_completion_interruptible_timeout(
6508 &pAdapter->disconnect_comp_var,
6509 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6510
6511 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6512 pHddCtx->isAmpAllowed = VOS_FALSE;
6513 sme_RoamConnect(pHddCtx->hHal,
6514 pAdapter->sessionId, &(pWextState->roamProfile),
6515 &roamId);
6516 }
6517
6518 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6519 pAdapterNode = pNext;
6520 }
6521
6522 EXIT();
6523
6524 return VOS_STATUS_SUCCESS;
6525}
6526
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006527void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6528{
6529 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6530 VOS_STATUS status;
6531 hdd_adapter_t *pAdapter;
6532 hdd_station_ctx_t *pHddStaCtx;
6533 hdd_ap_ctx_t *pHddApCtx;
6534 hdd_hostapd_state_t * pHostapdState;
6535 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6536 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6537 const char *p2pMode = "DEV";
6538 const char *ccMode = "Standalone";
6539 int n;
6540
6541 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6542 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6543 {
6544 pAdapter = pAdapterNode->pAdapter;
6545 switch (pAdapter->device_mode) {
6546 case WLAN_HDD_INFRA_STATION:
6547 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6548 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6549 staChannel = pHddStaCtx->conn_info.operationChannel;
6550 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6551 }
6552 break;
6553 case WLAN_HDD_P2P_CLIENT:
6554 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6555 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6556 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6557 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6558 p2pMode = "CLI";
6559 }
6560 break;
6561 case WLAN_HDD_P2P_GO:
6562 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6563 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6564 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6565 p2pChannel = pHddApCtx->operatingChannel;
6566 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6567 }
6568 p2pMode = "GO";
6569 break;
6570 case WLAN_HDD_SOFTAP:
6571 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6572 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6573 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6574 apChannel = pHddApCtx->operatingChannel;
6575 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6576 }
6577 break;
6578 default:
6579 break;
6580 }
6581 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6582 pAdapterNode = pNext;
6583 }
6584 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
6585 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
6586 }
6587 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
6588 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
6589 if (p2pChannel > 0) {
6590 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
6591 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
6592 }
6593 if (apChannel > 0) {
6594 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
6595 apChannel, MAC_ADDR_ARRAY(apBssid));
6596 }
6597
6598 if (p2pChannel > 0 && apChannel > 0) {
6599 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
6600 }
6601}
6602
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006603bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006604{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006605 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07006606}
6607
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006608/* Once SSR is disabled then it cannot be set. */
6609void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07006610{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006611 if (HDD_SSR_DISABLED == isSsrRequired)
6612 return;
6613
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 isSsrRequired = value;
6615}
6616
6617VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
6618 hdd_adapter_list_node_t** ppAdapterNode)
6619{
6620 VOS_STATUS status;
6621 spin_lock(&pHddCtx->hddAdapters.lock);
6622 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
6623 (hdd_list_node_t**) ppAdapterNode );
6624 spin_unlock(&pHddCtx->hddAdapters.lock);
6625 return status;
6626}
6627
6628VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
6629 hdd_adapter_list_node_t* pAdapterNode,
6630 hdd_adapter_list_node_t** pNextAdapterNode)
6631{
6632 VOS_STATUS status;
6633 spin_lock(&pHddCtx->hddAdapters.lock);
6634 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
6635 (hdd_list_node_t*) pAdapterNode,
6636 (hdd_list_node_t**)pNextAdapterNode );
6637
6638 spin_unlock(&pHddCtx->hddAdapters.lock);
6639 return status;
6640}
6641
6642VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
6643 hdd_adapter_list_node_t* pAdapterNode)
6644{
6645 VOS_STATUS status;
6646 spin_lock(&pHddCtx->hddAdapters.lock);
6647 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
6648 &pAdapterNode->node );
6649 spin_unlock(&pHddCtx->hddAdapters.lock);
6650 return status;
6651}
6652
6653VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
6654 hdd_adapter_list_node_t** ppAdapterNode)
6655{
6656 VOS_STATUS status;
6657 spin_lock(&pHddCtx->hddAdapters.lock);
6658 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
6659 (hdd_list_node_t**) ppAdapterNode );
6660 spin_unlock(&pHddCtx->hddAdapters.lock);
6661 return status;
6662}
6663
6664VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
6665 hdd_adapter_list_node_t* pAdapterNode)
6666{
6667 VOS_STATUS status;
6668 spin_lock(&pHddCtx->hddAdapters.lock);
6669 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
6670 (hdd_list_node_t*) pAdapterNode );
6671 spin_unlock(&pHddCtx->hddAdapters.lock);
6672 return status;
6673}
6674
6675VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
6676 hdd_adapter_list_node_t* pAdapterNode)
6677{
6678 VOS_STATUS status;
6679 spin_lock(&pHddCtx->hddAdapters.lock);
6680 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
6681 (hdd_list_node_t*) pAdapterNode );
6682 spin_unlock(&pHddCtx->hddAdapters.lock);
6683 return status;
6684}
6685
6686hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
6687 tSirMacAddr macAddr )
6688{
6689 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6690 hdd_adapter_t *pAdapter;
6691 VOS_STATUS status;
6692
6693 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6694
6695 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6696 {
6697 pAdapter = pAdapterNode->pAdapter;
6698
6699 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
6700 macAddr, sizeof(tSirMacAddr) ) )
6701 {
6702 return pAdapter;
6703 }
6704 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6705 pAdapterNode = pNext;
6706 }
6707
6708 return NULL;
6709
6710}
6711
6712hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
6713{
6714 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6715 hdd_adapter_t *pAdapter;
6716 VOS_STATUS status;
6717
6718 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6719
6720 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6721 {
6722 pAdapter = pAdapterNode->pAdapter;
6723
6724 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
6725 IFNAMSIZ ) )
6726 {
6727 return pAdapter;
6728 }
6729 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6730 pAdapterNode = pNext;
6731 }
6732
6733 return NULL;
6734
6735}
6736
6737hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
6738{
6739 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6740 hdd_adapter_t *pAdapter;
6741 VOS_STATUS status;
6742
6743 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6744
6745 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6746 {
6747 pAdapter = pAdapterNode->pAdapter;
6748
6749 if( pAdapter && (mode == pAdapter->device_mode) )
6750 {
6751 return pAdapter;
6752 }
6753 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6754 pAdapterNode = pNext;
6755 }
6756
6757 return NULL;
6758
6759}
6760
6761//Remove this function later
6762hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
6763{
6764 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6765 hdd_adapter_t *pAdapter;
6766 VOS_STATUS status;
6767
6768 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6769
6770 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6771 {
6772 pAdapter = pAdapterNode->pAdapter;
6773
6774 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
6775 {
6776 return pAdapter;
6777 }
6778
6779 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6780 pAdapterNode = pNext;
6781 }
6782
6783 return NULL;
6784
6785}
6786
Jeff Johnson295189b2012-06-20 16:38:30 -07006787/**---------------------------------------------------------------------------
6788
6789 \brief hdd_set_monitor_tx_adapter() -
6790
6791 This API initializes the adapter to be used while transmitting on monitor
6792 adapter.
6793
6794 \param - pHddCtx - Pointer to the HDD context.
6795 pAdapter - Adapter that will used for TX. This can be NULL.
6796 \return - None.
6797 --------------------------------------------------------------------------*/
6798void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6799{
6800 hdd_adapter_t *pMonAdapter;
6801
6802 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
6803
6804 if( NULL != pMonAdapter )
6805 {
6806 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
6807 }
6808}
Jeff Johnson295189b2012-06-20 16:38:30 -07006809/**---------------------------------------------------------------------------
6810
6811 \brief hdd_select_queue() -
6812
6813 This API returns the operating channel of the requested device mode
6814
6815 \param - pHddCtx - Pointer to the HDD context.
6816 - mode - Device mode for which operating channel is required
6817 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
6818 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
6819 \return - channel number. "0" id the requested device is not found OR it is not connected.
6820 --------------------------------------------------------------------------*/
6821v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
6822{
6823 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6824 VOS_STATUS status;
6825 hdd_adapter_t *pAdapter;
6826 v_U8_t operatingChannel = 0;
6827
6828 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6829
6830 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6831 {
6832 pAdapter = pAdapterNode->pAdapter;
6833
6834 if( mode == pAdapter->device_mode )
6835 {
6836 switch(pAdapter->device_mode)
6837 {
6838 case WLAN_HDD_INFRA_STATION:
6839 case WLAN_HDD_P2P_CLIENT:
6840 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6841 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
6842 break;
6843 case WLAN_HDD_SOFTAP:
6844 case WLAN_HDD_P2P_GO:
6845 /*softap connection info */
6846 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6847 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
6848 break;
6849 default:
6850 break;
6851 }
6852
6853 break; //Found the device of interest. break the loop
6854 }
6855
6856 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6857 pAdapterNode = pNext;
6858 }
6859 return operatingChannel;
6860}
6861
6862#ifdef WLAN_FEATURE_PACKET_FILTERING
6863/**---------------------------------------------------------------------------
6864
6865 \brief hdd_set_multicast_list() -
6866
6867 This used to set the multicast address list.
6868
6869 \param - dev - Pointer to the WLAN device.
6870 - skb - Pointer to OS packet (sk_buff).
6871 \return - success/fail
6872
6873 --------------------------------------------------------------------------*/
6874static void hdd_set_multicast_list(struct net_device *dev)
6875{
6876 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 int mc_count;
6878 int i = 0;
6879 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306880
6881 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 {
6883 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306884 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 return;
6886 }
6887
6888 if (dev->flags & IFF_ALLMULTI)
6889 {
6890 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006891 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306892 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 }
6894 else
6895 {
6896 mc_count = netdev_mc_count(dev);
6897 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006898 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
6900 {
6901 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006902 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306903 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 return;
6905 }
6906
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306907 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07006908
6909 netdev_for_each_mc_addr(ha, dev) {
6910 if (i == mc_count)
6911 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306912 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
6913 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08006914 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306916 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 i++;
6918 }
6919 }
6920 return;
6921}
6922#endif
6923
6924/**---------------------------------------------------------------------------
6925
6926 \brief hdd_select_queue() -
6927
6928 This function is registered with the Linux OS for network
6929 core to decide which queue to use first.
6930
6931 \param - dev - Pointer to the WLAN device.
6932 - skb - Pointer to OS packet (sk_buff).
6933 \return - ac, Queue Index/access category corresponding to UP in IP header
6934
6935 --------------------------------------------------------------------------*/
6936v_U16_t hdd_select_queue(struct net_device *dev,
6937 struct sk_buff *skb)
6938{
6939 return hdd_wmm_select_queue(dev, skb);
6940}
6941
6942
6943/**---------------------------------------------------------------------------
6944
6945 \brief hdd_wlan_initial_scan() -
6946
6947 This function triggers the initial scan
6948
6949 \param - pAdapter - Pointer to the HDD adapter.
6950
6951 --------------------------------------------------------------------------*/
6952void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
6953{
6954 tCsrScanRequest scanReq;
6955 tCsrChannelInfo channelInfo;
6956 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07006957 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6959
6960 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
6961 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
6962 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
6963
6964 if(sme_Is11dSupported(pHddCtx->hHal))
6965 {
6966 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
6967 if ( HAL_STATUS_SUCCESS( halStatus ) )
6968 {
6969 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
6970 if( !scanReq.ChannelInfo.ChannelList )
6971 {
6972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
6973 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006974 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 return;
6976 }
6977 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
6978 channelInfo.numOfChannels);
6979 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
6980 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006981 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 }
6983
6984 scanReq.scanType = eSIR_PASSIVE_SCAN;
6985 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
6986 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
6987 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
6988 }
6989 else
6990 {
6991 scanReq.scanType = eSIR_ACTIVE_SCAN;
6992 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
6993 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
6994 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
6995 }
6996
6997 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
6998 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6999 {
7000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7001 __func__, halStatus );
7002 }
7003
7004 if(sme_Is11dSupported(pHddCtx->hHal))
7005 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7006}
7007
Jeff Johnson295189b2012-06-20 16:38:30 -07007008/**---------------------------------------------------------------------------
7009
7010 \brief hdd_full_power_callback() - HDD full power callback function
7011
7012 This is the function invoked by SME to inform the result of a full power
7013 request issued by HDD
7014
7015 \param - callbackcontext - Pointer to cookie
7016 \param - status - result of request
7017
7018 \return - None
7019
7020 --------------------------------------------------------------------------*/
7021static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7022{
Jeff Johnson72a40512013-12-19 10:14:15 -08007023 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007024
7025 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307026 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007027
7028 if (NULL == callbackContext)
7029 {
7030 hddLog(VOS_TRACE_LEVEL_ERROR,
7031 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007032 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 return;
7034 }
7035
Jeff Johnson72a40512013-12-19 10:14:15 -08007036 /* there is a race condition that exists between this callback
7037 function and the caller since the caller could time out either
7038 before or while this code is executing. we use a spinlock to
7039 serialize these actions */
7040 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007041
7042 if (POWER_CONTEXT_MAGIC != pContext->magic)
7043 {
7044 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007045 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 hddLog(VOS_TRACE_LEVEL_WARN,
7047 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007048 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 return;
7050 }
7051
Jeff Johnson72a40512013-12-19 10:14:15 -08007052 /* context is valid so caller is still waiting */
7053
7054 /* paranoia: invalidate the magic */
7055 pContext->magic = 0;
7056
7057 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007058 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007059
7060 /* serialization is complete */
7061 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007062}
7063
7064/**---------------------------------------------------------------------------
7065
7066 \brief hdd_wlan_exit() - HDD WLAN exit function
7067
7068 This is the driver exit point (invoked during rmmod)
7069
7070 \param - pHddCtx - Pointer to the HDD Context
7071
7072 \return - None
7073
7074 --------------------------------------------------------------------------*/
7075void hdd_wlan_exit(hdd_context_t *pHddCtx)
7076{
7077 eHalStatus halStatus;
7078 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7079 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307080 struct wiphy *wiphy = pHddCtx->wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 hdd_adapter_t* pAdapter;
Jeff Johnson72a40512013-12-19 10:14:15 -08007082 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 long lrc;
7084
7085 ENTER();
7086
Jeff Johnson88ba7742013-02-27 14:36:02 -08007087 if (VOS_FTM_MODE != hdd_get_conparam())
7088 {
7089 // Unloading, restart logic is no more required.
7090 wlan_hdd_restart_deinit(pHddCtx);
7091 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007092
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007096 {
7097 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7098 WLAN_HDD_INFRA_STATION);
7099 if (pAdapter == NULL)
7100 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7101
7102 if (pAdapter != NULL)
7103 {
7104 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7105 hdd_UnregisterWext(pAdapter->dev);
7106 }
7107 }
7108 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007109
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007111 {
7112 wlan_hdd_ftm_close(pHddCtx);
7113 goto free_hdd_ctx;
7114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 //Stop the Interface TX queue.
7116 //netif_tx_disable(pWlanDev);
7117 //netif_carrier_off(pWlanDev);
7118
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7120 {
7121 pAdapter = hdd_get_adapter(pHddCtx,
7122 WLAN_HDD_SOFTAP);
7123 }
7124 else
7125 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007127 {
7128 pAdapter = hdd_get_adapter(pHddCtx,
7129 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007130 if (pAdapter == NULL)
7131 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007134 /* DeRegister with platform driver as client for Suspend/Resume */
7135 vosStatus = hddDeregisterPmOps(pHddCtx);
7136 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7137 {
7138 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7139 VOS_ASSERT(0);
7140 }
7141
7142 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7143 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7144 {
7145 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7146 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007147
7148 // Cancel any outstanding scan requests. We are about to close all
7149 // of our adapters, but an adapter structure is what SME passes back
7150 // to our callback function. Hence if there are any outstanding scan
7151 // requests then there is a race condition between when the adapter
7152 // is closed and when the callback is invoked. We try to resolve that
7153 // race condition here by canceling any outstanding scans before we
7154 // close the adapters.
7155 // Note that the scans may be cancelled in an asynchronous manner, so
7156 // ideally there needs to be some kind of synchronization. Rather than
7157 // introduce a new synchronization here, we will utilize the fact that
7158 // we are about to Request Full Power, and since that is synchronized,
7159 // the expectation is that by the time Request Full Power has completed,
7160 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007161 if (NULL != pAdapter)
7162 hdd_abort_mac_scan( pHddCtx, pAdapter->sessionId);
7163 else
7164 hddLog(VOS_TRACE_LEVEL_ERROR,
7165 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007166
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007167 //Stop the traffic monitor timer
7168 if ( VOS_TIMER_STATE_RUNNING ==
7169 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7170 {
7171 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7172 }
7173
7174 // Destroy the traffic monitor timer
7175 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7176 &pHddCtx->tx_rx_trafficTmr)))
7177 {
7178 hddLog(VOS_TRACE_LEVEL_ERROR,
7179 "%s: Cannot deallocate Traffic monitor timer", __func__);
7180 }
7181
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 //Disable IMPS/BMPS as we do not want the device to enter any power
7183 //save mode during shutdown
7184 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7185 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7186 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7187
7188 //Ensure that device is in full power as we will touch H/W during vos_Stop
7189 init_completion(&powerContext.completion);
7190 powerContext.magic = POWER_CONTEXT_MAGIC;
7191
7192 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7193 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7194
7195 if (eHAL_STATUS_SUCCESS != halStatus)
7196 {
7197 if (eHAL_STATUS_PMC_PENDING == halStatus)
7198 {
7199 /* request was sent -- wait for the response */
7200 lrc = wait_for_completion_interruptible_timeout(
7201 &powerContext.completion,
7202 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 if (lrc <= 0)
7204 {
7205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007206 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 }
7208 }
7209 else
7210 {
7211 hddLog(VOS_TRACE_LEVEL_ERROR,
7212 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007213 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007214 /* continue -- need to clean up as much as possible */
7215 }
7216 }
7217
Jeff Johnson72a40512013-12-19 10:14:15 -08007218 /* either we never sent a request, we sent a request and received a
7219 response or we sent a request and timed out. if we never sent a
7220 request or if we sent a request and got a response, we want to
7221 clear the magic out of paranoia. if we timed out there is a
7222 race condition such that the callback function could be
7223 executing at the same time we are. of primary concern is if the
7224 callback function had already verified the "magic" but had not
7225 yet set the completion variable when a timeout occurred. we
7226 serialize these activities by invalidating the magic while
7227 holding a shared spinlock which will cause us to block if the
7228 callback is currently executing */
7229 spin_lock(&hdd_context_lock);
7230 powerContext.magic = 0;
7231 spin_unlock(&hdd_context_lock);
7232
Yue Ma0d4891e2013-08-06 17:01:45 -07007233 hdd_debugfs_exit(pHddCtx);
7234
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 // Unregister the Net Device Notifier
7236 unregister_netdevice_notifier(&hdd_netdev_notifier);
7237
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 hdd_stop_all_adapters( pHddCtx );
7239
Jeff Johnson295189b2012-06-20 16:38:30 -07007240#ifdef WLAN_BTAMP_FEATURE
7241 vosStatus = WLANBAP_Stop(pVosContext);
7242 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7243 {
7244 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7245 "%s: Failed to stop BAP",__func__);
7246 }
7247#endif //WLAN_BTAMP_FEATURE
7248
7249 //Stop all the modules
7250 vosStatus = vos_stop( pVosContext );
7251 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7252 {
7253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7254 "%s: Failed to stop VOSS",__func__);
7255 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7256 }
7257
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 //Assert Deep sleep signal now to put Libra HW in lowest power state
7259 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7260 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7261
7262 //Vote off any PMIC voltage supplies
7263 vos_chipPowerDown(NULL, NULL, NULL);
7264
7265 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7266
Leo Chang59cdc7e2013-07-10 10:08:21 -07007267
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007269 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007270
7271 //Close the scheduler before calling vos_close to make sure no thread is
7272 // scheduled after the each module close is called i.e after all the data
7273 // structures are freed.
7274 vosStatus = vos_sched_close( pVosContext );
7275 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7276 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7277 "%s: Failed to close VOSS Scheduler",__func__);
7278 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7279 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007280#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007281#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7282 /* Destroy the wake lock */
7283 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7284#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007285 /* Destroy the wake lock */
7286 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007287#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007288
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307289#ifdef CONFIG_ENABLE_LINUX_REG
7290 vosStatus = vos_nv_close();
7291 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7292 {
7293 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7294 "%s: Failed to close NV", __func__);
7295 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7296 }
7297#endif
7298
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 //Close VOSS
7300 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7301 vos_close(pVosContext);
7302
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 //Close Watchdog
7304 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7305 vos_watchdog_close(pVosContext);
7306
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307307 //Clean up HDD Nlink Service
7308 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007309#ifdef WLAN_KD_READY_NOTIFIER
7310 nl_srv_exit(pHddCtx->ptt_pid);
7311#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307312 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007313#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 /* Cancel the vote for XO Core ON.
7316 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7317 * exited at this point
7318 */
7319 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007320 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7322 {
7323 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7324 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007325 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 }
7327
7328 hdd_close_all_adapters( pHddCtx );
7329
7330
7331 //Free up dynamically allocated members inside HDD Adapter
7332 kfree(pHddCtx->cfg_ini);
7333 pHddCtx->cfg_ini= NULL;
7334
7335 /* free the power on lock from platform driver */
7336 if (free_riva_power_on_lock("wlan"))
7337 {
7338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7339 __func__);
7340 }
7341
Jeff Johnson88ba7742013-02-27 14:36:02 -08007342free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007343 /* FTM mode, WIPHY did not registered
7344 If un-register here, system crash will happen */
7345 if (VOS_FTM_MODE != hdd_get_conparam())
7346 {
7347 wiphy_unregister(wiphy) ;
7348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007349 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 if (hdd_is_ssr_required())
7351 {
7352 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007353 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 msleep(5000);
7355 }
7356 hdd_set_ssr_required (VOS_FALSE);
7357}
7358
7359
7360/**---------------------------------------------------------------------------
7361
7362 \brief hdd_update_config_from_nv() - Function to update the contents of
7363 the running configuration with parameters taken from NV storage
7364
7365 \param - pHddCtx - Pointer to the HDD global context
7366
7367 \return - VOS_STATUS_SUCCESS if successful
7368
7369 --------------------------------------------------------------------------*/
7370static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7371{
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 v_BOOL_t itemIsValid = VOS_FALSE;
7373 VOS_STATUS status;
7374 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7375 v_U8_t macLoop;
7376
7377 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7378 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7379 if(status != VOS_STATUS_SUCCESS)
7380 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007381 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 return VOS_STATUS_E_FAILURE;
7383 }
7384
7385 if (itemIsValid == VOS_TRUE)
7386 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007387 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007388 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7389 VOS_MAX_CONCURRENCY_PERSONA);
7390 if(status != VOS_STATUS_SUCCESS)
7391 {
7392 /* Get MAC from NV fail, not update CFG info
7393 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007394 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007395 return VOS_STATUS_E_FAILURE;
7396 }
7397
7398 /* If first MAC is not valid, treat all others are not valid
7399 * Then all MACs will be got from ini file */
7400 if(vos_is_macaddr_zero(&macFromNV[0]))
7401 {
7402 /* MAC address in NV file is not configured yet */
7403 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7404 return VOS_STATUS_E_INVAL;
7405 }
7406
7407 /* Get MAC address from NV, update CFG info */
7408 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7409 {
7410 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7411 {
7412 printk(KERN_ERR "not valid MAC from NV for %d", macLoop);
7413 /* This MAC is not valid, skip it
7414 * This MAC will be got from ini file */
7415 }
7416 else
7417 {
7418 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7419 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7420 VOS_MAC_ADDR_SIZE);
7421 }
7422 }
7423 }
7424 else
7425 {
7426 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7427 return VOS_STATUS_E_FAILURE;
7428 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007429
Jeff Johnson295189b2012-06-20 16:38:30 -07007430
7431 return VOS_STATUS_SUCCESS;
7432}
7433
7434/**---------------------------------------------------------------------------
7435
7436 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7437
7438 \param - pAdapter - Pointer to the HDD
7439
7440 \return - None
7441
7442 --------------------------------------------------------------------------*/
7443VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7444{
7445 eHalStatus halStatus;
7446 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307447 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007448
Jeff Johnson295189b2012-06-20 16:38:30 -07007449
7450 // Send ready indication to the HDD. This will kick off the MAC
7451 // into a 'running' state and should kick off an initial scan.
7452 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7453 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7454 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307455 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 "code %08d [x%08x]",__func__, halStatus, halStatus );
7457 return VOS_STATUS_E_FAILURE;
7458 }
7459
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307460 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7462 // And RIVA will crash
7463 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7464 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307465 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7466 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7467
7468
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 return VOS_STATUS_SUCCESS;
7470}
7471
Jeff Johnson295189b2012-06-20 16:38:30 -07007472/* wake lock APIs for HDD */
7473void hdd_prevent_suspend(void)
7474{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007475#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007477#else
7478 wcnss_prevent_suspend();
7479#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007480}
7481
7482void hdd_allow_suspend(void)
7483{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007484#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007486#else
7487 wcnss_allow_suspend();
7488#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007489}
7490
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007491void hdd_allow_suspend_timeout(v_U32_t timeout)
7492{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007493#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007494 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007495#else
7496 /* Do nothing as there is no API in wcnss for timeout*/
7497#endif
7498}
7499
Jeff Johnson295189b2012-06-20 16:38:30 -07007500/**---------------------------------------------------------------------------
7501
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007502 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7503 information between Host and Riva
7504
7505 This function gets reported version of FW
7506 It also finds the version of Riva headers used to compile the host
7507 It compares the above two and prints a warning if they are different
7508 It gets the SW and HW version string
7509 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7510 indicating the features they support through a bitmap
7511
7512 \param - pHddCtx - Pointer to HDD context
7513
7514 \return - void
7515
7516 --------------------------------------------------------------------------*/
7517
7518void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7519{
7520
7521 tSirVersionType versionCompiled;
7522 tSirVersionType versionReported;
7523 tSirVersionString versionString;
7524 tANI_U8 fwFeatCapsMsgSupported = 0;
7525 VOS_STATUS vstatus;
7526
7527 /* retrieve and display WCNSS version information */
7528 do {
7529
7530 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7531 &versionCompiled);
7532 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7533 {
7534 hddLog(VOS_TRACE_LEVEL_FATAL,
7535 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007536 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007537 break;
7538 }
7539
7540 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7541 &versionReported);
7542 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7543 {
7544 hddLog(VOS_TRACE_LEVEL_FATAL,
7545 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007546 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007547 break;
7548 }
7549
7550 if ((versionCompiled.major != versionReported.major) ||
7551 (versionCompiled.minor != versionReported.minor) ||
7552 (versionCompiled.version != versionReported.version) ||
7553 (versionCompiled.revision != versionReported.revision))
7554 {
7555 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7556 "Host expected %u.%u.%u.%u\n",
7557 WLAN_MODULE_NAME,
7558 (int)versionReported.major,
7559 (int)versionReported.minor,
7560 (int)versionReported.version,
7561 (int)versionReported.revision,
7562 (int)versionCompiled.major,
7563 (int)versionCompiled.minor,
7564 (int)versionCompiled.version,
7565 (int)versionCompiled.revision);
7566 }
7567 else
7568 {
7569 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
7570 WLAN_MODULE_NAME,
7571 (int)versionReported.major,
7572 (int)versionReported.minor,
7573 (int)versionReported.version,
7574 (int)versionReported.revision);
7575 }
7576
7577 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
7578 versionString,
7579 sizeof(versionString));
7580 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7581 {
7582 hddLog(VOS_TRACE_LEVEL_FATAL,
7583 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007584 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007585 break;
7586 }
7587
7588 pr_info("%s: WCNSS software version %s\n",
7589 WLAN_MODULE_NAME, versionString);
7590
7591 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
7592 versionString,
7593 sizeof(versionString));
7594 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7595 {
7596 hddLog(VOS_TRACE_LEVEL_FATAL,
7597 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007598 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007599 break;
7600 }
7601
7602 pr_info("%s: WCNSS hardware version %s\n",
7603 WLAN_MODULE_NAME, versionString);
7604
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007605 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
7606 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007607 send the message only if it the riva is 1.1
7608 minor numbers for different riva branches:
7609 0 -> (1.0)Mainline Build
7610 1 -> (1.1)Mainline Build
7611 2->(1.04) Stability Build
7612 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007613 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007614 ((versionReported.minor>=1) && (versionReported.version>=1)))
7615 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
7616 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007617
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007618 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08007619 {
7620#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
7621 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
7622 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
7623#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07007624 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
7625 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
7626 {
7627 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
7628 }
7629
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007630 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08007631 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007632
7633 } while (0);
7634
7635}
7636
7637/**---------------------------------------------------------------------------
7638
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307639 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
7640
7641 \param - pHddCtx - Pointer to the hdd context
7642
7643 \return - true if hardware supports 5GHz
7644
7645 --------------------------------------------------------------------------*/
7646static boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
7647{
7648 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
7649 * then hardware support 5Ghz.
7650 */
7651 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
7652 {
7653 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
7654 return true;
7655 }
7656 else
7657 {
7658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
7659 __func__);
7660 return false;
7661 }
7662}
7663
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307664/**---------------------------------------------------------------------------
7665
7666 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
7667 generate function
7668
7669 This is generate the random mac address for WLAN interface
7670
7671 \param - pHddCtx - Pointer to HDD context
7672 idx - Start interface index to get auto
7673 generated mac addr.
7674 mac_addr - Mac address
7675
7676 \return - 0 for success, < 0 for failure
7677
7678 --------------------------------------------------------------------------*/
7679
7680static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
7681 int idx, v_MACADDR_t mac_addr)
7682{
7683 int i;
7684 unsigned int serialno;
7685 serialno = wcnss_get_serial_number();
7686
7687 if (0 != serialno)
7688 {
7689 /* MAC address has 3 bytes of OUI so we have a maximum of 3
7690 bytes of the serial number that can be used to generate
7691 the other 3 bytes of the MAC address. Mask off all but
7692 the lower 3 bytes (this will also make sure we don't
7693 overflow in the next step) */
7694 serialno &= 0x00FFFFFF;
7695
7696 /* we need a unique address for each session */
7697 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
7698
7699 /* autogen other Mac addresses */
7700 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7701 {
7702 /* start with the entire default address */
7703 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
7704 /* then replace the lower 3 bytes */
7705 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
7706 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
7707 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
7708
7709 serialno++;
7710 hddLog(VOS_TRACE_LEVEL_ERROR,
7711 "%s: Derived Mac Addr: "
7712 MAC_ADDRESS_STR, __func__,
7713 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
7714 }
7715
7716 }
7717 else
7718 {
7719 hddLog(LOGE, FL("Failed to Get Serial NO"));
7720 return -1;
7721 }
7722 return 0;
7723}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307724
7725/**---------------------------------------------------------------------------
7726
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 \brief hdd_wlan_startup() - HDD init function
7728
7729 This is the driver startup code executed once a WLAN device has been detected
7730
7731 \param - dev - Pointer to the underlying device
7732
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007733 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07007734
7735 --------------------------------------------------------------------------*/
7736
7737int hdd_wlan_startup(struct device *dev )
7738{
7739 VOS_STATUS status;
7740 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07007741 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007742 hdd_context_t *pHddCtx = NULL;
7743 v_CONTEXT_t pVosContext= NULL;
7744#ifdef WLAN_BTAMP_FEATURE
7745 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
7746 WLANBAP_ConfigType btAmpConfig;
7747 hdd_config_t *pConfig;
7748#endif
7749 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307751 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07007752
7753 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 /*
7755 * cfg80211: wiphy allocation
7756 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307757 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007758
7759 if(wiphy == NULL)
7760 {
7761 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007762 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 }
7764
7765 pHddCtx = wiphy_priv(wiphy);
7766
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 //Initialize the adapter context to zeros.
7768 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
7769
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007771 hdd_prevent_suspend();
7772 pHddCtx->isLoadUnloadInProgress = TRUE;
7773
7774 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
7775
7776 /*Get vos context here bcoz vos_open requires it*/
7777 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
7778
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08007779 if(pVosContext == NULL)
7780 {
7781 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
7782 goto err_free_hdd_context;
7783 }
7784
Jeff Johnson295189b2012-06-20 16:38:30 -07007785 //Save the Global VOSS context in adapter context for future.
7786 pHddCtx->pvosContext = pVosContext;
7787
7788 //Save the adapter context in global context for future.
7789 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
7790
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 pHddCtx->parent_dev = dev;
7792
7793 init_completion(&pHddCtx->full_pwr_comp_var);
7794 init_completion(&pHddCtx->standby_comp_var);
7795 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007796 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08007797 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05307798 init_completion(&pHddCtx->wiphy_channel_update_event);
Amar Singhala49cbc52013-10-08 18:37:44 -07007799
7800#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07007801 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07007802#else
7803 init_completion(&pHddCtx->driver_crda_req);
7804#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007805
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05307806 spin_lock_init(&pHddCtx->schedScan_lock);
7807
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
7809
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307810#ifdef FEATURE_WLAN_TDLS
7811 /* tdls_lock is initialized before an hdd_open_adapter ( which is
7812 * invoked by other instances also) to protect the concurrent
7813 * access for the Adapters by TDLS module.
7814 */
7815 mutex_init(&pHddCtx->tdls_lock);
7816#endif
7817
Kiet Lam46b8e4e2013-11-06 21:49:53 +05307818 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 // Load all config first as TL config is needed during vos_open
7820 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
7821 if(pHddCtx->cfg_ini == NULL)
7822 {
7823 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
7824 goto err_free_hdd_context;
7825 }
7826
7827 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
7828
7829 // Read and parse the qcom_cfg.ini file
7830 status = hdd_parse_config_ini( pHddCtx );
7831 if ( VOS_STATUS_SUCCESS != status )
7832 {
7833 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
7834 __func__, WLAN_INI_FILE);
7835 goto err_config;
7836 }
Arif Hussaind5218912013-12-05 01:10:55 -08007837#ifdef MEMORY_DEBUG
7838 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
7839 vos_mem_init();
7840
7841 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
7842 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
7843#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007844
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05307845 /* INI has been read, initialise the configuredMcastBcastFilter with
7846 * INI value as this will serve as the default value
7847 */
7848 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
7849 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
7850 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307851
7852 if (false == hdd_is_5g_supported(pHddCtx))
7853 {
7854 //5Ghz is not supported.
7855 if (1 != pHddCtx->cfg_ini->nBandCapability)
7856 {
7857 hddLog(VOS_TRACE_LEVEL_INFO,
7858 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
7859 pHddCtx->cfg_ini->nBandCapability = 1;
7860 }
7861 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05307862
7863 /* If SNR Monitoring is enabled, FW has to parse all beacons
7864 * for calcaluting and storing the average SNR, so set Nth beacon
7865 * filter to 1 to enable FW to parse all the beaocons
7866 */
7867 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
7868 {
7869 /* The log level is deliberately set to WARN as overriding
7870 * nthBeaconFilter to 1 will increase power cosumption and this
7871 * might just prove helpful to detect the power issue.
7872 */
7873 hddLog(VOS_TRACE_LEVEL_WARN,
7874 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
7875 pHddCtx->cfg_ini->nthBeaconFilter = 1;
7876 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307878 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307880 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 {
7882 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307883 "%s: wlan_hdd_cfg80211_init return failure", __func__);
7884 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007886
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007887 // Update VOS trace levels based upon the cfg.ini
7888 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
7889 pHddCtx->cfg_ini->vosTraceEnableBAP);
7890 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
7891 pHddCtx->cfg_ini->vosTraceEnableTL);
7892 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
7893 pHddCtx->cfg_ini->vosTraceEnableWDI);
7894 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
7895 pHddCtx->cfg_ini->vosTraceEnableHDD);
7896 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
7897 pHddCtx->cfg_ini->vosTraceEnableSME);
7898 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
7899 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05307900 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
7901 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007902 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
7903 pHddCtx->cfg_ini->vosTraceEnableWDA);
7904 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
7905 pHddCtx->cfg_ini->vosTraceEnableSYS);
7906 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
7907 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007908 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
7909 pHddCtx->cfg_ini->vosTraceEnableSAP);
7910 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
7911 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007912
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 // Update WDI trace levels based upon the cfg.ini
7914 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
7915 pHddCtx->cfg_ini->wdiTraceEnableDAL);
7916 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
7917 pHddCtx->cfg_ini->wdiTraceEnableCTL);
7918 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
7919 pHddCtx->cfg_ini->wdiTraceEnableDAT);
7920 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
7921 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007922
Jeff Johnson88ba7742013-02-27 14:36:02 -08007923 if (VOS_FTM_MODE == hdd_get_conparam())
7924 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007925 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
7926 {
7927 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
7928 goto err_free_hdd_context;
7929 }
7930 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
7931 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08007932 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007933
Jeff Johnson88ba7742013-02-27 14:36:02 -08007934 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7936 {
7937 status = vos_watchdog_open(pVosContext,
7938 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
7939
7940 if(!VOS_IS_STATUS_SUCCESS( status ))
7941 {
7942 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307943 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 }
7945 }
7946
7947 pHddCtx->isLogpInProgress = FALSE;
7948 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
7949
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
7951 if(!VOS_IS_STATUS_SUCCESS(status))
7952 {
7953 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 }
7956
Amar Singhala49cbc52013-10-08 18:37:44 -07007957#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007958 /* initialize the NV module. This is required so that
7959 we can initialize the channel information in wiphy
7960 from the NV.bin data. The channel information in
7961 wiphy needs to be initialized before wiphy registration */
7962
7963 status = vos_nv_open();
7964 if (!VOS_IS_STATUS_SUCCESS(status))
7965 {
7966 /* NV module cannot be initialized */
7967 hddLog( VOS_TRACE_LEVEL_FATAL,
7968 "%s: vos_nv_open failed", __func__);
7969 goto err_clkvote;
7970 }
7971
7972 status = vos_init_wiphy_from_nv_bin();
7973 if (!VOS_IS_STATUS_SUCCESS(status))
7974 {
7975 /* NV module cannot be initialized */
7976 hddLog( VOS_TRACE_LEVEL_FATAL,
7977 "%s: vos_init_wiphy failed", __func__);
7978 goto err_vos_nv_close;
7979 }
7980
Amar Singhala49cbc52013-10-08 18:37:44 -07007981 /* registration of wiphy dev with cfg80211 */
7982 if (0 > wlan_hdd_cfg80211_register(wiphy))
7983 {
7984 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
Amar Singhal0a402232013-10-11 20:57:16 -07007985 goto err_vos_nv_close;
Amar Singhala49cbc52013-10-08 18:37:44 -07007986 }
7987#endif
7988
Jeff Johnson295189b2012-06-20 16:38:30 -07007989 status = vos_open( &pVosContext, 0);
7990 if ( !VOS_IS_STATUS_SUCCESS( status ))
7991 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08007992 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Amar Singhala49cbc52013-10-08 18:37:44 -07007993 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 }
7995
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
7997
7998 if ( NULL == pHddCtx->hHal )
7999 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008000 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 goto err_vosclose;
8002 }
8003
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008004 status = vos_preStart( pHddCtx->pvosContext );
8005 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8006 {
8007 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
8008 goto err_vosclose;
8009 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008010
Arif Hussaineaf68602013-12-30 23:10:44 -08008011 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8012 {
8013 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8015 __func__, enable_dfs_chan_scan);
8016 }
8017 if (0 == enable_11d || 1 == enable_11d)
8018 {
8019 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8020 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8021 __func__, enable_11d);
8022 }
8023
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008024 /* Note that the vos_preStart() sequence triggers the cfg download.
8025 The cfg download must occur before we update the SME config
8026 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008027 status = hdd_set_sme_config( pHddCtx );
8028
8029 if ( VOS_STATUS_SUCCESS != status )
8030 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008031 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
8032 goto err_vosclose;
8033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008034
8035 //Initialize the WMM module
8036 status = hdd_wmm_init(pHddCtx);
8037 if (!VOS_IS_STATUS_SUCCESS(status))
8038 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008039 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 goto err_vosclose;
8041 }
8042
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 /* In the integrated architecture we update the configuration from
8044 the INI file and from NV before vOSS has been started so that
8045 the final contents are available to send down to the cCPU */
8046
8047 // Apply the cfg.ini to cfg.dat
8048 if (FALSE == hdd_update_config_dat(pHddCtx))
8049 {
8050 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
8051 goto err_vosclose;
8052 }
8053
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308054 // Get mac addr from platform driver
8055 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8056
8057 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308059 /* Store the mac addr for first interface */
8060 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8061
8062 hddLog(VOS_TRACE_LEVEL_ERROR,
8063 "%s: WLAN Mac Addr: "
8064 MAC_ADDRESS_STR, __func__,
8065 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8066
8067 /* Here, passing Arg2 as 1 because we do not want to change the
8068 last 3 bytes (means non OUI bytes) of first interface mac
8069 addr.
8070 */
8071 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8072 {
8073 hddLog(VOS_TRACE_LEVEL_ERROR,
8074 "%s: Failed to generate wlan interface mac addr "
8075 "using MAC from ini file ", __func__);
8076 }
8077 }
8078 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8079 {
8080 // Apply the NV to cfg.dat
8081 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008082#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8083 /* There was not a valid set of MAC Addresses in NV. See if the
8084 default addresses were modified by the cfg.ini settings. If so,
8085 we'll use them, but if not, we'll autogenerate a set of MAC
8086 addresses based upon the device serial number */
8087
8088 static const v_MACADDR_t default_address =
8089 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008090
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308091 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8092 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 {
8094 /* cfg.ini has the default address, invoke autogen logic */
8095
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308096 /* Here, passing Arg2 as 0 because we want to change the
8097 last 3 bytes (means non OUI bytes) of all the interfaces
8098 mac addr.
8099 */
8100 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8101 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308103 hddLog(VOS_TRACE_LEVEL_ERROR,
8104 "%s: Failed to generate wlan interface mac addr "
8105 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8106 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 }
8109 else
8110#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8111 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008112 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 "%s: Invalid MAC address in NV, using MAC from ini file "
8114 MAC_ADDRESS_STR, __func__,
8115 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8116 }
8117 }
8118 {
8119 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308120
8121 /* Set the MAC Address Currently this is used by HAL to
8122 * add self sta. Remove this once self sta is added as
8123 * part of session open.
8124 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8126 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8127 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308128
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 if (!HAL_STATUS_SUCCESS( halStatus ))
8130 {
8131 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8132 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Madan Mohan Koyyalamudib8b126b2012-11-15 17:37:30 -08008133 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 }
8135 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008136
8137 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8138 Note: Firmware image will be read and downloaded inside vos_start API */
8139 status = vos_start( pHddCtx->pvosContext );
8140 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8141 {
8142 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
8143 goto err_vosclose;
8144 }
8145
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008146 /* Exchange capability info between Host and FW and also get versioning info from FW */
8147 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008148
8149 status = hdd_post_voss_start_config( pHddCtx );
8150 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8151 {
8152 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8153 __func__);
8154 goto err_vosstop;
8155 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008156
8157#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308158 wlan_hdd_cfg80211_update_reg_info( wiphy );
8159
8160 /* registration of wiphy dev with cfg80211 */
8161 if (0 > wlan_hdd_cfg80211_register(wiphy))
8162 {
8163 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8164 goto err_vosstop;
8165 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008166#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008167
Jeff Johnson295189b2012-06-20 16:38:30 -07008168 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8169 {
8170 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8171 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8172 }
8173 else
8174 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8176 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8177 if (pAdapter != NULL)
8178 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308179 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008180 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308181 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8182 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8183 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008184
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308185 /* Generate the P2P Device Address. This consists of the device's
8186 * primary MAC address with the locally administered bit set.
8187 */
8188 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008189 }
8190 else
8191 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308192 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8193 if (p2p_dev_addr != NULL)
8194 {
8195 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8196 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8197 }
8198 else
8199 {
8200 hddLog(VOS_TRACE_LEVEL_FATAL,
8201 "%s: Failed to allocate mac_address for p2p_device",
8202 __func__);
8203 goto err_close_adapter;
8204 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008206
8207 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8208 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8209 if ( NULL == pP2pAdapter )
8210 {
8211 hddLog(VOS_TRACE_LEVEL_FATAL,
8212 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008213 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008214 goto err_close_adapter;
8215 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008216 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008218
8219 if( pAdapter == NULL )
8220 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8222 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008224
Arif Hussain66559122013-11-21 10:11:40 -08008225 if (country_code)
8226 {
8227 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008228 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008229 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8230#ifndef CONFIG_ENABLE_LINUX_REG
8231 hdd_checkandupdate_phymode(pAdapter, country_code);
8232#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008233 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8234 (void *)(tSmeChangeCountryCallback)
8235 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008236 country_code,
8237 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308238 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008239 if (eHAL_STATUS_SUCCESS == ret)
8240 {
Arif Hussaincb607082013-12-20 11:57:42 -08008241 ret = wait_for_completion_interruptible_timeout(
8242 &pAdapter->change_country_code,
8243 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8244
8245 if (0 >= ret)
8246 {
8247 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8248 "%s: SME while setting country code timed out", __func__);
8249 }
Arif Hussain66559122013-11-21 10:11:40 -08008250 }
8251 else
8252 {
Arif Hussaincb607082013-12-20 11:57:42 -08008253 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8254 "%s: SME Change Country code from module param fail ret=%d",
8255 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008256 }
8257 }
8258
Jeff Johnson295189b2012-06-20 16:38:30 -07008259#ifdef WLAN_BTAMP_FEATURE
8260 vStatus = WLANBAP_Open(pVosContext);
8261 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8262 {
8263 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8264 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008265 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 }
8267
8268 vStatus = BSL_Init(pVosContext);
8269 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8270 {
8271 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8272 "%s: Failed to Init BSL",__func__);
8273 goto err_bap_close;
8274 }
8275 vStatus = WLANBAP_Start(pVosContext);
8276 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8277 {
8278 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8279 "%s: Failed to start TL",__func__);
8280 goto err_bap_close;
8281 }
8282
8283 pConfig = pHddCtx->cfg_ini;
8284 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8285 status = WLANBAP_SetConfig(&btAmpConfig);
8286
8287#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008288
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008289#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8290 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8291 {
8292 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8293 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8294 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8295 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8296 }
8297#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008298#ifdef FEATURE_WLAN_SCAN_PNO
8299 /*SME must send channel update configuration to RIVA*/
8300 sme_UpdateChannelConfig(pHddCtx->hHal);
8301#endif
8302
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 /* Register with platform driver as client for Suspend/Resume */
8304 status = hddRegisterPmOps(pHddCtx);
8305 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8306 {
8307 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8308#ifdef WLAN_BTAMP_FEATURE
8309 goto err_bap_stop;
8310#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008311 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008312#endif //WLAN_BTAMP_FEATURE
8313 }
8314
Yue Ma0d4891e2013-08-06 17:01:45 -07008315 /* Open debugfs interface */
8316 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8317 {
8318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8319 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008320 }
8321
Jeff Johnson295189b2012-06-20 16:38:30 -07008322 /* Register TM level change handler function to the platform */
8323 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8324 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8325 {
8326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8327 goto err_unregister_pmops;
8328 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008329
8330 /* register for riva power on lock to platform driver */
8331 if (req_riva_power_on_lock("wlan"))
8332 {
8333 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8334 __func__);
8335 goto err_unregister_pmops;
8336 }
8337
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 // register net device notifier for device change notification
8339 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8340
8341 if(ret < 0)
8342 {
8343 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8344 goto err_free_power_on_lock;
8345 }
8346
8347 //Initialize the nlink service
8348 if(nl_srv_init() != 0)
8349 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308350 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 goto err_reg_netdev;
8352 }
8353
Leo Chang4ce1cc52013-10-21 18:27:15 -07008354#ifdef WLAN_KD_READY_NOTIFIER
8355 pHddCtx->kd_nl_init = 1;
8356#endif /* WLAN_KD_READY_NOTIFIER */
8357
Jeff Johnson295189b2012-06-20 16:38:30 -07008358 //Initialize the BTC service
8359 if(btc_activate_service(pHddCtx) != 0)
8360 {
8361 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8362 goto err_nl_srv;
8363 }
8364
8365#ifdef PTT_SOCK_SVC_ENABLE
8366 //Initialize the PTT service
8367 if(ptt_sock_activate_svc(pHddCtx) != 0)
8368 {
8369 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8370 goto err_nl_srv;
8371 }
8372#endif
8373
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008377 /* Action frame registered in one adapter which will
8378 * applicable to all interfaces
8379 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008380 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008381 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008382
8383 mutex_init(&pHddCtx->sap_lock);
8384
8385 pHddCtx->isLoadUnloadInProgress = FALSE;
8386
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008387#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008388#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8389 /* Initialize the wake lcok */
8390 wake_lock_init(&pHddCtx->rx_wake_lock,
8391 WAKE_LOCK_SUSPEND,
8392 "qcom_rx_wakelock");
8393#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008394 /* Initialize the wake lcok */
8395 wake_lock_init(&pHddCtx->sap_wake_lock,
8396 WAKE_LOCK_SUSPEND,
8397 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008398#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008399
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008400 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8401 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008402
8403 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8404 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308405#ifndef CONFIG_ENABLE_LINUX_REG
8406 /*updating wiphy so that regulatory user hints can be processed*/
8407 if (wiphy)
8408 {
8409 regulatory_hint(wiphy, "00");
8410 }
8411#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008412 // Initialize the restart logic
8413 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308414
Leo Chang0b0e45a2013-12-15 15:18:55 -08008415#ifdef FEATURE_WLAN_CH_AVOID
8416 /* Plug in avoid channel notification callback */
8417 sme_AddChAvoidCallback(pHddCtx->hHal,
8418 hdd_hostapd_ch_avoid_cb);
8419#endif /* FEATURE_WLAN_CH_AVOID */
8420
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008421 //Register the traffic monitor timer now
8422 if ( pHddCtx->cfg_ini->dynSplitscan)
8423 {
8424 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8425 VOS_TIMER_TYPE_SW,
8426 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8427 (void *)pHddCtx);
8428 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 goto success;
8430
8431err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008432#ifdef WLAN_KD_READY_NOTIFIER
8433 nl_srv_exit(pHddCtx->ptt_pid);
8434#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008436#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008437err_reg_netdev:
8438 unregister_netdevice_notifier(&hdd_netdev_notifier);
8439
8440err_free_power_on_lock:
8441 free_riva_power_on_lock("wlan");
8442
8443err_unregister_pmops:
8444 hddDevTmUnregisterNotifyCallback(pHddCtx);
8445 hddDeregisterPmOps(pHddCtx);
8446
Yue Ma0d4891e2013-08-06 17:01:45 -07008447 hdd_debugfs_exit(pHddCtx);
8448
Jeff Johnson295189b2012-06-20 16:38:30 -07008449#ifdef WLAN_BTAMP_FEATURE
8450err_bap_stop:
8451 WLANBAP_Stop(pVosContext);
8452#endif
8453
8454#ifdef WLAN_BTAMP_FEATURE
8455err_bap_close:
8456 WLANBAP_Close(pVosContext);
8457#endif
8458
Jeff Johnson295189b2012-06-20 16:38:30 -07008459err_close_adapter:
8460 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008461
8462#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308463 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008464#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008465
8466err_vosstop:
8467 vos_stop(pVosContext);
8468
Amar Singhala49cbc52013-10-08 18:37:44 -07008469err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 status = vos_sched_close( pVosContext );
8471 if (!VOS_IS_STATUS_SUCCESS(status)) {
8472 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8473 "%s: Failed to close VOSS Scheduler", __func__);
8474 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8475 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008476 vos_close(pVosContext );
8477
8478err_wiphy_unregister:
8479
8480#ifdef CONFIG_ENABLE_LINUX_REG
8481 wiphy_unregister(wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07008482
Amar Singhal0a402232013-10-11 20:57:16 -07008483err_vos_nv_close:
8484
8485 vos_nv_close();
8486
Jeff Johnson295189b2012-06-20 16:38:30 -07008487err_clkvote:
Amar Singhala49cbc52013-10-08 18:37:44 -07008488#endif
8489
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008490 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008491
8492err_wdclose:
8493 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8494 vos_watchdog_close(pVosContext);
8495
Jeff Johnson295189b2012-06-20 16:38:30 -07008496err_config:
8497 kfree(pHddCtx->cfg_ini);
8498 pHddCtx->cfg_ini= NULL;
8499
8500err_free_hdd_context:
8501 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07008502 wiphy_free(wiphy) ;
8503 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 VOS_BUG(1);
8505
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08008506 if (hdd_is_ssr_required())
8507 {
8508 /* WDI timeout had happened during load, so SSR is needed here */
8509 subsystem_restart("wcnss");
8510 msleep(5000);
8511 }
8512 hdd_set_ssr_required (VOS_FALSE);
8513
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008514 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008515
8516success:
8517 EXIT();
8518 return 0;
8519}
8520
8521/**---------------------------------------------------------------------------
8522
Jeff Johnson32d95a32012-09-10 13:15:23 -07008523 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07008524
Jeff Johnson32d95a32012-09-10 13:15:23 -07008525 This is the driver entry point - called in different timeline depending
8526 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07008527
8528 \param - None
8529
8530 \return - 0 for success, non zero for failure
8531
8532 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07008533static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008534{
8535 VOS_STATUS status;
8536 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 struct device *dev = NULL;
8538 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008539#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8540 int max_retries = 0;
8541#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008542
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308543#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8544 vos_wconn_trace_init();
8545#endif
8546
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 ENTER();
8548
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008549#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07008551#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008552
8553 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
8554 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
8555
8556 //Power Up Libra WLAN card first if not already powered up
8557 status = vos_chipPowerUp(NULL,NULL,NULL);
8558 if (!VOS_IS_STATUS_SUCCESS(status))
8559 {
8560 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
8561 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308562#ifdef WLAN_OPEN_SOURCE
8563 wake_lock_destroy(&wlan_wake_lock);
8564#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008565 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 }
8567
Jeff Johnson295189b2012-06-20 16:38:30 -07008568#ifdef ANI_BUS_TYPE_PCI
8569
8570 dev = wcnss_wlan_get_device();
8571
8572#endif // ANI_BUS_TYPE_PCI
8573
8574#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008575
8576#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8577 /* wait until WCNSS driver downloads NV */
8578 while (!wcnss_device_ready() && 5 >= ++max_retries) {
8579 msleep(1000);
8580 }
8581 if (max_retries >= 5) {
8582 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308583#ifdef WLAN_OPEN_SOURCE
8584 wake_lock_destroy(&wlan_wake_lock);
8585#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008586 return -ENODEV;
8587 }
8588#endif
8589
Jeff Johnson295189b2012-06-20 16:38:30 -07008590 dev = wcnss_wlan_get_device();
8591#endif // ANI_BUS_TYPE_PLATFORM
8592
8593
8594 do {
8595 if (NULL == dev) {
8596 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
8597 ret_status = -1;
8598 break;
8599 }
8600
Jeff Johnson295189b2012-06-20 16:38:30 -07008601#ifdef TIMER_MANAGER
8602 vos_timer_manager_init();
8603#endif
8604
8605 /* Preopen VOSS so that it is ready to start at least SAL */
8606 status = vos_preOpen(&pVosContext);
8607
8608 if (!VOS_IS_STATUS_SUCCESS(status))
8609 {
8610 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
8611 ret_status = -1;
8612 break;
8613 }
8614
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008615#ifndef MODULE
8616 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
8617 */
8618 hdd_set_conparam((v_UINT_t)con_mode);
8619#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008620
8621 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008622 if (hdd_wlan_startup(dev))
8623 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008625 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 vos_preClose( &pVosContext );
8627 ret_status = -1;
8628 break;
8629 }
8630
8631 /* Cancel the vote for XO Core ON
8632 * This is done here for safety purposes in case we re-initialize without turning
8633 * it OFF in any error scenario.
8634 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008635 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008637 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
8639 {
8640 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08008641 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 }
8643 } while (0);
8644
8645 if (0 != ret_status)
8646 {
8647 //Assert Deep sleep signal now to put Libra HW in lowest power state
8648 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
8649 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
8650
8651 //Vote off any PMIC voltage supplies
8652 vos_chipPowerDown(NULL, NULL, NULL);
8653#ifdef TIMER_MANAGER
8654 vos_timer_exit();
8655#endif
8656#ifdef MEMORY_DEBUG
8657 vos_mem_exit();
8658#endif
8659
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008660#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008661 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008662#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
8664 }
8665 else
8666 {
8667 //Send WLAN UP indication to Nlink Service
8668 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
8669
8670 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 }
8672
8673 EXIT();
8674
8675 return ret_status;
8676}
8677
Jeff Johnson32d95a32012-09-10 13:15:23 -07008678/**---------------------------------------------------------------------------
8679
8680 \brief hdd_module_init() - Init Function
8681
8682 This is the driver entry point (invoked when module is loaded using insmod)
8683
8684 \param - None
8685
8686 \return - 0 for success, non zero for failure
8687
8688 --------------------------------------------------------------------------*/
8689#ifdef MODULE
8690static int __init hdd_module_init ( void)
8691{
8692 return hdd_driver_init();
8693}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008694#else /* #ifdef MODULE */
8695static int __init hdd_module_init ( void)
8696{
8697 /* Driver initialization is delayed to fwpath_changed_handler */
8698 return 0;
8699}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008700#endif /* #ifdef MODULE */
8701
Jeff Johnson295189b2012-06-20 16:38:30 -07008702
8703/**---------------------------------------------------------------------------
8704
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008705 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008706
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008707 This is the driver exit point (invoked when module is unloaded using rmmod
8708 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07008709
8710 \param - None
8711
8712 \return - None
8713
8714 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008715static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008716{
8717 hdd_context_t *pHddCtx = NULL;
8718 v_CONTEXT_t pVosContext = NULL;
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008719 int retry = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008720
8721 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
8722
8723 //Get the global vos context
8724 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8725
8726 if(!pVosContext)
8727 {
8728 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
8729 goto done;
8730 }
8731
8732 //Get the HDD context.
8733 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
8734
8735 if(!pHddCtx)
8736 {
8737 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
8738 }
8739 else
8740 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008741 while(isWDresetInProgress()) {
8742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8743 "%s:SSR in Progress; block rmmod for 1 second!!!", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008744 msleep(1000);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008745
8746 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
8747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8748 "%s:SSR never completed, fatal error", __func__);
8749 VOS_BUG(0);
8750 }
8751 }
8752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753
8754 pHddCtx->isLoadUnloadInProgress = TRUE;
8755 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8756
8757 //Do all the cleanup before deregistering the driver
8758 hdd_wlan_exit(pHddCtx);
8759 }
8760
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 vos_preClose( &pVosContext );
8762
8763#ifdef TIMER_MANAGER
8764 vos_timer_exit();
8765#endif
8766#ifdef MEMORY_DEBUG
8767 vos_mem_exit();
8768#endif
8769
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308770#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8771 vos_wconn_trace_exit();
8772#endif
8773
Jeff Johnson295189b2012-06-20 16:38:30 -07008774done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008775#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008777#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
8779}
8780
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008781/**---------------------------------------------------------------------------
8782
8783 \brief hdd_module_exit() - Exit function
8784
8785 This is the driver exit point (invoked when module is unloaded using rmmod)
8786
8787 \param - None
8788
8789 \return - None
8790
8791 --------------------------------------------------------------------------*/
8792static void __exit hdd_module_exit(void)
8793{
8794 hdd_driver_exit();
8795}
8796
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008797#ifdef MODULE
8798static int fwpath_changed_handler(const char *kmessage,
8799 struct kernel_param *kp)
8800{
Jeff Johnson76052702013-04-16 13:55:05 -07008801 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008802}
8803
8804static int con_mode_handler(const char *kmessage,
8805 struct kernel_param *kp)
8806{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07008807 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008808}
8809#else /* #ifdef MODULE */
8810/**---------------------------------------------------------------------------
8811
Jeff Johnson76052702013-04-16 13:55:05 -07008812 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008813
Jeff Johnson76052702013-04-16 13:55:05 -07008814 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008815 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07008816 - invoked when module parameter fwpath is modified from userspace to signal
8817 initializing the WLAN driver or when con_mode is modified from userspace
8818 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008819
8820 \return - 0 for success, non zero for failure
8821
8822 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07008823static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008824{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008825 int ret_status;
8826
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008827 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008828 ret_status = hdd_driver_init();
8829 wlan_hdd_inited = ret_status ? 0 : 1;
8830 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008831 }
8832
8833 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07008834
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008835 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07008836
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008837 ret_status = hdd_driver_init();
8838 wlan_hdd_inited = ret_status ? 0 : 1;
8839 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008840}
8841
Jeff Johnson295189b2012-06-20 16:38:30 -07008842/**---------------------------------------------------------------------------
8843
Jeff Johnson76052702013-04-16 13:55:05 -07008844 \brief fwpath_changed_handler() - Handler Function
8845
8846 Handle changes to the fwpath parameter
8847
8848 \return - 0 for success, non zero for failure
8849
8850 --------------------------------------------------------------------------*/
8851static int fwpath_changed_handler(const char *kmessage,
8852 struct kernel_param *kp)
8853{
8854 int ret;
8855
8856 ret = param_set_copystring(kmessage, kp);
8857 if (0 == ret)
8858 ret = kickstart_driver();
8859 return ret;
8860}
8861
8862/**---------------------------------------------------------------------------
8863
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008864 \brief con_mode_handler() -
8865
8866 Handler function for module param con_mode when it is changed by userspace
8867 Dynamically linked - do nothing
8868 Statically linked - exit and init driver, as in rmmod and insmod
8869
Jeff Johnson76052702013-04-16 13:55:05 -07008870 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008871
Jeff Johnson76052702013-04-16 13:55:05 -07008872 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008873
8874 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07008875static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008876{
Jeff Johnson76052702013-04-16 13:55:05 -07008877 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008878
Jeff Johnson76052702013-04-16 13:55:05 -07008879 ret = param_set_int(kmessage, kp);
8880 if (0 == ret)
8881 ret = kickstart_driver();
8882 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008883}
8884#endif /* #ifdef MODULE */
8885
8886/**---------------------------------------------------------------------------
8887
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 \brief hdd_get_conparam() -
8889
8890 This is the driver exit point (invoked when module is unloaded using rmmod)
8891
8892 \param - None
8893
8894 \return - tVOS_CON_MODE
8895
8896 --------------------------------------------------------------------------*/
8897tVOS_CON_MODE hdd_get_conparam ( void )
8898{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008899#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008901#else
8902 return (tVOS_CON_MODE)curr_con_mode;
8903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008904}
8905void hdd_set_conparam ( v_UINT_t newParam )
8906{
8907 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008908#ifndef MODULE
8909 curr_con_mode = con_mode;
8910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008911}
8912/**---------------------------------------------------------------------------
8913
8914 \brief hdd_softap_sta_deauth() - function
8915
8916 This to take counter measure to handle deauth req from HDD
8917
8918 \param - pAdapter - Pointer to the HDD
8919
8920 \param - enable - boolean value
8921
8922 \return - None
8923
8924 --------------------------------------------------------------------------*/
8925
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008926VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008927{
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008929 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07008930
8931 ENTER();
8932
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008933 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
8934 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008935
8936 //Ignore request to deauth bcmc station
8937 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008938 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07008939
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008940 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07008941
8942 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008943 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07008944}
8945
8946/**---------------------------------------------------------------------------
8947
8948 \brief hdd_softap_sta_disassoc() - function
8949
8950 This to take counter measure to handle deauth req from HDD
8951
8952 \param - pAdapter - Pointer to the HDD
8953
8954 \param - enable - boolean value
8955
8956 \return - None
8957
8958 --------------------------------------------------------------------------*/
8959
8960void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
8961{
8962 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
8963
8964 ENTER();
8965
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308966 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008967
8968 //Ignore request to disassoc bcmc station
8969 if( pDestMacAddress[0] & 0x1 )
8970 return;
8971
8972 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
8973}
8974
8975void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
8976{
8977 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
8978
8979 ENTER();
8980
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308981 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008982
8983 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
8984}
8985
Jeff Johnson295189b2012-06-20 16:38:30 -07008986/**---------------------------------------------------------------------------
8987 *
8988 * \brief hdd_get__concurrency_mode() -
8989 *
8990 *
8991 * \param - None
8992 *
8993 * \return - CONCURRENCY MODE
8994 *
8995 * --------------------------------------------------------------------------*/
8996tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
8997{
8998 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
8999 hdd_context_t *pHddCtx;
9000
9001 if (NULL != pVosContext)
9002 {
9003 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9004 if (NULL != pHddCtx)
9005 {
9006 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9007 }
9008 }
9009
9010 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009011 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 return VOS_STA;
9013}
9014
9015/* Decide whether to allow/not the apps power collapse.
9016 * Allow apps power collapse if we are in connected state.
9017 * if not, allow only if we are in IMPS */
9018v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9019{
9020 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009021 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009022 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9024 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9025 hdd_adapter_t *pAdapter = NULL;
9026 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009027 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009028
Jeff Johnson295189b2012-06-20 16:38:30 -07009029 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9030 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009031
Yathish9f22e662012-12-10 14:21:35 -08009032 concurrent_state = hdd_get_concurrency_mode();
9033
9034#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9035 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9036 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9037 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9038 return TRUE;
9039#endif
9040
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 /*loop through all adapters. TBD fix for Concurrency */
9042 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9043 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9044 {
9045 pAdapter = pAdapterNode->pAdapter;
9046 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9047 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9048 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009049 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009051 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009052 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9053 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009055 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009056 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9057 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 return FALSE;
9059 }
9060 }
9061 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9062 pAdapterNode = pNext;
9063 }
9064 return TRUE;
9065}
9066
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009067/* Decides whether to send suspend notification to Riva
9068 * if any adapter is in BMPS; then it is required */
9069v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9070{
9071 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9072 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9073
9074 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9075 {
9076 return TRUE;
9077 }
9078 return FALSE;
9079}
9080
Jeff Johnson295189b2012-06-20 16:38:30 -07009081void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9082{
9083 switch(mode)
9084 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009085 case VOS_STA_MODE:
9086 case VOS_P2P_CLIENT_MODE:
9087 case VOS_P2P_GO_MODE:
9088 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009089 pHddCtx->concurrency_mode |= (1 << mode);
9090 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 break;
9092 default:
9093 break;
9094
9095 }
9096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9097 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9098}
9099
9100
9101void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9102{
9103 switch(mode)
9104 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009105 case VOS_STA_MODE:
9106 case VOS_P2P_CLIENT_MODE:
9107 case VOS_P2P_GO_MODE:
9108 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 pHddCtx->no_of_sessions[mode]--;
9110 if (!(pHddCtx->no_of_sessions[mode]))
9111 pHddCtx->concurrency_mode &= (~(1 << mode));
9112 break;
9113 default:
9114 break;
9115 }
9116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9117 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9118}
9119
Jeff Johnsone7245742012-09-05 17:12:55 -07009120/**---------------------------------------------------------------------------
9121 *
9122 * \brief wlan_hdd_restart_init
9123 *
9124 * This function initalizes restart timer/flag. An internal function.
9125 *
9126 * \param - pHddCtx
9127 *
9128 * \return - None
9129 *
9130 * --------------------------------------------------------------------------*/
9131
9132static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9133{
9134 /* Initialize */
9135 pHddCtx->hdd_restart_retries = 0;
9136 atomic_set(&pHddCtx->isRestartInProgress, 0);
9137 vos_timer_init(&pHddCtx->hdd_restart_timer,
9138 VOS_TIMER_TYPE_SW,
9139 wlan_hdd_restart_timer_cb,
9140 pHddCtx);
9141}
9142/**---------------------------------------------------------------------------
9143 *
9144 * \brief wlan_hdd_restart_deinit
9145 *
9146 * This function cleans up the resources used. An internal function.
9147 *
9148 * \param - pHddCtx
9149 *
9150 * \return - None
9151 *
9152 * --------------------------------------------------------------------------*/
9153
9154static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9155{
9156
9157 VOS_STATUS vos_status;
9158 /* Block any further calls */
9159 atomic_set(&pHddCtx->isRestartInProgress, 1);
9160 /* Cleanup */
9161 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9162 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009163 hddLog(LOGW, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009164 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9165 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009166 hddLog(LOGW, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009167
9168}
9169
9170/**---------------------------------------------------------------------------
9171 *
9172 * \brief wlan_hdd_framework_restart
9173 *
9174 * This function uses a cfg80211 API to start a framework initiated WLAN
9175 * driver module unload/load.
9176 *
9177 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9178 *
9179 *
9180 * \param - pHddCtx
9181 *
9182 * \return - VOS_STATUS_SUCCESS: Success
9183 * VOS_STATUS_E_EMPTY: Adapter is Empty
9184 * VOS_STATUS_E_NOMEM: No memory
9185
9186 * --------------------------------------------------------------------------*/
9187
9188static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9189{
9190 VOS_STATUS status = VOS_STATUS_SUCCESS;
9191 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009192 int len = (sizeof (struct ieee80211_mgmt));
9193 struct ieee80211_mgmt *mgmt = NULL;
9194
9195 /* Prepare the DEAUTH managment frame with reason code */
9196 mgmt = kzalloc(len, GFP_KERNEL);
9197 if(mgmt == NULL)
9198 {
9199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9200 "%s: memory allocation failed (%d bytes)", __func__, len);
9201 return VOS_STATUS_E_NOMEM;
9202 }
9203 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009204
9205 /* Iterate over all adapters/devices */
9206 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9207 do
9208 {
9209 if( (status == VOS_STATUS_SUCCESS) &&
9210 pAdapterNode &&
9211 pAdapterNode->pAdapter)
9212 {
9213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9214 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9215 pAdapterNode->pAdapter->dev->name,
9216 pAdapterNode->pAdapter->device_mode,
9217 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009218 /*
9219 * CFG80211 event to restart the driver
9220 *
9221 * 'cfg80211_send_unprot_deauth' sends a
9222 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9223 * of SME(Linux Kernel) state machine.
9224 *
9225 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9226 * the driver.
9227 *
9228 */
9229
9230 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009231 }
9232 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9233 pAdapterNode = pNext;
9234 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9235
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009236
9237 /* Free the allocated management frame */
9238 kfree(mgmt);
9239
Jeff Johnsone7245742012-09-05 17:12:55 -07009240 /* Retry until we unload or reach max count */
9241 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9242 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9243
9244 return status;
9245
9246}
9247/**---------------------------------------------------------------------------
9248 *
9249 * \brief wlan_hdd_restart_timer_cb
9250 *
9251 * Restart timer callback. An internal function.
9252 *
9253 * \param - User data:
9254 *
9255 * \return - None
9256 *
9257 * --------------------------------------------------------------------------*/
9258
9259void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9260{
9261 hdd_context_t *pHddCtx = usrDataForCallback;
9262 wlan_hdd_framework_restart(pHddCtx);
9263 return;
9264
9265}
9266
9267
9268/**---------------------------------------------------------------------------
9269 *
9270 * \brief wlan_hdd_restart_driver
9271 *
9272 * This function sends an event to supplicant to restart the WLAN driver.
9273 *
9274 * This function is called from vos_wlanRestart.
9275 *
9276 * \param - pHddCtx
9277 *
9278 * \return - VOS_STATUS_SUCCESS: Success
9279 * VOS_STATUS_E_EMPTY: Adapter is Empty
9280 * VOS_STATUS_E_ALREADY: Request already in progress
9281
9282 * --------------------------------------------------------------------------*/
9283VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9284{
9285 VOS_STATUS status = VOS_STATUS_SUCCESS;
9286
9287 /* A tight check to make sure reentrancy */
9288 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9289 {
9290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9291 "%s: WLAN restart is already in progress", __func__);
9292
9293 return VOS_STATUS_E_ALREADY;
9294 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009295 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009296#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009297 wcnss_reset_intr();
9298#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009299
Jeff Johnsone7245742012-09-05 17:12:55 -07009300 return status;
9301}
9302
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009303/*
9304 * API to find if there is any STA or P2P-Client is connected
9305 */
9306VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9307{
9308 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9309}
Jeff Johnsone7245742012-09-05 17:12:55 -07009310
Jeff Johnson295189b2012-06-20 16:38:30 -07009311//Register the module init/exit functions
9312module_init(hdd_module_init);
9313module_exit(hdd_module_exit);
9314
9315MODULE_LICENSE("Dual BSD/GPL");
9316MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9317MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9318
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009319module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9320 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009321
Jeff Johnson76052702013-04-16 13:55:05 -07009322module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009323 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009324
9325module_param(enable_dfs_chan_scan, int,
9326 S_IRUSR | S_IRGRP | S_IROTH);
9327
9328module_param(enable_11d, int,
9329 S_IRUSR | S_IRGRP | S_IROTH);
9330
9331module_param(country_code, charp,
9332 S_IRUSR | S_IRGRP | S_IROTH);