blob: aa3fd22134de0dd08767a726486d2be2b9e98991 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/*========================================================================
31
32 \file wlan_hdd_main.c
33
34 \brief WLAN Host Device Driver implementation
35
36 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
37
38 Qualcomm Confidential and Proprietary.
39
40 ========================================================================*/
41
42/**=========================================================================
43
44 EDIT HISTORY FOR FILE
45
46
47 This section contains comments describing changes made to the module.
48 Notice that changes are listed in reverse chronological order.
49
50
51 $Header:$ $DateTime: $ $Author: $
52
53
54 when who what, where, why
55 -------- --- --------------------------------------------------------
56 04/5/09 Shailender Created module.
57 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
58 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
59 ==========================================================================*/
60
61/*--------------------------------------------------------------------------
62 Include Files
63 ------------------------------------------------------------------------*/
64//#include <wlan_qct_driver.h>
65#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_api.h>
67#include <vos_sched.h>
68#include <vos_power.h>
69#include <linux/etherdevice.h>
70#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#ifdef ANI_BUS_TYPE_PLATFORM
72#include <linux/wcnss_wlan.h>
73#endif //ANI_BUS_TYPE_PLATFORM
74#ifdef ANI_BUS_TYPE_PCI
75#include "wcnss_wlan.h"
76#endif /* ANI_BUS_TYPE_PCI */
77#include <wlan_hdd_tx_rx.h>
78#include <palTimer.h>
79#include <wniApi.h>
80#include <wlan_nlink_srv.h>
81#include <wlan_btc_svc.h>
82#include <wlan_hdd_cfg.h>
83#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053084#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070085#include <wlan_hdd_wowl.h>
86#include <wlan_hdd_misc.h>
87#include <wlan_hdd_wext.h>
88#ifdef WLAN_BTAMP_FEATURE
89#include <bap_hdd_main.h>
90#include <bapInternal.h>
91#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053092#include "wlan_hdd_trace.h"
93#include "vos_types.h"
94#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095#include <linux/wireless.h>
96#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053097#include <linux/inetdevice.h>
98#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include "wlan_hdd_cfg80211.h"
100#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700102int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#include "sapApi.h"
104#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700105#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
107#include <soc/qcom/subsystem_restart.h>
108#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include <wlan_hdd_hostapd.h>
112#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "wlan_hdd_dev_pwr.h"
115#ifdef WLAN_BTAMP_FEATURE
116#include "bap_hdd_misc.h"
117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700118#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800120#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530121#ifdef FEATURE_WLAN_TDLS
122#include "wlan_hdd_tdls.h"
123#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700124#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126#ifdef MODULE
127#define WLAN_MODULE_NAME module_name(THIS_MODULE)
128#else
129#define WLAN_MODULE_NAME "wlan"
130#endif
131
132#ifdef TIMER_MANAGER
133#define TIMER_MANAGER_STR " +TIMER_MANAGER"
134#else
135#define TIMER_MANAGER_STR ""
136#endif
137
138#ifdef MEMORY_DEBUG
139#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
140#else
141#define MEMORY_DEBUG_STR ""
142#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530143#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700144/* the Android framework expects this param even though we don't use it */
145#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700146static char fwpath_buffer[BUF_LEN];
147static struct kparam_string fwpath = {
148 .string = fwpath_buffer,
149 .maxlen = BUF_LEN,
150};
Arif Hussain66559122013-11-21 10:11:40 -0800151
152static char *country_code;
153static int enable_11d = -1;
154static int enable_dfs_chan_scan = -1;
155
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700156#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700157static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700159
Jeff Johnsone7245742012-09-05 17:12:55 -0700160/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800161 * spinlock for synchronizing asynchronous request/response
162 * (full description of use in wlan_hdd_main.h)
163 */
164DEFINE_SPINLOCK(hdd_context_lock);
165
166/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700167 * The rate at which the driver sends RESTART event to supplicant
168 * once the function 'vos_wlanRestart()' is called
169 *
170 */
171#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
172#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700173
174/*
175 * Size of Driver command strings from upper layer
176 */
177#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
178#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
179
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800180#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700181#define TID_MIN_VALUE 0
182#define TID_MAX_VALUE 15
183static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
184 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800185static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
186 tCsrEseBeaconReq *pEseBcnReq);
187#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700188
Atul Mittal1d722422014-03-19 11:15:07 +0530189/*
190 * Maximum buffer size used for returning the data back to user space
191 */
192#define WLAN_MAX_BUF_SIZE 1024
193#define WLAN_PRIV_DATA_MAX_LEN 8192
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);
222
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800223#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800224void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
225static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700226static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
228 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700229static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
230 tANI_U8 *pTargetApBssid,
231 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800232#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
238
Jeff Johnson295189b2012-06-20 16:38:30 -0700239static int hdd_netdev_notifier_call(struct notifier_block * nb,
240 unsigned long state,
241 void *ndev)
242{
243 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700244 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700245 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700246#ifdef WLAN_BTAMP_FEATURE
247 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700248#endif
249
250 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700251 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700252 (strncmp(dev->name, "p2p", 3)))
253 return NOTIFY_DONE;
254
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700256 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700257
Jeff Johnson27cee452013-03-27 11:10:24 -0700258 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700259 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800260 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 VOS_ASSERT(0);
262 return NOTIFY_DONE;
263 }
264
Jeff Johnson27cee452013-03-27 11:10:24 -0700265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
266 if (NULL == pHddCtx)
267 {
268 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
269 VOS_ASSERT(0);
270 return NOTIFY_DONE;
271 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800272 if (pHddCtx->isLogpInProgress)
273 return NOTIFY_DONE;
274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275
276 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
277 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278
279 switch (state) {
280 case NETDEV_REGISTER:
281 break;
282
283 case NETDEV_UNREGISTER:
284 break;
285
286 case NETDEV_UP:
287 break;
288
289 case NETDEV_DOWN:
290 break;
291
292 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700293 if(TRUE == pAdapter->isLinkUpSvcNeeded)
294 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295 break;
296
297 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700298 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530300 long result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800301 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530302 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId,
303 eCSR_SCAN_ABORT_DEFAULT);
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));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530307 if (result <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 {
309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530310 "%s: Timeout occurred while waiting for abortscan %ld",
311 __func__, result);
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
Mihir Shete18156292014-03-11 15:38:30 +0530475 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530476 {
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)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530556 {
557 long ret;
558
559 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700560 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530561 if (0 >= ret)
562 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
563 ret);
564 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700565
566 }
567}
568#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530569void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
570{
571 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
572 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
573 hdd_config_t *cfg_param;
574 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530575 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530576
577 if (NULL == pHddCtx)
578 {
579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
580 "HDD Context is null !!");
581 return ;
582 }
583
584 cfg_param = pHddCtx->cfg_ini;
585
586 if (NULL == cfg_param)
587 {
588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
589 "cfg_params not available !!");
590 return ;
591 }
592
593 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
594
595 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
596 {
597 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
598 (eCSR_DOT11_MODE_11ac == phyMode) ||
599 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
602 "Setting phymode to 11n!!");
603 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
604 }
605 }
606 else
607 {
608 /*New country Supports 11ac as well resetting value back from .ini*/
609 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
610 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
611 return ;
612 }
613
614 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
615 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
616 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
617 {
618 VOS_STATUS vosStatus;
619
620 // need to issue a disconnect to CSR.
621 INIT_COMPLETION(pAdapter->disconnect_comp_var);
622 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
623 pAdapter->sessionId,
624 eCSR_DISCONNECT_REASON_UNSPECIFIED );
625
626 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530627 {
628 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530629 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530630 if (ret <= 0)
631 {
632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
633 "wait on disconnect_comp_var is failed %ld", ret);
634 }
635 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530636
637 }
638}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700639#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530640
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700641void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
642{
643 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
644 hdd_config_t *cfg_param;
645
646 if (NULL == pHddCtx)
647 {
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
649 "HDD Context is null !!");
650 return ;
651 }
652
653 cfg_param = pHddCtx->cfg_ini;
654
655 if (NULL == cfg_param)
656 {
657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
658 "cfg_params not available !!");
659 return ;
660 }
661
662 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
663 {
664 /*New country doesn't support DFS */
665 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
666 }
667 else
668 {
669 /*New country Supports DFS as well resetting value back from .ini*/
670 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
671 }
672
673}
674
Rajeev79dbe4c2013-10-05 11:03:42 +0530675#ifdef FEATURE_WLAN_BATCH_SCAN
676
677/**---------------------------------------------------------------------------
678
679 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
680 input string
681
682 This function extracts assigned integer from string in below format:
683 "STRING=10" : extracts integer 10 from this string
684
685 \param - pInPtr Pointer to input string
686 \param - base Base for string to int conversion(10 for decimal 16 for hex)
687 \param - pOutPtr Pointer to variable in which extracted integer needs to be
688 assigned
689 \param - pLastArg to tell whether it is last arguement in input string or
690 not
691
692 \return - NULL for failure cases
693 pointer to next arguement in input string for success cases
694 --------------------------------------------------------------------------*/
695static tANI_U8 *
696hdd_extract_assigned_int_from_str
697(
698 tANI_U8 *pInPtr,
699 tANI_U8 base,
700 tANI_U32 *pOutPtr,
701 tANI_U8 *pLastArg
702)
703{
704 int tempInt;
705 int v = 0;
706 char buf[32];
707 int val = 0;
708 *pLastArg = FALSE;
709
710 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
711 if (NULL == pInPtr)
712 {
713 return NULL;
714 }
715
716 pInPtr++;
717
718 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
719
720 val = sscanf(pInPtr, "%32s ", buf);
721 if (val < 0 && val > strlen(pInPtr))
722 {
723 return NULL;
724 }
725 pInPtr += val;
726 v = kstrtos32(buf, base, &tempInt);
727 if (v < 0)
728 {
729 return NULL;
730 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800731 if (tempInt < 0)
732 {
733 tempInt = 0;
734 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530735 *pOutPtr = tempInt;
736
737 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
738 if (NULL == pInPtr)
739 {
740 *pLastArg = TRUE;
741 return NULL;
742 }
743 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
744
745 return pInPtr;
746}
747
748/**---------------------------------------------------------------------------
749
750 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
751 input string
752
753 This function extracts assigned character from string in below format:
754 "STRING=A" : extracts char 'A' from this string
755
756 \param - pInPtr Pointer to input string
757 \param - pOutPtr Pointer to variable in which extracted char needs to be
758 assigned
759 \param - pLastArg to tell whether it is last arguement in input string or
760 not
761
762 \return - NULL for failure cases
763 pointer to next arguement in input string for success cases
764 --------------------------------------------------------------------------*/
765static tANI_U8 *
766hdd_extract_assigned_char_from_str
767(
768 tANI_U8 *pInPtr,
769 tANI_U8 *pOutPtr,
770 tANI_U8 *pLastArg
771)
772{
773 *pLastArg = FALSE;
774
775 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
776 if (NULL == pInPtr)
777 {
778 return NULL;
779 }
780
781 pInPtr++;
782
783 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
784
785 *pOutPtr = *pInPtr;
786
787 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
788 if (NULL == pInPtr)
789 {
790 *pLastArg = TRUE;
791 return NULL;
792 }
793 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
794
795 return pInPtr;
796}
797
798
799/**---------------------------------------------------------------------------
800
801 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
802
803 This function parses set batch scan command in below format:
804 WLS_BATCHING_SET <space> followed by below arguements
805 "SCANFREQ=XX" : Optional defaults to 30 sec
806 "MSCAN=XX" : Required number of scans to attempt to batch
807 "BESTN=XX" : Best Network (RSSI) defaults to 16
808 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
809 A. implies only 5 GHz , B. implies only 2.4GHz
810 "RTT=X" : optional defaults to 0
811 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
812 error
813
814 For example input commands:
815 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
816 translated into set batch scan with following parameters:
817 a) Frequence 60 seconds
818 b) Batch 10 scans together
819 c) Best RSSI to be 20
820 d) 5GHz band only
821 e) RTT is equal to 0
822
823 \param - pValue Pointer to input channel list
824 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
825
826 \return - 0 for success non-zero for failure
827
828 --------------------------------------------------------------------------*/
829static int
830hdd_parse_set_batchscan_command
831(
832 tANI_U8 *pValue,
833 tSirSetBatchScanReq *pHddSetBatchScanReq
834)
835{
836 tANI_U8 *inPtr = pValue;
837 tANI_U8 val = 0;
838 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800839 tANI_U32 nScanFreq;
840 tANI_U32 nMscan;
841 tANI_U32 nBestN;
842 tANI_U8 ucRfBand;
843 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800844 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530845
846 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800847 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
848 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
849 nRtt = 0;
850 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530851
852 /*go to space after WLS_BATCHING_SET command*/
853 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
854 /*no argument after the command*/
855 if (NULL == inPtr)
856 {
857 return -EINVAL;
858 }
859
860 /*no space after the command*/
861 else if (SPACE_ASCII_VALUE != *inPtr)
862 {
863 return -EINVAL;
864 }
865
866 /*removing empty spaces*/
867 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
868
869 /*no argument followed by spaces*/
870 if ('\0' == *inPtr)
871 {
872 return -EINVAL;
873 }
874
875 /*check and parse SCANFREQ*/
876 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
877 {
878 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800879 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800880
Rajeev Kumarc933d982013-11-18 20:04:20 -0800881 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800882 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800883 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800884 }
885
Rajeev79dbe4c2013-10-05 11:03:42 +0530886 if ( (NULL == inPtr) || (TRUE == lastArg))
887 {
888 return -EINVAL;
889 }
890 }
891
892 /*check and parse MSCAN*/
893 if ((strncmp(inPtr, "MSCAN", 5) == 0))
894 {
895 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800896 &nMscan, &lastArg);
897
898 if (0 == nMscan)
899 {
900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
901 "invalid MSCAN=%d", nMscan);
902 return -EINVAL;
903 }
904
Rajeev79dbe4c2013-10-05 11:03:42 +0530905 if (TRUE == lastArg)
906 {
907 goto done;
908 }
909 else if (NULL == inPtr)
910 {
911 return -EINVAL;
912 }
913 }
914 else
915 {
916 return -EINVAL;
917 }
918
919 /*check and parse BESTN*/
920 if ((strncmp(inPtr, "BESTN", 5) == 0))
921 {
922 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800923 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800924
Rajeev Kumarc933d982013-11-18 20:04:20 -0800925 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800926 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800927 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800928 }
929
Rajeev79dbe4c2013-10-05 11:03:42 +0530930 if (TRUE == lastArg)
931 {
932 goto done;
933 }
934 else if (NULL == inPtr)
935 {
936 return -EINVAL;
937 }
938 }
939
940 /*check and parse CHANNEL*/
941 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
942 {
943 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944
Rajeev79dbe4c2013-10-05 11:03:42 +0530945 if (('A' == val) || ('a' == val))
946 {
c_hpothuebf89732014-02-25 13:00:24 +0530947 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530948 }
949 else if (('B' == val) || ('b' == val))
950 {
c_hpothuebf89732014-02-25 13:00:24 +0530951 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530952 }
953 else
954 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800955 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
956 }
957
958 if (TRUE == lastArg)
959 {
960 goto done;
961 }
962 else if (NULL == inPtr)
963 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530964 return -EINVAL;
965 }
966 }
967
968 /*check and parse RTT*/
969 if ((strncmp(inPtr, "RTT", 3) == 0))
970 {
971 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800972 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 if (TRUE == lastArg)
974 {
975 goto done;
976 }
977 if (NULL == inPtr)
978 {
979 return -EINVAL;
980 }
981 }
982
983
984done:
985
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800986 pHddSetBatchScanReq->scanFrequency = nScanFreq;
987 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
988 pHddSetBatchScanReq->bestNetwork = nBestN;
989 pHddSetBatchScanReq->rfBand = ucRfBand;
990 pHddSetBatchScanReq->rtt = nRtt;
991
Rajeev79dbe4c2013-10-05 11:03:42 +0530992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
993 "Received WLS_BATCHING_SET with SCANFREQ=%d "
994 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
995 pHddSetBatchScanReq->scanFrequency,
996 pHddSetBatchScanReq->numberOfScansToBatch,
997 pHddSetBatchScanReq->bestNetwork,
998 pHddSetBatchScanReq->rfBand,
999 pHddSetBatchScanReq->rtt);
1000
1001 return 0;
1002}/*End of hdd_parse_set_batchscan_command*/
1003
1004/**---------------------------------------------------------------------------
1005
1006 \brief hdd_set_batch_scan_req_callback () - This function is called after
1007 receiving set batch scan response from FW and it saves set batch scan
1008 response data FW to HDD context and sets the completion event on
1009 which hdd_ioctl is waiting
1010
1011 \param - callbackContext Pointer to HDD adapter
1012 \param - pRsp Pointer to set batch scan response data received from FW
1013
1014 \return - nothing
1015
1016 --------------------------------------------------------------------------*/
1017static void hdd_set_batch_scan_req_callback
1018(
1019 void *callbackContext,
1020 tSirSetBatchScanRsp *pRsp
1021)
1022{
1023 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1024 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1025
1026 /*sanity check*/
1027 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1028 {
1029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1030 "%s: Invalid pAdapter magic", __func__);
1031 VOS_ASSERT(0);
1032 return;
1033 }
1034 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1035
1036 /*save set batch scan response*/
1037 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1038
1039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1040 "Received set batch scan rsp from FW with nScansToBatch=%d",
1041 pHddSetBatchScanRsp->nScansToBatch);
1042
1043 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1044 complete(&pAdapter->hdd_set_batch_scan_req_var);
1045
1046 return;
1047}/*End of hdd_set_batch_scan_req_callback*/
1048
1049
1050/**---------------------------------------------------------------------------
1051
1052 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1053 info in hdd batch scan response queue
1054
1055 \param - pAdapter Pointer to hdd adapter
1056 \param - pAPMetaInfo Pointer to access point meta info
1057 \param - scanId scan ID of batch scan response
1058 \param - isLastAp tells whether AP is last AP in batch scan response or not
1059
1060 \return - nothing
1061
1062 --------------------------------------------------------------------------*/
1063static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1064 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1065{
1066 tHddBatchScanRsp *pHead;
1067 tHddBatchScanRsp *pNode;
1068 tHddBatchScanRsp *pPrev;
1069 tHddBatchScanRsp *pTemp;
1070 tANI_U8 ssidLen;
1071
1072 /*head of hdd batch scan response queue*/
1073 pHead = pAdapter->pBatchScanRsp;
1074
1075 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1076 if (NULL == pNode)
1077 {
1078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1079 "%s: Could not allocate memory", __func__);
1080 VOS_ASSERT(0);
1081 return;
1082 }
1083
1084 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1085 sizeof(pNode->ApInfo.bssid));
1086 ssidLen = strlen(pApMetaInfo->ssid);
1087 if (SIR_MAX_SSID_SIZE < ssidLen)
1088 {
1089 /*invalid scan result*/
1090 vos_mem_free(pNode);
1091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1092 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1093 return;
1094 }
1095 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1096 /*null terminate ssid*/
1097 pNode->ApInfo.ssid[ssidLen] = '\0';
1098 pNode->ApInfo.ch = pApMetaInfo->ch;
1099 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1100 pNode->ApInfo.age = pApMetaInfo->timestamp;
1101 pNode->ApInfo.batchId = scanId;
1102 pNode->ApInfo.isLastAp = isLastAp;
1103
1104 pNode->pNext = NULL;
1105 if (NULL == pHead)
1106 {
1107 pAdapter->pBatchScanRsp = pNode;
1108 }
1109 else
1110 {
1111 pTemp = pHead;
1112 while (NULL != pTemp)
1113 {
1114 pPrev = pTemp;
1115 pTemp = pTemp->pNext;
1116 }
1117 pPrev->pNext = pNode;
1118 }
1119
1120 return;
1121}/*End of hdd_populate_batch_scan_rsp_queue*/
1122
1123/**---------------------------------------------------------------------------
1124
1125 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1126 receiving batch scan response indication from FW. It saves get batch scan
1127 response data in HDD batch scan response queue. This callback sets the
1128 completion event on which hdd_ioctl is waiting only after getting complete
1129 batch scan response data from FW
1130
1131 \param - callbackContext Pointer to HDD adapter
1132 \param - pRsp Pointer to get batch scan response data received from FW
1133
1134 \return - nothing
1135
1136 --------------------------------------------------------------------------*/
1137static void hdd_batch_scan_result_ind_callback
1138(
1139 void *callbackContext,
1140 void *pRsp
1141)
1142{
1143 v_BOOL_t isLastAp;
1144 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001145 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301146 tANI_U32 numberScanList;
1147 tANI_U32 nextScanListOffset;
1148 tANI_U32 nextApMetaInfoOffset;
1149 hdd_adapter_t* pAdapter;
1150 tpSirBatchScanList pScanList;
1151 tpSirBatchScanNetworkInfo pApMetaInfo;
1152 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1153 tSirSetBatchScanReq *pReq;
1154
1155 pAdapter = (hdd_adapter_t *)callbackContext;
1156 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001157 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301158 {
1159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1160 "%s: Invalid pAdapter magic", __func__);
1161 VOS_ASSERT(0);
1162 return;
1163 }
1164
1165 /*initialize locals*/
1166 pReq = &pAdapter->hddSetBatchScanReq;
1167 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1168 isLastAp = FALSE;
1169 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001170 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301171 numberScanList = 0;
1172 nextScanListOffset = 0;
1173 nextApMetaInfoOffset = 0;
1174 pScanList = NULL;
1175 pApMetaInfo = NULL;
1176
1177 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1178 {
1179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1180 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1181 isLastAp = TRUE;
1182 goto done;
1183 }
1184
1185 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1187 "Batch scan rsp: numberScalList %d", numberScanList);
1188
1189 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1190 {
1191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1192 "%s: numberScanList %d", __func__, numberScanList);
1193 isLastAp = TRUE;
1194 goto done;
1195 }
1196
1197 while (numberScanList)
1198 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001199 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301200 nextScanListOffset);
1201 if (NULL == pScanList)
1202 {
1203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1204 "%s: pScanList is %p", __func__, pScanList);
1205 isLastAp = TRUE;
1206 goto done;
1207 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001208 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001210 "Batch scan rsp: numApMetaInfo %d scanId %d",
1211 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301212
1213 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1214 {
1215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1216 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1217 isLastAp = TRUE;
1218 goto done;
1219 }
1220
Rajeev Kumarce651e42013-10-21 18:57:15 -07001221 /*Initialize next AP meta info offset for next scan list*/
1222 nextApMetaInfoOffset = 0;
1223
Rajeev79dbe4c2013-10-05 11:03:42 +05301224 while (numApMetaInfo)
1225 {
1226 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1227 nextApMetaInfoOffset);
1228 if (NULL == pApMetaInfo)
1229 {
1230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1231 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1232 isLastAp = TRUE;
1233 goto done;
1234 }
1235 /*calculate AP age*/
1236 pApMetaInfo->timestamp =
1237 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1238
1239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001240 "%s: bssId "MAC_ADDRESS_STR
1241 " ch %d rssi %d timestamp %d", __func__,
1242 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1243 pApMetaInfo->ch, pApMetaInfo->rssi,
1244 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301245
1246 /*mark last AP in batch scan response*/
1247 if ((TRUE == pBatchScanRsp->isLastResult) &&
1248 (1 == numberScanList) && (1 == numApMetaInfo))
1249 {
1250 isLastAp = TRUE;
1251 }
1252
1253 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1254 /*store batch scan repsonse in hdd queue*/
1255 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1256 pScanList->scanId, isLastAp);
1257 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1258
1259 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1260 numApMetaInfo--;
1261 }
1262
Rajeev Kumarce651e42013-10-21 18:57:15 -07001263 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1264 + (sizeof(tSirBatchScanNetworkInfo)
1265 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301266 numberScanList--;
1267 }
1268
1269done:
1270
1271 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1272 requested from hdd_ioctl*/
1273 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1274 (TRUE == isLastAp))
1275 {
1276 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1277 complete(&pAdapter->hdd_get_batch_scan_req_var);
1278 }
1279
1280 return;
1281}/*End of hdd_batch_scan_result_ind_callback*/
1282
1283/**---------------------------------------------------------------------------
1284
1285 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1286 response as per batch scan FR request format by putting proper markers
1287
1288 \param - pDest pointer to destination buffer
1289 \param - cur_len current length
1290 \param - tot_len total remaining size which can be written to user space
1291 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1292 \param - pAdapter Pointer to HDD adapter
1293
1294 \return - ret no of characters written
1295
1296 --------------------------------------------------------------------------*/
1297static tANI_U32
1298hdd_format_batch_scan_rsp
1299(
1300 tANI_U8 *pDest,
1301 tANI_U32 cur_len,
1302 tANI_U32 tot_len,
1303 tHddBatchScanRsp *pApMetaInfo,
1304 hdd_adapter_t* pAdapter
1305)
1306{
1307 tANI_U32 ret = 0;
1308 tANI_U32 rem_len = 0;
1309 tANI_U8 temp_len = 0;
1310 tANI_U8 temp_total_len = 0;
1311 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1312 tANI_U8 *pTemp = temp;
1313
1314 /*Batch scan reponse needs to be returned to user space in
1315 following format:
1316 "scancount=X\n" where X is the number of scans in current batch
1317 batch
1318 "trunc\n" optional present if current scan truncated
1319 "bssid=XX:XX:XX:XX:XX:XX\n"
1320 "ssid=XXXX\n"
1321 "freq=X\n" frequency in Mhz
1322 "level=XX\n"
1323 "age=X\n" ms
1324 "dist=X\n" cm (-1 if not available)
1325 "errror=X\n" (-1if not available)
1326 "====\n" (end of ap marker)
1327 "####\n" (end of scan marker)
1328 "----\n" (end of results)*/
1329 /*send scan result in above format to user space based on
1330 available length*/
1331 /*The GET response may have more data than the driver can return in its
1332 buffer. In that case the buffer should be filled to the nearest complete
1333 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1334 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1335 The final buffer should end with "----\n"*/
1336
1337 /*sanity*/
1338 if (cur_len > tot_len)
1339 {
1340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1341 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1342 return 0;
1343 }
1344 else
1345 {
1346 rem_len = (tot_len - cur_len);
1347 }
1348
1349 /*end scan marker*/
1350 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1351 {
1352 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1353 pTemp += temp_len;
1354 temp_total_len += temp_len;
1355 }
1356
1357 /*bssid*/
1358 temp_len = snprintf(pTemp, sizeof(temp),
1359 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1360 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1361 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1362 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1363 pTemp += temp_len;
1364 temp_total_len += temp_len;
1365
1366 /*ssid*/
1367 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1368 pApMetaInfo->ApInfo.ssid);
1369 pTemp += temp_len;
1370 temp_total_len += temp_len;
1371
1372 /*freq*/
1373 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001374 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301375 pTemp += temp_len;
1376 temp_total_len += temp_len;
1377
1378 /*level*/
1379 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1380 pApMetaInfo->ApInfo.rssi);
1381 pTemp += temp_len;
1382 temp_total_len += temp_len;
1383
1384 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001385 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301386 pApMetaInfo->ApInfo.age);
1387 pTemp += temp_len;
1388 temp_total_len += temp_len;
1389
1390 /*dist*/
1391 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1392 pTemp += temp_len;
1393 temp_total_len += temp_len;
1394
1395 /*error*/
1396 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1397 pTemp += temp_len;
1398 temp_total_len += temp_len;
1399
1400 /*end AP marker*/
1401 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404
1405 /*last AP in batch scan response*/
1406 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1407 {
1408 /*end scan marker*/
1409 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1410 pTemp += temp_len;
1411 temp_total_len += temp_len;
1412
1413 /*end batch scan result marker*/
1414 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1415 pTemp += temp_len;
1416 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001417
Rajeev79dbe4c2013-10-05 11:03:42 +05301418 }
1419
1420 if (temp_total_len < rem_len)
1421 {
1422 ret = temp_total_len + 1;
1423 strlcpy(pDest, temp, ret);
1424 pAdapter->isTruncated = FALSE;
1425 }
1426 else
1427 {
1428 pAdapter->isTruncated = TRUE;
1429 if (rem_len >= strlen("%%%%"))
1430 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001431 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301432 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001433 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301434 {
1435 ret = 0;
1436 }
1437 }
1438
1439 return ret;
1440
1441}/*End of hdd_format_batch_scan_rsp*/
1442
1443/**---------------------------------------------------------------------------
1444
1445 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1446 buffer starting with head of hdd batch scan response queue
1447
1448 \param - pAdapter Pointer to HDD adapter
1449 \param - pDest Pointer to user data buffer
1450 \param - cur_len current offset in user buffer
1451 \param - rem_len remaining no of bytes in user buffer
1452
1453 \return - number of bytes written in user buffer
1454
1455 --------------------------------------------------------------------------*/
1456
1457tANI_U32 hdd_populate_user_batch_scan_rsp
1458(
1459 hdd_adapter_t* pAdapter,
1460 tANI_U8 *pDest,
1461 tANI_U32 cur_len,
1462 tANI_U32 rem_len
1463)
1464{
1465 tHddBatchScanRsp *pHead;
1466 tHddBatchScanRsp *pPrev;
1467 tANI_U32 len;
1468
Rajeev79dbe4c2013-10-05 11:03:42 +05301469 pAdapter->isTruncated = FALSE;
1470
1471 /*head of hdd batch scan response queue*/
1472 pHead = pAdapter->pBatchScanRsp;
1473 while (pHead)
1474 {
1475 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1476 pAdapter);
1477 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001478 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301479 cur_len += len;
1480 if(TRUE == pAdapter->isTruncated)
1481 {
1482 /*result is truncated return rest of scan rsp in next req*/
1483 cur_len = rem_len;
1484 break;
1485 }
1486 pPrev = pHead;
1487 pHead = pHead->pNext;
1488 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001489 if (TRUE == pPrev->ApInfo.isLastAp)
1490 {
1491 pAdapter->prev_batch_id = 0;
1492 }
1493 else
1494 {
1495 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1496 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301497 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001498 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301499 }
1500
1501 return cur_len;
1502}/*End of hdd_populate_user_batch_scan_rsp*/
1503
1504/**---------------------------------------------------------------------------
1505
1506 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1507 scan response data from HDD queue to user space
1508 It does following in detail:
1509 a) if HDD has enough data in its queue then it 1st copies data to user
1510 space and then send get batch scan indication message to FW. In this
1511 case it does not wait on any event and batch scan response data will
1512 be populated in HDD response queue in MC thread context after receiving
1513 indication from FW
1514 b) else send get batch scan indication message to FW and wait on an event
1515 which will be set once HDD receives complete batch scan response from
1516 FW and then this function returns batch scan response to user space
1517
1518 \param - pAdapter Pointer to HDD adapter
1519 \param - pPrivData Pointer to priv_data
1520
1521 \return - 0 for success -EFAULT for failure
1522
1523 --------------------------------------------------------------------------*/
1524
1525int hdd_return_batch_scan_rsp_to_user
1526(
1527 hdd_adapter_t* pAdapter,
1528 hdd_priv_data_t *pPrivData,
1529 tANI_U8 *command
1530)
1531{
1532 tANI_U8 *pDest;
1533 tANI_U32 count = 0;
1534 tANI_U32 len = 0;
1535 tANI_U32 cur_len = 0;
1536 tANI_U32 rem_len = 0;
1537 eHalStatus halStatus;
1538 unsigned long rc;
1539 tSirTriggerBatchScanResultInd *pReq;
1540
1541 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1542 pReq->param = 0;/*batch scan client*/
1543 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1544 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1545
1546 cur_len = pPrivData->used_len;
1547 if (pPrivData->total_len > pPrivData->used_len)
1548 {
1549 rem_len = pPrivData->total_len - pPrivData->used_len;
1550 }
1551 else
1552 {
1553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1554 "%s: Invalid user data buffer total_len %d used_len %d",
1555 __func__, pPrivData->total_len, pPrivData->used_len);
1556 return -EFAULT;
1557 }
1558
1559 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1560 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1561 cur_len, rem_len);
1562 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1563
1564 /*enough scan result available in cache to return to user space or
1565 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001566 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301567 {
1568 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1569 halStatus = sme_TriggerBatchScanResultInd(
1570 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1571 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1572 pAdapter);
1573 if ( eHAL_STATUS_SUCCESS == halStatus )
1574 {
1575 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1576 {
1577 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1578 rc = wait_for_completion_timeout(
1579 &pAdapter->hdd_get_batch_scan_req_var,
1580 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1581 if (0 == rc)
1582 {
1583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1584 "%s: Timeout waiting to fetch batch scan rsp from fw",
1585 __func__);
1586 return -EFAULT;
1587 }
1588 }
1589
1590 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001591 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301592 pDest += len;
1593 cur_len += len;
1594
1595 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1596 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1597 cur_len, rem_len);
1598 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1599
1600 count = 0;
1601 len = (len - pPrivData->used_len);
1602 pDest = (command + pPrivData->used_len);
1603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001604 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301605 while(count < len)
1606 {
1607 printk("%c", *(pDest + count));
1608 count++;
1609 }
1610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1611 "%s: copy %d data to user buffer", __func__, len);
1612 if (copy_to_user(pPrivData->buf, pDest, len))
1613 {
1614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1615 "%s: failed to copy data to user buffer", __func__);
1616 return -EFAULT;
1617 }
1618 }
1619 else
1620 {
1621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1622 "sme_GetBatchScanScan returned failure halStatus %d",
1623 halStatus);
1624 return -EINVAL;
1625 }
1626 }
1627 else
1628 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301629 count = 0;
1630 len = (len - pPrivData->used_len);
1631 pDest = (command + pPrivData->used_len);
1632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001633 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301634 while(count < len)
1635 {
1636 printk("%c", *(pDest + count));
1637 count++;
1638 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1640 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301641 if (copy_to_user(pPrivData->buf, pDest, len))
1642 {
1643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1644 "%s: failed to copy data to user buffer", __func__);
1645 return -EFAULT;
1646 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301647 }
1648
1649 return 0;
1650} /*End of hdd_return_batch_scan_rsp_to_user*/
1651
Rajeev Kumar8b373292014-01-08 20:36:55 -08001652
1653/**---------------------------------------------------------------------------
1654
1655 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1656 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1657 WLS_BATCHING VERSION
1658 WLS_BATCHING SET
1659 WLS_BATCHING GET
1660 WLS_BATCHING STOP
1661
1662 \param - pAdapter Pointer to HDD adapter
1663 \param - pPrivdata Pointer to priv_data
1664 \param - command Pointer to command
1665
1666 \return - 0 for success -EFAULT for failure
1667
1668 --------------------------------------------------------------------------*/
1669
1670int hdd_handle_batch_scan_ioctl
1671(
1672 hdd_adapter_t *pAdapter,
1673 hdd_priv_data_t *pPrivdata,
1674 tANI_U8 *command
1675)
1676{
1677 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001678 hdd_context_t *pHddCtx;
1679
1680 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1681 ret = wlan_hdd_validate_context(pHddCtx);
1682 if (ret)
1683 {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1685 "%s: HDD context is not valid!", __func__);
1686 goto exit;
1687 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001688
1689 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1690 {
1691 char extra[32];
1692 tANI_U8 len = 0;
1693 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1694
1695 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1696 {
1697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1698 "%s: Batch scan feature is not supported by FW", __func__);
1699 ret = -EINVAL;
1700 goto exit;
1701 }
1702
1703 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1704 version);
1705 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1706 {
1707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1708 "%s: failed to copy data to user buffer", __func__);
1709 ret = -EFAULT;
1710 goto exit;
1711 }
1712 ret = HDD_BATCH_SCAN_VERSION;
1713 }
1714 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1715 {
1716 int status;
1717 tANI_U8 *value = (command + 16);
1718 eHalStatus halStatus;
1719 unsigned long rc;
1720 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1721 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1722
1723 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1724 {
1725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1726 "%s: Batch scan feature is not supported by FW", __func__);
1727 ret = -EINVAL;
1728 goto exit;
1729 }
1730
1731 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1732 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1733 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1734 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1735 {
1736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1737 "Received WLS_BATCHING SET command in invalid mode %d "
1738 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
1739 pAdapter->device_mode);
1740 ret = -EINVAL;
1741 goto exit;
1742 }
1743
1744 status = hdd_parse_set_batchscan_command(value, pReq);
1745 if (status)
1746 {
1747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1748 "Invalid WLS_BATCHING SET command");
1749 ret = -EINVAL;
1750 goto exit;
1751 }
1752
1753
1754 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1755 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1756 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1757 pAdapter);
1758
1759 if ( eHAL_STATUS_SUCCESS == halStatus )
1760 {
1761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1762 "sme_SetBatchScanReq returned success halStatus %d",
1763 halStatus);
1764 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1765 {
1766 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1767 rc = wait_for_completion_timeout(
1768 &pAdapter->hdd_set_batch_scan_req_var,
1769 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1770 if (0 == rc)
1771 {
1772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1773 "%s: Timeout waiting for set batch scan to complete",
1774 __func__);
1775 ret = -EINVAL;
1776 goto exit;
1777 }
1778 }
1779 if ( !pRsp->nScansToBatch )
1780 {
1781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1782 "%s: Received set batch scan failure response from FW",
1783 __func__);
1784 ret = -EINVAL;
1785 goto exit;
1786 }
1787 /*As per the Batch Scan Framework API we should return the MIN of
1788 either MSCAN or the max # of scans firmware can cache*/
1789 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
1790
1791 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1792
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "%s: request MSCAN %d response MSCAN %d ret %d",
1795 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
1796 }
1797 else
1798 {
1799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1800 "sme_SetBatchScanReq returned failure halStatus %d",
1801 halStatus);
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805 }
1806 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1807 {
1808 eHalStatus halStatus;
1809 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1810 pInd->param = 0;
1811
1812 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1813 {
1814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1815 "%s: Batch scan feature is not supported by FW", __func__);
1816 ret = -EINVAL;
1817 goto exit;
1818 }
1819
1820 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1821 {
1822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1823 "Batch scan is not yet enabled batch scan state %d",
1824 pAdapter->batchScanState);
1825 ret = -EINVAL;
1826 goto exit;
1827 }
1828
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001829 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1830 hdd_deinit_batch_scan(pAdapter);
1831 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1832
Rajeev Kumar8b373292014-01-08 20:36:55 -08001833 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1834
1835 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1836 pAdapter->sessionId);
1837 if ( eHAL_STATUS_SUCCESS == halStatus )
1838 {
1839 ret = 0;
1840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1841 "sme_StopBatchScanInd returned success halStatus %d",
1842 halStatus);
1843 }
1844 else
1845 {
1846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1847 "sme_StopBatchScanInd returned failure halStatus %d",
1848 halStatus);
1849 ret = -EINVAL;
1850 goto exit;
1851 }
1852 }
1853 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1854 {
1855 tANI_U32 remain_len;
1856
1857 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1858 {
1859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1860 "%s: Batch scan feature is not supported by FW", __func__);
1861 ret = -EINVAL;
1862 goto exit;
1863 }
1864
1865 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1866 {
1867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1868 "Batch scan is not yet enabled could not return results"
1869 "Batch Scan state %d",
1870 pAdapter->batchScanState);
1871 ret = -EINVAL;
1872 goto exit;
1873 }
1874
1875 pPrivdata->used_len = 16;
1876 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1877 if (remain_len < pPrivdata->total_len)
1878 {
1879 /*Clear previous batch scan response data if any*/
1880 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1881 }
1882 else
1883 {
1884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1885 "Invalid total length from user space can't fetch batch"
1886 " scan response total_len %d used_len %d remain len %d",
1887 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1888 ret = -EINVAL;
1889 goto exit;
1890 }
1891 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1892 }
1893
1894exit:
1895
1896 return ret;
1897}
1898
1899
Rajeev79dbe4c2013-10-05 11:03:42 +05301900#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1901
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001902static int hdd_driver_command(hdd_adapter_t *pAdapter,
1903 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07001904{
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 hdd_priv_data_t priv_data;
1906 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001907 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001908
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001909 /*
1910 * Note that valid pointers are provided by caller
1911 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001912
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001913 /* copy to local struct to avoid numerous changes to legacy code */
1914 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07001915
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001916 if (priv_data.total_len <= 0 ||
1917 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001918 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001919 hddLog(VOS_TRACE_LEVEL_WARN,
1920 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1921 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001922 ret = -EINVAL;
1923 goto exit;
1924 }
1925
1926 /* Allocate +1 for '\0' */
1927 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001928 if (!command)
1929 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001930 hddLog(VOS_TRACE_LEVEL_ERROR,
1931 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001932 ret = -ENOMEM;
1933 goto exit;
1934 }
1935
1936 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1937 {
1938 ret = -EFAULT;
1939 goto exit;
1940 }
1941
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001942 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001943 command[priv_data.total_len] = '\0';
1944
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001945 /* at one time the following block of code was conditional. braces
1946 * have been retained to avoid re-indenting the legacy code
1947 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001948 {
1949 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1950
1951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07001952 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07001953
1954 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
1955 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1957 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
1958 pAdapter->sessionId, (unsigned)
1959 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
1960 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
1961 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
1962 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
1964 sizeof(tSirMacAddr)))
1965 {
1966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001967 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001968 ret = -EFAULT;
1969 }
1970 }
Amar Singhal0974e402013-02-12 14:27:46 -08001971 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 {
Amar Singhal0974e402013-02-12 14:27:46 -08001973 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001974
Jeff Johnson295189b2012-06-20 16:38:30 -07001975 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001976
1977 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08001980 "%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 -07001981 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001982 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301983 if(ret != 0)
1984 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001985 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08001986 }
Kiet Lamf040f472013-11-20 21:15:23 +05301987 else if(strncmp(command, "SETWMMPS", 8) == 0)
1988 {
1989 tANI_U8 *ptr = command;
1990 ret = hdd_wmmps_helper(pAdapter, ptr);
1991 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001992 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
1993 {
1994 char *country_code;
1995
1996 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001997
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001998 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001999 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002000#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302001 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002002#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002003 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2004 (void *)(tSmeChangeCountryCallback)
2005 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302006 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002007 if (eHAL_STATUS_SUCCESS == ret)
2008 {
2009 ret = wait_for_completion_interruptible_timeout(
2010 &pAdapter->change_country_code,
2011 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2012 if (0 >= ret)
2013 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302015 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002016 }
2017 }
2018 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002019 {
2020 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002021 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002022 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002023 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002024
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002025 }
2026 /*
2027 command should be a string having format
2028 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2029 */
Amar Singhal0974e402013-02-12 14:27:46 -08002030 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002031 {
Amar Singhal0974e402013-02-12 14:27:46 -08002032 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002033
2034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002035 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002036
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002037 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002038 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002039 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2040 {
2041 int suspend = 0;
2042 tANI_U8 *ptr = (tANI_U8*)command + 15;
2043
2044 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302045 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2046 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2047 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002048 hdd_set_wlan_suspend_mode(suspend);
2049 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002050#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2051 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2052 {
2053 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002054 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002055 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2056 eHalStatus status = eHAL_STATUS_SUCCESS;
2057
2058 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2059 value = value + 15;
2060
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002061 /* Convert the value from ascii to integer */
2062 ret = kstrtos8(value, 10, &rssi);
2063 if (ret < 0)
2064 {
2065 /* If the input value is greater than max value of datatype, then also
2066 kstrtou8 fails */
2067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2068 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002069 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002070 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2071 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2072 ret = -EINVAL;
2073 goto exit;
2074 }
2075
Srinivas Girigowdade697412013-02-14 16:31:48 -08002076 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002077
Srinivas Girigowdade697412013-02-14 16:31:48 -08002078 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2079 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2080 {
2081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2082 "Neighbor lookup threshold value %d is out of range"
2083 " (Min: %d Max: %d)", lookUpThreshold,
2084 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2085 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2086 ret = -EINVAL;
2087 goto exit;
2088 }
2089
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2091 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2092 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2094 "%s: Received Command to Set Roam trigger"
2095 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2096
2097 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2098 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2099 if (eHAL_STATUS_SUCCESS != status)
2100 {
2101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2102 "%s: Failed to set roam trigger, try again", __func__);
2103 ret = -EPERM;
2104 goto exit;
2105 }
2106
2107 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2108 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2109 }
2110 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2111 {
2112 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2113 int rssi = (-1) * lookUpThreshold;
2114 char extra[32];
2115 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302116 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2117 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2118 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002119 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002120 if (copy_to_user(priv_data.buf, &extra, len + 1))
2121 {
2122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2123 "%s: failed to copy data to user buffer", __func__);
2124 ret = -EFAULT;
2125 goto exit;
2126 }
2127 }
2128 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2129 {
2130 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002131 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002132 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002133
Srinivas Girigowdade697412013-02-14 16:31:48 -08002134 /* input refresh period is in terms of seconds */
2135 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2136 value = value + 18;
2137 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002138 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002139 if (ret < 0)
2140 {
2141 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002142 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002144 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002145 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002146 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2147 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002148 ret = -EINVAL;
2149 goto exit;
2150 }
2151
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002152 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2153 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002154 {
2155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002156 "Roam scan period value %d is out of range"
2157 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002158 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2159 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002160 ret = -EINVAL;
2161 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302162 }
2163 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2164 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2165 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002166 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002167
2168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2169 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002170 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002171
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002172 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2173 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002174 }
2175 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2176 {
2177 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2178 char extra[32];
2179 tANI_U8 len = 0;
2180
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302181 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2182 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2183 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002184 len = scnprintf(extra, sizeof(extra), "%s %d",
2185 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002186 /* Returned value is in units of seconds */
2187 if (copy_to_user(priv_data.buf, &extra, len + 1))
2188 {
2189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2190 "%s: failed to copy data to user buffer", __func__);
2191 ret = -EFAULT;
2192 goto exit;
2193 }
2194 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002195 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2196 {
2197 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002198 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002199 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002200
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002201 /* input refresh period is in terms of seconds */
2202 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2203 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002204
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002205 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002206 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002207 if (ret < 0)
2208 {
2209 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002210 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002212 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002213 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002214 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2215 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2216 ret = -EINVAL;
2217 goto exit;
2218 }
2219
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002220 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2221 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2222 {
2223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2224 "Neighbor scan results refresh period value %d is out of range"
2225 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2226 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2227 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2228 ret = -EINVAL;
2229 goto exit;
2230 }
2231 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2232
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2234 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002235 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002236
2237 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2238 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2239 }
2240 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2241 {
2242 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2243 char extra[32];
2244 tANI_U8 len = 0;
2245
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002246 len = scnprintf(extra, sizeof(extra), "%s %d",
2247 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002248 /* Returned value is in units of seconds */
2249 if (copy_to_user(priv_data.buf, &extra, len + 1))
2250 {
2251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2252 "%s: failed to copy data to user buffer", __func__);
2253 ret = -EFAULT;
2254 goto exit;
2255 }
2256 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002257#ifdef FEATURE_WLAN_LFR
2258 /* SETROAMMODE */
2259 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2260 {
2261 tANI_U8 *value = command;
2262 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2263
2264 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2265 value = value + SIZE_OF_SETROAMMODE + 1;
2266
2267 /* Convert the value from ascii to integer */
2268 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2269 if (ret < 0)
2270 {
2271 /* If the input value is greater than max value of datatype, then also
2272 kstrtou8 fails */
2273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2274 "%s: kstrtou8 failed range [%d - %d]", __func__,
2275 CFG_LFR_FEATURE_ENABLED_MIN,
2276 CFG_LFR_FEATURE_ENABLED_MAX);
2277 ret = -EINVAL;
2278 goto exit;
2279 }
2280 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2281 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2282 {
2283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2284 "Roam Mode value %d is out of range"
2285 " (Min: %d Max: %d)", roamMode,
2286 CFG_LFR_FEATURE_ENABLED_MIN,
2287 CFG_LFR_FEATURE_ENABLED_MAX);
2288 ret = -EINVAL;
2289 goto exit;
2290 }
2291
2292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2293 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2294 /*
2295 * Note that
2296 * SETROAMMODE 0 is to enable LFR while
2297 * SETROAMMODE 1 is to disable LFR, but
2298 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2299 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2300 */
2301 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2302 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2303 else
2304 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2305
2306 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2307 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2308 }
2309 /* GETROAMMODE */
2310 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2311 {
2312 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2313 char extra[32];
2314 tANI_U8 len = 0;
2315
2316 /*
2317 * roamMode value shall be inverted because the sementics is different.
2318 */
2319 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2320 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2321 else
2322 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2323
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002324 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002325 if (copy_to_user(priv_data.buf, &extra, len + 1))
2326 {
2327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2328 "%s: failed to copy data to user buffer", __func__);
2329 ret = -EFAULT;
2330 goto exit;
2331 }
2332 }
2333#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002334#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002335#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002336 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2337 {
2338 tANI_U8 *value = command;
2339 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2340
2341 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2342 value = value + 13;
2343 /* Convert the value from ascii to integer */
2344 ret = kstrtou8(value, 10, &roamRssiDiff);
2345 if (ret < 0)
2346 {
2347 /* If the input value is greater than max value of datatype, then also
2348 kstrtou8 fails */
2349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2350 "%s: kstrtou8 failed range [%d - %d]", __func__,
2351 CFG_ROAM_RSSI_DIFF_MIN,
2352 CFG_ROAM_RSSI_DIFF_MAX);
2353 ret = -EINVAL;
2354 goto exit;
2355 }
2356
2357 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2358 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2359 {
2360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2361 "Roam rssi diff value %d is out of range"
2362 " (Min: %d Max: %d)", roamRssiDiff,
2363 CFG_ROAM_RSSI_DIFF_MIN,
2364 CFG_ROAM_RSSI_DIFF_MAX);
2365 ret = -EINVAL;
2366 goto exit;
2367 }
2368
2369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2370 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2371
2372 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2373 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2374 }
2375 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2376 {
2377 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2378 char extra[32];
2379 tANI_U8 len = 0;
2380
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302381 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2382 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2383 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002384 len = scnprintf(extra, sizeof(extra), "%s %d",
2385 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002386 if (copy_to_user(priv_data.buf, &extra, len + 1))
2387 {
2388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2389 "%s: failed to copy data to user buffer", __func__);
2390 ret = -EFAULT;
2391 goto exit;
2392 }
2393 }
2394#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002395#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002396 else if (strncmp(command, "GETBAND", 7) == 0)
2397 {
2398 int band = -1;
2399 char extra[32];
2400 tANI_U8 len = 0;
2401 hdd_getBand_helper(pHddCtx, &band);
2402
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2404 TRACE_CODE_HDD_GETBAND_IOCTL,
2405 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002406 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002407 if (copy_to_user(priv_data.buf, &extra, len + 1))
2408 {
2409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 "%s: failed to copy data to user buffer", __func__);
2411 ret = -EFAULT;
2412 goto exit;
2413 }
2414 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2416 {
2417 tANI_U8 *value = command;
2418 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2419 tANI_U8 numChannels = 0;
2420 eHalStatus status = eHAL_STATUS_SUCCESS;
2421
2422 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2423 if (eHAL_STATUS_SUCCESS != status)
2424 {
2425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2426 "%s: Failed to parse channel list information", __func__);
2427 ret = -EINVAL;
2428 goto exit;
2429 }
2430
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302431 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2432 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2433 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002434 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2435 {
2436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2437 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2438 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2439 ret = -EINVAL;
2440 goto exit;
2441 }
2442 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2443 numChannels);
2444 if (eHAL_STATUS_SUCCESS != status)
2445 {
2446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2447 "%s: Failed to update channel list information", __func__);
2448 ret = -EINVAL;
2449 goto exit;
2450 }
2451 }
2452 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2453 {
2454 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2455 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002456 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002457 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002458 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002459
2460 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2461 ChannelList, &numChannels ))
2462 {
2463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2464 "%s: failed to get roam scan channel list", __func__);
2465 ret = -EFAULT;
2466 goto exit;
2467 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302468 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2469 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2470 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002471 /* output channel list is of the format
2472 [Number of roam scan channels][Channel1][Channel2]... */
2473 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002474 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002475 for (j = 0; (j < numChannels); j++)
2476 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002477 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2478 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002479 }
2480
2481 if (copy_to_user(priv_data.buf, &extra, len + 1))
2482 {
2483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2484 "%s: failed to copy data to user buffer", __func__);
2485 ret = -EFAULT;
2486 goto exit;
2487 }
2488 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002489 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2490 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002491 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002492 char extra[32];
2493 tANI_U8 len = 0;
2494
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002495 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002496 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002497 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002498 hdd_is_okc_mode_enabled(pHddCtx) &&
2499 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2500 {
2501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002502 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002503 " hence this operation is not permitted!", __func__);
2504 ret = -EPERM;
2505 goto exit;
2506 }
2507
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002508 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002509 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002510 if (copy_to_user(priv_data.buf, &extra, len + 1))
2511 {
2512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2513 "%s: failed to copy data to user buffer", __func__);
2514 ret = -EFAULT;
2515 goto exit;
2516 }
2517 }
2518 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2519 {
2520 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2521 char extra[32];
2522 tANI_U8 len = 0;
2523
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002524 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002525 then this operation is not permitted (return FAILURE) */
2526 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002527 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002528 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2529 {
2530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002531 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002532 " hence this operation is not permitted!", __func__);
2533 ret = -EPERM;
2534 goto exit;
2535 }
2536
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002537 len = scnprintf(extra, sizeof(extra), "%s %d",
2538 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002539 if (copy_to_user(priv_data.buf, &extra, len + 1))
2540 {
2541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2542 "%s: failed to copy data to user buffer", __func__);
2543 ret = -EFAULT;
2544 goto exit;
2545 }
2546 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002547 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002548 {
2549 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2550 char extra[32];
2551 tANI_U8 len = 0;
2552
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002553 len = scnprintf(extra, sizeof(extra), "%s %d",
2554 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 if (copy_to_user(priv_data.buf, &extra, len + 1))
2556 {
2557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2558 "%s: failed to copy data to user buffer", __func__);
2559 ret = -EFAULT;
2560 goto exit;
2561 }
2562 }
2563 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2564 {
2565 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2566 char extra[32];
2567 tANI_U8 len = 0;
2568
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002569 len = scnprintf(extra, sizeof(extra), "%s %d",
2570 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002571 if (copy_to_user(priv_data.buf, &extra, len + 1))
2572 {
2573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2574 "%s: failed to copy data to user buffer", __func__);
2575 ret = -EFAULT;
2576 goto exit;
2577 }
2578 }
2579 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2580 {
2581 tANI_U8 *value = command;
2582 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2583
2584 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2585 value = value + 26;
2586 /* Convert the value from ascii to integer */
2587 ret = kstrtou8(value, 10, &minTime);
2588 if (ret < 0)
2589 {
2590 /* If the input value is greater than max value of datatype, then also
2591 kstrtou8 fails */
2592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2593 "%s: kstrtou8 failed range [%d - %d]", __func__,
2594 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2595 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2596 ret = -EINVAL;
2597 goto exit;
2598 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002599 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2600 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2601 {
2602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2603 "scan min channel time value %d is out of range"
2604 " (Min: %d Max: %d)", minTime,
2605 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2606 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2607 ret = -EINVAL;
2608 goto exit;
2609 }
2610
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302611 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2612 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2613 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2615 "%s: Received Command to change channel min time = %d", __func__, minTime);
2616
2617 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2618 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2619 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002620 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2621 {
2622 tANI_U8 *value = command;
2623 tANI_U8 channel = 0;
2624 tANI_U8 dwellTime = 0;
2625 tANI_U8 bufLen = 0;
2626 tANI_U8 *buf = NULL;
2627 tSirMacAddr targetApBssid;
2628 eHalStatus status = eHAL_STATUS_SUCCESS;
2629 struct ieee80211_channel chan;
2630 tANI_U8 finalLen = 0;
2631 tANI_U8 *finalBuf = NULL;
2632 tANI_U8 temp = 0;
2633 u64 cookie;
2634 hdd_station_ctx_t *pHddStaCtx = NULL;
2635 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2636
2637 /* if not associated, no need to send action frame */
2638 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2639 {
2640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2641 ret = -EINVAL;
2642 goto exit;
2643 }
2644
2645 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2646 &dwellTime, &buf, &bufLen);
2647 if (eHAL_STATUS_SUCCESS != status)
2648 {
2649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2650 "%s: Failed to parse send action frame data", __func__);
2651 ret = -EINVAL;
2652 goto exit;
2653 }
2654
2655 /* if the target bssid is different from currently associated AP,
2656 then no need to send action frame */
2657 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2658 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2659 {
2660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2661 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002662 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002663 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002664 goto exit;
2665 }
2666
2667 /* if the channel number is different from operating channel then
2668 no need to send action frame */
2669 if (channel != pHddStaCtx->conn_info.operationChannel)
2670 {
2671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2672 "%s: channel(%d) is different from operating channel(%d)",
2673 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2674 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002675 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002676 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002677 goto exit;
2678 }
2679 chan.center_freq = sme_ChnToFreq(channel);
2680
2681 finalLen = bufLen + 24;
2682 finalBuf = vos_mem_malloc(finalLen);
2683 if (NULL == finalBuf)
2684 {
2685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2686 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002687 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002688 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002689 goto exit;
2690 }
2691 vos_mem_zero(finalBuf, finalLen);
2692
2693 /* Fill subtype */
2694 temp = SIR_MAC_MGMT_ACTION << 4;
2695 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2696
2697 /* Fill type */
2698 temp = SIR_MAC_MGMT_FRAME;
2699 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2700
2701 /* Fill destination address (bssid of the AP) */
2702 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2703
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002704 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002705 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2706
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002707 /* Fill BSSID (AP mac address) */
2708 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002709
2710 /* Fill received buffer from 24th address */
2711 vos_mem_copy(finalBuf + 24, buf, bufLen);
2712
Jeff Johnson11c33152013-04-16 17:52:40 -07002713 /* done with the parsed buffer */
2714 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002715 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002716
DARAM SUDHA39eede62014-02-12 11:16:40 +05302717 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2719 &(pAdapter->wdev),
2720#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002721 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002722#endif
2723 &chan, 0,
2724#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2725 NL80211_CHAN_HT20, 1,
2726#endif
2727 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002728 1, &cookie );
2729 vos_mem_free(finalBuf);
2730 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002731 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2732 {
2733 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2734 char extra[32];
2735 tANI_U8 len = 0;
2736
2737 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002738 len = scnprintf(extra, sizeof(extra), "%s %d",
2739 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302740 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2741 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2742 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002743 if (copy_to_user(priv_data.buf, &extra, len + 1))
2744 {
2745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2746 "%s: failed to copy data to user buffer", __func__);
2747 ret = -EFAULT;
2748 goto exit;
2749 }
2750 }
2751 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2752 {
2753 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002754 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002755
2756 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2757 value = value + 19;
2758 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002759 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002760 if (ret < 0)
2761 {
2762 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002763 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002765 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002766 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2767 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2768 ret = -EINVAL;
2769 goto exit;
2770 }
2771
2772 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2773 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2774 {
2775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2776 "lfr mode value %d is out of range"
2777 " (Min: %d Max: %d)", maxTime,
2778 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2779 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2780 ret = -EINVAL;
2781 goto exit;
2782 }
2783
2784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2785 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2786
2787 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2788 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2789 }
2790 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2791 {
2792 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2793 char extra[32];
2794 tANI_U8 len = 0;
2795
2796 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002797 len = scnprintf(extra, sizeof(extra), "%s %d",
2798 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002799 if (copy_to_user(priv_data.buf, &extra, len + 1))
2800 {
2801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2802 "%s: failed to copy data to user buffer", __func__);
2803 ret = -EFAULT;
2804 goto exit;
2805 }
2806 }
2807 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2808 {
2809 tANI_U8 *value = command;
2810 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2811
2812 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2813 value = value + 16;
2814 /* Convert the value from ascii to integer */
2815 ret = kstrtou16(value, 10, &val);
2816 if (ret < 0)
2817 {
2818 /* If the input value is greater than max value of datatype, then also
2819 kstrtou16 fails */
2820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2821 "%s: kstrtou16 failed range [%d - %d]", __func__,
2822 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2823 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2824 ret = -EINVAL;
2825 goto exit;
2826 }
2827
2828 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2829 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2830 {
2831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2832 "scan home time value %d is out of range"
2833 " (Min: %d Max: %d)", val,
2834 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2835 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2836 ret = -EINVAL;
2837 goto exit;
2838 }
2839
2840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2841 "%s: Received Command to change scan home time = %d", __func__, val);
2842
2843 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2844 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2845 }
2846 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2847 {
2848 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2849 char extra[32];
2850 tANI_U8 len = 0;
2851
2852 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002853 len = scnprintf(extra, sizeof(extra), "%s %d",
2854 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002855 if (copy_to_user(priv_data.buf, &extra, len + 1))
2856 {
2857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2858 "%s: failed to copy data to user buffer", __func__);
2859 ret = -EFAULT;
2860 goto exit;
2861 }
2862 }
2863 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2864 {
2865 tANI_U8 *value = command;
2866 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2867
2868 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2869 value = value + 17;
2870 /* Convert the value from ascii to integer */
2871 ret = kstrtou8(value, 10, &val);
2872 if (ret < 0)
2873 {
2874 /* If the input value is greater than max value of datatype, then also
2875 kstrtou8 fails */
2876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2877 "%s: kstrtou8 failed range [%d - %d]", __func__,
2878 CFG_ROAM_INTRA_BAND_MIN,
2879 CFG_ROAM_INTRA_BAND_MAX);
2880 ret = -EINVAL;
2881 goto exit;
2882 }
2883
2884 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2885 (val > CFG_ROAM_INTRA_BAND_MAX))
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2888 "intra band mode value %d is out of range"
2889 " (Min: %d Max: %d)", val,
2890 CFG_ROAM_INTRA_BAND_MIN,
2891 CFG_ROAM_INTRA_BAND_MAX);
2892 ret = -EINVAL;
2893 goto exit;
2894 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2896 "%s: Received Command to change intra band = %d", __func__, val);
2897
2898 pHddCtx->cfg_ini->nRoamIntraBand = val;
2899 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2900 }
2901 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2902 {
2903 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2904 char extra[32];
2905 tANI_U8 len = 0;
2906
2907 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002908 len = scnprintf(extra, sizeof(extra), "%s %d",
2909 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002910 if (copy_to_user(priv_data.buf, &extra, len + 1))
2911 {
2912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2913 "%s: failed to copy data to user buffer", __func__);
2914 ret = -EFAULT;
2915 goto exit;
2916 }
2917 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002918 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2919 {
2920 tANI_U8 *value = command;
2921 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2922
2923 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2924 value = value + 15;
2925 /* Convert the value from ascii to integer */
2926 ret = kstrtou8(value, 10, &nProbes);
2927 if (ret < 0)
2928 {
2929 /* If the input value is greater than max value of datatype, then also
2930 kstrtou8 fails */
2931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2932 "%s: kstrtou8 failed range [%d - %d]", __func__,
2933 CFG_ROAM_SCAN_N_PROBES_MIN,
2934 CFG_ROAM_SCAN_N_PROBES_MAX);
2935 ret = -EINVAL;
2936 goto exit;
2937 }
2938
2939 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2940 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2941 {
2942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2943 "NProbes value %d is out of range"
2944 " (Min: %d Max: %d)", nProbes,
2945 CFG_ROAM_SCAN_N_PROBES_MIN,
2946 CFG_ROAM_SCAN_N_PROBES_MAX);
2947 ret = -EINVAL;
2948 goto exit;
2949 }
2950
2951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2952 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
2953
2954 pHddCtx->cfg_ini->nProbes = nProbes;
2955 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
2956 }
2957 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
2958 {
2959 tANI_U8 val = sme_getRoamScanNProbes((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, "SETSCANHOMEAWAYTIME", 19) == 0)
2973 {
2974 tANI_U8 *value = command;
2975 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
2976
2977 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
2978 /* input value is in units of msec */
2979 value = value + 20;
2980 /* Convert the value from ascii to integer */
2981 ret = kstrtou16(value, 10, &homeAwayTime);
2982 if (ret < 0)
2983 {
2984 /* If the input value is greater than max value of datatype, then also
2985 kstrtou8 fails */
2986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2987 "%s: kstrtou8 failed range [%d - %d]", __func__,
2988 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2989 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2990 ret = -EINVAL;
2991 goto exit;
2992 }
2993
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002994 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
2995 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
2996 {
2997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2998 "homeAwayTime value %d is out of range"
2999 " (Min: %d Max: %d)", homeAwayTime,
3000 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3001 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3002 ret = -EINVAL;
3003 goto exit;
3004 }
3005
3006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3007 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003008 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3009 {
3010 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3011 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3012 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003013 }
3014 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3015 {
3016 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3017 char extra[32];
3018 tANI_U8 len = 0;
3019
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003020 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003021 if (copy_to_user(priv_data.buf, &extra, len + 1))
3022 {
3023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3024 "%s: failed to copy data to user buffer", __func__);
3025 ret = -EFAULT;
3026 goto exit;
3027 }
3028 }
3029 else if (strncmp(command, "REASSOC", 7) == 0)
3030 {
3031 tANI_U8 *value = command;
3032 tANI_U8 channel = 0;
3033 tSirMacAddr targetApBssid;
3034 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003035#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3036 tCsrHandoffRequest handoffInfo;
3037#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003038 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003039 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3040
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003041 /* if not associated, no need to proceed with reassoc */
3042 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3043 {
3044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3045 ret = -EINVAL;
3046 goto exit;
3047 }
3048
3049 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3050 if (eHAL_STATUS_SUCCESS != status)
3051 {
3052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3053 "%s: Failed to parse reassoc command data", __func__);
3054 ret = -EINVAL;
3055 goto exit;
3056 }
3057
3058 /* if the target bssid is same as currently associated AP,
3059 then no need to proceed with reassoc */
3060 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3061 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3062 {
3063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3064 ret = -EINVAL;
3065 goto exit;
3066 }
3067
3068 /* Check channel number is a valid channel number */
3069 if(VOS_STATUS_SUCCESS !=
3070 wlan_hdd_validate_operation_channel(pAdapter, channel))
3071 {
3072 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003073 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003074 return -EINVAL;
3075 }
3076
3077 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003078#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3079 handoffInfo.channel = channel;
3080 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3081 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3082#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003083 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003084 else if (strncmp(command, "SETWESMODE", 10) == 0)
3085 {
3086 tANI_U8 *value = command;
3087 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3088
3089 /* Move pointer to ahead of SETWESMODE<delimiter> */
3090 value = value + 11;
3091 /* Convert the value from ascii to integer */
3092 ret = kstrtou8(value, 10, &wesMode);
3093 if (ret < 0)
3094 {
3095 /* If the input value is greater than max value of datatype, then also
3096 kstrtou8 fails */
3097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3098 "%s: kstrtou8 failed range [%d - %d]", __func__,
3099 CFG_ENABLE_WES_MODE_NAME_MIN,
3100 CFG_ENABLE_WES_MODE_NAME_MAX);
3101 ret = -EINVAL;
3102 goto exit;
3103 }
3104
3105 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3106 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3107 {
3108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3109 "WES Mode value %d is out of range"
3110 " (Min: %d Max: %d)", wesMode,
3111 CFG_ENABLE_WES_MODE_NAME_MIN,
3112 CFG_ENABLE_WES_MODE_NAME_MAX);
3113 ret = -EINVAL;
3114 goto exit;
3115 }
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3117 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3118
3119 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3120 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3121 }
3122 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3123 {
3124 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3125 char extra[32];
3126 tANI_U8 len = 0;
3127
Arif Hussain826d9412013-11-12 16:44:54 -08003128 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003129 if (copy_to_user(priv_data.buf, &extra, len + 1))
3130 {
3131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3132 "%s: failed to copy data to user buffer", __func__);
3133 ret = -EFAULT;
3134 goto exit;
3135 }
3136 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003137#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003138#ifdef FEATURE_WLAN_LFR
3139 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3140 {
3141 tANI_U8 *value = command;
3142 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3143
3144 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3145 value = value + 12;
3146 /* Convert the value from ascii to integer */
3147 ret = kstrtou8(value, 10, &lfrMode);
3148 if (ret < 0)
3149 {
3150 /* If the input value is greater than max value of datatype, then also
3151 kstrtou8 fails */
3152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3153 "%s: kstrtou8 failed range [%d - %d]", __func__,
3154 CFG_LFR_FEATURE_ENABLED_MIN,
3155 CFG_LFR_FEATURE_ENABLED_MAX);
3156 ret = -EINVAL;
3157 goto exit;
3158 }
3159
3160 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3161 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3162 {
3163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3164 "lfr mode value %d is out of range"
3165 " (Min: %d Max: %d)", lfrMode,
3166 CFG_LFR_FEATURE_ENABLED_MIN,
3167 CFG_LFR_FEATURE_ENABLED_MAX);
3168 ret = -EINVAL;
3169 goto exit;
3170 }
3171
3172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3173 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3174
3175 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3176 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3177 }
3178#endif
3179#ifdef WLAN_FEATURE_VOWIFI_11R
3180 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3181 {
3182 tANI_U8 *value = command;
3183 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3184
3185 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3186 value = value + 18;
3187 /* Convert the value from ascii to integer */
3188 ret = kstrtou8(value, 10, &ft);
3189 if (ret < 0)
3190 {
3191 /* If the input value is greater than max value of datatype, then also
3192 kstrtou8 fails */
3193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3194 "%s: kstrtou8 failed range [%d - %d]", __func__,
3195 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3196 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3197 ret = -EINVAL;
3198 goto exit;
3199 }
3200
3201 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3202 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3203 {
3204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3205 "ft mode value %d is out of range"
3206 " (Min: %d Max: %d)", ft,
3207 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3208 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3209 ret = -EINVAL;
3210 goto exit;
3211 }
3212
3213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3214 "%s: Received Command to change ft mode = %d", __func__, ft);
3215
3216 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3217 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3218 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303219
3220 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3221 {
3222 tANI_U8 *value = command;
3223 tSirMacAddr targetApBssid;
3224 tANI_U8 trigger = 0;
3225 eHalStatus status = eHAL_STATUS_SUCCESS;
3226 hdd_station_ctx_t *pHddStaCtx = NULL;
3227 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3228
3229 /* if not associated, no need to proceed with reassoc */
3230 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3231 {
3232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3233 ret = -EINVAL;
3234 goto exit;
3235 }
3236
3237 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3238 if (eHAL_STATUS_SUCCESS != status)
3239 {
3240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3241 "%s: Failed to parse reassoc command data", __func__);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 /* if the target bssid is same as currently associated AP,
3247 then no need to proceed with reassoc */
3248 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3249 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3250 {
3251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3252 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3253 __func__);
3254 ret = -EINVAL;
3255 goto exit;
3256 }
3257
3258 /* Proceed with scan/roam */
3259 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3260 &targetApBssid[0],
3261 (tSmeFastRoamTrigger)(trigger));
3262 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003263#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003264#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003265 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3266 {
3267 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003268 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003269
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003270 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003271 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003272 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003273 hdd_is_okc_mode_enabled(pHddCtx) &&
3274 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3275 {
3276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003277 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003278 " hence this operation is not permitted!", __func__);
3279 ret = -EPERM;
3280 goto exit;
3281 }
3282
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003283 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3284 value = value + 11;
3285 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003286 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003287 if (ret < 0)
3288 {
3289 /* If the input value is greater than max value of datatype, then also
3290 kstrtou8 fails */
3291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3292 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003293 CFG_ESE_FEATURE_ENABLED_MIN,
3294 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003295 ret = -EINVAL;
3296 goto exit;
3297 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003298 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3299 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003300 {
3301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003302 "Ese mode value %d is out of range"
3303 " (Min: %d Max: %d)", eseMode,
3304 CFG_ESE_FEATURE_ENABLED_MIN,
3305 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003306 ret = -EINVAL;
3307 goto exit;
3308 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003310 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003311
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003312 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3313 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003314 }
3315#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003316 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3317 {
3318 tANI_U8 *value = command;
3319 tANI_BOOLEAN roamScanControl = 0;
3320
3321 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3322 value = value + 19;
3323 /* Convert the value from ascii to integer */
3324 ret = kstrtou8(value, 10, &roamScanControl);
3325 if (ret < 0)
3326 {
3327 /* If the input value is greater than max value of datatype, then also
3328 kstrtou8 fails */
3329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3330 "%s: kstrtou8 failed ", __func__);
3331 ret = -EINVAL;
3332 goto exit;
3333 }
3334
3335 if (0 != roamScanControl)
3336 {
3337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3338 "roam scan control invalid value = %d",
3339 roamScanControl);
3340 ret = -EINVAL;
3341 goto exit;
3342 }
3343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3344 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3345
3346 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3347 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003348#ifdef FEATURE_WLAN_OKC
3349 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3350 {
3351 tANI_U8 *value = command;
3352 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3353
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003354 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003355 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003356 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003357 hdd_is_okc_mode_enabled(pHddCtx) &&
3358 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3359 {
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003361 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003362 " hence this operation is not permitted!", __func__);
3363 ret = -EPERM;
3364 goto exit;
3365 }
3366
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003367 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3368 value = value + 11;
3369 /* Convert the value from ascii to integer */
3370 ret = kstrtou8(value, 10, &okcMode);
3371 if (ret < 0)
3372 {
3373 /* If the input value is greater than max value of datatype, then also
3374 kstrtou8 fails */
3375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3376 "%s: kstrtou8 failed range [%d - %d]", __func__,
3377 CFG_OKC_FEATURE_ENABLED_MIN,
3378 CFG_OKC_FEATURE_ENABLED_MAX);
3379 ret = -EINVAL;
3380 goto exit;
3381 }
3382
3383 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3384 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3385 {
3386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3387 "Okc mode value %d is out of range"
3388 " (Min: %d Max: %d)", okcMode,
3389 CFG_OKC_FEATURE_ENABLED_MIN,
3390 CFG_OKC_FEATURE_ENABLED_MAX);
3391 ret = -EINVAL;
3392 goto exit;
3393 }
3394
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3396 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3397
3398 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3399 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003400#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003401 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3402 {
3403 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3404 char extra[32];
3405 tANI_U8 len = 0;
3406
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003407 len = scnprintf(extra, sizeof(extra), "%s %d",
3408 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003409 if (copy_to_user(priv_data.buf, &extra, len + 1))
3410 {
3411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3412 "%s: failed to copy data to user buffer", __func__);
3413 ret = -EFAULT;
3414 goto exit;
3415 }
3416 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303417#ifdef WLAN_FEATURE_PACKET_FILTERING
3418 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3419 {
3420 tANI_U8 filterType = 0;
3421 tANI_U8 *value = command;
3422
3423 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3424 value = value + 22;
3425
3426 /* Convert the value from ascii to integer */
3427 ret = kstrtou8(value, 10, &filterType);
3428 if (ret < 0)
3429 {
3430 /* If the input value is greater than max value of datatype,
3431 * then also kstrtou8 fails
3432 */
3433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3434 "%s: kstrtou8 failed range ", __func__);
3435 ret = -EINVAL;
3436 goto exit;
3437 }
3438
3439 if (filterType != 0 && filterType != 1)
3440 {
3441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3442 "%s: Accepted Values are 0 and 1 ", __func__);
3443 ret = -EINVAL;
3444 goto exit;
3445 }
3446 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3447 pAdapter->sessionId);
3448 }
3449#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303450 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3451 {
3452 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303453 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303454 if ('1' == *dhcpPhase)
3455 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303457 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303458
3459 pHddCtx->btCoexModeSet = TRUE;
3460
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303461 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303462 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303463 }
3464 else if ('2' == *dhcpPhase)
3465 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303467 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303468
3469 pHddCtx->btCoexModeSet = FALSE;
3470
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303471 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303472 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303473 }
3474 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003475 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3476 {
3477 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
3478 }
3479 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3480 {
3481 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
3482 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303483 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3484 {
3485 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3486 char extra[32];
3487 tANI_U8 len = 0;
3488
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003489 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303490 (int)pCfg->nActiveMaxChnTime);
3491 if (copy_to_user(priv_data.buf, &extra, len + 1))
3492 {
3493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3494 "%s: failed to copy data to user buffer", __func__);
3495 ret = -EFAULT;
3496 goto exit;
3497 }
3498 ret = len;
3499 }
3500 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3501 {
3502 tANI_U8 *value = command;
3503 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3504 int val = 0, temp;
3505
3506 value = value + 13;
3507 temp = kstrtou32(value, 10, &val);
3508 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3509 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3510 {
3511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3512 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3513 ret = -EFAULT;
3514 goto exit;
3515 }
3516 pCfg->nActiveMaxChnTime = val;
3517 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003518 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3519 {
3520 tANI_U8 filterType = 0;
3521 tANI_U8 *value;
3522 value = command + 9;
3523
3524 /* Convert the value from ascii to integer */
3525 ret = kstrtou8(value, 10, &filterType);
3526 if (ret < 0)
3527 {
3528 /* If the input value is greater than max value of datatype,
3529 * then also kstrtou8 fails
3530 */
3531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3532 "%s: kstrtou8 failed range ", __func__);
3533 ret = -EINVAL;
3534 goto exit;
3535 }
3536 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3537 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3538 {
3539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3540 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3541 " 2-Sink ", __func__);
3542 ret = -EINVAL;
3543 goto exit;
3544 }
3545 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3546 pHddCtx->drvr_miracast = filterType;
3547 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3548 }
Leo Chang614d2072013-08-22 14:59:44 -07003549 else if (strncmp(command, "SETMCRATE", 9) == 0)
3550 {
Leo Chang614d2072013-08-22 14:59:44 -07003551 tANI_U8 *value = command;
3552 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003553 tSirRateUpdateInd *rateUpdate;
3554 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003555
3556 /* Only valid for SAP mode */
3557 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3558 {
3559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3560 "%s: SAP mode is not running", __func__);
3561 ret = -EFAULT;
3562 goto exit;
3563 }
3564
3565 /* Move pointer to ahead of SETMCRATE<delimiter> */
3566 /* input value is in units of hundred kbps */
3567 value = value + 10;
3568 /* Convert the value from ascii to integer, decimal base */
3569 ret = kstrtouint(value, 10, &targetRate);
3570
Leo Chang1f98cbd2013-10-17 15:03:52 -07003571 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3572 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003573 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003574 hddLog(VOS_TRACE_LEVEL_ERROR,
3575 "%s: SETMCRATE indication alloc fail", __func__);
3576 ret = -EFAULT;
3577 goto exit;
3578 }
3579 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3580
3581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3582 "MC Target rate %d", targetRate);
3583 /* Ignore unicast */
3584 rateUpdate->ucastDataRate = -1;
3585 rateUpdate->mcastDataRate24GHz = targetRate;
3586 rateUpdate->mcastDataRate5GHz = targetRate;
3587 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3588 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3589 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3590 if (eHAL_STATUS_SUCCESS != status)
3591 {
3592 hddLog(VOS_TRACE_LEVEL_ERROR,
3593 "%s: SET_MC_RATE failed", __func__);
3594 vos_mem_free(rateUpdate);
3595 ret = -EFAULT;
3596 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003597 }
3598 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303599#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003600 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303601 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003602 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303603 }
3604#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003605#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003606 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3607 {
3608 tANI_U8 *value = command;
3609 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3610 tANI_U8 numChannels = 0;
3611 eHalStatus status = eHAL_STATUS_SUCCESS;
3612
3613 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3614 if (eHAL_STATUS_SUCCESS != status)
3615 {
3616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3617 "%s: Failed to parse channel list information", __func__);
3618 ret = -EINVAL;
3619 goto exit;
3620 }
3621
3622 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3623 {
3624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3625 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3626 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3627 ret = -EINVAL;
3628 goto exit;
3629 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003630 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003631 ChannelList,
3632 numChannels);
3633 if (eHAL_STATUS_SUCCESS != status)
3634 {
3635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3636 "%s: Failed to update channel list information", __func__);
3637 ret = -EINVAL;
3638 goto exit;
3639 }
3640 }
3641 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3642 {
3643 tANI_U8 *value = command;
3644 char extra[128] = {0};
3645 int len = 0;
3646 tANI_U8 tid = 0;
3647 hdd_station_ctx_t *pHddStaCtx = NULL;
3648 tAniTrafStrmMetrics tsmMetrics;
3649 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3650
3651 /* if not associated, return error */
3652 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3653 {
3654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3655 ret = -EINVAL;
3656 goto exit;
3657 }
3658
3659 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3660 value = value + 12;
3661 /* Convert the value from ascii to integer */
3662 ret = kstrtou8(value, 10, &tid);
3663 if (ret < 0)
3664 {
3665 /* If the input value is greater than max value of datatype, then also
3666 kstrtou8 fails */
3667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3668 "%s: kstrtou8 failed range [%d - %d]", __func__,
3669 TID_MIN_VALUE,
3670 TID_MAX_VALUE);
3671 ret = -EINVAL;
3672 goto exit;
3673 }
3674
3675 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3676 {
3677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3678 "tid value %d is out of range"
3679 " (Min: %d Max: %d)", tid,
3680 TID_MIN_VALUE,
3681 TID_MAX_VALUE);
3682 ret = -EINVAL;
3683 goto exit;
3684 }
3685
3686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3687 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3688
3689 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3690 {
3691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3692 "%s: failed to get tsm stats", __func__);
3693 ret = -EFAULT;
3694 goto exit;
3695 }
3696
3697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3698 "UplinkPktQueueDly(%d)\n"
3699 "UplinkPktQueueDlyHist[0](%d)\n"
3700 "UplinkPktQueueDlyHist[1](%d)\n"
3701 "UplinkPktQueueDlyHist[2](%d)\n"
3702 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303703 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003704 "UplinkPktLoss(%d)\n"
3705 "UplinkPktCount(%d)\n"
3706 "RoamingCount(%d)\n"
3707 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3708 tsmMetrics.UplinkPktQueueDlyHist[0],
3709 tsmMetrics.UplinkPktQueueDlyHist[1],
3710 tsmMetrics.UplinkPktQueueDlyHist[2],
3711 tsmMetrics.UplinkPktQueueDlyHist[3],
3712 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3713 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3714
3715 /* Output TSM stats is of the format
3716 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3717 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003718 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003719 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3720 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3721 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3722 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3723 tsmMetrics.RoamingDly);
3724
3725 if (copy_to_user(priv_data.buf, &extra, len + 1))
3726 {
3727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3728 "%s: failed to copy data to user buffer", __func__);
3729 ret = -EFAULT;
3730 goto exit;
3731 }
3732 }
3733 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3734 {
3735 tANI_U8 *value = command;
3736 tANI_U8 *cckmIe = NULL;
3737 tANI_U8 cckmIeLen = 0;
3738 eHalStatus status = eHAL_STATUS_SUCCESS;
3739
3740 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3741 if (eHAL_STATUS_SUCCESS != status)
3742 {
3743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3744 "%s: Failed to parse cckm ie data", __func__);
3745 ret = -EINVAL;
3746 goto exit;
3747 }
3748
3749 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3750 {
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "%s: CCKM Ie input length is more than max[%d]", __func__,
3753 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003754 vos_mem_free(cckmIe);
3755 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003756 ret = -EINVAL;
3757 goto exit;
3758 }
3759 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003760 vos_mem_free(cckmIe);
3761 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003762 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003763 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3764 {
3765 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003766 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003767 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003768 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003769 if (eHAL_STATUS_SUCCESS != status)
3770 {
3771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003772 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003773 ret = -EINVAL;
3774 goto exit;
3775 }
3776
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003777 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3778 if (eHAL_STATUS_SUCCESS != status)
3779 {
3780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3781 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3782 ret = -EINVAL;
3783 goto exit;
3784 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003785 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003786#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003787 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303788 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3789 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
3790 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003791 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3792 __func__, command);
3793 }
3794
Jeff Johnson295189b2012-06-20 16:38:30 -07003795 }
3796exit:
3797 if (command)
3798 {
3799 kfree(command);
3800 }
3801 return ret;
3802}
3803
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003804#ifdef CONFIG_COMPAT
3805static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3806{
3807 struct {
3808 compat_uptr_t buf;
3809 int used_len;
3810 int total_len;
3811 } compat_priv_data;
3812 hdd_priv_data_t priv_data;
3813 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003814
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003815 /*
3816 * Note that pAdapter and ifr have already been verified by caller,
3817 * and HDD context has also been validated
3818 */
3819 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
3820 sizeof(compat_priv_data))) {
3821 ret = -EFAULT;
3822 goto exit;
3823 }
3824 priv_data.buf = compat_ptr(compat_priv_data.buf);
3825 priv_data.used_len = compat_priv_data.used_len;
3826 priv_data.total_len = compat_priv_data.total_len;
3827 ret = hdd_driver_command(pAdapter, &priv_data);
3828 exit:
3829 return ret;
3830}
3831#else /* CONFIG_COMPAT */
3832static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3833{
3834 /* will never be invoked */
3835 return 0;
3836}
3837#endif /* CONFIG_COMPAT */
3838
3839static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3840{
3841 hdd_priv_data_t priv_data;
3842 int ret = 0;
3843
3844 /*
3845 * Note that pAdapter and ifr have already been verified by caller,
3846 * and HDD context has also been validated
3847 */
3848 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
3849 ret = -EFAULT;
3850 } else {
3851 ret = hdd_driver_command(pAdapter, &priv_data);
3852 }
3853 return ret;
3854}
3855
3856int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
3857{
3858 hdd_adapter_t *pAdapter;
3859 hdd_context_t *pHddCtx;
3860 int ret;
3861
3862 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3863 if (NULL == pAdapter) {
3864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3865 "%s: HDD adapter context is Null", __func__);
3866 ret = -ENODEV;
3867 goto exit;
3868 }
3869 if (dev != pAdapter->dev) {
3870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3871 "%s: HDD adapter/dev inconsistency", __func__);
3872 ret = -ENODEV;
3873 goto exit;
3874 }
3875
3876 if ((!ifr) || (!ifr->ifr_data)) {
3877 ret = -EINVAL;
3878 goto exit;
3879 }
3880
3881 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3882 ret = wlan_hdd_validate_context(pHddCtx);
3883 if (ret) {
3884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3885 "%s: invalid context", __func__);
3886 ret = -EBUSY;
3887 goto exit;
3888 }
3889
3890 switch (cmd) {
3891 case (SIOCDEVPRIVATE + 1):
3892 if (is_compat_task())
3893 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
3894 else
3895 ret = hdd_driver_ioctl(pAdapter, ifr);
3896 break;
3897 default:
3898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
3899 __func__, cmd);
3900 ret = -EINVAL;
3901 break;
3902 }
3903 exit:
3904 return ret;
3905}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003906
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003907#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003908/**---------------------------------------------------------------------------
3909
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003910 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003911
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003912 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003913 CCXBEACONREQ<space><Number of fields><space><Measurement token>
3914 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
3915 <space>Scan Mode N<space>Meas Duration N
3916 if the Number of bcn req fields (N) does not match with the actual number of fields passed
3917 then take N.
3918 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
3919 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
3920 This function does not take care of removing duplicate channels from the list
3921
3922 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003923 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003924
3925 \return - 0 for success non-zero for failure
3926
3927 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003928static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
3929 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003930{
3931 tANI_U8 *inPtr = pValue;
3932 int tempInt = 0;
3933 int j = 0, i = 0, v = 0;
3934 char buf[32];
3935
3936 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
3937 /*no argument after the command*/
3938 if (NULL == inPtr)
3939 {
3940 return -EINVAL;
3941 }
3942 /*no space after the command*/
3943 else if (SPACE_ASCII_VALUE != *inPtr)
3944 {
3945 return -EINVAL;
3946 }
3947
3948 /*removing empty spaces*/
3949 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3950
3951 /*no argument followed by spaces*/
3952 if ('\0' == *inPtr) return -EINVAL;
3953
3954 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003955 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003956 if (1 != v) return -EINVAL;
3957
3958 v = kstrtos32(buf, 10, &tempInt);
3959 if ( v < 0) return -EINVAL;
3960
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003961 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003962
3963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003964 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003965
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003966 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003967 {
3968 for (i = 0; i < 4; i++)
3969 {
3970 /*inPtr pointing to the beginning of first space after number of ie fields*/
3971 inPtr = strpbrk( inPtr, " " );
3972 /*no ie data after the number of ie fields argument*/
3973 if (NULL == inPtr) return -EINVAL;
3974
3975 /*removing empty space*/
3976 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3977
3978 /*no ie data after the number of ie fields argument and spaces*/
3979 if ( '\0' == *inPtr ) return -EINVAL;
3980
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003981 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003982 if (1 != v) return -EINVAL;
3983
3984 v = kstrtos32(buf, 10, &tempInt);
3985 if (v < 0) return -EINVAL;
3986
3987 switch (i)
3988 {
3989 case 0: /* Measurement token */
3990 if (tempInt <= 0)
3991 {
3992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3993 "Invalid Measurement Token(%d)", tempInt);
3994 return -EINVAL;
3995 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003996 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003997 break;
3998
3999 case 1: /* Channel number */
4000 if ((tempInt <= 0) ||
4001 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4002 {
4003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4004 "Invalid Channel Number(%d)", tempInt);
4005 return -EINVAL;
4006 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004007 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004008 break;
4009
4010 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004011 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004012 {
4013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4014 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4015 return -EINVAL;
4016 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004017 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004018 break;
4019
4020 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004021 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4022 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004023 {
4024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4025 "Invalid Measurement Duration(%d)", tempInt);
4026 return -EINVAL;
4027 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004028 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004029 break;
4030 }
4031 }
4032 }
4033
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004034 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004035 {
4036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304037 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004038 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004039 pEseBcnReq->bcnReq[j].measurementToken,
4040 pEseBcnReq->bcnReq[j].channel,
4041 pEseBcnReq->bcnReq[j].scanMode,
4042 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004043 }
4044
4045 return VOS_STATUS_SUCCESS;
4046}
4047
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004048static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4049{
4050 struct statsContext *pStatsContext = NULL;
4051 hdd_adapter_t *pAdapter = NULL;
4052
4053 if (NULL == pContext)
4054 {
4055 hddLog(VOS_TRACE_LEVEL_ERROR,
4056 "%s: Bad param, pContext [%p]",
4057 __func__, pContext);
4058 return;
4059 }
4060
Jeff Johnson72a40512013-12-19 10:14:15 -08004061 /* there is a race condition that exists between this callback
4062 function and the caller since the caller could time out either
4063 before or while this code is executing. we use a spinlock to
4064 serialize these actions */
4065 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004066
4067 pStatsContext = pContext;
4068 pAdapter = pStatsContext->pAdapter;
4069 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4070 {
4071 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004072 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004073 hddLog(VOS_TRACE_LEVEL_WARN,
4074 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4075 __func__, pAdapter, pStatsContext->magic);
4076 return;
4077 }
4078
Jeff Johnson72a40512013-12-19 10:14:15 -08004079 /* context is valid so caller is still waiting */
4080
4081 /* paranoia: invalidate the magic */
4082 pStatsContext->magic = 0;
4083
4084 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004085 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4086 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4087 tsmMetrics.UplinkPktQueueDlyHist,
4088 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4089 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4090 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4091 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4092 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4093 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4094 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4095
Jeff Johnson72a40512013-12-19 10:14:15 -08004096 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004097 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004098
4099 /* serialization is complete */
4100 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004101}
4102
4103
4104
4105static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4106 tAniTrafStrmMetrics* pTsmMetrics)
4107{
4108 hdd_station_ctx_t *pHddStaCtx = NULL;
4109 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004110 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004111 long lrc;
4112 struct statsContext context;
4113 hdd_context_t *pHddCtx = NULL;
4114
4115 if (NULL == pAdapter)
4116 {
4117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4118 return VOS_STATUS_E_FAULT;
4119 }
4120
4121 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4122 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4123
4124 /* we are connected prepare our callback context */
4125 init_completion(&context.completion);
4126 context.pAdapter = pAdapter;
4127 context.magic = STATS_CONTEXT_MAGIC;
4128
4129 /* query tsm stats */
4130 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4131 pHddStaCtx->conn_info.staId[ 0 ],
4132 pHddStaCtx->conn_info.bssId,
4133 &context, pHddCtx->pvosContext, tid);
4134
4135 if (eHAL_STATUS_SUCCESS != hstatus)
4136 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4138 __func__);
4139 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004140 }
4141 else
4142 {
4143 /* request was sent -- wait for the response */
4144 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4145 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004146 if (lrc <= 0)
4147 {
4148 hddLog(VOS_TRACE_LEVEL_ERROR,
4149 "%s: SME %s while retrieving statistics",
4150 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004151 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004152 }
4153 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004154
Jeff Johnson72a40512013-12-19 10:14:15 -08004155 /* either we never sent a request, we sent a request and received a
4156 response or we sent a request and timed out. if we never sent a
4157 request or if we sent a request and got a response, we want to
4158 clear the magic out of paranoia. if we timed out there is a
4159 race condition such that the callback function could be
4160 executing at the same time we are. of primary concern is if the
4161 callback function had already verified the "magic" but had not
4162 yet set the completion variable when a timeout occurred. we
4163 serialize these activities by invalidating the magic while
4164 holding a shared spinlock which will cause us to block if the
4165 callback is currently executing */
4166 spin_lock(&hdd_context_lock);
4167 context.magic = 0;
4168 spin_unlock(&hdd_context_lock);
4169
4170 if (VOS_STATUS_SUCCESS == vstatus)
4171 {
4172 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4173 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4174 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4175 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4176 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4177 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4178 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4179 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4180 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4181 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4182 }
4183 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004184}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004185#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004186
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004187#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004188void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4189{
4190 eCsrBand band = -1;
4191 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4192 switch (band)
4193 {
4194 case eCSR_BAND_ALL:
4195 *pBand = WLAN_HDD_UI_BAND_AUTO;
4196 break;
4197
4198 case eCSR_BAND_24:
4199 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4200 break;
4201
4202 case eCSR_BAND_5G:
4203 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4204 break;
4205
4206 default:
4207 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4208 *pBand = -1;
4209 break;
4210 }
4211}
4212
4213/**---------------------------------------------------------------------------
4214
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004215 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4216
4217 This function parses the send action frame data passed in the format
4218 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4219
Srinivas Girigowda56076852013-08-20 14:00:50 -07004220 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004221 \param - pTargetApBssid Pointer to target Ap bssid
4222 \param - pChannel Pointer to the Target AP channel
4223 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4224 \param - pBuf Pointer to data
4225 \param - pBufLen Pointer to data length
4226
4227 \return - 0 for success non-zero for failure
4228
4229 --------------------------------------------------------------------------*/
4230VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4231 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4232{
4233 tANI_U8 *inPtr = pValue;
4234 tANI_U8 *dataEnd;
4235 int tempInt;
4236 int j = 0;
4237 int i = 0;
4238 int v = 0;
4239 tANI_U8 tempBuf[32];
4240 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004241 /* 12 hexa decimal digits, 5 ':' and '\0' */
4242 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004243
4244 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4245 /*no argument after the command*/
4246 if (NULL == inPtr)
4247 {
4248 return -EINVAL;
4249 }
4250
4251 /*no space after the command*/
4252 else if (SPACE_ASCII_VALUE != *inPtr)
4253 {
4254 return -EINVAL;
4255 }
4256
4257 /*removing empty spaces*/
4258 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4259
4260 /*no argument followed by spaces*/
4261 if ('\0' == *inPtr)
4262 {
4263 return -EINVAL;
4264 }
4265
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004266 v = sscanf(inPtr, "%17s", macAddress);
4267 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004268 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4270 "Invalid MAC address or All hex inputs are not read (%d)", v);
4271 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004272 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004273
4274 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4275 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4276 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4277 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4278 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4279 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004280
4281 /* point to the next argument */
4282 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4283 /*no argument after the command*/
4284 if (NULL == inPtr) return -EINVAL;
4285
4286 /*removing empty spaces*/
4287 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4288
4289 /*no argument followed by spaces*/
4290 if ('\0' == *inPtr)
4291 {
4292 return -EINVAL;
4293 }
4294
4295 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004296 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004297 if (1 != v) return -EINVAL;
4298
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004299 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304300 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304301 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004302
4303 *pChannel = tempInt;
4304
4305 /* point to the next argument */
4306 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4307 /*no argument after the command*/
4308 if (NULL == inPtr) return -EINVAL;
4309 /*removing empty spaces*/
4310 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4311
4312 /*no argument followed by spaces*/
4313 if ('\0' == *inPtr)
4314 {
4315 return -EINVAL;
4316 }
4317
4318 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004319 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004320 if (1 != v) return -EINVAL;
4321
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004322 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004323 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004324
4325 *pDwellTime = tempInt;
4326
4327 /* point to the next argument */
4328 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4329 /*no argument after the command*/
4330 if (NULL == inPtr) return -EINVAL;
4331 /*removing empty spaces*/
4332 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4333
4334 /*no argument followed by spaces*/
4335 if ('\0' == *inPtr)
4336 {
4337 return -EINVAL;
4338 }
4339
4340 /* find the length of data */
4341 dataEnd = inPtr;
4342 while(('\0' != *dataEnd) )
4343 {
4344 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004345 }
Kiet Lambe150c22013-11-21 16:30:32 +05304346 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004347 if ( *pBufLen <= 0) return -EINVAL;
4348
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004349 /* Allocate the number of bytes based on the number of input characters
4350 whether it is even or odd.
4351 if the number of input characters are even, then we need N/2 byte.
4352 if the number of input characters are odd, then we need do (N+1)/2 to
4353 compensate rounding off.
4354 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4355 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4356 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004357 if (NULL == *pBuf)
4358 {
4359 hddLog(VOS_TRACE_LEVEL_FATAL,
4360 "%s: vos_mem_alloc failed ", __func__);
4361 return -EINVAL;
4362 }
4363
4364 /* the buffer received from the upper layer is character buffer,
4365 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4366 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4367 and f0 in 3rd location */
4368 for (i = 0, j = 0; j < *pBufLen; j += 2)
4369 {
Kiet Lambe150c22013-11-21 16:30:32 +05304370 if( j+1 == *pBufLen)
4371 {
4372 tempByte = hdd_parse_hex(inPtr[j]);
4373 }
4374 else
4375 {
4376 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4377 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004378 (*pBuf)[i++] = tempByte;
4379 }
4380 *pBufLen = i;
4381 return VOS_STATUS_SUCCESS;
4382}
4383
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004384/**---------------------------------------------------------------------------
4385
Srinivas Girigowdade697412013-02-14 16:31:48 -08004386 \brief hdd_parse_channellist() - HDD Parse channel list
4387
4388 This function parses the channel list passed in the format
4389 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004390 if the Number of channels (N) does not match with the actual number of channels passed
4391 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4392 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4393 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4394 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004395
4396 \param - pValue Pointer to input channel list
4397 \param - ChannelList Pointer to local output array to record channel list
4398 \param - pNumChannels Pointer to number of roam scan channels
4399
4400 \return - 0 for success non-zero for failure
4401
4402 --------------------------------------------------------------------------*/
4403VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4404{
4405 tANI_U8 *inPtr = pValue;
4406 int tempInt;
4407 int j = 0;
4408 int v = 0;
4409 char buf[32];
4410
4411 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4412 /*no argument after the command*/
4413 if (NULL == inPtr)
4414 {
4415 return -EINVAL;
4416 }
4417
4418 /*no space after the command*/
4419 else if (SPACE_ASCII_VALUE != *inPtr)
4420 {
4421 return -EINVAL;
4422 }
4423
4424 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004425 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004426
4427 /*no argument followed by spaces*/
4428 if ('\0' == *inPtr)
4429 {
4430 return -EINVAL;
4431 }
4432
4433 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004434 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004435 if (1 != v) return -EINVAL;
4436
Srinivas Girigowdade697412013-02-14 16:31:48 -08004437 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004438 if ((v < 0) ||
4439 (tempInt <= 0) ||
4440 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4441 {
4442 return -EINVAL;
4443 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004444
4445 *pNumChannels = tempInt;
4446
4447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4448 "Number of channels are: %d", *pNumChannels);
4449
4450 for (j = 0; j < (*pNumChannels); j++)
4451 {
4452 /*inPtr pointing to the beginning of first space after number of channels*/
4453 inPtr = strpbrk( inPtr, " " );
4454 /*no channel list after the number of channels argument*/
4455 if (NULL == inPtr)
4456 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004457 if (0 != j)
4458 {
4459 *pNumChannels = j;
4460 return VOS_STATUS_SUCCESS;
4461 }
4462 else
4463 {
4464 return -EINVAL;
4465 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004466 }
4467
4468 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004469 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004470
4471 /*no channel list after the number of channels argument and spaces*/
4472 if ( '\0' == *inPtr )
4473 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004474 if (0 != j)
4475 {
4476 *pNumChannels = j;
4477 return VOS_STATUS_SUCCESS;
4478 }
4479 else
4480 {
4481 return -EINVAL;
4482 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004483 }
4484
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004485 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004486 if (1 != v) return -EINVAL;
4487
Srinivas Girigowdade697412013-02-14 16:31:48 -08004488 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004489 if ((v < 0) ||
4490 (tempInt <= 0) ||
4491 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4492 {
4493 return -EINVAL;
4494 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004495 pChannelList[j] = tempInt;
4496
4497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4498 "Channel %d added to preferred channel list",
4499 pChannelList[j] );
4500 }
4501
Srinivas Girigowdade697412013-02-14 16:31:48 -08004502 return VOS_STATUS_SUCCESS;
4503}
4504
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004505
4506/**---------------------------------------------------------------------------
4507
4508 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4509
4510 This function parses the reasoc command data passed in the format
4511 REASSOC<space><bssid><space><channel>
4512
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004513 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004514 \param - pTargetApBssid Pointer to target Ap bssid
4515 \param - pChannel Pointer to the Target AP channel
4516
4517 \return - 0 for success non-zero for failure
4518
4519 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004520VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4521 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004522{
4523 tANI_U8 *inPtr = pValue;
4524 int tempInt;
4525 int v = 0;
4526 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004527 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004528 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004529
4530 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4531 /*no argument after the command*/
4532 if (NULL == inPtr)
4533 {
4534 return -EINVAL;
4535 }
4536
4537 /*no space after the command*/
4538 else if (SPACE_ASCII_VALUE != *inPtr)
4539 {
4540 return -EINVAL;
4541 }
4542
4543 /*removing empty spaces*/
4544 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4545
4546 /*no argument followed by spaces*/
4547 if ('\0' == *inPtr)
4548 {
4549 return -EINVAL;
4550 }
4551
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004552 v = sscanf(inPtr, "%17s", macAddress);
4553 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004554 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4556 "Invalid MAC address or All hex inputs are not read (%d)", v);
4557 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004558 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004559
4560 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4561 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4562 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4563 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4564 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4565 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004566
4567 /* point to the next argument */
4568 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4569 /*no argument after the command*/
4570 if (NULL == inPtr) return -EINVAL;
4571
4572 /*removing empty spaces*/
4573 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4574
4575 /*no argument followed by spaces*/
4576 if ('\0' == *inPtr)
4577 {
4578 return -EINVAL;
4579 }
4580
4581 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004582 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004583 if (1 != v) return -EINVAL;
4584
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004585 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004586 if ((v < 0) ||
4587 (tempInt <= 0) ||
4588 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4589 {
4590 return -EINVAL;
4591 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004592
4593 *pChannel = tempInt;
4594 return VOS_STATUS_SUCCESS;
4595}
4596
4597#endif
4598
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004599#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004600/**---------------------------------------------------------------------------
4601
4602 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4603
4604 This function parses the SETCCKM IE command
4605 SETCCKMIE<space><ie data>
4606
4607 \param - pValue Pointer to input data
4608 \param - pCckmIe Pointer to output cckm Ie
4609 \param - pCckmIeLen Pointer to output cckm ie length
4610
4611 \return - 0 for success non-zero for failure
4612
4613 --------------------------------------------------------------------------*/
4614VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4615 tANI_U8 *pCckmIeLen)
4616{
4617 tANI_U8 *inPtr = pValue;
4618 tANI_U8 *dataEnd;
4619 int j = 0;
4620 int i = 0;
4621 tANI_U8 tempByte = 0;
4622
4623 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4624 /*no argument after the command*/
4625 if (NULL == inPtr)
4626 {
4627 return -EINVAL;
4628 }
4629
4630 /*no space after the command*/
4631 else if (SPACE_ASCII_VALUE != *inPtr)
4632 {
4633 return -EINVAL;
4634 }
4635
4636 /*removing empty spaces*/
4637 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4638
4639 /*no argument followed by spaces*/
4640 if ('\0' == *inPtr)
4641 {
4642 return -EINVAL;
4643 }
4644
4645 /* find the length of data */
4646 dataEnd = inPtr;
4647 while(('\0' != *dataEnd) )
4648 {
4649 dataEnd++;
4650 ++(*pCckmIeLen);
4651 }
4652 if ( *pCckmIeLen <= 0) return -EINVAL;
4653
4654 /* Allocate the number of bytes based on the number of input characters
4655 whether it is even or odd.
4656 if the number of input characters are even, then we need N/2 byte.
4657 if the number of input characters are odd, then we need do (N+1)/2 to
4658 compensate rounding off.
4659 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4660 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4661 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4662 if (NULL == *pCckmIe)
4663 {
4664 hddLog(VOS_TRACE_LEVEL_FATAL,
4665 "%s: vos_mem_alloc failed ", __func__);
4666 return -EINVAL;
4667 }
4668 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4669 /* the buffer received from the upper layer is character buffer,
4670 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4671 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4672 and f0 in 3rd location */
4673 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4674 {
4675 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4676 (*pCckmIe)[i++] = tempByte;
4677 }
4678 *pCckmIeLen = i;
4679
4680 return VOS_STATUS_SUCCESS;
4681}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004682#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004683
Jeff Johnson295189b2012-06-20 16:38:30 -07004684/**---------------------------------------------------------------------------
4685
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004686 \brief hdd_is_valid_mac_address() - Validate MAC address
4687
4688 This function validates whether the given MAC address is valid or not
4689 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4690 where X is the hexa decimal digit character and separated by ':'
4691 This algorithm works even if MAC address is not separated by ':'
4692
4693 This code checks given input string mac contains exactly 12 hexadecimal digits.
4694 and a separator colon : appears in the input string only after
4695 an even number of hex digits.
4696
4697 \param - pMacAddr pointer to the input MAC address
4698 \return - 1 for valid and 0 for invalid
4699
4700 --------------------------------------------------------------------------*/
4701
4702v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4703{
4704 int xdigit = 0;
4705 int separator = 0;
4706 while (*pMacAddr)
4707 {
4708 if (isxdigit(*pMacAddr))
4709 {
4710 xdigit++;
4711 }
4712 else if (':' == *pMacAddr)
4713 {
4714 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4715 break;
4716
4717 ++separator;
4718 }
4719 else
4720 {
4721 separator = -1;
4722 /* Invalid MAC found */
4723 return 0;
4724 }
4725 ++pMacAddr;
4726 }
4727 return (xdigit == 12 && (separator == 5 || separator == 0));
4728}
4729
4730/**---------------------------------------------------------------------------
4731
Jeff Johnson295189b2012-06-20 16:38:30 -07004732 \brief hdd_open() - HDD Open function
4733
4734 This is called in response to ifconfig up
4735
4736 \param - dev Pointer to net_device structure
4737
4738 \return - 0 for success non-zero for failure
4739
4740 --------------------------------------------------------------------------*/
4741int hdd_open (struct net_device *dev)
4742{
4743 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4744 hdd_context_t *pHddCtx;
4745 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4746 VOS_STATUS status;
4747 v_BOOL_t in_standby = TRUE;
4748
4749 if (NULL == pAdapter)
4750 {
4751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304752 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004753 return -ENODEV;
4754 }
4755
4756 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304757 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4758 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004759 if (NULL == pHddCtx)
4760 {
4761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004762 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004763 return -ENODEV;
4764 }
4765
4766 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4767 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4768 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004769 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4770 {
4771 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304772 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004773 in_standby = FALSE;
4774 break;
4775 }
4776 else
4777 {
4778 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4779 pAdapterNode = pNext;
4780 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004781 }
4782
4783 if (TRUE == in_standby)
4784 {
4785 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4786 {
4787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4788 "wlan out of power save", __func__);
4789 return -EINVAL;
4790 }
4791 }
4792
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004793 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004794 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4795 {
4796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004797 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004798 /* Enable TX queues only when we are connected */
4799 netif_tx_start_all_queues(dev);
4800 }
4801
4802 return 0;
4803}
4804
4805int hdd_mon_open (struct net_device *dev)
4806{
4807 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4808
4809 if(pAdapter == NULL) {
4810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004811 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004812 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004813 }
4814
4815 netif_start_queue(dev);
4816
4817 return 0;
4818}
4819/**---------------------------------------------------------------------------
4820
4821 \brief hdd_stop() - HDD stop function
4822
4823 This is called in response to ifconfig down
4824
4825 \param - dev Pointer to net_device structure
4826
4827 \return - 0 for success non-zero for failure
4828
4829 --------------------------------------------------------------------------*/
4830
4831int hdd_stop (struct net_device *dev)
4832{
4833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4834 hdd_context_t *pHddCtx;
4835 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4836 VOS_STATUS status;
4837 v_BOOL_t enter_standby = TRUE;
4838
4839 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004840 if (NULL == pAdapter)
4841 {
4842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304843 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004844 return -ENODEV;
4845 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304846 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4847 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004848 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4849 if (NULL == pHddCtx)
4850 {
4851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004852 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004853 return -ENODEV;
4854 }
4855
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004856 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004857 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4858 netif_tx_disable(pAdapter->dev);
4859 netif_carrier_off(pAdapter->dev);
4860
4861
4862 /* SoftAP ifaces should never go in power save mode
4863 making sure same here. */
4864 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4865 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004866 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 )
4868 {
4869 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4871 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004872 EXIT();
4873 return 0;
4874 }
4875
4876 /* Find if any iface is up then
4877 if any iface is up then can't put device to sleep/ power save mode. */
4878 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4879 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4880 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004881 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4882 {
4883 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304884 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004885 enter_standby = FALSE;
4886 break;
4887 }
4888 else
4889 {
4890 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4891 pAdapterNode = pNext;
4892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 }
4894
4895 if (TRUE == enter_standby)
4896 {
4897 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
4898 "entering standby", __func__);
4899 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
4900 {
4901 /*log and return success*/
4902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
4903 "wlan in power save", __func__);
4904 }
4905 }
4906
4907 EXIT();
4908 return 0;
4909}
4910
4911/**---------------------------------------------------------------------------
4912
4913 \brief hdd_uninit() - HDD uninit function
4914
4915 This is called during the netdev unregister to uninitialize all data
4916associated with the device
4917
4918 \param - dev Pointer to net_device structure
4919
4920 \return - void
4921
4922 --------------------------------------------------------------------------*/
4923static void hdd_uninit (struct net_device *dev)
4924{
4925 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4926
4927 ENTER();
4928
4929 do
4930 {
4931 if (NULL == pAdapter)
4932 {
4933 hddLog(VOS_TRACE_LEVEL_FATAL,
4934 "%s: NULL pAdapter", __func__);
4935 break;
4936 }
4937
4938 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
4939 {
4940 hddLog(VOS_TRACE_LEVEL_FATAL,
4941 "%s: Invalid magic", __func__);
4942 break;
4943 }
4944
4945 if (NULL == pAdapter->pHddCtx)
4946 {
4947 hddLog(VOS_TRACE_LEVEL_FATAL,
4948 "%s: NULL pHddCtx", __func__);
4949 break;
4950 }
4951
4952 if (dev != pAdapter->dev)
4953 {
4954 hddLog(VOS_TRACE_LEVEL_FATAL,
4955 "%s: Invalid device reference", __func__);
4956 /* we haven't validated all cases so let this go for now */
4957 }
4958
4959 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
4960
4961 /* after uninit our adapter structure will no longer be valid */
4962 pAdapter->dev = NULL;
4963 pAdapter->magic = 0;
4964 } while (0);
4965
4966 EXIT();
4967}
4968
4969/**---------------------------------------------------------------------------
4970
4971 \brief hdd_release_firmware() -
4972
4973 This function calls the release firmware API to free the firmware buffer.
4974
4975 \param - pFileName Pointer to the File Name.
4976 pCtx - Pointer to the adapter .
4977
4978
4979 \return - 0 for success, non zero for failure
4980
4981 --------------------------------------------------------------------------*/
4982
4983VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
4984{
4985 VOS_STATUS status = VOS_STATUS_SUCCESS;
4986 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4987 ENTER();
4988
4989
4990 if (!strcmp(WLAN_FW_FILE, pFileName)) {
4991
4992 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
4993
4994 if(pHddCtx->fw) {
4995 release_firmware(pHddCtx->fw);
4996 pHddCtx->fw = NULL;
4997 }
4998 else
4999 status = VOS_STATUS_E_FAILURE;
5000 }
5001 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5002 if(pHddCtx->nv) {
5003 release_firmware(pHddCtx->nv);
5004 pHddCtx->nv = NULL;
5005 }
5006 else
5007 status = VOS_STATUS_E_FAILURE;
5008
5009 }
5010
5011 EXIT();
5012 return status;
5013}
5014
5015/**---------------------------------------------------------------------------
5016
5017 \brief hdd_request_firmware() -
5018
5019 This function reads the firmware file using the request firmware
5020 API and returns the the firmware data and the firmware file size.
5021
5022 \param - pfileName - Pointer to the file name.
5023 - pCtx - Pointer to the adapter .
5024 - ppfw_data - Pointer to the pointer of the firmware data.
5025 - pSize - Pointer to the file size.
5026
5027 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5028
5029 --------------------------------------------------------------------------*/
5030
5031
5032VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5033{
5034 int status;
5035 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5036 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5037 ENTER();
5038
5039 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5040
5041 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5042
5043 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5044 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5045 __func__, pfileName);
5046 retval = VOS_STATUS_E_FAILURE;
5047 }
5048
5049 else {
5050 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5051 *pSize = pHddCtx->fw->size;
5052 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5053 __func__, *pSize);
5054 }
5055 }
5056 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5057
5058 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5059
5060 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5061 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5062 __func__, pfileName);
5063 retval = VOS_STATUS_E_FAILURE;
5064 }
5065
5066 else {
5067 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5068 *pSize = pHddCtx->nv->size;
5069 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5070 __func__, *pSize);
5071 }
5072 }
5073
5074 EXIT();
5075 return retval;
5076}
5077/**---------------------------------------------------------------------------
5078 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5079
5080 This is the function invoked by SME to inform the result of a full power
5081 request issued by HDD
5082
5083 \param - callbackcontext - Pointer to cookie
5084 status - result of request
5085
5086 \return - None
5087
5088--------------------------------------------------------------------------*/
5089void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5090{
5091 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5092
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005093 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005094 if(&pHddCtx->full_pwr_comp_var)
5095 {
5096 complete(&pHddCtx->full_pwr_comp_var);
5097 }
5098}
5099
5100/**---------------------------------------------------------------------------
5101
5102 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5103
5104 This is the function invoked by SME to inform the result of BMPS
5105 request issued by HDD
5106
5107 \param - callbackcontext - Pointer to cookie
5108 status - result of request
5109
5110 \return - None
5111
5112--------------------------------------------------------------------------*/
5113void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5114{
5115
5116 struct completion *completion_var = (struct completion*) callbackContext;
5117
Arif Hussain6d2a3322013-11-17 19:50:10 -08005118 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005119 if(completion_var != NULL)
5120 {
5121 complete(completion_var);
5122 }
5123}
5124
5125/**---------------------------------------------------------------------------
5126
5127 \brief hdd_get_cfg_file_size() -
5128
5129 This function reads the configuration file using the request firmware
5130 API and returns the configuration file size.
5131
5132 \param - pCtx - Pointer to the adapter .
5133 - pFileName - Pointer to the file name.
5134 - pBufSize - Pointer to the buffer size.
5135
5136 \return - 0 for success, non zero for failure
5137
5138 --------------------------------------------------------------------------*/
5139
5140VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5141{
5142 int status;
5143 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5144
5145 ENTER();
5146
5147 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5148
5149 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5150 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5151 status = VOS_STATUS_E_FAILURE;
5152 }
5153 else {
5154 *pBufSize = pHddCtx->fw->size;
5155 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5156 release_firmware(pHddCtx->fw);
5157 pHddCtx->fw = NULL;
5158 }
5159
5160 EXIT();
5161 return VOS_STATUS_SUCCESS;
5162}
5163
5164/**---------------------------------------------------------------------------
5165
5166 \brief hdd_read_cfg_file() -
5167
5168 This function reads the configuration file using the request firmware
5169 API and returns the cfg data and the buffer size of the configuration file.
5170
5171 \param - pCtx - Pointer to the adapter .
5172 - pFileName - Pointer to the file name.
5173 - pBuffer - Pointer to the data buffer.
5174 - pBufSize - Pointer to the buffer size.
5175
5176 \return - 0 for success, non zero for failure
5177
5178 --------------------------------------------------------------------------*/
5179
5180VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5181 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5182{
5183 int status;
5184 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5185
5186 ENTER();
5187
5188 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5189
5190 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5191 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5192 return VOS_STATUS_E_FAILURE;
5193 }
5194 else {
5195 if(*pBufSize != pHddCtx->fw->size) {
5196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5197 "file size", __func__);
5198 release_firmware(pHddCtx->fw);
5199 pHddCtx->fw = NULL;
5200 return VOS_STATUS_E_FAILURE;
5201 }
5202 else {
5203 if(pBuffer) {
5204 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5205 }
5206 release_firmware(pHddCtx->fw);
5207 pHddCtx->fw = NULL;
5208 }
5209 }
5210
5211 EXIT();
5212
5213 return VOS_STATUS_SUCCESS;
5214}
5215
5216/**---------------------------------------------------------------------------
5217
Jeff Johnson295189b2012-06-20 16:38:30 -07005218 \brief hdd_set_mac_address() -
5219
5220 This function sets the user specified mac address using
5221 the command ifconfig wlanX hw ether <mac adress>.
5222
5223 \param - dev - Pointer to the net device.
5224 - addr - Pointer to the sockaddr.
5225 \return - 0 for success, non zero for failure
5226
5227 --------------------------------------------------------------------------*/
5228
5229static int hdd_set_mac_address(struct net_device *dev, void *addr)
5230{
5231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5232 struct sockaddr *psta_mac_addr = addr;
5233 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5234
5235 ENTER();
5236
5237 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5238
5239#ifdef HDD_SESSIONIZE
5240 // set the MAC address though the STA ID CFG.
5241 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5242 (v_U8_t *)&pAdapter->macAddressCurrent,
5243 sizeof( pAdapter->macAddressCurrent ),
5244 hdd_set_mac_addr_cb, VOS_FALSE );
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305245
5246 if(eHAL_STATUS_SUCCESS != halStatus)
5247 {
5248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5249 "%s: failed to set MAC address in CFG", __func__);
5250 }
5251
Jeff Johnson295189b2012-06-20 16:38:30 -07005252#endif
5253
5254 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5255
5256 EXIT();
5257 return halStatus;
5258}
5259
5260tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5261{
5262 int i;
5263 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5264 {
Abhishek Singheb183782014-02-06 13:37:21 +05305265 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005266 break;
5267 }
5268
5269 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5270 return NULL;
5271
5272 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5273 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5274}
5275
5276void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5277{
5278 int i;
5279 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5280 {
5281 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5282 {
5283 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5284 break;
5285 }
5286 }
5287 return;
5288}
5289
5290#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5291 static struct net_device_ops wlan_drv_ops = {
5292 .ndo_open = hdd_open,
5293 .ndo_stop = hdd_stop,
5294 .ndo_uninit = hdd_uninit,
5295 .ndo_start_xmit = hdd_hard_start_xmit,
5296 .ndo_tx_timeout = hdd_tx_timeout,
5297 .ndo_get_stats = hdd_stats,
5298 .ndo_do_ioctl = hdd_ioctl,
5299 .ndo_set_mac_address = hdd_set_mac_address,
5300 .ndo_select_queue = hdd_select_queue,
5301#ifdef WLAN_FEATURE_PACKET_FILTERING
5302#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5303 .ndo_set_rx_mode = hdd_set_multicast_list,
5304#else
5305 .ndo_set_multicast_list = hdd_set_multicast_list,
5306#endif //LINUX_VERSION_CODE
5307#endif
5308 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 static struct net_device_ops wlan_mon_drv_ops = {
5310 .ndo_open = hdd_mon_open,
5311 .ndo_stop = hdd_stop,
5312 .ndo_uninit = hdd_uninit,
5313 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5314 .ndo_tx_timeout = hdd_tx_timeout,
5315 .ndo_get_stats = hdd_stats,
5316 .ndo_do_ioctl = hdd_ioctl,
5317 .ndo_set_mac_address = hdd_set_mac_address,
5318 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005319
5320#endif
5321
5322void hdd_set_station_ops( struct net_device *pWlanDev )
5323{
5324#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005325 pWlanDev->netdev_ops = &wlan_drv_ops;
5326#else
5327 pWlanDev->open = hdd_open;
5328 pWlanDev->stop = hdd_stop;
5329 pWlanDev->uninit = hdd_uninit;
5330 pWlanDev->hard_start_xmit = NULL;
5331 pWlanDev->tx_timeout = hdd_tx_timeout;
5332 pWlanDev->get_stats = hdd_stats;
5333 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 pWlanDev->set_mac_address = hdd_set_mac_address;
5335#endif
5336}
5337
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005338static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005339{
5340 struct net_device *pWlanDev = NULL;
5341 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005342 /*
5343 * cfg80211 initialization and registration....
5344 */
5345 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5346
Jeff Johnson295189b2012-06-20 16:38:30 -07005347 if(pWlanDev != NULL)
5348 {
5349
5350 //Save the pointer to the net_device in the HDD adapter
5351 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5352
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5354
5355 pAdapter->dev = pWlanDev;
5356 pAdapter->pHddCtx = pHddCtx;
5357 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5358
5359 init_completion(&pAdapter->session_open_comp_var);
5360 init_completion(&pAdapter->session_close_comp_var);
5361 init_completion(&pAdapter->disconnect_comp_var);
5362 init_completion(&pAdapter->linkup_event_var);
5363 init_completion(&pAdapter->cancel_rem_on_chan_var);
5364 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305365 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5367 init_completion(&pAdapter->offchannel_tx_event);
5368#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005369 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005370#ifdef FEATURE_WLAN_TDLS
5371 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005372 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005373 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305374 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005375#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 init_completion(&pHddCtx->mc_sus_event_var);
5377 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305378 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005379 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005380 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005381
Rajeev79dbe4c2013-10-05 11:03:42 +05305382#ifdef FEATURE_WLAN_BATCH_SCAN
5383 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5384 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5385 pAdapter->pBatchScanRsp = NULL;
5386 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005387 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005388 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305389 mutex_init(&pAdapter->hdd_batch_scan_lock);
5390#endif
5391
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 pAdapter->isLinkUpSvcNeeded = FALSE;
5393 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5394 //Init the net_device structure
5395 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5396
5397 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5398 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5399 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5400 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5401
5402 hdd_set_station_ops( pAdapter->dev );
5403
5404 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005405 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5406 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5407 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005408 /* set pWlanDev's parent to underlying device */
5409 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5410 }
5411
5412 return pAdapter;
5413}
5414
5415VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5416{
5417 struct net_device *pWlanDev = pAdapter->dev;
5418 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5419 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5420 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5421
5422 if( rtnl_lock_held )
5423 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005424 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5426 {
5427 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5428 return VOS_STATUS_E_FAILURE;
5429 }
5430 }
5431 if (register_netdevice(pWlanDev))
5432 {
5433 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5434 return VOS_STATUS_E_FAILURE;
5435 }
5436 }
5437 else
5438 {
5439 if(register_netdev(pWlanDev))
5440 {
5441 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5442 return VOS_STATUS_E_FAILURE;
5443 }
5444 }
5445 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5446
5447 return VOS_STATUS_SUCCESS;
5448}
5449
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005450static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005451{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005452 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005453
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005454 if (NULL == pAdapter)
5455 {
5456 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5457 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005459
5460 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5461 {
5462 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5463 return eHAL_STATUS_NOT_INITIALIZED;
5464 }
5465
5466 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5467
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005468#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005469 /* need to make sure all of our scheduled work has completed.
5470 * This callback is called from MC thread context, so it is safe to
5471 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005472 *
5473 * Even though this is called from MC thread context, if there is a faulty
5474 * work item in the system, that can hang this call forever. So flushing
5475 * this global work queue is not safe; and now we make sure that
5476 * individual work queues are stopped correctly. But the cancel work queue
5477 * is a GPL only API, so the proprietary version of the driver would still
5478 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005479 */
5480 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005481#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005482
5483 /* We can be blocked while waiting for scheduled work to be
5484 * flushed, and the adapter structure can potentially be freed, in
5485 * which case the magic will have been reset. So make sure the
5486 * magic is still good, and hence the adapter structure is still
5487 * valid, before signaling completion */
5488 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5489 {
5490 complete(&pAdapter->session_close_comp_var);
5491 }
5492
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 return eHAL_STATUS_SUCCESS;
5494}
5495
5496VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5497{
5498 struct net_device *pWlanDev = pAdapter->dev;
5499 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5500 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5501 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5502 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305503 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005504
5505 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005506 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 //Open a SME session for future operation
5508 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005509 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005510 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5511 {
5512 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005513 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 halStatus, halStatus );
5515 status = VOS_STATUS_E_FAILURE;
5516 goto error_sme_open;
5517 }
5518
5519 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305520 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 &pAdapter->session_open_comp_var,
5522 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305523 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 {
5525 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305526 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 status = VOS_STATUS_E_FAILURE;
5528 goto error_sme_open;
5529 }
5530
5531 // Register wireless extensions
5532 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5533 {
5534 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005535 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 halStatus, halStatus );
5537 status = VOS_STATUS_E_FAILURE;
5538 goto error_register_wext;
5539 }
5540 //Safe to register the hard_start_xmit function again
5541#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5542 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5543#else
5544 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5545#endif
5546
5547 //Set the Connection State to Not Connected
5548 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5549
5550 //Set the default operation channel
5551 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5552
5553 /* Make the default Auth Type as OPEN*/
5554 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5555
5556 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5557 {
5558 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005559 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 status, status );
5561 goto error_init_txrx;
5562 }
5563
5564 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5565
5566 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5567 {
5568 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005569 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 status, status );
5571 goto error_wmm_init;
5572 }
5573
5574 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5575
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005576#ifdef FEATURE_WLAN_TDLS
5577 if(0 != wlan_hdd_tdls_init(pAdapter))
5578 {
5579 status = VOS_STATUS_E_FAILURE;
5580 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5581 goto error_tdls_init;
5582 }
5583 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5584#endif
5585
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 return VOS_STATUS_SUCCESS;
5587
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005588#ifdef FEATURE_WLAN_TDLS
5589error_tdls_init:
5590 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5591 hdd_wmm_adapter_close(pAdapter);
5592#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005593error_wmm_init:
5594 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5595 hdd_deinit_tx_rx(pAdapter);
5596error_init_txrx:
5597 hdd_UnregisterWext(pWlanDev);
5598error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005599 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005600 {
5601 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005602 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005604 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305606 unsigned long rc;
5607
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305609 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005611 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305612 if (rc <= 0)
5613 hddLog(VOS_TRACE_LEVEL_ERROR,
5614 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 }
5616}
5617error_sme_open:
5618 return status;
5619}
5620
Jeff Johnson295189b2012-06-20 16:38:30 -07005621void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5622{
5623 hdd_cfg80211_state_t *cfgState;
5624
5625 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5626
5627 if( NULL != cfgState->buf )
5628 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305629 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005630 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5631 rc = wait_for_completion_interruptible_timeout(
5632 &pAdapter->tx_action_cnf_event,
5633 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305634 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005635 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305637 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5638 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 }
5640 }
5641 return;
5642}
Jeff Johnson295189b2012-06-20 16:38:30 -07005643
5644void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5645{
5646 ENTER();
5647 switch ( pAdapter->device_mode )
5648 {
5649 case WLAN_HDD_INFRA_STATION:
5650 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005651 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005652 {
5653 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5654 {
5655 hdd_deinit_tx_rx( pAdapter );
5656 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5657 }
5658
5659 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5660 {
5661 hdd_wmm_adapter_close( pAdapter );
5662 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5663 }
5664
Jeff Johnson295189b2012-06-20 16:38:30 -07005665 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005666#ifdef FEATURE_WLAN_TDLS
5667 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5668 {
5669 wlan_hdd_tdls_exit(pAdapter);
5670 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5671 }
5672#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005673
5674 break;
5675 }
5676
5677 case WLAN_HDD_SOFTAP:
5678 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005679 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305680
5681 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5682 {
5683 hdd_wmm_adapter_close( pAdapter );
5684 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5685 }
5686
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005688
5689 hdd_unregister_hostapd(pAdapter);
5690 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005691 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 break;
5693 }
5694
5695 case WLAN_HDD_MONITOR:
5696 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005697 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5699 {
5700 hdd_deinit_tx_rx( pAdapter );
5701 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5702 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 if(NULL != pAdapterforTx)
5704 {
5705 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 break;
5708 }
5709
5710
5711 default:
5712 break;
5713 }
5714
5715 EXIT();
5716}
5717
5718void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5719{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005720 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305721
5722 ENTER();
5723 if (NULL == pAdapter)
5724 {
5725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5726 "%s: HDD adapter is Null", __func__);
5727 return;
5728 }
5729
5730 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005731
Rajeev79dbe4c2013-10-05 11:03:42 +05305732#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305733 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5734 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005735 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305736 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5737 )
5738 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005739 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305740 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005741 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5742 {
5743 hdd_deinit_batch_scan(pAdapter);
5744 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305745 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005746 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305747#endif
5748
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5750 if( rtnl_held )
5751 {
5752 unregister_netdevice(pWlanDev);
5753 }
5754 else
5755 {
5756 unregister_netdev(pWlanDev);
5757 }
5758 // note that the pAdapter is no longer valid at this point
5759 // since the memory has been reclaimed
5760 }
5761
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305762 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005763}
5764
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005765void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5766{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305767 VOS_STATUS status;
5768 hdd_adapter_t *pAdapter = NULL;
5769 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005770
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305771 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005772
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305773 /*loop through all adapters.*/
5774 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005775 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305776 pAdapter = pAdapterNode->pAdapter;
5777 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5778 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005779
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305780 { // we skip this registration for modes other than STA and P2P client modes.
5781 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5782 pAdapterNode = pNext;
5783 continue;
5784 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005785
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305786 //Apply Dynamic DTIM For P2P
5787 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5788 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5789 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5790 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5791 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5792 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5793 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5794 (eConnectionState_Associated ==
5795 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5796 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5797 {
5798 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005799
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305800 powerRequest.uIgnoreDTIM = 1;
5801 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5802
5803 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5804 {
5805 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5806 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5807 }
5808 else
5809 {
5810 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5811 }
5812
5813 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5814 * specified during Enter/Exit BMPS when LCD off*/
5815 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5816 NULL, eANI_BOOLEAN_FALSE);
5817 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5818 NULL, eANI_BOOLEAN_FALSE);
5819
5820 /* switch to the DTIM specified in cfg.ini */
5821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5822 "Switch to DTIM %d", powerRequest.uListenInterval);
5823 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5824 break;
5825
5826 }
5827
5828 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5829 pAdapterNode = pNext;
5830 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005831}
5832
5833void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5834{
5835 /*Switch back to DTIM 1*/
5836 tSirSetPowerParamsReq powerRequest = { 0 };
5837
5838 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5839 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005840 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005841
5842 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5843 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5844 NULL, eANI_BOOLEAN_FALSE);
5845 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5846 NULL, eANI_BOOLEAN_FALSE);
5847
5848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5849 "Switch to DTIM%d",powerRequest.uListenInterval);
5850 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5851
5852}
5853
Jeff Johnson295189b2012-06-20 16:38:30 -07005854VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5855{
5856 VOS_STATUS status = VOS_STATUS_SUCCESS;
5857
5858 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5859 {
5860 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5861 }
5862
5863 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5864 {
5865 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5866 }
5867
5868 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5869 {
5870 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5871 }
5872
5873 return status;
5874}
5875
5876VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5877{
5878 hdd_adapter_t *pAdapter = NULL;
5879 eHalStatus halStatus;
5880 VOS_STATUS status = VOS_STATUS_E_INVAL;
5881 v_BOOL_t disableBmps = FALSE;
5882 v_BOOL_t disableImps = FALSE;
5883
5884 switch(session_type)
5885 {
5886 case WLAN_HDD_INFRA_STATION:
5887 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 case WLAN_HDD_P2P_CLIENT:
5889 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 //Exit BMPS -> Is Sta/P2P Client is already connected
5891 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5892 if((NULL != pAdapter)&&
5893 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5894 {
5895 disableBmps = TRUE;
5896 }
5897
5898 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
5899 if((NULL != pAdapter)&&
5900 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5901 {
5902 disableBmps = TRUE;
5903 }
5904
5905 //Exit both Bmps and Imps incase of Go/SAP Mode
5906 if((WLAN_HDD_SOFTAP == session_type) ||
5907 (WLAN_HDD_P2P_GO == session_type))
5908 {
5909 disableBmps = TRUE;
5910 disableImps = TRUE;
5911 }
5912
5913 if(TRUE == disableImps)
5914 {
5915 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5916 {
5917 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5918 }
5919 }
5920
5921 if(TRUE == disableBmps)
5922 {
5923 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5924 {
5925 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5926
5927 if(eHAL_STATUS_SUCCESS != halStatus)
5928 {
5929 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005930 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 VOS_ASSERT(0);
5932 return status;
5933 }
5934 }
5935
5936 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5937 {
5938 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
5939
5940 if(eHAL_STATUS_SUCCESS != halStatus)
5941 {
5942 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005943 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 VOS_ASSERT(0);
5945 return status;
5946 }
5947 }
5948 }
5949
5950 if((TRUE == disableBmps) ||
5951 (TRUE == disableImps))
5952 {
5953 /* Now, get the chip into Full Power now */
5954 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
5955 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
5956 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
5957
5958 if(halStatus != eHAL_STATUS_SUCCESS)
5959 {
5960 if(halStatus == eHAL_STATUS_PMC_PENDING)
5961 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305962 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305964 ret = wait_for_completion_interruptible_timeout(
5965 &pHddCtx->full_pwr_comp_var,
5966 msecs_to_jiffies(1000));
5967 if (ret <= 0)
5968 {
5969 hddLog(VOS_TRACE_LEVEL_ERROR,
5970 "%s: wait on full_pwr_comp_var failed %ld",
5971 __func__, ret);
5972 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 }
5974 else
5975 {
5976 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005977 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 VOS_ASSERT(0);
5979 return status;
5980 }
5981 }
5982
5983 status = VOS_STATUS_SUCCESS;
5984 }
5985
5986 break;
5987 }
5988 return status;
5989}
5990
5991hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005992 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07005993 tANI_U8 rtnl_held )
5994{
5995 hdd_adapter_t *pAdapter = NULL;
5996 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
5997 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5998 VOS_STATUS exitbmpsStatus;
5999
Arif Hussain6d2a3322013-11-17 19:50:10 -08006000 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006001
Nirav Shah436658f2014-02-28 17:05:45 +05306002 if(macAddr == NULL)
6003 {
6004 /* Not received valid macAddr */
6005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6006 "%s:Unable to add virtual intf: Not able to get"
6007 "valid mac address",__func__);
6008 return NULL;
6009 }
6010
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 //Disable BMPS incase of Concurrency
6012 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6013
6014 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6015 {
6016 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306017 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 VOS_ASSERT(0);
6019 return NULL;
6020 }
6021
6022 switch(session_type)
6023 {
6024 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006026 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 {
6028 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6029
6030 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306031 {
6032 hddLog(VOS_TRACE_LEVEL_FATAL,
6033 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306035 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006036
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306037#ifdef FEATURE_WLAN_TDLS
6038 /* A Mutex Lock is introduced while changing/initializing the mode to
6039 * protect the concurrent access for the Adapters by TDLS module.
6040 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306041 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306042#endif
6043
Jeff Johnsone7245742012-09-05 17:12:55 -07006044 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6045 NL80211_IFTYPE_P2P_CLIENT:
6046 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006047
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306049#ifdef FEATURE_WLAN_TDLS
6050 mutex_unlock(&pHddCtx->tdls_lock);
6051#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306052
6053 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 if( VOS_STATUS_SUCCESS != status )
6055 goto err_free_netdev;
6056
6057 status = hdd_register_interface( pAdapter, rtnl_held );
6058 if( VOS_STATUS_SUCCESS != status )
6059 {
6060 hdd_deinit_adapter(pHddCtx, pAdapter);
6061 goto err_free_netdev;
6062 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306063
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306064 // Workqueue which gets scheduled in IPv4 notification callback.
6065 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6066
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306067#ifdef WLAN_NS_OFFLOAD
6068 // Workqueue which gets scheduled in IPv6 notification callback.
6069 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6070#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 //Stop the Interface TX queue.
6072 netif_tx_disable(pAdapter->dev);
6073 //netif_tx_disable(pWlanDev);
6074 netif_carrier_off(pAdapter->dev);
6075
6076 break;
6077 }
6078
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 case WLAN_HDD_SOFTAP:
6081 {
6082 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6083 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306084 {
6085 hddLog(VOS_TRACE_LEVEL_FATAL,
6086 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306088 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006089
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6091 NL80211_IFTYPE_AP:
6092 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006093 pAdapter->device_mode = session_type;
6094
6095 status = hdd_init_ap_mode(pAdapter);
6096 if( VOS_STATUS_SUCCESS != status )
6097 goto err_free_netdev;
6098
6099 status = hdd_register_hostapd( pAdapter, rtnl_held );
6100 if( VOS_STATUS_SUCCESS != status )
6101 {
6102 hdd_deinit_adapter(pHddCtx, pAdapter);
6103 goto err_free_netdev;
6104 }
6105
6106 netif_tx_disable(pAdapter->dev);
6107 netif_carrier_off(pAdapter->dev);
6108
6109 hdd_set_conparam( 1 );
6110 break;
6111 }
6112 case WLAN_HDD_MONITOR:
6113 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6115 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306116 {
6117 hddLog(VOS_TRACE_LEVEL_FATAL,
6118 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006121
6122 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6123 pAdapter->device_mode = session_type;
6124 status = hdd_register_interface( pAdapter, rtnl_held );
6125#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6126 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6127#else
6128 pAdapter->dev->open = hdd_mon_open;
6129 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6130#endif
6131 hdd_init_tx_rx( pAdapter );
6132 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6133 //Set adapter to be used for data tx. It will use either GO or softap.
6134 pAdapter->sessionCtx.monitor.pAdapterForTx =
6135 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006136 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6137 {
6138 pAdapter->sessionCtx.monitor.pAdapterForTx =
6139 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6140 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006141 /* This workqueue will be used to transmit management packet over
6142 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006143 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6144 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6145 return NULL;
6146 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006147
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6149 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 }
6151 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 case WLAN_HDD_FTM:
6153 {
6154 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6155
6156 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306157 {
6158 hddLog(VOS_TRACE_LEVEL_FATAL,
6159 FL("failed to allocate adapter for session %d"), session_type);
6160 return NULL;
6161 }
6162
Jeff Johnson295189b2012-06-20 16:38:30 -07006163 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6164 * message while loading driver in FTM mode. */
6165 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6166 pAdapter->device_mode = session_type;
6167 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306168
6169 hdd_init_tx_rx( pAdapter );
6170
6171 //Stop the Interface TX queue.
6172 netif_tx_disable(pAdapter->dev);
6173 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 }
6175 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006176 default:
6177 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306178 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6179 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 VOS_ASSERT(0);
6181 return NULL;
6182 }
6183 }
6184
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 if( VOS_STATUS_SUCCESS == status )
6186 {
6187 //Add it to the hdd's session list.
6188 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6189 if( NULL == pHddAdapterNode )
6190 {
6191 status = VOS_STATUS_E_NOMEM;
6192 }
6193 else
6194 {
6195 pHddAdapterNode->pAdapter = pAdapter;
6196 status = hdd_add_adapter_back ( pHddCtx,
6197 pHddAdapterNode );
6198 }
6199 }
6200
6201 if( VOS_STATUS_SUCCESS != status )
6202 {
6203 if( NULL != pAdapter )
6204 {
6205 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6206 pAdapter = NULL;
6207 }
6208 if( NULL != pHddAdapterNode )
6209 {
6210 vos_mem_free( pHddAdapterNode );
6211 }
6212
6213 goto resume_bmps;
6214 }
6215
6216 if(VOS_STATUS_SUCCESS == status)
6217 {
6218 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6219
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006220 //Initialize the WoWL service
6221 if(!hdd_init_wowl(pAdapter))
6222 {
6223 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6224 goto err_free_netdev;
6225 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 return pAdapter;
6228
6229err_free_netdev:
6230 free_netdev(pAdapter->dev);
6231 wlan_hdd_release_intf_addr( pHddCtx,
6232 pAdapter->macAddressCurrent.bytes );
6233
6234resume_bmps:
6235 //If bmps disabled enable it
6236 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6237 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306238 if (pHddCtx->hdd_wlan_suspended)
6239 {
6240 hdd_set_pwrparams(pHddCtx);
6241 }
6242 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 }
6244 return NULL;
6245}
6246
6247VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6248 tANI_U8 rtnl_held )
6249{
6250 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6251 VOS_STATUS status;
6252
6253 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6254 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306255 {
6256 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6257 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006260
6261 while ( pCurrent->pAdapter != pAdapter )
6262 {
6263 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6264 if( VOS_STATUS_SUCCESS != status )
6265 break;
6266
6267 pCurrent = pNext;
6268 }
6269 pAdapterNode = pCurrent;
6270 if( VOS_STATUS_SUCCESS == status )
6271 {
6272 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6273 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306274
6275#ifdef FEATURE_WLAN_TDLS
6276
6277 /* A Mutex Lock is introduced while changing/initializing the mode to
6278 * protect the concurrent access for the Adapters by TDLS module.
6279 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306280 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306281#endif
6282
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 hdd_remove_adapter( pHddCtx, pAdapterNode );
6284 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006285 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006286
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306287#ifdef FEATURE_WLAN_TDLS
6288 mutex_unlock(&pHddCtx->tdls_lock);
6289#endif
6290
Jeff Johnson295189b2012-06-20 16:38:30 -07006291
6292 /* If there is a single session of STA/P2P client, re-enable BMPS */
6293 if ((!vos_concurrent_sessions_running()) &&
6294 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6295 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6296 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306297 if (pHddCtx->hdd_wlan_suspended)
6298 {
6299 hdd_set_pwrparams(pHddCtx);
6300 }
6301 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 }
6303
6304 return VOS_STATUS_SUCCESS;
6305 }
6306
6307 return VOS_STATUS_E_FAILURE;
6308}
6309
6310VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6311{
6312 hdd_adapter_list_node_t *pHddAdapterNode;
6313 VOS_STATUS status;
6314
6315 ENTER();
6316
6317 do
6318 {
6319 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6320 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6321 {
6322 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6323 vos_mem_free( pHddAdapterNode );
6324 }
6325 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6326
6327 EXIT();
6328
6329 return VOS_STATUS_SUCCESS;
6330}
6331
6332void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6333{
6334 v_U8_t addIE[1] = {0};
6335
6336 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6337 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6338 eANI_BOOLEAN_FALSE) )
6339 {
6340 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006341 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 }
6343
6344 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6345 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6346 eANI_BOOLEAN_FALSE) )
6347 {
6348 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006349 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 }
6351
6352 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6353 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6354 eANI_BOOLEAN_FALSE) )
6355 {
6356 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006357 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 }
6359}
6360
6361VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6362{
6363 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6364 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6365 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306366 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306367 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006368
6369 ENTER();
6370
6371 switch(pAdapter->device_mode)
6372 {
6373 case WLAN_HDD_INFRA_STATION:
6374 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006375 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306376 {
6377 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6378 if( hdd_connIsConnected(pstation) ||
6379 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 {
6381 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6382 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6383 pAdapter->sessionId,
6384 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6385 else
6386 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6387 pAdapter->sessionId,
6388 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6389 //success implies disconnect command got queued up successfully
6390 if(halStatus == eHAL_STATUS_SUCCESS)
6391 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306392 ret = wait_for_completion_interruptible_timeout(
6393 &pAdapter->disconnect_comp_var,
6394 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6395 if (ret <= 0)
6396 {
6397 hddLog(VOS_TRACE_LEVEL_ERROR,
6398 "%s: wait on disconnect_comp_var failed %ld",
6399 __func__, ret);
6400 }
6401 }
6402 else
6403 {
6404 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6405 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 }
6407 memset(&wrqu, '\0', sizeof(wrqu));
6408 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6409 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6410 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6411 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306412 else if(pstation->conn_info.connState ==
6413 eConnectionState_Disconnecting)
6414 {
6415 ret = wait_for_completion_interruptible_timeout(
6416 &pAdapter->disconnect_comp_var,
6417 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6418 if (ret <= 0)
6419 {
6420 hddLog(VOS_TRACE_LEVEL_ERROR,
6421 FL("wait on disconnect_comp_var failed %ld"), ret);
6422 }
6423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 else
6425 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306426 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6427 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306429 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6430 {
6431 while (pAdapter->is_roc_inprogress)
6432 {
6433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6434 "%s: ROC in progress for session %d!!!",
6435 __func__, pAdapter->sessionId);
6436 // waiting for ROC to expire
6437 msleep(500);
6438 /* In GO present case , if retry exceeds 3,
6439 it means something went wrong. */
6440 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6441 {
6442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6443 "%s: ROC completion is not received.!!!", __func__);
6444 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6445 pAdapter->sessionId);
6446 wait_for_completion_interruptible_timeout(
6447 &pAdapter->cancel_rem_on_chan_var,
6448 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6449 break;
6450 }
6451 }
6452 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306453#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306454#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306455 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6456#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306457 if (pAdapter->ipv6_notifier_registered)
6458 {
6459 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6460 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6461 pAdapter->ipv6_notifier_registered = false;
6462 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306463#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306464 if (pAdapter->ipv4_notifier_registered)
6465 {
6466 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6467 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6468 pAdapter->ipv4_notifier_registered = false;
6469 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306470#ifdef WLAN_OPEN_SOURCE
6471 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6472#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6474 {
6475 INIT_COMPLETION(pAdapter->session_close_comp_var);
6476 if (eHAL_STATUS_SUCCESS ==
6477 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6478 hdd_smeCloseSessionCallback, pAdapter))
6479 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306480 unsigned long ret;
6481
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306483 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 &pAdapter->session_close_comp_var,
6485 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306486 if ( 0 >= ret)
6487 {
6488 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6489 __func__, ret);
6490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 }
6492 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306493 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 break;
6495
6496 case WLAN_HDD_SOFTAP:
6497 case WLAN_HDD_P2P_GO:
6498 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306499 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6500 while (pAdapter->is_roc_inprogress) {
6501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6502 "%s: ROC in progress for session %d!!!",
6503 __func__, pAdapter->sessionId);
6504 msleep(500);
6505 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6507 "%s: ROC completion is not received.!!!", __func__);
6508 WLANSAP_CancelRemainOnChannel(
6509 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6510 wait_for_completion_interruptible_timeout(
6511 &pAdapter->cancel_rem_on_chan_var,
6512 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6513 break;
6514 }
6515 }
6516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 mutex_lock(&pHddCtx->sap_lock);
6518 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6519 {
6520 VOS_STATUS status;
6521 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6522
6523 //Stop Bss.
6524 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6525 if (VOS_IS_STATUS_SUCCESS(status))
6526 {
6527 hdd_hostapd_state_t *pHostapdState =
6528 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6529
6530 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6531
6532 if (!VOS_IS_STATUS_SUCCESS(status))
6533 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306534 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6535 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006536 }
6537 }
6538 else
6539 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006540 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 }
6542 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6543
6544 if (eHAL_STATUS_FAILURE ==
6545 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6546 0, NULL, eANI_BOOLEAN_FALSE))
6547 {
6548 hddLog(LOGE,
6549 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006550 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 }
6552
6553 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6554 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6555 eANI_BOOLEAN_FALSE) )
6556 {
6557 hddLog(LOGE,
6558 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6559 }
6560
6561 // Reset WNI_CFG_PROBE_RSP Flags
6562 wlan_hdd_reset_prob_rspies(pAdapter);
6563 kfree(pAdapter->sessionCtx.ap.beacon);
6564 pAdapter->sessionCtx.ap.beacon = NULL;
6565 }
6566 mutex_unlock(&pHddCtx->sap_lock);
6567 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006568
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006570#ifdef WLAN_OPEN_SOURCE
6571 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6572#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006574
Jeff Johnson295189b2012-06-20 16:38:30 -07006575 default:
6576 break;
6577 }
6578
6579 EXIT();
6580 return VOS_STATUS_SUCCESS;
6581}
6582
6583VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6584{
6585 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6586 VOS_STATUS status;
6587 hdd_adapter_t *pAdapter;
6588
6589 ENTER();
6590
6591 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6592
6593 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6594 {
6595 pAdapter = pAdapterNode->pAdapter;
6596 netif_tx_disable(pAdapter->dev);
6597 netif_carrier_off(pAdapter->dev);
6598
6599 hdd_stop_adapter( pHddCtx, pAdapter );
6600
6601 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6602 pAdapterNode = pNext;
6603 }
6604
6605 EXIT();
6606
6607 return VOS_STATUS_SUCCESS;
6608}
6609
Rajeev Kumarf999e582014-01-09 17:33:29 -08006610
6611#ifdef FEATURE_WLAN_BATCH_SCAN
6612/**---------------------------------------------------------------------------
6613
6614 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6615 structures
6616
6617 \param - pAdapter Pointer to HDD adapter
6618
6619 \return - None
6620
6621 --------------------------------------------------------------------------*/
6622void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6623{
6624 tHddBatchScanRsp *pNode;
6625 tHddBatchScanRsp *pPrev;
6626
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306627 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006628 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306629 hddLog(VOS_TRACE_LEVEL_ERROR,
6630 "%s: Adapter context is Null", __func__);
6631 return;
6632 }
6633
6634 pNode = pAdapter->pBatchScanRsp;
6635 while (pNode)
6636 {
6637 pPrev = pNode;
6638 pNode = pNode->pNext;
6639 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006640 }
6641
6642 pAdapter->pBatchScanRsp = NULL;
6643 pAdapter->numScanList = 0;
6644 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6645 pAdapter->prev_batch_id = 0;
6646
6647 return;
6648}
6649#endif
6650
6651
Jeff Johnson295189b2012-06-20 16:38:30 -07006652VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6653{
6654 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6655 VOS_STATUS status;
6656 hdd_adapter_t *pAdapter;
6657
6658 ENTER();
6659
6660 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6661
6662 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6663 {
6664 pAdapter = pAdapterNode->pAdapter;
6665 netif_tx_disable(pAdapter->dev);
6666 netif_carrier_off(pAdapter->dev);
6667
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006668 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6669
Jeff Johnson295189b2012-06-20 16:38:30 -07006670 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306671 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6672 {
6673 hdd_wmm_adapter_close( pAdapter );
6674 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006676
Rajeev Kumarf999e582014-01-09 17:33:29 -08006677#ifdef FEATURE_WLAN_BATCH_SCAN
6678 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6679 {
6680 hdd_deinit_batch_scan(pAdapter);
6681 }
6682#endif
6683
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6685 pAdapterNode = pNext;
6686 }
6687
6688 EXIT();
6689
6690 return VOS_STATUS_SUCCESS;
6691}
6692
6693VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6694{
6695 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6696 VOS_STATUS status;
6697 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306698 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006699
6700 ENTER();
6701
6702 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6703
6704 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6705 {
6706 pAdapter = pAdapterNode->pAdapter;
6707
6708 switch(pAdapter->device_mode)
6709 {
6710 case WLAN_HDD_INFRA_STATION:
6711 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006712 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306713
6714 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6715
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 hdd_init_station_mode(pAdapter);
6717 /* Open the gates for HDD to receive Wext commands */
6718 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006719 pHddCtx->scan_info.mScanPending = FALSE;
6720 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006721
6722 //Trigger the initial scan
6723 hdd_wlan_initial_scan(pAdapter);
6724
6725 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306726 if (eConnectionState_Associated == connState ||
6727 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006728 {
6729 union iwreq_data wrqu;
6730 memset(&wrqu, '\0', sizeof(wrqu));
6731 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6732 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6733 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006734 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006735
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 /* indicate disconnected event to nl80211 */
6737 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6738 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306740 else if (eConnectionState_Connecting == connState)
6741 {
6742 /*
6743 * Indicate connect failure to supplicant if we were in the
6744 * process of connecting
6745 */
6746 cfg80211_connect_result(pAdapter->dev, NULL,
6747 NULL, 0, NULL, 0,
6748 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6749 GFP_KERNEL);
6750 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 break;
6752
6753 case WLAN_HDD_SOFTAP:
6754 /* softAP can handle SSR */
6755 break;
6756
6757 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006760 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006761 break;
6762
6763 case WLAN_HDD_MONITOR:
6764 /* monitor interface start */
6765 break;
6766 default:
6767 break;
6768 }
6769
6770 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6771 pAdapterNode = pNext;
6772 }
6773
6774 EXIT();
6775
6776 return VOS_STATUS_SUCCESS;
6777}
6778
6779VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6780{
6781 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6782 hdd_adapter_t *pAdapter;
6783 VOS_STATUS status;
6784 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306785 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006786
6787 ENTER();
6788
6789 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6790
6791 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6792 {
6793 pAdapter = pAdapterNode->pAdapter;
6794
6795 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6796 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6797 {
6798 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6799 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6800
6801 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6802 init_completion(&pAdapter->disconnect_comp_var);
6803 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6804 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6805
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306806 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 &pAdapter->disconnect_comp_var,
6808 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306809 if (0 >= ret)
6810 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6811 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006812
6813 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6814 pHddCtx->isAmpAllowed = VOS_FALSE;
6815 sme_RoamConnect(pHddCtx->hHal,
6816 pAdapter->sessionId, &(pWextState->roamProfile),
6817 &roamId);
6818 }
6819
6820 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6821 pAdapterNode = pNext;
6822 }
6823
6824 EXIT();
6825
6826 return VOS_STATUS_SUCCESS;
6827}
6828
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006829void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6830{
6831 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6832 VOS_STATUS status;
6833 hdd_adapter_t *pAdapter;
6834 hdd_station_ctx_t *pHddStaCtx;
6835 hdd_ap_ctx_t *pHddApCtx;
6836 hdd_hostapd_state_t * pHostapdState;
6837 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6838 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6839 const char *p2pMode = "DEV";
6840 const char *ccMode = "Standalone";
6841 int n;
6842
6843 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6844 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6845 {
6846 pAdapter = pAdapterNode->pAdapter;
6847 switch (pAdapter->device_mode) {
6848 case WLAN_HDD_INFRA_STATION:
6849 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6850 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6851 staChannel = pHddStaCtx->conn_info.operationChannel;
6852 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6853 }
6854 break;
6855 case WLAN_HDD_P2P_CLIENT:
6856 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6857 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6858 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6859 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6860 p2pMode = "CLI";
6861 }
6862 break;
6863 case WLAN_HDD_P2P_GO:
6864 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6865 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6866 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6867 p2pChannel = pHddApCtx->operatingChannel;
6868 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6869 }
6870 p2pMode = "GO";
6871 break;
6872 case WLAN_HDD_SOFTAP:
6873 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6874 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6875 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6876 apChannel = pHddApCtx->operatingChannel;
6877 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6878 }
6879 break;
6880 default:
6881 break;
6882 }
6883 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6884 pAdapterNode = pNext;
6885 }
6886 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
6887 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
6888 }
6889 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
6890 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
6891 if (p2pChannel > 0) {
6892 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
6893 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
6894 }
6895 if (apChannel > 0) {
6896 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
6897 apChannel, MAC_ADDR_ARRAY(apBssid));
6898 }
6899
6900 if (p2pChannel > 0 && apChannel > 0) {
6901 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
6902 }
6903}
6904
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006905bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006906{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006907 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07006908}
6909
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006910/* Once SSR is disabled then it cannot be set. */
6911void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07006912{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006913 if (HDD_SSR_DISABLED == isSsrRequired)
6914 return;
6915
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 isSsrRequired = value;
6917}
6918
6919VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
6920 hdd_adapter_list_node_t** ppAdapterNode)
6921{
6922 VOS_STATUS status;
6923 spin_lock(&pHddCtx->hddAdapters.lock);
6924 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
6925 (hdd_list_node_t**) ppAdapterNode );
6926 spin_unlock(&pHddCtx->hddAdapters.lock);
6927 return status;
6928}
6929
6930VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
6931 hdd_adapter_list_node_t* pAdapterNode,
6932 hdd_adapter_list_node_t** pNextAdapterNode)
6933{
6934 VOS_STATUS status;
6935 spin_lock(&pHddCtx->hddAdapters.lock);
6936 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
6937 (hdd_list_node_t*) pAdapterNode,
6938 (hdd_list_node_t**)pNextAdapterNode );
6939
6940 spin_unlock(&pHddCtx->hddAdapters.lock);
6941 return status;
6942}
6943
6944VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
6945 hdd_adapter_list_node_t* pAdapterNode)
6946{
6947 VOS_STATUS status;
6948 spin_lock(&pHddCtx->hddAdapters.lock);
6949 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
6950 &pAdapterNode->node );
6951 spin_unlock(&pHddCtx->hddAdapters.lock);
6952 return status;
6953}
6954
6955VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
6956 hdd_adapter_list_node_t** ppAdapterNode)
6957{
6958 VOS_STATUS status;
6959 spin_lock(&pHddCtx->hddAdapters.lock);
6960 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
6961 (hdd_list_node_t**) ppAdapterNode );
6962 spin_unlock(&pHddCtx->hddAdapters.lock);
6963 return status;
6964}
6965
6966VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
6967 hdd_adapter_list_node_t* pAdapterNode)
6968{
6969 VOS_STATUS status;
6970 spin_lock(&pHddCtx->hddAdapters.lock);
6971 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
6972 (hdd_list_node_t*) pAdapterNode );
6973 spin_unlock(&pHddCtx->hddAdapters.lock);
6974 return status;
6975}
6976
6977VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
6978 hdd_adapter_list_node_t* pAdapterNode)
6979{
6980 VOS_STATUS status;
6981 spin_lock(&pHddCtx->hddAdapters.lock);
6982 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
6983 (hdd_list_node_t*) pAdapterNode );
6984 spin_unlock(&pHddCtx->hddAdapters.lock);
6985 return status;
6986}
6987
6988hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
6989 tSirMacAddr macAddr )
6990{
6991 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6992 hdd_adapter_t *pAdapter;
6993 VOS_STATUS status;
6994
6995 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6996
6997 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6998 {
6999 pAdapter = pAdapterNode->pAdapter;
7000
7001 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7002 macAddr, sizeof(tSirMacAddr) ) )
7003 {
7004 return pAdapter;
7005 }
7006 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7007 pAdapterNode = pNext;
7008 }
7009
7010 return NULL;
7011
7012}
7013
7014hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7015{
7016 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7017 hdd_adapter_t *pAdapter;
7018 VOS_STATUS status;
7019
7020 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7021
7022 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7023 {
7024 pAdapter = pAdapterNode->pAdapter;
7025
7026 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7027 IFNAMSIZ ) )
7028 {
7029 return pAdapter;
7030 }
7031 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7032 pAdapterNode = pNext;
7033 }
7034
7035 return NULL;
7036
7037}
7038
7039hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7040{
7041 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7042 hdd_adapter_t *pAdapter;
7043 VOS_STATUS status;
7044
7045 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7046
7047 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7048 {
7049 pAdapter = pAdapterNode->pAdapter;
7050
7051 if( pAdapter && (mode == pAdapter->device_mode) )
7052 {
7053 return pAdapter;
7054 }
7055 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7056 pAdapterNode = pNext;
7057 }
7058
7059 return NULL;
7060
7061}
7062
7063//Remove this function later
7064hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7065{
7066 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7067 hdd_adapter_t *pAdapter;
7068 VOS_STATUS status;
7069
7070 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7071
7072 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7073 {
7074 pAdapter = pAdapterNode->pAdapter;
7075
7076 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7077 {
7078 return pAdapter;
7079 }
7080
7081 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7082 pAdapterNode = pNext;
7083 }
7084
7085 return NULL;
7086
7087}
7088
Jeff Johnson295189b2012-06-20 16:38:30 -07007089/**---------------------------------------------------------------------------
7090
7091 \brief hdd_set_monitor_tx_adapter() -
7092
7093 This API initializes the adapter to be used while transmitting on monitor
7094 adapter.
7095
7096 \param - pHddCtx - Pointer to the HDD context.
7097 pAdapter - Adapter that will used for TX. This can be NULL.
7098 \return - None.
7099 --------------------------------------------------------------------------*/
7100void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7101{
7102 hdd_adapter_t *pMonAdapter;
7103
7104 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7105
7106 if( NULL != pMonAdapter )
7107 {
7108 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7109 }
7110}
Jeff Johnson295189b2012-06-20 16:38:30 -07007111/**---------------------------------------------------------------------------
7112
7113 \brief hdd_select_queue() -
7114
7115 This API returns the operating channel of the requested device mode
7116
7117 \param - pHddCtx - Pointer to the HDD context.
7118 - mode - Device mode for which operating channel is required
7119 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7120 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7121 \return - channel number. "0" id the requested device is not found OR it is not connected.
7122 --------------------------------------------------------------------------*/
7123v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7124{
7125 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7126 VOS_STATUS status;
7127 hdd_adapter_t *pAdapter;
7128 v_U8_t operatingChannel = 0;
7129
7130 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7131
7132 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7133 {
7134 pAdapter = pAdapterNode->pAdapter;
7135
7136 if( mode == pAdapter->device_mode )
7137 {
7138 switch(pAdapter->device_mode)
7139 {
7140 case WLAN_HDD_INFRA_STATION:
7141 case WLAN_HDD_P2P_CLIENT:
7142 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7143 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7144 break;
7145 case WLAN_HDD_SOFTAP:
7146 case WLAN_HDD_P2P_GO:
7147 /*softap connection info */
7148 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7149 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7150 break;
7151 default:
7152 break;
7153 }
7154
7155 break; //Found the device of interest. break the loop
7156 }
7157
7158 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7159 pAdapterNode = pNext;
7160 }
7161 return operatingChannel;
7162}
7163
7164#ifdef WLAN_FEATURE_PACKET_FILTERING
7165/**---------------------------------------------------------------------------
7166
7167 \brief hdd_set_multicast_list() -
7168
7169 This used to set the multicast address list.
7170
7171 \param - dev - Pointer to the WLAN device.
7172 - skb - Pointer to OS packet (sk_buff).
7173 \return - success/fail
7174
7175 --------------------------------------------------------------------------*/
7176static void hdd_set_multicast_list(struct net_device *dev)
7177{
7178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 int mc_count;
7180 int i = 0;
7181 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307182
7183 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 {
7185 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307186 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 return;
7188 }
7189
7190 if (dev->flags & IFF_ALLMULTI)
7191 {
7192 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007193 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307194 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007195 }
7196 else
7197 {
7198 mc_count = netdev_mc_count(dev);
7199 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007200 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007201 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7202 {
7203 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007204 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307205 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 return;
7207 }
7208
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307209 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007210
7211 netdev_for_each_mc_addr(ha, dev) {
7212 if (i == mc_count)
7213 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307214 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7215 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307218 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 i++;
7220 }
7221 }
7222 return;
7223}
7224#endif
7225
7226/**---------------------------------------------------------------------------
7227
7228 \brief hdd_select_queue() -
7229
7230 This function is registered with the Linux OS for network
7231 core to decide which queue to use first.
7232
7233 \param - dev - Pointer to the WLAN device.
7234 - skb - Pointer to OS packet (sk_buff).
7235 \return - ac, Queue Index/access category corresponding to UP in IP header
7236
7237 --------------------------------------------------------------------------*/
7238v_U16_t hdd_select_queue(struct net_device *dev,
7239 struct sk_buff *skb)
7240{
7241 return hdd_wmm_select_queue(dev, skb);
7242}
7243
7244
7245/**---------------------------------------------------------------------------
7246
7247 \brief hdd_wlan_initial_scan() -
7248
7249 This function triggers the initial scan
7250
7251 \param - pAdapter - Pointer to the HDD adapter.
7252
7253 --------------------------------------------------------------------------*/
7254void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7255{
7256 tCsrScanRequest scanReq;
7257 tCsrChannelInfo channelInfo;
7258 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007259 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7261
7262 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7263 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7264 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7265
7266 if(sme_Is11dSupported(pHddCtx->hHal))
7267 {
7268 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7269 if ( HAL_STATUS_SUCCESS( halStatus ) )
7270 {
7271 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7272 if( !scanReq.ChannelInfo.ChannelList )
7273 {
7274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7275 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007276 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 return;
7278 }
7279 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7280 channelInfo.numOfChannels);
7281 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7282 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007283 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 }
7285
7286 scanReq.scanType = eSIR_PASSIVE_SCAN;
7287 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7288 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7289 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7290 }
7291 else
7292 {
7293 scanReq.scanType = eSIR_ACTIVE_SCAN;
7294 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7295 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7296 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7297 }
7298
7299 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7300 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7301 {
7302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7303 __func__, halStatus );
7304 }
7305
7306 if(sme_Is11dSupported(pHddCtx->hHal))
7307 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7308}
7309
Jeff Johnson295189b2012-06-20 16:38:30 -07007310/**---------------------------------------------------------------------------
7311
7312 \brief hdd_full_power_callback() - HDD full power callback function
7313
7314 This is the function invoked by SME to inform the result of a full power
7315 request issued by HDD
7316
7317 \param - callbackcontext - Pointer to cookie
7318 \param - status - result of request
7319
7320 \return - None
7321
7322 --------------------------------------------------------------------------*/
7323static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7324{
Jeff Johnson72a40512013-12-19 10:14:15 -08007325 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007326
7327 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307328 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007329
7330 if (NULL == callbackContext)
7331 {
7332 hddLog(VOS_TRACE_LEVEL_ERROR,
7333 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007334 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 return;
7336 }
7337
Jeff Johnson72a40512013-12-19 10:14:15 -08007338 /* there is a race condition that exists between this callback
7339 function and the caller since the caller could time out either
7340 before or while this code is executing. we use a spinlock to
7341 serialize these actions */
7342 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007343
7344 if (POWER_CONTEXT_MAGIC != pContext->magic)
7345 {
7346 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007347 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 hddLog(VOS_TRACE_LEVEL_WARN,
7349 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007350 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 return;
7352 }
7353
Jeff Johnson72a40512013-12-19 10:14:15 -08007354 /* context is valid so caller is still waiting */
7355
7356 /* paranoia: invalidate the magic */
7357 pContext->magic = 0;
7358
7359 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007360 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007361
7362 /* serialization is complete */
7363 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007364}
7365
7366/**---------------------------------------------------------------------------
7367
7368 \brief hdd_wlan_exit() - HDD WLAN exit function
7369
7370 This is the driver exit point (invoked during rmmod)
7371
7372 \param - pHddCtx - Pointer to the HDD Context
7373
7374 \return - None
7375
7376 --------------------------------------------------------------------------*/
7377void hdd_wlan_exit(hdd_context_t *pHddCtx)
7378{
7379 eHalStatus halStatus;
7380 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7381 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307382 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007383 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007384 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 long lrc;
7386
7387 ENTER();
7388
Jeff Johnson88ba7742013-02-27 14:36:02 -08007389 if (VOS_FTM_MODE != hdd_get_conparam())
7390 {
7391 // Unloading, restart logic is no more required.
7392 wlan_hdd_restart_deinit(pHddCtx);
7393 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007394
Jeff Johnson295189b2012-06-20 16:38:30 -07007395 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007396 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007397 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007398 {
7399 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7400 WLAN_HDD_INFRA_STATION);
7401 if (pAdapter == NULL)
7402 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7403
7404 if (pAdapter != NULL)
7405 {
7406 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7407 hdd_UnregisterWext(pAdapter->dev);
7408 }
7409 }
7410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007411
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007413 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307414 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007415 wlan_hdd_ftm_close(pHddCtx);
7416 goto free_hdd_ctx;
7417 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 //Stop the Interface TX queue.
7419 //netif_tx_disable(pWlanDev);
7420 //netif_carrier_off(pWlanDev);
7421
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7423 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307424 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007425 pAdapter = hdd_get_adapter(pHddCtx,
7426 WLAN_HDD_SOFTAP);
7427 }
7428 else
7429 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007430 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307432 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 pAdapter = hdd_get_adapter(pHddCtx,
7434 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007435 if (pAdapter == NULL)
7436 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007437 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007438 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307439
7440 if(NULL == pAdapter)
7441 {
7442 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7443 goto free_hdd_ctx;
7444 }
7445
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 /* DeRegister with platform driver as client for Suspend/Resume */
7447 vosStatus = hddDeregisterPmOps(pHddCtx);
7448 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7449 {
7450 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7451 VOS_ASSERT(0);
7452 }
7453
7454 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7455 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7456 {
7457 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007459
7460 // Cancel any outstanding scan requests. We are about to close all
7461 // of our adapters, but an adapter structure is what SME passes back
7462 // to our callback function. Hence if there are any outstanding scan
7463 // requests then there is a race condition between when the adapter
7464 // is closed and when the callback is invoked. We try to resolve that
7465 // race condition here by canceling any outstanding scans before we
7466 // close the adapters.
7467 // Note that the scans may be cancelled in an asynchronous manner, so
7468 // ideally there needs to be some kind of synchronization. Rather than
7469 // introduce a new synchronization here, we will utilize the fact that
7470 // we are about to Request Full Power, and since that is synchronized,
7471 // the expectation is that by the time Request Full Power has completed,
7472 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007473 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307474 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007475 else
7476 hddLog(VOS_TRACE_LEVEL_ERROR,
7477 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007478
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007479 //Stop the traffic monitor timer
7480 if ( VOS_TIMER_STATE_RUNNING ==
7481 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7482 {
7483 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7484 }
7485
7486 // Destroy the traffic monitor timer
7487 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7488 &pHddCtx->tx_rx_trafficTmr)))
7489 {
7490 hddLog(VOS_TRACE_LEVEL_ERROR,
7491 "%s: Cannot deallocate Traffic monitor timer", __func__);
7492 }
7493
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 //Disable IMPS/BMPS as we do not want the device to enter any power
7495 //save mode during shutdown
7496 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7497 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7498 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7499
7500 //Ensure that device is in full power as we will touch H/W during vos_Stop
7501 init_completion(&powerContext.completion);
7502 powerContext.magic = POWER_CONTEXT_MAGIC;
7503
7504 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7505 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7506
7507 if (eHAL_STATUS_SUCCESS != halStatus)
7508 {
7509 if (eHAL_STATUS_PMC_PENDING == halStatus)
7510 {
7511 /* request was sent -- wait for the response */
7512 lrc = wait_for_completion_interruptible_timeout(
7513 &powerContext.completion,
7514 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 if (lrc <= 0)
7516 {
7517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007518 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 }
7520 }
7521 else
7522 {
7523 hddLog(VOS_TRACE_LEVEL_ERROR,
7524 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007525 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 /* continue -- need to clean up as much as possible */
7527 }
7528 }
7529
Jeff Johnson72a40512013-12-19 10:14:15 -08007530 /* either we never sent a request, we sent a request and received a
7531 response or we sent a request and timed out. if we never sent a
7532 request or if we sent a request and got a response, we want to
7533 clear the magic out of paranoia. if we timed out there is a
7534 race condition such that the callback function could be
7535 executing at the same time we are. of primary concern is if the
7536 callback function had already verified the "magic" but had not
7537 yet set the completion variable when a timeout occurred. we
7538 serialize these activities by invalidating the magic while
7539 holding a shared spinlock which will cause us to block if the
7540 callback is currently executing */
7541 spin_lock(&hdd_context_lock);
7542 powerContext.magic = 0;
7543 spin_unlock(&hdd_context_lock);
7544
Yue Ma0d4891e2013-08-06 17:01:45 -07007545 hdd_debugfs_exit(pHddCtx);
7546
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 // Unregister the Net Device Notifier
7548 unregister_netdevice_notifier(&hdd_netdev_notifier);
7549
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 hdd_stop_all_adapters( pHddCtx );
7551
Jeff Johnson295189b2012-06-20 16:38:30 -07007552#ifdef WLAN_BTAMP_FEATURE
7553 vosStatus = WLANBAP_Stop(pVosContext);
7554 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7555 {
7556 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7557 "%s: Failed to stop BAP",__func__);
7558 }
7559#endif //WLAN_BTAMP_FEATURE
7560
7561 //Stop all the modules
7562 vosStatus = vos_stop( pVosContext );
7563 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7564 {
7565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7566 "%s: Failed to stop VOSS",__func__);
7567 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7568 }
7569
Jeff Johnson295189b2012-06-20 16:38:30 -07007570 //Assert Deep sleep signal now to put Libra HW in lowest power state
7571 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7572 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7573
7574 //Vote off any PMIC voltage supplies
7575 vos_chipPowerDown(NULL, NULL, NULL);
7576
7577 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7578
Leo Chang59cdc7e2013-07-10 10:08:21 -07007579
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007582
7583 //Close the scheduler before calling vos_close to make sure no thread is
7584 // scheduled after the each module close is called i.e after all the data
7585 // structures are freed.
7586 vosStatus = vos_sched_close( pVosContext );
7587 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7588 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7589 "%s: Failed to close VOSS Scheduler",__func__);
7590 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7591 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007592#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007593#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7594 /* Destroy the wake lock */
7595 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7596#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007597 /* Destroy the wake lock */
7598 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007599#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007600
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307601#ifdef CONFIG_ENABLE_LINUX_REG
7602 vosStatus = vos_nv_close();
7603 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7604 {
7605 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7606 "%s: Failed to close NV", __func__);
7607 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7608 }
7609#endif
7610
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 //Close VOSS
7612 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7613 vos_close(pVosContext);
7614
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 //Close Watchdog
7616 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7617 vos_watchdog_close(pVosContext);
7618
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307619 //Clean up HDD Nlink Service
7620 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007621#ifdef WLAN_KD_READY_NOTIFIER
7622 nl_srv_exit(pHddCtx->ptt_pid);
7623#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307624 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007625#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307626
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307627#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
7628 if(pHddCtx->cfg_ini->wlanLoggingEnable)
7629 {
7630 wlan_logging_sock_deactivate_svc();
7631 }
7632#endif
7633
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 /* Cancel the vote for XO Core ON.
7635 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7636 * exited at this point
7637 */
7638 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007639 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7641 {
7642 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7643 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007644 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 }
7646
7647 hdd_close_all_adapters( pHddCtx );
7648
7649
7650 //Free up dynamically allocated members inside HDD Adapter
7651 kfree(pHddCtx->cfg_ini);
7652 pHddCtx->cfg_ini= NULL;
7653
7654 /* free the power on lock from platform driver */
7655 if (free_riva_power_on_lock("wlan"))
7656 {
7657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7658 __func__);
7659 }
7660
Jeff Johnson88ba7742013-02-27 14:36:02 -08007661free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007662 /* FTM mode, WIPHY did not registered
7663 If un-register here, system crash will happen */
7664 if (VOS_FTM_MODE != hdd_get_conparam())
7665 {
7666 wiphy_unregister(wiphy) ;
7667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 if (hdd_is_ssr_required())
7670 {
7671 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007672 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 msleep(5000);
7674 }
7675 hdd_set_ssr_required (VOS_FALSE);
7676}
7677
7678
7679/**---------------------------------------------------------------------------
7680
7681 \brief hdd_update_config_from_nv() - Function to update the contents of
7682 the running configuration with parameters taken from NV storage
7683
7684 \param - pHddCtx - Pointer to the HDD global context
7685
7686 \return - VOS_STATUS_SUCCESS if successful
7687
7688 --------------------------------------------------------------------------*/
7689static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7690{
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 v_BOOL_t itemIsValid = VOS_FALSE;
7692 VOS_STATUS status;
7693 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7694 v_U8_t macLoop;
7695
7696 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7697 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7698 if(status != VOS_STATUS_SUCCESS)
7699 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007700 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 return VOS_STATUS_E_FAILURE;
7702 }
7703
7704 if (itemIsValid == VOS_TRUE)
7705 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007706 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007707 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7708 VOS_MAX_CONCURRENCY_PERSONA);
7709 if(status != VOS_STATUS_SUCCESS)
7710 {
7711 /* Get MAC from NV fail, not update CFG info
7712 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007713 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 return VOS_STATUS_E_FAILURE;
7715 }
7716
7717 /* If first MAC is not valid, treat all others are not valid
7718 * Then all MACs will be got from ini file */
7719 if(vos_is_macaddr_zero(&macFromNV[0]))
7720 {
7721 /* MAC address in NV file is not configured yet */
7722 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7723 return VOS_STATUS_E_INVAL;
7724 }
7725
7726 /* Get MAC address from NV, update CFG info */
7727 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7728 {
7729 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7730 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307731 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007732 /* This MAC is not valid, skip it
7733 * This MAC will be got from ini file */
7734 }
7735 else
7736 {
7737 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7738 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7739 VOS_MAC_ADDR_SIZE);
7740 }
7741 }
7742 }
7743 else
7744 {
7745 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7746 return VOS_STATUS_E_FAILURE;
7747 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007748
Jeff Johnson295189b2012-06-20 16:38:30 -07007749
7750 return VOS_STATUS_SUCCESS;
7751}
7752
7753/**---------------------------------------------------------------------------
7754
7755 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7756
7757 \param - pAdapter - Pointer to the HDD
7758
7759 \return - None
7760
7761 --------------------------------------------------------------------------*/
7762VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7763{
7764 eHalStatus halStatus;
7765 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307766 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007767
Jeff Johnson295189b2012-06-20 16:38:30 -07007768
7769 // Send ready indication to the HDD. This will kick off the MAC
7770 // into a 'running' state and should kick off an initial scan.
7771 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7772 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7773 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307774 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 "code %08d [x%08x]",__func__, halStatus, halStatus );
7776 return VOS_STATUS_E_FAILURE;
7777 }
7778
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307779 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7781 // And RIVA will crash
7782 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7783 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307784 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7785 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7786
7787
Jeff Johnson295189b2012-06-20 16:38:30 -07007788 return VOS_STATUS_SUCCESS;
7789}
7790
Jeff Johnson295189b2012-06-20 16:38:30 -07007791/* wake lock APIs for HDD */
7792void hdd_prevent_suspend(void)
7793{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007794#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007796#else
7797 wcnss_prevent_suspend();
7798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007799}
7800
7801void hdd_allow_suspend(void)
7802{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007803#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007805#else
7806 wcnss_allow_suspend();
7807#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007808}
7809
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307810void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007811{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007812#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007813 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007814#else
7815 /* Do nothing as there is no API in wcnss for timeout*/
7816#endif
7817}
7818
Jeff Johnson295189b2012-06-20 16:38:30 -07007819/**---------------------------------------------------------------------------
7820
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007821 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7822 information between Host and Riva
7823
7824 This function gets reported version of FW
7825 It also finds the version of Riva headers used to compile the host
7826 It compares the above two and prints a warning if they are different
7827 It gets the SW and HW version string
7828 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7829 indicating the features they support through a bitmap
7830
7831 \param - pHddCtx - Pointer to HDD context
7832
7833 \return - void
7834
7835 --------------------------------------------------------------------------*/
7836
7837void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7838{
7839
7840 tSirVersionType versionCompiled;
7841 tSirVersionType versionReported;
7842 tSirVersionString versionString;
7843 tANI_U8 fwFeatCapsMsgSupported = 0;
7844 VOS_STATUS vstatus;
7845
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007846 memset(&versionCompiled, 0, sizeof(versionCompiled));
7847 memset(&versionReported, 0, sizeof(versionReported));
7848
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007849 /* retrieve and display WCNSS version information */
7850 do {
7851
7852 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7853 &versionCompiled);
7854 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7855 {
7856 hddLog(VOS_TRACE_LEVEL_FATAL,
7857 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007858 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007859 break;
7860 }
7861
7862 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7863 &versionReported);
7864 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7865 {
7866 hddLog(VOS_TRACE_LEVEL_FATAL,
7867 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007868 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007869 break;
7870 }
7871
7872 if ((versionCompiled.major != versionReported.major) ||
7873 (versionCompiled.minor != versionReported.minor) ||
7874 (versionCompiled.version != versionReported.version) ||
7875 (versionCompiled.revision != versionReported.revision))
7876 {
7877 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7878 "Host expected %u.%u.%u.%u\n",
7879 WLAN_MODULE_NAME,
7880 (int)versionReported.major,
7881 (int)versionReported.minor,
7882 (int)versionReported.version,
7883 (int)versionReported.revision,
7884 (int)versionCompiled.major,
7885 (int)versionCompiled.minor,
7886 (int)versionCompiled.version,
7887 (int)versionCompiled.revision);
7888 }
7889 else
7890 {
7891 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
7892 WLAN_MODULE_NAME,
7893 (int)versionReported.major,
7894 (int)versionReported.minor,
7895 (int)versionReported.version,
7896 (int)versionReported.revision);
7897 }
7898
7899 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
7900 versionString,
7901 sizeof(versionString));
7902 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7903 {
7904 hddLog(VOS_TRACE_LEVEL_FATAL,
7905 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007906 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007907 break;
7908 }
7909
7910 pr_info("%s: WCNSS software version %s\n",
7911 WLAN_MODULE_NAME, versionString);
7912
7913 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
7914 versionString,
7915 sizeof(versionString));
7916 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7917 {
7918 hddLog(VOS_TRACE_LEVEL_FATAL,
7919 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007920 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007921 break;
7922 }
7923
7924 pr_info("%s: WCNSS hardware version %s\n",
7925 WLAN_MODULE_NAME, versionString);
7926
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007927 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
7928 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007929 send the message only if it the riva is 1.1
7930 minor numbers for different riva branches:
7931 0 -> (1.0)Mainline Build
7932 1 -> (1.1)Mainline Build
7933 2->(1.04) Stability Build
7934 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007935 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007936 ((versionReported.minor>=1) && (versionReported.version>=1)))
7937 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
7938 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007939
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007940 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08007941 {
7942#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
7943 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
7944 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
7945#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07007946 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
7947 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
7948 {
7949 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
7950 }
7951
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007952 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08007953 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007954
7955 } while (0);
7956
7957}
7958
7959/**---------------------------------------------------------------------------
7960
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307961 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
7962
7963 \param - pHddCtx - Pointer to the hdd context
7964
7965 \return - true if hardware supports 5GHz
7966
7967 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307968boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307969{
7970 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
7971 * then hardware support 5Ghz.
7972 */
7973 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
7974 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307976 return true;
7977 }
7978 else
7979 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05307980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307981 __func__);
7982 return false;
7983 }
7984}
7985
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307986/**---------------------------------------------------------------------------
7987
7988 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
7989 generate function
7990
7991 This is generate the random mac address for WLAN interface
7992
7993 \param - pHddCtx - Pointer to HDD context
7994 idx - Start interface index to get auto
7995 generated mac addr.
7996 mac_addr - Mac address
7997
7998 \return - 0 for success, < 0 for failure
7999
8000 --------------------------------------------------------------------------*/
8001
8002static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8003 int idx, v_MACADDR_t mac_addr)
8004{
8005 int i;
8006 unsigned int serialno;
8007 serialno = wcnss_get_serial_number();
8008
8009 if (0 != serialno)
8010 {
8011 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8012 bytes of the serial number that can be used to generate
8013 the other 3 bytes of the MAC address. Mask off all but
8014 the lower 3 bytes (this will also make sure we don't
8015 overflow in the next step) */
8016 serialno &= 0x00FFFFFF;
8017
8018 /* we need a unique address for each session */
8019 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8020
8021 /* autogen other Mac addresses */
8022 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8023 {
8024 /* start with the entire default address */
8025 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8026 /* then replace the lower 3 bytes */
8027 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8028 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8029 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8030
8031 serialno++;
8032 hddLog(VOS_TRACE_LEVEL_ERROR,
8033 "%s: Derived Mac Addr: "
8034 MAC_ADDRESS_STR, __func__,
8035 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8036 }
8037
8038 }
8039 else
8040 {
8041 hddLog(LOGE, FL("Failed to Get Serial NO"));
8042 return -1;
8043 }
8044 return 0;
8045}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308046
8047/**---------------------------------------------------------------------------
8048
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308049 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8050 completed to flush out the scan results
8051
8052 11d scan is done during driver load and is a passive scan on all
8053 channels supported by the device, 11d scans may find some APs on
8054 frequencies which are forbidden to be used in the regulatory domain
8055 the device is operating in. If these APs are notified to the supplicant
8056 it may try to connect to these APs, thus flush out all the scan results
8057 which are present in SME after 11d scan is done.
8058
8059 \return - eHalStatus
8060
8061 --------------------------------------------------------------------------*/
8062static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8063 tANI_U32 scanId, eCsrScanStatus status)
8064{
8065 ENTER();
8066
8067 sme_ScanFlushResult(halHandle, 0);
8068
8069 EXIT();
8070
8071 return eHAL_STATUS_SUCCESS;
8072}
8073
8074/**---------------------------------------------------------------------------
8075
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 \brief hdd_wlan_startup() - HDD init function
8077
8078 This is the driver startup code executed once a WLAN device has been detected
8079
8080 \param - dev - Pointer to the underlying device
8081
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008082 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008083
8084 --------------------------------------------------------------------------*/
8085
8086int hdd_wlan_startup(struct device *dev )
8087{
8088 VOS_STATUS status;
8089 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008090 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 hdd_context_t *pHddCtx = NULL;
8092 v_CONTEXT_t pVosContext= NULL;
8093#ifdef WLAN_BTAMP_FEATURE
8094 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8095 WLANBAP_ConfigType btAmpConfig;
8096 hdd_config_t *pConfig;
8097#endif
8098 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308100 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008101
8102 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 /*
8104 * cfg80211: wiphy allocation
8105 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308106 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008107
8108 if(wiphy == NULL)
8109 {
8110 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008111 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 }
8113
8114 pHddCtx = wiphy_priv(wiphy);
8115
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 //Initialize the adapter context to zeros.
8117 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8118
Jeff Johnson295189b2012-06-20 16:38:30 -07008119 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308121 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008122
8123 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8124
8125 /*Get vos context here bcoz vos_open requires it*/
8126 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8127
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008128 if(pVosContext == NULL)
8129 {
8130 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8131 goto err_free_hdd_context;
8132 }
8133
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 //Save the Global VOSS context in adapter context for future.
8135 pHddCtx->pvosContext = pVosContext;
8136
8137 //Save the adapter context in global context for future.
8138 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8139
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 pHddCtx->parent_dev = dev;
8141
8142 init_completion(&pHddCtx->full_pwr_comp_var);
8143 init_completion(&pHddCtx->standby_comp_var);
8144 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008145 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008146 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308147 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308148 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008149
8150#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008151 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008152#else
8153 init_completion(&pHddCtx->driver_crda_req);
8154#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008155
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308156 spin_lock_init(&pHddCtx->schedScan_lock);
8157
Jeff Johnson295189b2012-06-20 16:38:30 -07008158 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8159
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308160#ifdef FEATURE_WLAN_TDLS
8161 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8162 * invoked by other instances also) to protect the concurrent
8163 * access for the Adapters by TDLS module.
8164 */
8165 mutex_init(&pHddCtx->tdls_lock);
8166#endif
8167
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308168 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 // Load all config first as TL config is needed during vos_open
8170 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8171 if(pHddCtx->cfg_ini == NULL)
8172 {
8173 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8174 goto err_free_hdd_context;
8175 }
8176
8177 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8178
8179 // Read and parse the qcom_cfg.ini file
8180 status = hdd_parse_config_ini( pHddCtx );
8181 if ( VOS_STATUS_SUCCESS != status )
8182 {
8183 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8184 __func__, WLAN_INI_FILE);
8185 goto err_config;
8186 }
Arif Hussaind5218912013-12-05 01:10:55 -08008187#ifdef MEMORY_DEBUG
8188 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8189 vos_mem_init();
8190
8191 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8192 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008194
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308195 /* INI has been read, initialise the configuredMcastBcastFilter with
8196 * INI value as this will serve as the default value
8197 */
8198 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8199 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8200 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308201
8202 if (false == hdd_is_5g_supported(pHddCtx))
8203 {
8204 //5Ghz is not supported.
8205 if (1 != pHddCtx->cfg_ini->nBandCapability)
8206 {
8207 hddLog(VOS_TRACE_LEVEL_INFO,
8208 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8209 pHddCtx->cfg_ini->nBandCapability = 1;
8210 }
8211 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308212
8213 /* If SNR Monitoring is enabled, FW has to parse all beacons
8214 * for calcaluting and storing the average SNR, so set Nth beacon
8215 * filter to 1 to enable FW to parse all the beaocons
8216 */
8217 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8218 {
8219 /* The log level is deliberately set to WARN as overriding
8220 * nthBeaconFilter to 1 will increase power cosumption and this
8221 * might just prove helpful to detect the power issue.
8222 */
8223 hddLog(VOS_TRACE_LEVEL_WARN,
8224 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8225 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308228 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008230 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008232 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8233 {
8234 hddLog(VOS_TRACE_LEVEL_FATAL,
8235 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8236 goto err_config;
8237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008239
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008240 // Update VOS trace levels based upon the cfg.ini
8241 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8242 pHddCtx->cfg_ini->vosTraceEnableBAP);
8243 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8244 pHddCtx->cfg_ini->vosTraceEnableTL);
8245 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8246 pHddCtx->cfg_ini->vosTraceEnableWDI);
8247 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8248 pHddCtx->cfg_ini->vosTraceEnableHDD);
8249 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8250 pHddCtx->cfg_ini->vosTraceEnableSME);
8251 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8252 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308253 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8254 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008255 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8256 pHddCtx->cfg_ini->vosTraceEnableWDA);
8257 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8258 pHddCtx->cfg_ini->vosTraceEnableSYS);
8259 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8260 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008261 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8262 pHddCtx->cfg_ini->vosTraceEnableSAP);
8263 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8264 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008265
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 // Update WDI trace levels based upon the cfg.ini
8267 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8268 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8269 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8270 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8271 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8272 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8273 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8274 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008275
Jeff Johnson88ba7742013-02-27 14:36:02 -08008276 if (VOS_FTM_MODE == hdd_get_conparam())
8277 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8279 {
8280 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8281 goto err_free_hdd_context;
8282 }
8283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308284
8285 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008288
Jeff Johnson88ba7742013-02-27 14:36:02 -08008289 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8291 {
8292 status = vos_watchdog_open(pVosContext,
8293 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8294
8295 if(!VOS_IS_STATUS_SUCCESS( status ))
8296 {
8297 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308298 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008299 }
8300 }
8301
8302 pHddCtx->isLogpInProgress = FALSE;
8303 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8304
Jeff Johnson295189b2012-06-20 16:38:30 -07008305 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8306 if(!VOS_IS_STATUS_SUCCESS(status))
8307 {
8308 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008309 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 }
8311
Amar Singhala49cbc52013-10-08 18:37:44 -07008312#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008313 /* initialize the NV module. This is required so that
8314 we can initialize the channel information in wiphy
8315 from the NV.bin data. The channel information in
8316 wiphy needs to be initialized before wiphy registration */
8317
8318 status = vos_nv_open();
8319 if (!VOS_IS_STATUS_SUCCESS(status))
8320 {
8321 /* NV module cannot be initialized */
8322 hddLog( VOS_TRACE_LEVEL_FATAL,
8323 "%s: vos_nv_open failed", __func__);
8324 goto err_clkvote;
8325 }
8326
8327 status = vos_init_wiphy_from_nv_bin();
8328 if (!VOS_IS_STATUS_SUCCESS(status))
8329 {
8330 /* NV module cannot be initialized */
8331 hddLog( VOS_TRACE_LEVEL_FATAL,
8332 "%s: vos_init_wiphy failed", __func__);
8333 goto err_vos_nv_close;
8334 }
8335
Amar Singhala49cbc52013-10-08 18:37:44 -07008336#endif
8337
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308338 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 if ( !VOS_IS_STATUS_SUCCESS( status ))
8340 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008341 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308342 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 }
8344
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8346
8347 if ( NULL == pHddCtx->hHal )
8348 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008349 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008350 goto err_vosclose;
8351 }
8352
Mihir Shetee1093ba2014-01-21 20:13:32 +05308353#ifdef CONFIG_ENABLE_LINUX_REG
8354 /* registration of wiphy dev with cfg80211 */
8355 if (0 > wlan_hdd_cfg80211_register(wiphy))
8356 {
8357 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8358 goto err_vosclose;
8359 }
8360
8361 status = wlan_hdd_init_channels(pHddCtx);
8362 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8363 {
8364 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8365 __func__);
8366 goto err_wiphy_unregister;
8367 }
8368#endif
8369
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008370 status = vos_preStart( pHddCtx->pvosContext );
8371 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8372 {
8373 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308374 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008375 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008376
Arif Hussaineaf68602013-12-30 23:10:44 -08008377 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8378 {
8379 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8380 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8381 __func__, enable_dfs_chan_scan);
8382 }
8383 if (0 == enable_11d || 1 == enable_11d)
8384 {
8385 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8387 __func__, enable_11d);
8388 }
8389
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008390 /* Note that the vos_preStart() sequence triggers the cfg download.
8391 The cfg download must occur before we update the SME config
8392 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 status = hdd_set_sme_config( pHddCtx );
8394
8395 if ( VOS_STATUS_SUCCESS != status )
8396 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008397 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308398 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008399 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008400
8401 //Initialize the WMM module
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07008402 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
8403 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 if (!VOS_IS_STATUS_SUCCESS(status))
8405 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008406 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308407 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 }
8409
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 /* In the integrated architecture we update the configuration from
8411 the INI file and from NV before vOSS has been started so that
8412 the final contents are available to send down to the cCPU */
8413
8414 // Apply the cfg.ini to cfg.dat
8415 if (FALSE == hdd_update_config_dat(pHddCtx))
8416 {
8417 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308418 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 }
8420
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308421 // Get mac addr from platform driver
8422 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8423
8424 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308426 /* Store the mac addr for first interface */
8427 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8428
8429 hddLog(VOS_TRACE_LEVEL_ERROR,
8430 "%s: WLAN Mac Addr: "
8431 MAC_ADDRESS_STR, __func__,
8432 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8433
8434 /* Here, passing Arg2 as 1 because we do not want to change the
8435 last 3 bytes (means non OUI bytes) of first interface mac
8436 addr.
8437 */
8438 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8439 {
8440 hddLog(VOS_TRACE_LEVEL_ERROR,
8441 "%s: Failed to generate wlan interface mac addr "
8442 "using MAC from ini file ", __func__);
8443 }
8444 }
8445 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8446 {
8447 // Apply the NV to cfg.dat
8448 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008449#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8450 /* There was not a valid set of MAC Addresses in NV. See if the
8451 default addresses were modified by the cfg.ini settings. If so,
8452 we'll use them, but if not, we'll autogenerate a set of MAC
8453 addresses based upon the device serial number */
8454
8455 static const v_MACADDR_t default_address =
8456 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008457
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308458 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8459 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 {
8461 /* cfg.ini has the default address, invoke autogen logic */
8462
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308463 /* Here, passing Arg2 as 0 because we want to change the
8464 last 3 bytes (means non OUI bytes) of all the interfaces
8465 mac addr.
8466 */
8467 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8468 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308470 hddLog(VOS_TRACE_LEVEL_ERROR,
8471 "%s: Failed to generate wlan interface mac addr "
8472 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8473 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 }
8476 else
8477#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8478 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008479 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 "%s: Invalid MAC address in NV, using MAC from ini file "
8481 MAC_ADDRESS_STR, __func__,
8482 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8483 }
8484 }
8485 {
8486 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308487
8488 /* Set the MAC Address Currently this is used by HAL to
8489 * add self sta. Remove this once self sta is added as
8490 * part of session open.
8491 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8493 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8494 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308495
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 if (!HAL_STATUS_SUCCESS( halStatus ))
8497 {
8498 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8499 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308500 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 }
8502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008503
8504 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8505 Note: Firmware image will be read and downloaded inside vos_start API */
8506 status = vos_start( pHddCtx->pvosContext );
8507 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8508 {
8509 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308510 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008511 }
8512
Leo Chang6cec3e22014-01-21 15:33:49 -08008513#ifdef FEATURE_WLAN_CH_AVOID
8514 /* Plug in avoid channel notification callback
8515 * This should happen before ADD_SELF_STA
8516 * FW will send first IND with ADD_SELF_STA REQ from host */
8517 sme_AddChAvoidCallback(pHddCtx->hHal,
8518 hdd_hostapd_ch_avoid_cb);
8519#endif /* FEATURE_WLAN_CH_AVOID */
8520
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008521 /* Exchange capability info between Host and FW and also get versioning info from FW */
8522 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008523
8524 status = hdd_post_voss_start_config( pHddCtx );
8525 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8526 {
8527 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8528 __func__);
8529 goto err_vosstop;
8530 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008531
8532#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308533 wlan_hdd_cfg80211_update_reg_info( wiphy );
8534
8535 /* registration of wiphy dev with cfg80211 */
8536 if (0 > wlan_hdd_cfg80211_register(wiphy))
8537 {
8538 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8539 goto err_vosstop;
8540 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008541#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008542
Jeff Johnson295189b2012-06-20 16:38:30 -07008543 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8544 {
8545 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8546 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8547 }
8548 else
8549 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8551 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8552 if (pAdapter != NULL)
8553 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308554 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308556 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8557 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8558 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008559
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308560 /* Generate the P2P Device Address. This consists of the device's
8561 * primary MAC address with the locally administered bit set.
8562 */
8563 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008564 }
8565 else
8566 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308567 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8568 if (p2p_dev_addr != NULL)
8569 {
8570 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8571 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8572 }
8573 else
8574 {
8575 hddLog(VOS_TRACE_LEVEL_FATAL,
8576 "%s: Failed to allocate mac_address for p2p_device",
8577 __func__);
8578 goto err_close_adapter;
8579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008581
8582 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8583 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8584 if ( NULL == pP2pAdapter )
8585 {
8586 hddLog(VOS_TRACE_LEVEL_FATAL,
8587 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008588 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008589 goto err_close_adapter;
8590 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008593
8594 if( pAdapter == NULL )
8595 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8597 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008599
Arif Hussain66559122013-11-21 10:11:40 -08008600 if (country_code)
8601 {
8602 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008603 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008604 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8605#ifndef CONFIG_ENABLE_LINUX_REG
8606 hdd_checkandupdate_phymode(pAdapter, country_code);
8607#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008608 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8609 (void *)(tSmeChangeCountryCallback)
8610 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008611 country_code,
8612 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308613 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008614 if (eHAL_STATUS_SUCCESS == ret)
8615 {
Arif Hussaincb607082013-12-20 11:57:42 -08008616 ret = wait_for_completion_interruptible_timeout(
8617 &pAdapter->change_country_code,
8618 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8619
8620 if (0 >= ret)
8621 {
8622 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8623 "%s: SME while setting country code timed out", __func__);
8624 }
Arif Hussain66559122013-11-21 10:11:40 -08008625 }
8626 else
8627 {
Arif Hussaincb607082013-12-20 11:57:42 -08008628 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8629 "%s: SME Change Country code from module param fail ret=%d",
8630 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008631 }
8632 }
8633
Jeff Johnson295189b2012-06-20 16:38:30 -07008634#ifdef WLAN_BTAMP_FEATURE
8635 vStatus = WLANBAP_Open(pVosContext);
8636 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8637 {
8638 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8639 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008640 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008641 }
8642
8643 vStatus = BSL_Init(pVosContext);
8644 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8645 {
8646 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8647 "%s: Failed to Init BSL",__func__);
8648 goto err_bap_close;
8649 }
8650 vStatus = WLANBAP_Start(pVosContext);
8651 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8652 {
8653 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8654 "%s: Failed to start TL",__func__);
8655 goto err_bap_close;
8656 }
8657
8658 pConfig = pHddCtx->cfg_ini;
8659 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8660 status = WLANBAP_SetConfig(&btAmpConfig);
8661
8662#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008663
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008664#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8665 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8666 {
8667 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8668 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8669 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8670 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8671 }
8672#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008673#ifdef FEATURE_WLAN_SCAN_PNO
8674 /*SME must send channel update configuration to RIVA*/
8675 sme_UpdateChannelConfig(pHddCtx->hHal);
8676#endif
8677
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308678 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 /* Register with platform driver as client for Suspend/Resume */
8681 status = hddRegisterPmOps(pHddCtx);
8682 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8683 {
8684 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8685#ifdef WLAN_BTAMP_FEATURE
8686 goto err_bap_stop;
8687#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008688 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008689#endif //WLAN_BTAMP_FEATURE
8690 }
8691
Yue Ma0d4891e2013-08-06 17:01:45 -07008692 /* Open debugfs interface */
8693 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8694 {
8695 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8696 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008697 }
8698
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 /* Register TM level change handler function to the platform */
8700 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8701 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8702 {
8703 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8704 goto err_unregister_pmops;
8705 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008706
8707 /* register for riva power on lock to platform driver */
8708 if (req_riva_power_on_lock("wlan"))
8709 {
8710 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8711 __func__);
8712 goto err_unregister_pmops;
8713 }
8714
Jeff Johnson295189b2012-06-20 16:38:30 -07008715 // register net device notifier for device change notification
8716 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8717
8718 if(ret < 0)
8719 {
8720 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8721 goto err_free_power_on_lock;
8722 }
8723
8724 //Initialize the nlink service
8725 if(nl_srv_init() != 0)
8726 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308727 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 goto err_reg_netdev;
8729 }
8730
Leo Chang4ce1cc52013-10-21 18:27:15 -07008731#ifdef WLAN_KD_READY_NOTIFIER
8732 pHddCtx->kd_nl_init = 1;
8733#endif /* WLAN_KD_READY_NOTIFIER */
8734
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 //Initialize the BTC service
8736 if(btc_activate_service(pHddCtx) != 0)
8737 {
8738 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8739 goto err_nl_srv;
8740 }
8741
8742#ifdef PTT_SOCK_SVC_ENABLE
8743 //Initialize the PTT service
8744 if(ptt_sock_activate_svc(pHddCtx) != 0)
8745 {
8746 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8747 goto err_nl_srv;
8748 }
8749#endif
8750
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308751#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8752 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8753 {
8754 if(wlan_logging_sock_activate_svc(
8755 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8756 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8757 {
8758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8759 " failed", __func__);
8760 goto err_nl_srv;
8761 }
8762 }
8763#endif
8764
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008768 /* Action frame registered in one adapter which will
8769 * applicable to all interfaces
8770 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008771 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008773
8774 mutex_init(&pHddCtx->sap_lock);
8775
Mihir Shete18156292014-03-11 15:38:30 +05308776 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008777
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008778#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008779#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8780 /* Initialize the wake lcok */
8781 wake_lock_init(&pHddCtx->rx_wake_lock,
8782 WAKE_LOCK_SUSPEND,
8783 "qcom_rx_wakelock");
8784#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008785 /* Initialize the wake lcok */
8786 wake_lock_init(&pHddCtx->sap_wake_lock,
8787 WAKE_LOCK_SUSPEND,
8788 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008789#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008790
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008791 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8792 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008793
8794 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8795 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308796#ifndef CONFIG_ENABLE_LINUX_REG
8797 /*updating wiphy so that regulatory user hints can be processed*/
8798 if (wiphy)
8799 {
8800 regulatory_hint(wiphy, "00");
8801 }
8802#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008803 // Initialize the restart logic
8804 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308805
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008806 //Register the traffic monitor timer now
8807 if ( pHddCtx->cfg_ini->dynSplitscan)
8808 {
8809 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8810 VOS_TIMER_TYPE_SW,
8811 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8812 (void *)pHddCtx);
8813 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008814 goto success;
8815
8816err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008817#ifdef WLAN_KD_READY_NOTIFIER
8818 nl_srv_exit(pHddCtx->ptt_pid);
8819#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008821#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008822err_reg_netdev:
8823 unregister_netdevice_notifier(&hdd_netdev_notifier);
8824
8825err_free_power_on_lock:
8826 free_riva_power_on_lock("wlan");
8827
8828err_unregister_pmops:
8829 hddDevTmUnregisterNotifyCallback(pHddCtx);
8830 hddDeregisterPmOps(pHddCtx);
8831
Yue Ma0d4891e2013-08-06 17:01:45 -07008832 hdd_debugfs_exit(pHddCtx);
8833
Jeff Johnson295189b2012-06-20 16:38:30 -07008834#ifdef WLAN_BTAMP_FEATURE
8835err_bap_stop:
8836 WLANBAP_Stop(pVosContext);
8837#endif
8838
8839#ifdef WLAN_BTAMP_FEATURE
8840err_bap_close:
8841 WLANBAP_Close(pVosContext);
8842#endif
8843
Jeff Johnson295189b2012-06-20 16:38:30 -07008844err_close_adapter:
8845 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008846
8847#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308848 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008849#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008850
8851err_vosstop:
8852 vos_stop(pVosContext);
8853
Mihir Shetee1093ba2014-01-21 20:13:32 +05308854err_wiphy_unregister:
8855#ifdef CONFIG_ENABLE_LINUX_REG
8856 wiphy_unregister(wiphy);
8857#endif
8858
Amar Singhala49cbc52013-10-08 18:37:44 -07008859err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 status = vos_sched_close( pVosContext );
8861 if (!VOS_IS_STATUS_SUCCESS(status)) {
8862 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8863 "%s: Failed to close VOSS Scheduler", __func__);
8864 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8865 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008866 vos_close(pVosContext );
8867
Amar Singhal0a402232013-10-11 20:57:16 -07008868err_vos_nv_close:
8869
c_hpothue6a36282014-03-19 12:27:38 +05308870#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008871 vos_nv_close();
8872
Jeff Johnson295189b2012-06-20 16:38:30 -07008873err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05308874#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008875 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008876
8877err_wdclose:
8878 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8879 vos_watchdog_close(pVosContext);
8880
Jeff Johnson295189b2012-06-20 16:38:30 -07008881err_config:
8882 kfree(pHddCtx->cfg_ini);
8883 pHddCtx->cfg_ini= NULL;
8884
8885err_free_hdd_context:
8886 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 wiphy_free(wiphy) ;
8888 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008889 VOS_BUG(1);
8890
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08008891 if (hdd_is_ssr_required())
8892 {
8893 /* WDI timeout had happened during load, so SSR is needed here */
8894 subsystem_restart("wcnss");
8895 msleep(5000);
8896 }
8897 hdd_set_ssr_required (VOS_FALSE);
8898
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008899 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008900
8901success:
8902 EXIT();
8903 return 0;
8904}
8905
8906/**---------------------------------------------------------------------------
8907
Jeff Johnson32d95a32012-09-10 13:15:23 -07008908 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07008909
Jeff Johnson32d95a32012-09-10 13:15:23 -07008910 This is the driver entry point - called in different timeline depending
8911 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07008912
8913 \param - None
8914
8915 \return - 0 for success, non zero for failure
8916
8917 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07008918static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008919{
8920 VOS_STATUS status;
8921 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 struct device *dev = NULL;
8923 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008924#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8925 int max_retries = 0;
8926#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008927
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308928#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8929 vos_wconn_trace_init();
8930#endif
8931
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 ENTER();
8933
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008934#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07008936#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008937
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308938 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
8940 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
8941
8942 //Power Up Libra WLAN card first if not already powered up
8943 status = vos_chipPowerUp(NULL,NULL,NULL);
8944 if (!VOS_IS_STATUS_SUCCESS(status))
8945 {
8946 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
8947 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308948#ifdef WLAN_OPEN_SOURCE
8949 wake_lock_destroy(&wlan_wake_lock);
8950#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008951 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008952 }
8953
Jeff Johnson295189b2012-06-20 16:38:30 -07008954#ifdef ANI_BUS_TYPE_PCI
8955
8956 dev = wcnss_wlan_get_device();
8957
8958#endif // ANI_BUS_TYPE_PCI
8959
8960#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008961
8962#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8963 /* wait until WCNSS driver downloads NV */
8964 while (!wcnss_device_ready() && 5 >= ++max_retries) {
8965 msleep(1000);
8966 }
8967 if (max_retries >= 5) {
8968 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308969#ifdef WLAN_OPEN_SOURCE
8970 wake_lock_destroy(&wlan_wake_lock);
8971#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008972 return -ENODEV;
8973 }
8974#endif
8975
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 dev = wcnss_wlan_get_device();
8977#endif // ANI_BUS_TYPE_PLATFORM
8978
8979
8980 do {
8981 if (NULL == dev) {
8982 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
8983 ret_status = -1;
8984 break;
8985 }
8986
Jeff Johnson295189b2012-06-20 16:38:30 -07008987#ifdef TIMER_MANAGER
8988 vos_timer_manager_init();
8989#endif
8990
8991 /* Preopen VOSS so that it is ready to start at least SAL */
8992 status = vos_preOpen(&pVosContext);
8993
8994 if (!VOS_IS_STATUS_SUCCESS(status))
8995 {
8996 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
8997 ret_status = -1;
8998 break;
8999 }
9000
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009001#ifndef MODULE
9002 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9003 */
9004 hdd_set_conparam((v_UINT_t)con_mode);
9005#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009006
9007 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009008 if (hdd_wlan_startup(dev))
9009 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009011 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 vos_preClose( &pVosContext );
9013 ret_status = -1;
9014 break;
9015 }
9016
9017 /* Cancel the vote for XO Core ON
9018 * This is done here for safety purposes in case we re-initialize without turning
9019 * it OFF in any error scenario.
9020 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009021 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009023 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9025 {
9026 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009027 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 }
9029 } while (0);
9030
9031 if (0 != ret_status)
9032 {
9033 //Assert Deep sleep signal now to put Libra HW in lowest power state
9034 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9035 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9036
9037 //Vote off any PMIC voltage supplies
9038 vos_chipPowerDown(NULL, NULL, NULL);
9039#ifdef TIMER_MANAGER
9040 vos_timer_exit();
9041#endif
9042#ifdef MEMORY_DEBUG
9043 vos_mem_exit();
9044#endif
9045
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009046#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009048#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9050 }
9051 else
9052 {
9053 //Send WLAN UP indication to Nlink Service
9054 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9055
9056 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 }
9058
9059 EXIT();
9060
9061 return ret_status;
9062}
9063
Jeff Johnson32d95a32012-09-10 13:15:23 -07009064/**---------------------------------------------------------------------------
9065
9066 \brief hdd_module_init() - Init Function
9067
9068 This is the driver entry point (invoked when module is loaded using insmod)
9069
9070 \param - None
9071
9072 \return - 0 for success, non zero for failure
9073
9074 --------------------------------------------------------------------------*/
9075#ifdef MODULE
9076static int __init hdd_module_init ( void)
9077{
9078 return hdd_driver_init();
9079}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009080#else /* #ifdef MODULE */
9081static int __init hdd_module_init ( void)
9082{
9083 /* Driver initialization is delayed to fwpath_changed_handler */
9084 return 0;
9085}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009086#endif /* #ifdef MODULE */
9087
Jeff Johnson295189b2012-06-20 16:38:30 -07009088
9089/**---------------------------------------------------------------------------
9090
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009091 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009092
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009093 This is the driver exit point (invoked when module is unloaded using rmmod
9094 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009095
9096 \param - None
9097
9098 \return - None
9099
9100 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009101static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009102{
9103 hdd_context_t *pHddCtx = NULL;
9104 v_CONTEXT_t pVosContext = NULL;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309105 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009106
9107 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9108
9109 //Get the global vos context
9110 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9111
9112 if(!pVosContext)
9113 {
9114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9115 goto done;
9116 }
9117
9118 //Get the HDD context.
9119 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9120
9121 if(!pHddCtx)
9122 {
9123 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9124 }
9125 else
9126 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309127 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9128
9129 if (pHddCtx->isLogpInProgress)
9130 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309132 "%s:SSR in Progress; block rmmod !!!", __func__);
9133 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9134 msecs_to_jiffies(30000));
9135 if(!rc)
9136 {
9137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9138 "%s:SSR timedout, fatal error", __func__);
9139 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009140 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309141 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009142
Mihir Shete18156292014-03-11 15:38:30 +05309143 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9145
9146 //Do all the cleanup before deregistering the driver
9147 hdd_wlan_exit(pHddCtx);
9148 }
9149
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 vos_preClose( &pVosContext );
9151
9152#ifdef TIMER_MANAGER
9153 vos_timer_exit();
9154#endif
9155#ifdef MEMORY_DEBUG
9156 vos_mem_exit();
9157#endif
9158
Gopichand Nakkalad0774962013-05-24 11:32:21 +05309159#ifdef WCONN_TRACE_KMSG_LOG_BUFF
9160 vos_wconn_trace_exit();
9161#endif
9162
Jeff Johnson295189b2012-06-20 16:38:30 -07009163done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009164#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009166#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9168}
9169
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009170/**---------------------------------------------------------------------------
9171
9172 \brief hdd_module_exit() - Exit function
9173
9174 This is the driver exit point (invoked when module is unloaded using rmmod)
9175
9176 \param - None
9177
9178 \return - None
9179
9180 --------------------------------------------------------------------------*/
9181static void __exit hdd_module_exit(void)
9182{
9183 hdd_driver_exit();
9184}
9185
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009186#ifdef MODULE
9187static int fwpath_changed_handler(const char *kmessage,
9188 struct kernel_param *kp)
9189{
Jeff Johnson76052702013-04-16 13:55:05 -07009190 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009191}
9192
9193static int con_mode_handler(const char *kmessage,
9194 struct kernel_param *kp)
9195{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009196 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009197}
9198#else /* #ifdef MODULE */
9199/**---------------------------------------------------------------------------
9200
Jeff Johnson76052702013-04-16 13:55:05 -07009201 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009202
Jeff Johnson76052702013-04-16 13:55:05 -07009203 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009204 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009205 - invoked when module parameter fwpath is modified from userspace to signal
9206 initializing the WLAN driver or when con_mode is modified from userspace
9207 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009208
9209 \return - 0 for success, non zero for failure
9210
9211 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009212static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009213{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009214 int ret_status;
9215
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009216 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009217 ret_status = hdd_driver_init();
9218 wlan_hdd_inited = ret_status ? 0 : 1;
9219 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009220 }
9221
9222 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009223
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009224 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009225
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009226 ret_status = hdd_driver_init();
9227 wlan_hdd_inited = ret_status ? 0 : 1;
9228 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009229}
9230
Jeff Johnson295189b2012-06-20 16:38:30 -07009231/**---------------------------------------------------------------------------
9232
Jeff Johnson76052702013-04-16 13:55:05 -07009233 \brief fwpath_changed_handler() - Handler Function
9234
9235 Handle changes to the fwpath parameter
9236
9237 \return - 0 for success, non zero for failure
9238
9239 --------------------------------------------------------------------------*/
9240static int fwpath_changed_handler(const char *kmessage,
9241 struct kernel_param *kp)
9242{
9243 int ret;
9244
9245 ret = param_set_copystring(kmessage, kp);
9246 if (0 == ret)
9247 ret = kickstart_driver();
9248 return ret;
9249}
9250
9251/**---------------------------------------------------------------------------
9252
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009253 \brief con_mode_handler() -
9254
9255 Handler function for module param con_mode when it is changed by userspace
9256 Dynamically linked - do nothing
9257 Statically linked - exit and init driver, as in rmmod and insmod
9258
Jeff Johnson76052702013-04-16 13:55:05 -07009259 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009260
Jeff Johnson76052702013-04-16 13:55:05 -07009261 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009262
9263 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009264static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009265{
Jeff Johnson76052702013-04-16 13:55:05 -07009266 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009267
Jeff Johnson76052702013-04-16 13:55:05 -07009268 ret = param_set_int(kmessage, kp);
9269 if (0 == ret)
9270 ret = kickstart_driver();
9271 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009272}
9273#endif /* #ifdef MODULE */
9274
9275/**---------------------------------------------------------------------------
9276
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 \brief hdd_get_conparam() -
9278
9279 This is the driver exit point (invoked when module is unloaded using rmmod)
9280
9281 \param - None
9282
9283 \return - tVOS_CON_MODE
9284
9285 --------------------------------------------------------------------------*/
9286tVOS_CON_MODE hdd_get_conparam ( void )
9287{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009288#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009290#else
9291 return (tVOS_CON_MODE)curr_con_mode;
9292#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009293}
9294void hdd_set_conparam ( v_UINT_t newParam )
9295{
9296 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009297#ifndef MODULE
9298 curr_con_mode = con_mode;
9299#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009300}
9301/**---------------------------------------------------------------------------
9302
9303 \brief hdd_softap_sta_deauth() - function
9304
9305 This to take counter measure to handle deauth req from HDD
9306
9307 \param - pAdapter - Pointer to the HDD
9308
9309 \param - enable - boolean value
9310
9311 \return - None
9312
9313 --------------------------------------------------------------------------*/
9314
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009315VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009316{
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009318 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009319
9320 ENTER();
9321
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009322 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9323 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009324
9325 //Ignore request to deauth bcmc station
9326 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009327 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009328
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009329 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009330
9331 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009332 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009333}
9334
9335/**---------------------------------------------------------------------------
9336
9337 \brief hdd_softap_sta_disassoc() - function
9338
9339 This to take counter measure to handle deauth req from HDD
9340
9341 \param - pAdapter - Pointer to the HDD
9342
9343 \param - enable - boolean value
9344
9345 \return - None
9346
9347 --------------------------------------------------------------------------*/
9348
9349void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9350{
9351 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9352
9353 ENTER();
9354
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309355 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009356
9357 //Ignore request to disassoc bcmc station
9358 if( pDestMacAddress[0] & 0x1 )
9359 return;
9360
9361 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9362}
9363
9364void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9365{
9366 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9367
9368 ENTER();
9369
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309370 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009371
9372 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9373}
9374
Jeff Johnson295189b2012-06-20 16:38:30 -07009375/**---------------------------------------------------------------------------
9376 *
9377 * \brief hdd_get__concurrency_mode() -
9378 *
9379 *
9380 * \param - None
9381 *
9382 * \return - CONCURRENCY MODE
9383 *
9384 * --------------------------------------------------------------------------*/
9385tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9386{
9387 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9388 hdd_context_t *pHddCtx;
9389
9390 if (NULL != pVosContext)
9391 {
9392 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9393 if (NULL != pHddCtx)
9394 {
9395 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9396 }
9397 }
9398
9399 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009400 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 return VOS_STA;
9402}
9403
9404/* Decide whether to allow/not the apps power collapse.
9405 * Allow apps power collapse if we are in connected state.
9406 * if not, allow only if we are in IMPS */
9407v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9408{
9409 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009410 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009411 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9413 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9414 hdd_adapter_t *pAdapter = NULL;
9415 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009416 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009417
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9419 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420
Yathish9f22e662012-12-10 14:21:35 -08009421 concurrent_state = hdd_get_concurrency_mode();
9422
9423#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9424 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9425 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9426 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9427 return TRUE;
9428#endif
9429
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 /*loop through all adapters. TBD fix for Concurrency */
9431 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9432 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9433 {
9434 pAdapter = pAdapterNode->pAdapter;
9435 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9436 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9437 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009438 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009440 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009441 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9442 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009444 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009445 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9446 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 return FALSE;
9448 }
9449 }
9450 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9451 pAdapterNode = pNext;
9452 }
9453 return TRUE;
9454}
9455
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009456/* Decides whether to send suspend notification to Riva
9457 * if any adapter is in BMPS; then it is required */
9458v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9459{
9460 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9461 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9462
9463 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9464 {
9465 return TRUE;
9466 }
9467 return FALSE;
9468}
9469
Jeff Johnson295189b2012-06-20 16:38:30 -07009470void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9471{
9472 switch(mode)
9473 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009474 case VOS_STA_MODE:
9475 case VOS_P2P_CLIENT_MODE:
9476 case VOS_P2P_GO_MODE:
9477 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009478 pHddCtx->concurrency_mode |= (1 << mode);
9479 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 break;
9481 default:
9482 break;
9483
9484 }
9485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9486 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9487}
9488
9489
9490void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9491{
9492 switch(mode)
9493 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009494 case VOS_STA_MODE:
9495 case VOS_P2P_CLIENT_MODE:
9496 case VOS_P2P_GO_MODE:
9497 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 pHddCtx->no_of_sessions[mode]--;
9499 if (!(pHddCtx->no_of_sessions[mode]))
9500 pHddCtx->concurrency_mode &= (~(1 << mode));
9501 break;
9502 default:
9503 break;
9504 }
9505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9506 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9507}
9508
Jeff Johnsone7245742012-09-05 17:12:55 -07009509/**---------------------------------------------------------------------------
9510 *
9511 * \brief wlan_hdd_restart_init
9512 *
9513 * This function initalizes restart timer/flag. An internal function.
9514 *
9515 * \param - pHddCtx
9516 *
9517 * \return - None
9518 *
9519 * --------------------------------------------------------------------------*/
9520
9521static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9522{
9523 /* Initialize */
9524 pHddCtx->hdd_restart_retries = 0;
9525 atomic_set(&pHddCtx->isRestartInProgress, 0);
9526 vos_timer_init(&pHddCtx->hdd_restart_timer,
9527 VOS_TIMER_TYPE_SW,
9528 wlan_hdd_restart_timer_cb,
9529 pHddCtx);
9530}
9531/**---------------------------------------------------------------------------
9532 *
9533 * \brief wlan_hdd_restart_deinit
9534 *
9535 * This function cleans up the resources used. An internal function.
9536 *
9537 * \param - pHddCtx
9538 *
9539 * \return - None
9540 *
9541 * --------------------------------------------------------------------------*/
9542
9543static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9544{
9545
9546 VOS_STATUS vos_status;
9547 /* Block any further calls */
9548 atomic_set(&pHddCtx->isRestartInProgress, 1);
9549 /* Cleanup */
9550 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9551 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309552 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009553 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9554 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309555 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009556
9557}
9558
9559/**---------------------------------------------------------------------------
9560 *
9561 * \brief wlan_hdd_framework_restart
9562 *
9563 * This function uses a cfg80211 API to start a framework initiated WLAN
9564 * driver module unload/load.
9565 *
9566 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9567 *
9568 *
9569 * \param - pHddCtx
9570 *
9571 * \return - VOS_STATUS_SUCCESS: Success
9572 * VOS_STATUS_E_EMPTY: Adapter is Empty
9573 * VOS_STATUS_E_NOMEM: No memory
9574
9575 * --------------------------------------------------------------------------*/
9576
9577static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9578{
9579 VOS_STATUS status = VOS_STATUS_SUCCESS;
9580 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009581 int len = (sizeof (struct ieee80211_mgmt));
9582 struct ieee80211_mgmt *mgmt = NULL;
9583
9584 /* Prepare the DEAUTH managment frame with reason code */
9585 mgmt = kzalloc(len, GFP_KERNEL);
9586 if(mgmt == NULL)
9587 {
9588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9589 "%s: memory allocation failed (%d bytes)", __func__, len);
9590 return VOS_STATUS_E_NOMEM;
9591 }
9592 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009593
9594 /* Iterate over all adapters/devices */
9595 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9596 do
9597 {
9598 if( (status == VOS_STATUS_SUCCESS) &&
9599 pAdapterNode &&
9600 pAdapterNode->pAdapter)
9601 {
9602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9603 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9604 pAdapterNode->pAdapter->dev->name,
9605 pAdapterNode->pAdapter->device_mode,
9606 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009607 /*
9608 * CFG80211 event to restart the driver
9609 *
9610 * 'cfg80211_send_unprot_deauth' sends a
9611 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9612 * of SME(Linux Kernel) state machine.
9613 *
9614 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9615 * the driver.
9616 *
9617 */
9618
9619 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009620 }
9621 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9622 pAdapterNode = pNext;
9623 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9624
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009625
9626 /* Free the allocated management frame */
9627 kfree(mgmt);
9628
Jeff Johnsone7245742012-09-05 17:12:55 -07009629 /* Retry until we unload or reach max count */
9630 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9631 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9632
9633 return status;
9634
9635}
9636/**---------------------------------------------------------------------------
9637 *
9638 * \brief wlan_hdd_restart_timer_cb
9639 *
9640 * Restart timer callback. An internal function.
9641 *
9642 * \param - User data:
9643 *
9644 * \return - None
9645 *
9646 * --------------------------------------------------------------------------*/
9647
9648void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9649{
9650 hdd_context_t *pHddCtx = usrDataForCallback;
9651 wlan_hdd_framework_restart(pHddCtx);
9652 return;
9653
9654}
9655
9656
9657/**---------------------------------------------------------------------------
9658 *
9659 * \brief wlan_hdd_restart_driver
9660 *
9661 * This function sends an event to supplicant to restart the WLAN driver.
9662 *
9663 * This function is called from vos_wlanRestart.
9664 *
9665 * \param - pHddCtx
9666 *
9667 * \return - VOS_STATUS_SUCCESS: Success
9668 * VOS_STATUS_E_EMPTY: Adapter is Empty
9669 * VOS_STATUS_E_ALREADY: Request already in progress
9670
9671 * --------------------------------------------------------------------------*/
9672VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9673{
9674 VOS_STATUS status = VOS_STATUS_SUCCESS;
9675
9676 /* A tight check to make sure reentrancy */
9677 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9678 {
9679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9680 "%s: WLAN restart is already in progress", __func__);
9681
9682 return VOS_STATUS_E_ALREADY;
9683 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009684 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009685#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009686 wcnss_reset_intr();
9687#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009688
Jeff Johnsone7245742012-09-05 17:12:55 -07009689 return status;
9690}
9691
Mihir Shetee1093ba2014-01-21 20:13:32 +05309692/**---------------------------------------------------------------------------
9693 *
9694 * \brief wlan_hdd_init_channels
9695 *
9696 * This function is used to initialize the channel list in CSR
9697 *
9698 * This function is called from hdd_wlan_startup
9699 *
9700 * \param - pHddCtx: HDD context
9701 *
9702 * \return - VOS_STATUS_SUCCESS: Success
9703 * VOS_STATUS_E_FAULT: Failure reported by SME
9704
9705 * --------------------------------------------------------------------------*/
9706static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9707{
9708 eHalStatus status;
9709
9710 status = sme_InitChannels(pHddCtx->hHal);
9711 if (HAL_STATUS_SUCCESS(status))
9712 {
9713 return VOS_STATUS_SUCCESS;
9714 }
9715 else
9716 {
9717 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9718 __func__, status);
9719 return VOS_STATUS_E_FAULT;
9720 }
9721}
9722
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009723/*
9724 * API to find if there is any STA or P2P-Client is connected
9725 */
9726VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9727{
9728 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9729}
Jeff Johnsone7245742012-09-05 17:12:55 -07009730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731//Register the module init/exit functions
9732module_init(hdd_module_init);
9733module_exit(hdd_module_exit);
9734
9735MODULE_LICENSE("Dual BSD/GPL");
9736MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9737MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9738
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009739module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9740 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009741
Jeff Johnson76052702013-04-16 13:55:05 -07009742module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009743 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009744
9745module_param(enable_dfs_chan_scan, int,
9746 S_IRUSR | S_IRGRP | S_IROTH);
9747
9748module_param(enable_11d, int,
9749 S_IRUSR | S_IRGRP | S_IROTH);
9750
9751module_param(country_code, charp,
9752 S_IRUSR | S_IRGRP | S_IROTH);