blob: 102a8e2bf806f7df6ca94c0e3bc14e88db65246c [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;
c_hpothu92367912014-05-01 15:18:17 +0530155static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800156
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700158static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700159#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700160
Jeff Johnsone7245742012-09-05 17:12:55 -0700161/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800162 * spinlock for synchronizing asynchronous request/response
163 * (full description of use in wlan_hdd_main.h)
164 */
165DEFINE_SPINLOCK(hdd_context_lock);
166
167/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700168 * The rate at which the driver sends RESTART event to supplicant
169 * once the function 'vos_wlanRestart()' is called
170 *
171 */
172#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
173#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700174
175/*
176 * Size of Driver command strings from upper layer
177 */
178#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
179#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
180
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700182#define TID_MIN_VALUE 0
183#define TID_MAX_VALUE 15
184static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
185 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800186static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
187 tCsrEseBeaconReq *pEseBcnReq);
188#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700189
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +0530190static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx);
Atul Mittal1d722422014-03-19 11:15:07 +0530191/*
192 * Maximum buffer size used for returning the data back to user space
193 */
194#define WLAN_MAX_BUF_SIZE 1024
195#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700196/*
197 * Driver miracast parameters 0-Disabled
198 * 1-Source, 2-Sink
199 */
200#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
201#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
202
c_hpothu92367912014-05-01 15:18:17 +0530203//wait time for beacon miss rate.
204#define BCN_MISS_RATE_TIME 500
205
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800206#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700207static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700210static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700211
212//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700213static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
214static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
215static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
216void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800217void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219v_U16_t hdd_select_queue(struct net_device *dev,
220 struct sk_buff *skb);
221
222#ifdef WLAN_FEATURE_PACKET_FILTERING
223static void hdd_set_multicast_list(struct net_device *dev);
224#endif
225
226void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
227
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800228#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800229void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
230static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700231static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
232 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
233 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700234static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
235 tANI_U8 *pTargetApBssid,
236 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800237#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800238#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700239VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800240#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700241
Mihir Shetee1093ba2014-01-21 20:13:32 +0530242static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530243const char * hdd_device_modetoString(v_U8_t device_mode)
244{
245 switch(device_mode)
246 {
247 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
248 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
250 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
251 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
252 CASE_RETURN_STRING( WLAN_HDD_FTM );
253 CASE_RETURN_STRING( WLAN_HDD_IBSS );
254 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
255 default:
256 return "device_mode Unknown";
257 }
258}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530259
Jeff Johnson295189b2012-06-20 16:38:30 -0700260static int hdd_netdev_notifier_call(struct notifier_block * nb,
261 unsigned long state,
262 void *ndev)
263{
264 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700266 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267#ifdef WLAN_BTAMP_FEATURE
268 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530270 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700271
272 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700274 (strncmp(dev->name, "p2p", 3)))
275 return NOTIFY_DONE;
276
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
Jeff Johnson27cee452013-03-27 11:10:24 -0700280 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 VOS_ASSERT(0);
284 return NOTIFY_DONE;
285 }
286
Jeff Johnson27cee452013-03-27 11:10:24 -0700287 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
288 if (NULL == pHddCtx)
289 {
290 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
291 VOS_ASSERT(0);
292 return NOTIFY_DONE;
293 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800294 if (pHddCtx->isLogpInProgress)
295 return NOTIFY_DONE;
296
Jeff Johnson27cee452013-03-27 11:10:24 -0700297
298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
299 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301 switch (state) {
302 case NETDEV_REGISTER:
303 break;
304
305 case NETDEV_UNREGISTER:
306 break;
307
308 case NETDEV_UP:
309 break;
310
311 case NETDEV_DOWN:
312 break;
313
314 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700315 if(TRUE == pAdapter->isLinkUpSvcNeeded)
316 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 break;
318
319 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530320 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530321 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530322 {
323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
324 "%s: Timeout occurred while waiting for abortscan %ld",
325 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327 else
328 {
329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530330 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 }
332#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 status = WLANBAP_StopAmp();
335 if(VOS_STATUS_SUCCESS != status )
336 {
337 pHddCtx->isAmpAllowed = VOS_TRUE;
338 hddLog(VOS_TRACE_LEVEL_FATAL,
339 "%s: Failed to stop AMP", __func__);
340 }
341 else
342 {
343 //a state m/c implementation in PAL is TBD to avoid this delay
344 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700345 if ( pHddCtx->isAmpAllowed )
346 {
347 WLANBAP_DeregisterFromHCI();
348 pHddCtx->isAmpAllowed = VOS_FALSE;
349 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 }
351#endif //WLAN_BTAMP_FEATURE
352 break;
353
354 default:
355 break;
356 }
357
358 return NOTIFY_DONE;
359}
360
361struct notifier_block hdd_netdev_notifier = {
362 .notifier_call = hdd_netdev_notifier_call,
363};
364
365/*---------------------------------------------------------------------------
366 * Function definitions
367 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700368void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
369void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700371static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700372#ifndef MODULE
373/* current con_mode - used only for statically linked driver
374 * con_mode is changed by userspace to indicate a mode change which will
375 * result in calling the module exit and init functions. The module
376 * exit function will clean up based on the value of con_mode prior to it
377 * being changed by userspace. So curr_con_mode records the current con_mode
378 * for exit when con_mode becomes the next mode for init
379 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700380static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700381#endif
382
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800383/**---------------------------------------------------------------------------
384
385 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
386
387 Called immediately after the cfg.ini is read in order to configure
388 the desired trace levels.
389
390 \param - moduleId - module whose trace level is being configured
391 \param - bitmask - bitmask of log levels to be enabled
392
393 \return - void
394
395 --------------------------------------------------------------------------*/
396static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
397{
398 wpt_tracelevel level;
399
400 /* if the bitmask is the default value, then a bitmask was not
401 specified in cfg.ini, so leave the logging level alone (it
402 will remain at the "compiled in" default value) */
403 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
404 {
405 return;
406 }
407
408 /* a mask was specified. start by disabling all logging */
409 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
410
411 /* now cycle through the bitmask until all "set" bits are serviced */
412 level = VOS_TRACE_LEVEL_FATAL;
413 while (0 != bitmask)
414 {
415 if (bitmask & 1)
416 {
417 vos_trace_setValue(moduleId, level, 1);
418 }
419 level++;
420 bitmask >>= 1;
421 }
422}
423
424
Jeff Johnson295189b2012-06-20 16:38:30 -0700425/**---------------------------------------------------------------------------
426
427 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
428
429 Called immediately after the cfg.ini is read in order to configure
430 the desired trace levels in the WDI.
431
432 \param - moduleId - module whose trace level is being configured
433 \param - bitmask - bitmask of log levels to be enabled
434
435 \return - void
436
437 --------------------------------------------------------------------------*/
438static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
439{
440 wpt_tracelevel level;
441
442 /* if the bitmask is the default value, then a bitmask was not
443 specified in cfg.ini, so leave the logging level alone (it
444 will remain at the "compiled in" default value) */
445 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
446 {
447 return;
448 }
449
450 /* a mask was specified. start by disabling all logging */
451 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
452
453 /* now cycle through the bitmask until all "set" bits are serviced */
454 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
455 while (0 != bitmask)
456 {
457 if (bitmask & 1)
458 {
459 wpalTraceSetLevel(moduleId, level, 1);
460 }
461 level++;
462 bitmask >>= 1;
463 }
464}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530466/*
467 * FUNCTION: wlan_hdd_validate_context
468 * This function is used to check the HDD context
469 */
470int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
471{
472 ENTER();
473
474 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
475 {
476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
477 "%s: HDD context is Null", __func__);
478 return -ENODEV;
479 }
480
481 if (pHddCtx->isLogpInProgress)
482 {
483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "%s: LOGP in Progress. Ignore!!!", __func__);
485 return -EAGAIN;
486 }
487
Mihir Shete18156292014-03-11 15:38:30 +0530488 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530489 {
490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
491 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
492 return -EAGAIN;
493 }
494 return 0;
495}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700496#ifdef CONFIG_ENABLE_LINUX_REG
497void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
498{
499 hdd_adapter_t *pAdapter = NULL;
500 hdd_station_ctx_t *pHddStaCtx = NULL;
501 eCsrPhyMode phyMode;
502 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530503
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700504 if (NULL == pHddCtx)
505 {
506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
507 "HDD Context is null !!");
508 return ;
509 }
510
511 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
512 if (NULL == pAdapter)
513 {
514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
515 "pAdapter is null !!");
516 return ;
517 }
518
519 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
520 if (NULL == pHddStaCtx)
521 {
522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
523 "pHddStaCtx is null !!");
524 return ;
525 }
526
527 cfg_param = pHddCtx->cfg_ini;
528 if (NULL == cfg_param)
529 {
530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
531 "cfg_params not available !!");
532 return ;
533 }
534
535 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
536
537 if (!pHddCtx->isVHT80Allowed)
538 {
539 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
540 (eCSR_DOT11_MODE_11ac == phyMode) ||
541 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
542 {
543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
544 "Setting phymode to 11n!!");
545 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
546 }
547 }
548 else
549 {
550 /*New country Supports 11ac as well resetting value back from .ini*/
551 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
552 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
553 return ;
554 }
555
556 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
557 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
558 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
559 {
560 VOS_STATUS vosStatus;
561
562 // need to issue a disconnect to CSR.
563 INIT_COMPLETION(pAdapter->disconnect_comp_var);
564 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
565 pAdapter->sessionId,
566 eCSR_DISCONNECT_REASON_UNSPECIFIED );
567
568 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530569 {
570 long ret;
571
572 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700573 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530574 if (0 >= ret)
575 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
576 ret);
577 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700578
579 }
580}
581#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530582void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
583{
584 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
585 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
586 hdd_config_t *cfg_param;
587 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530588 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589
590 if (NULL == pHddCtx)
591 {
592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
593 "HDD Context is null !!");
594 return ;
595 }
596
597 cfg_param = pHddCtx->cfg_ini;
598
599 if (NULL == cfg_param)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
602 "cfg_params not available !!");
603 return ;
604 }
605
606 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
607
608 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
609 {
610 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
611 (eCSR_DOT11_MODE_11ac == phyMode) ||
612 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
613 {
614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
615 "Setting phymode to 11n!!");
616 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
617 }
618 }
619 else
620 {
621 /*New country Supports 11ac as well resetting value back from .ini*/
622 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
623 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
624 return ;
625 }
626
627 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
628 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
629 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
630 {
631 VOS_STATUS vosStatus;
632
633 // need to issue a disconnect to CSR.
634 INIT_COMPLETION(pAdapter->disconnect_comp_var);
635 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
636 pAdapter->sessionId,
637 eCSR_DISCONNECT_REASON_UNSPECIFIED );
638
639 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530640 {
641 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530643 if (ret <= 0)
644 {
645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
646 "wait on disconnect_comp_var is failed %ld", ret);
647 }
648 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649
650 }
651}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700652#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530653
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700654void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
655{
656 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
657 hdd_config_t *cfg_param;
658
659 if (NULL == pHddCtx)
660 {
661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
662 "HDD Context is null !!");
663 return ;
664 }
665
666 cfg_param = pHddCtx->cfg_ini;
667
668 if (NULL == cfg_param)
669 {
670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
671 "cfg_params not available !!");
672 return ;
673 }
674
675 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
676 {
677 /*New country doesn't support DFS */
678 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
679 }
680 else
681 {
682 /*New country Supports DFS as well resetting value back from .ini*/
683 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
684 }
685
686}
687
Rajeev79dbe4c2013-10-05 11:03:42 +0530688#ifdef FEATURE_WLAN_BATCH_SCAN
689
690/**---------------------------------------------------------------------------
691
692 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
693 input string
694
695 This function extracts assigned integer from string in below format:
696 "STRING=10" : extracts integer 10 from this string
697
698 \param - pInPtr Pointer to input string
699 \param - base Base for string to int conversion(10 for decimal 16 for hex)
700 \param - pOutPtr Pointer to variable in which extracted integer needs to be
701 assigned
702 \param - pLastArg to tell whether it is last arguement in input string or
703 not
704
705 \return - NULL for failure cases
706 pointer to next arguement in input string for success cases
707 --------------------------------------------------------------------------*/
708static tANI_U8 *
709hdd_extract_assigned_int_from_str
710(
711 tANI_U8 *pInPtr,
712 tANI_U8 base,
713 tANI_U32 *pOutPtr,
714 tANI_U8 *pLastArg
715)
716{
717 int tempInt;
718 int v = 0;
719 char buf[32];
720 int val = 0;
721 *pLastArg = FALSE;
722
723 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
724 if (NULL == pInPtr)
725 {
726 return NULL;
727 }
728
729 pInPtr++;
730
731 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
732
733 val = sscanf(pInPtr, "%32s ", buf);
734 if (val < 0 && val > strlen(pInPtr))
735 {
736 return NULL;
737 }
738 pInPtr += val;
739 v = kstrtos32(buf, base, &tempInt);
740 if (v < 0)
741 {
742 return NULL;
743 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800744 if (tempInt < 0)
745 {
746 tempInt = 0;
747 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530748 *pOutPtr = tempInt;
749
750 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
751 if (NULL == pInPtr)
752 {
753 *pLastArg = TRUE;
754 return NULL;
755 }
756 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
757
758 return pInPtr;
759}
760
761/**---------------------------------------------------------------------------
762
763 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
764 input string
765
766 This function extracts assigned character from string in below format:
767 "STRING=A" : extracts char 'A' from this string
768
769 \param - pInPtr Pointer to input string
770 \param - pOutPtr Pointer to variable in which extracted char needs to be
771 assigned
772 \param - pLastArg to tell whether it is last arguement in input string or
773 not
774
775 \return - NULL for failure cases
776 pointer to next arguement in input string for success cases
777 --------------------------------------------------------------------------*/
778static tANI_U8 *
779hdd_extract_assigned_char_from_str
780(
781 tANI_U8 *pInPtr,
782 tANI_U8 *pOutPtr,
783 tANI_U8 *pLastArg
784)
785{
786 *pLastArg = FALSE;
787
788 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
789 if (NULL == pInPtr)
790 {
791 return NULL;
792 }
793
794 pInPtr++;
795
796 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
797
798 *pOutPtr = *pInPtr;
799
800 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
801 if (NULL == pInPtr)
802 {
803 *pLastArg = TRUE;
804 return NULL;
805 }
806 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
807
808 return pInPtr;
809}
810
811
812/**---------------------------------------------------------------------------
813
814 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
815
816 This function parses set batch scan command in below format:
817 WLS_BATCHING_SET <space> followed by below arguements
818 "SCANFREQ=XX" : Optional defaults to 30 sec
819 "MSCAN=XX" : Required number of scans to attempt to batch
820 "BESTN=XX" : Best Network (RSSI) defaults to 16
821 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
822 A. implies only 5 GHz , B. implies only 2.4GHz
823 "RTT=X" : optional defaults to 0
824 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
825 error
826
827 For example input commands:
828 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
829 translated into set batch scan with following parameters:
830 a) Frequence 60 seconds
831 b) Batch 10 scans together
832 c) Best RSSI to be 20
833 d) 5GHz band only
834 e) RTT is equal to 0
835
836 \param - pValue Pointer to input channel list
837 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
838
839 \return - 0 for success non-zero for failure
840
841 --------------------------------------------------------------------------*/
842static int
843hdd_parse_set_batchscan_command
844(
845 tANI_U8 *pValue,
846 tSirSetBatchScanReq *pHddSetBatchScanReq
847)
848{
849 tANI_U8 *inPtr = pValue;
850 tANI_U8 val = 0;
851 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800852 tANI_U32 nScanFreq;
853 tANI_U32 nMscan;
854 tANI_U32 nBestN;
855 tANI_U8 ucRfBand;
856 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800857 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530858
859 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
861 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
862 nRtt = 0;
863 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530864
865 /*go to space after WLS_BATCHING_SET command*/
866 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
867 /*no argument after the command*/
868 if (NULL == inPtr)
869 {
870 return -EINVAL;
871 }
872
873 /*no space after the command*/
874 else if (SPACE_ASCII_VALUE != *inPtr)
875 {
876 return -EINVAL;
877 }
878
879 /*removing empty spaces*/
880 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
881
882 /*no argument followed by spaces*/
883 if ('\0' == *inPtr)
884 {
885 return -EINVAL;
886 }
887
888 /*check and parse SCANFREQ*/
889 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
890 {
891 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800892 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800893
Rajeev Kumarc933d982013-11-18 20:04:20 -0800894 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800895 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800897 }
898
Rajeev79dbe4c2013-10-05 11:03:42 +0530899 if ( (NULL == inPtr) || (TRUE == lastArg))
900 {
901 return -EINVAL;
902 }
903 }
904
905 /*check and parse MSCAN*/
906 if ((strncmp(inPtr, "MSCAN", 5) == 0))
907 {
908 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800909 &nMscan, &lastArg);
910
911 if (0 == nMscan)
912 {
913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
914 "invalid MSCAN=%d", nMscan);
915 return -EINVAL;
916 }
917
Rajeev79dbe4c2013-10-05 11:03:42 +0530918 if (TRUE == lastArg)
919 {
920 goto done;
921 }
922 else if (NULL == inPtr)
923 {
924 return -EINVAL;
925 }
926 }
927 else
928 {
929 return -EINVAL;
930 }
931
932 /*check and parse BESTN*/
933 if ((strncmp(inPtr, "BESTN", 5) == 0))
934 {
935 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800936 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800937
Rajeev Kumarc933d982013-11-18 20:04:20 -0800938 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800939 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800940 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800941 }
942
Rajeev79dbe4c2013-10-05 11:03:42 +0530943 if (TRUE == lastArg)
944 {
945 goto done;
946 }
947 else if (NULL == inPtr)
948 {
949 return -EINVAL;
950 }
951 }
952
953 /*check and parse CHANNEL*/
954 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
955 {
956 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800957
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 if (('A' == val) || ('a' == val))
959 {
c_hpothuebf89732014-02-25 13:00:24 +0530960 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530961 }
962 else if (('B' == val) || ('b' == val))
963 {
c_hpothuebf89732014-02-25 13:00:24 +0530964 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530965 }
966 else
967 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800968 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
969 }
970
971 if (TRUE == lastArg)
972 {
973 goto done;
974 }
975 else if (NULL == inPtr)
976 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530977 return -EINVAL;
978 }
979 }
980
981 /*check and parse RTT*/
982 if ((strncmp(inPtr, "RTT", 3) == 0))
983 {
984 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800985 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530986 if (TRUE == lastArg)
987 {
988 goto done;
989 }
990 if (NULL == inPtr)
991 {
992 return -EINVAL;
993 }
994 }
995
996
997done:
998
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800999 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1000 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1001 pHddSetBatchScanReq->bestNetwork = nBestN;
1002 pHddSetBatchScanReq->rfBand = ucRfBand;
1003 pHddSetBatchScanReq->rtt = nRtt;
1004
Rajeev79dbe4c2013-10-05 11:03:42 +05301005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1006 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1007 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1008 pHddSetBatchScanReq->scanFrequency,
1009 pHddSetBatchScanReq->numberOfScansToBatch,
1010 pHddSetBatchScanReq->bestNetwork,
1011 pHddSetBatchScanReq->rfBand,
1012 pHddSetBatchScanReq->rtt);
1013
1014 return 0;
1015}/*End of hdd_parse_set_batchscan_command*/
1016
1017/**---------------------------------------------------------------------------
1018
1019 \brief hdd_set_batch_scan_req_callback () - This function is called after
1020 receiving set batch scan response from FW and it saves set batch scan
1021 response data FW to HDD context and sets the completion event on
1022 which hdd_ioctl is waiting
1023
1024 \param - callbackContext Pointer to HDD adapter
1025 \param - pRsp Pointer to set batch scan response data received from FW
1026
1027 \return - nothing
1028
1029 --------------------------------------------------------------------------*/
1030static void hdd_set_batch_scan_req_callback
1031(
1032 void *callbackContext,
1033 tSirSetBatchScanRsp *pRsp
1034)
1035{
1036 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1037 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1038
1039 /*sanity check*/
1040 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1041 {
1042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1043 "%s: Invalid pAdapter magic", __func__);
1044 VOS_ASSERT(0);
1045 return;
1046 }
1047 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1048
1049 /*save set batch scan response*/
1050 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1051
1052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1053 "Received set batch scan rsp from FW with nScansToBatch=%d",
1054 pHddSetBatchScanRsp->nScansToBatch);
1055
1056 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1057 complete(&pAdapter->hdd_set_batch_scan_req_var);
1058
1059 return;
1060}/*End of hdd_set_batch_scan_req_callback*/
1061
1062
1063/**---------------------------------------------------------------------------
1064
1065 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1066 info in hdd batch scan response queue
1067
1068 \param - pAdapter Pointer to hdd adapter
1069 \param - pAPMetaInfo Pointer to access point meta info
1070 \param - scanId scan ID of batch scan response
1071 \param - isLastAp tells whether AP is last AP in batch scan response or not
1072
1073 \return - nothing
1074
1075 --------------------------------------------------------------------------*/
1076static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1077 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1078{
1079 tHddBatchScanRsp *pHead;
1080 tHddBatchScanRsp *pNode;
1081 tHddBatchScanRsp *pPrev;
1082 tHddBatchScanRsp *pTemp;
1083 tANI_U8 ssidLen;
1084
1085 /*head of hdd batch scan response queue*/
1086 pHead = pAdapter->pBatchScanRsp;
1087
1088 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1089 if (NULL == pNode)
1090 {
1091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1092 "%s: Could not allocate memory", __func__);
1093 VOS_ASSERT(0);
1094 return;
1095 }
1096
1097 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1098 sizeof(pNode->ApInfo.bssid));
1099 ssidLen = strlen(pApMetaInfo->ssid);
1100 if (SIR_MAX_SSID_SIZE < ssidLen)
1101 {
1102 /*invalid scan result*/
1103 vos_mem_free(pNode);
1104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1105 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1106 return;
1107 }
1108 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1109 /*null terminate ssid*/
1110 pNode->ApInfo.ssid[ssidLen] = '\0';
1111 pNode->ApInfo.ch = pApMetaInfo->ch;
1112 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1113 pNode->ApInfo.age = pApMetaInfo->timestamp;
1114 pNode->ApInfo.batchId = scanId;
1115 pNode->ApInfo.isLastAp = isLastAp;
1116
1117 pNode->pNext = NULL;
1118 if (NULL == pHead)
1119 {
1120 pAdapter->pBatchScanRsp = pNode;
1121 }
1122 else
1123 {
1124 pTemp = pHead;
1125 while (NULL != pTemp)
1126 {
1127 pPrev = pTemp;
1128 pTemp = pTemp->pNext;
1129 }
1130 pPrev->pNext = pNode;
1131 }
1132
1133 return;
1134}/*End of hdd_populate_batch_scan_rsp_queue*/
1135
1136/**---------------------------------------------------------------------------
1137
1138 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1139 receiving batch scan response indication from FW. It saves get batch scan
1140 response data in HDD batch scan response queue. This callback sets the
1141 completion event on which hdd_ioctl is waiting only after getting complete
1142 batch scan response data from FW
1143
1144 \param - callbackContext Pointer to HDD adapter
1145 \param - pRsp Pointer to get batch scan response data received from FW
1146
1147 \return - nothing
1148
1149 --------------------------------------------------------------------------*/
1150static void hdd_batch_scan_result_ind_callback
1151(
1152 void *callbackContext,
1153 void *pRsp
1154)
1155{
1156 v_BOOL_t isLastAp;
1157 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001158 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301159 tANI_U32 numberScanList;
1160 tANI_U32 nextScanListOffset;
1161 tANI_U32 nextApMetaInfoOffset;
1162 hdd_adapter_t* pAdapter;
1163 tpSirBatchScanList pScanList;
1164 tpSirBatchScanNetworkInfo pApMetaInfo;
1165 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1166 tSirSetBatchScanReq *pReq;
1167
1168 pAdapter = (hdd_adapter_t *)callbackContext;
1169 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001170 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301171 {
1172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1173 "%s: Invalid pAdapter magic", __func__);
1174 VOS_ASSERT(0);
1175 return;
1176 }
1177
1178 /*initialize locals*/
1179 pReq = &pAdapter->hddSetBatchScanReq;
1180 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1181 isLastAp = FALSE;
1182 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001183 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301184 numberScanList = 0;
1185 nextScanListOffset = 0;
1186 nextApMetaInfoOffset = 0;
1187 pScanList = NULL;
1188 pApMetaInfo = NULL;
1189
1190 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1191 {
1192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1193 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1194 isLastAp = TRUE;
1195 goto done;
1196 }
1197
1198 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1200 "Batch scan rsp: numberScalList %d", numberScanList);
1201
1202 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1203 {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1205 "%s: numberScanList %d", __func__, numberScanList);
1206 isLastAp = TRUE;
1207 goto done;
1208 }
1209
1210 while (numberScanList)
1211 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001212 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301213 nextScanListOffset);
1214 if (NULL == pScanList)
1215 {
1216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1217 "%s: pScanList is %p", __func__, pScanList);
1218 isLastAp = TRUE;
1219 goto done;
1220 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001221 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001223 "Batch scan rsp: numApMetaInfo %d scanId %d",
1224 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301225
1226 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1227 {
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1229 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1230 isLastAp = TRUE;
1231 goto done;
1232 }
1233
Rajeev Kumarce651e42013-10-21 18:57:15 -07001234 /*Initialize next AP meta info offset for next scan list*/
1235 nextApMetaInfoOffset = 0;
1236
Rajeev79dbe4c2013-10-05 11:03:42 +05301237 while (numApMetaInfo)
1238 {
1239 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1240 nextApMetaInfoOffset);
1241 if (NULL == pApMetaInfo)
1242 {
1243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1244 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1245 isLastAp = TRUE;
1246 goto done;
1247 }
1248 /*calculate AP age*/
1249 pApMetaInfo->timestamp =
1250 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1251
1252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001253 "%s: bssId "MAC_ADDRESS_STR
1254 " ch %d rssi %d timestamp %d", __func__,
1255 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1256 pApMetaInfo->ch, pApMetaInfo->rssi,
1257 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301258
1259 /*mark last AP in batch scan response*/
1260 if ((TRUE == pBatchScanRsp->isLastResult) &&
1261 (1 == numberScanList) && (1 == numApMetaInfo))
1262 {
1263 isLastAp = TRUE;
1264 }
1265
1266 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1267 /*store batch scan repsonse in hdd queue*/
1268 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1269 pScanList->scanId, isLastAp);
1270 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1271
1272 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1273 numApMetaInfo--;
1274 }
1275
Rajeev Kumarce651e42013-10-21 18:57:15 -07001276 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1277 + (sizeof(tSirBatchScanNetworkInfo)
1278 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301279 numberScanList--;
1280 }
1281
1282done:
1283
1284 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1285 requested from hdd_ioctl*/
1286 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1287 (TRUE == isLastAp))
1288 {
1289 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1290 complete(&pAdapter->hdd_get_batch_scan_req_var);
1291 }
1292
1293 return;
1294}/*End of hdd_batch_scan_result_ind_callback*/
1295
1296/**---------------------------------------------------------------------------
1297
1298 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1299 response as per batch scan FR request format by putting proper markers
1300
1301 \param - pDest pointer to destination buffer
1302 \param - cur_len current length
1303 \param - tot_len total remaining size which can be written to user space
1304 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1305 \param - pAdapter Pointer to HDD adapter
1306
1307 \return - ret no of characters written
1308
1309 --------------------------------------------------------------------------*/
1310static tANI_U32
1311hdd_format_batch_scan_rsp
1312(
1313 tANI_U8 *pDest,
1314 tANI_U32 cur_len,
1315 tANI_U32 tot_len,
1316 tHddBatchScanRsp *pApMetaInfo,
1317 hdd_adapter_t* pAdapter
1318)
1319{
1320 tANI_U32 ret = 0;
1321 tANI_U32 rem_len = 0;
1322 tANI_U8 temp_len = 0;
1323 tANI_U8 temp_total_len = 0;
1324 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1325 tANI_U8 *pTemp = temp;
1326
1327 /*Batch scan reponse needs to be returned to user space in
1328 following format:
1329 "scancount=X\n" where X is the number of scans in current batch
1330 batch
1331 "trunc\n" optional present if current scan truncated
1332 "bssid=XX:XX:XX:XX:XX:XX\n"
1333 "ssid=XXXX\n"
1334 "freq=X\n" frequency in Mhz
1335 "level=XX\n"
1336 "age=X\n" ms
1337 "dist=X\n" cm (-1 if not available)
1338 "errror=X\n" (-1if not available)
1339 "====\n" (end of ap marker)
1340 "####\n" (end of scan marker)
1341 "----\n" (end of results)*/
1342 /*send scan result in above format to user space based on
1343 available length*/
1344 /*The GET response may have more data than the driver can return in its
1345 buffer. In that case the buffer should be filled to the nearest complete
1346 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1347 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1348 The final buffer should end with "----\n"*/
1349
1350 /*sanity*/
1351 if (cur_len > tot_len)
1352 {
1353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1354 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1355 return 0;
1356 }
1357 else
1358 {
1359 rem_len = (tot_len - cur_len);
1360 }
1361
1362 /*end scan marker*/
1363 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1364 {
1365 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1366 pTemp += temp_len;
1367 temp_total_len += temp_len;
1368 }
1369
1370 /*bssid*/
1371 temp_len = snprintf(pTemp, sizeof(temp),
1372 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1373 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1374 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1375 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1376 pTemp += temp_len;
1377 temp_total_len += temp_len;
1378
1379 /*ssid*/
1380 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1381 pApMetaInfo->ApInfo.ssid);
1382 pTemp += temp_len;
1383 temp_total_len += temp_len;
1384
1385 /*freq*/
1386 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001387 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301388 pTemp += temp_len;
1389 temp_total_len += temp_len;
1390
1391 /*level*/
1392 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1393 pApMetaInfo->ApInfo.rssi);
1394 pTemp += temp_len;
1395 temp_total_len += temp_len;
1396
1397 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001398 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301399 pApMetaInfo->ApInfo.age);
1400 pTemp += temp_len;
1401 temp_total_len += temp_len;
1402
1403 /*dist*/
1404 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1405 pTemp += temp_len;
1406 temp_total_len += temp_len;
1407
1408 /*error*/
1409 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1410 pTemp += temp_len;
1411 temp_total_len += temp_len;
1412
1413 /*end AP marker*/
1414 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1415 pTemp += temp_len;
1416 temp_total_len += temp_len;
1417
1418 /*last AP in batch scan response*/
1419 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1420 {
1421 /*end scan marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*end batch scan result marker*/
1427 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1428 pTemp += temp_len;
1429 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001430
Rajeev79dbe4c2013-10-05 11:03:42 +05301431 }
1432
1433 if (temp_total_len < rem_len)
1434 {
1435 ret = temp_total_len + 1;
1436 strlcpy(pDest, temp, ret);
1437 pAdapter->isTruncated = FALSE;
1438 }
1439 else
1440 {
1441 pAdapter->isTruncated = TRUE;
1442 if (rem_len >= strlen("%%%%"))
1443 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001444 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301445 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001446 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301447 {
1448 ret = 0;
1449 }
1450 }
1451
1452 return ret;
1453
1454}/*End of hdd_format_batch_scan_rsp*/
1455
1456/**---------------------------------------------------------------------------
1457
1458 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1459 buffer starting with head of hdd batch scan response queue
1460
1461 \param - pAdapter Pointer to HDD adapter
1462 \param - pDest Pointer to user data buffer
1463 \param - cur_len current offset in user buffer
1464 \param - rem_len remaining no of bytes in user buffer
1465
1466 \return - number of bytes written in user buffer
1467
1468 --------------------------------------------------------------------------*/
1469
1470tANI_U32 hdd_populate_user_batch_scan_rsp
1471(
1472 hdd_adapter_t* pAdapter,
1473 tANI_U8 *pDest,
1474 tANI_U32 cur_len,
1475 tANI_U32 rem_len
1476)
1477{
1478 tHddBatchScanRsp *pHead;
1479 tHddBatchScanRsp *pPrev;
1480 tANI_U32 len;
1481
Rajeev79dbe4c2013-10-05 11:03:42 +05301482 pAdapter->isTruncated = FALSE;
1483
1484 /*head of hdd batch scan response queue*/
1485 pHead = pAdapter->pBatchScanRsp;
1486 while (pHead)
1487 {
1488 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1489 pAdapter);
1490 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001491 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301492 cur_len += len;
1493 if(TRUE == pAdapter->isTruncated)
1494 {
1495 /*result is truncated return rest of scan rsp in next req*/
1496 cur_len = rem_len;
1497 break;
1498 }
1499 pPrev = pHead;
1500 pHead = pHead->pNext;
1501 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001502 if (TRUE == pPrev->ApInfo.isLastAp)
1503 {
1504 pAdapter->prev_batch_id = 0;
1505 }
1506 else
1507 {
1508 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1509 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301510 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001511 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301512 }
1513
1514 return cur_len;
1515}/*End of hdd_populate_user_batch_scan_rsp*/
1516
1517/**---------------------------------------------------------------------------
1518
1519 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1520 scan response data from HDD queue to user space
1521 It does following in detail:
1522 a) if HDD has enough data in its queue then it 1st copies data to user
1523 space and then send get batch scan indication message to FW. In this
1524 case it does not wait on any event and batch scan response data will
1525 be populated in HDD response queue in MC thread context after receiving
1526 indication from FW
1527 b) else send get batch scan indication message to FW and wait on an event
1528 which will be set once HDD receives complete batch scan response from
1529 FW and then this function returns batch scan response to user space
1530
1531 \param - pAdapter Pointer to HDD adapter
1532 \param - pPrivData Pointer to priv_data
1533
1534 \return - 0 for success -EFAULT for failure
1535
1536 --------------------------------------------------------------------------*/
1537
1538int hdd_return_batch_scan_rsp_to_user
1539(
1540 hdd_adapter_t* pAdapter,
1541 hdd_priv_data_t *pPrivData,
1542 tANI_U8 *command
1543)
1544{
1545 tANI_U8 *pDest;
1546 tANI_U32 count = 0;
1547 tANI_U32 len = 0;
1548 tANI_U32 cur_len = 0;
1549 tANI_U32 rem_len = 0;
1550 eHalStatus halStatus;
1551 unsigned long rc;
1552 tSirTriggerBatchScanResultInd *pReq;
1553
1554 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1555 pReq->param = 0;/*batch scan client*/
1556 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1557 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1558
1559 cur_len = pPrivData->used_len;
1560 if (pPrivData->total_len > pPrivData->used_len)
1561 {
1562 rem_len = pPrivData->total_len - pPrivData->used_len;
1563 }
1564 else
1565 {
1566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1567 "%s: Invalid user data buffer total_len %d used_len %d",
1568 __func__, pPrivData->total_len, pPrivData->used_len);
1569 return -EFAULT;
1570 }
1571
1572 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1573 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1574 cur_len, rem_len);
1575 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1576
1577 /*enough scan result available in cache to return to user space or
1578 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001579 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301580 {
1581 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1582 halStatus = sme_TriggerBatchScanResultInd(
1583 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1584 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1585 pAdapter);
1586 if ( eHAL_STATUS_SUCCESS == halStatus )
1587 {
1588 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1589 {
1590 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1591 rc = wait_for_completion_timeout(
1592 &pAdapter->hdd_get_batch_scan_req_var,
1593 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1594 if (0 == rc)
1595 {
1596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1597 "%s: Timeout waiting to fetch batch scan rsp from fw",
1598 __func__);
1599 return -EFAULT;
1600 }
1601 }
1602
1603 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001604 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301605 pDest += len;
1606 cur_len += len;
1607
1608 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1609 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1610 cur_len, rem_len);
1611 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1612
1613 count = 0;
1614 len = (len - pPrivData->used_len);
1615 pDest = (command + pPrivData->used_len);
1616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001617 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301618 while(count < len)
1619 {
1620 printk("%c", *(pDest + count));
1621 count++;
1622 }
1623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1624 "%s: copy %d data to user buffer", __func__, len);
1625 if (copy_to_user(pPrivData->buf, pDest, len))
1626 {
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "%s: failed to copy data to user buffer", __func__);
1629 return -EFAULT;
1630 }
1631 }
1632 else
1633 {
1634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1635 "sme_GetBatchScanScan returned failure halStatus %d",
1636 halStatus);
1637 return -EINVAL;
1638 }
1639 }
1640 else
1641 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301642 count = 0;
1643 len = (len - pPrivData->used_len);
1644 pDest = (command + pPrivData->used_len);
1645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001646 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301647 while(count < len)
1648 {
1649 printk("%c", *(pDest + count));
1650 count++;
1651 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1653 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301654 if (copy_to_user(pPrivData->buf, pDest, len))
1655 {
1656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: failed to copy data to user buffer", __func__);
1658 return -EFAULT;
1659 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301660 }
1661
1662 return 0;
1663} /*End of hdd_return_batch_scan_rsp_to_user*/
1664
Rajeev Kumar8b373292014-01-08 20:36:55 -08001665
1666/**---------------------------------------------------------------------------
1667
1668 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1669 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1670 WLS_BATCHING VERSION
1671 WLS_BATCHING SET
1672 WLS_BATCHING GET
1673 WLS_BATCHING STOP
1674
1675 \param - pAdapter Pointer to HDD adapter
1676 \param - pPrivdata Pointer to priv_data
1677 \param - command Pointer to command
1678
1679 \return - 0 for success -EFAULT for failure
1680
1681 --------------------------------------------------------------------------*/
1682
1683int hdd_handle_batch_scan_ioctl
1684(
1685 hdd_adapter_t *pAdapter,
1686 hdd_priv_data_t *pPrivdata,
1687 tANI_U8 *command
1688)
1689{
1690 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001691 hdd_context_t *pHddCtx;
1692
1693 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1694 ret = wlan_hdd_validate_context(pHddCtx);
1695 if (ret)
1696 {
1697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1698 "%s: HDD context is not valid!", __func__);
1699 goto exit;
1700 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001701
1702 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1703 {
1704 char extra[32];
1705 tANI_U8 len = 0;
1706 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1707
1708 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1709 {
1710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1711 "%s: Batch scan feature is not supported by FW", __func__);
1712 ret = -EINVAL;
1713 goto exit;
1714 }
1715
1716 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1717 version);
1718 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1719 {
1720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "%s: failed to copy data to user buffer", __func__);
1722 ret = -EFAULT;
1723 goto exit;
1724 }
1725 ret = HDD_BATCH_SCAN_VERSION;
1726 }
1727 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1728 {
1729 int status;
1730 tANI_U8 *value = (command + 16);
1731 eHalStatus halStatus;
1732 unsigned long rc;
1733 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1734 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1735
1736 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1737 {
1738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1739 "%s: Batch scan feature is not supported by FW", __func__);
1740 ret = -EINVAL;
1741 goto exit;
1742 }
1743
1744 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1745 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1746 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1747 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1748 {
1749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301750 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001751 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301752 hdd_device_modetoString(pAdapter->device_mode),
1753 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001754 ret = -EINVAL;
1755 goto exit;
1756 }
1757
1758 status = hdd_parse_set_batchscan_command(value, pReq);
1759 if (status)
1760 {
1761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1762 "Invalid WLS_BATCHING SET command");
1763 ret = -EINVAL;
1764 goto exit;
1765 }
1766
1767
1768 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1769 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1770 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1771 pAdapter);
1772
1773 if ( eHAL_STATUS_SUCCESS == halStatus )
1774 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301775 char extra[32];
1776 tANI_U8 len = 0;
1777 tANI_U8 mScan = 0;
1778
Rajeev Kumar8b373292014-01-08 20:36:55 -08001779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1780 "sme_SetBatchScanReq returned success halStatus %d",
1781 halStatus);
1782 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1783 {
1784 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1785 rc = wait_for_completion_timeout(
1786 &pAdapter->hdd_set_batch_scan_req_var,
1787 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1788 if (0 == rc)
1789 {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1791 "%s: Timeout waiting for set batch scan to complete",
1792 __func__);
1793 ret = -EINVAL;
1794 goto exit;
1795 }
1796 }
1797 if ( !pRsp->nScansToBatch )
1798 {
1799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1800 "%s: Received set batch scan failure response from FW",
1801 __func__);
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805 /*As per the Batch Scan Framework API we should return the MIN of
1806 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301807 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001808
1809 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1810
1811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1812 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301813 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1814 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1815 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1816 {
1817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1818 "%s: failed to copy MSCAN value to user buffer", __func__);
1819 ret = -EFAULT;
1820 goto exit;
1821 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001822 }
1823 else
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "sme_SetBatchScanReq returned failure halStatus %d",
1827 halStatus);
1828 ret = -EINVAL;
1829 goto exit;
1830 }
1831 }
1832 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1833 {
1834 eHalStatus halStatus;
1835 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1836 pInd->param = 0;
1837
1838 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1839 {
1840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1841 "%s: Batch scan feature is not supported by FW", __func__);
1842 ret = -EINVAL;
1843 goto exit;
1844 }
1845
1846 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "Batch scan is not yet enabled batch scan state %d",
1850 pAdapter->batchScanState);
1851 ret = -EINVAL;
1852 goto exit;
1853 }
1854
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001855 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1856 hdd_deinit_batch_scan(pAdapter);
1857 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1858
Rajeev Kumar8b373292014-01-08 20:36:55 -08001859 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1860
1861 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1862 pAdapter->sessionId);
1863 if ( eHAL_STATUS_SUCCESS == halStatus )
1864 {
1865 ret = 0;
1866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1867 "sme_StopBatchScanInd returned success halStatus %d",
1868 halStatus);
1869 }
1870 else
1871 {
1872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1873 "sme_StopBatchScanInd returned failure halStatus %d",
1874 halStatus);
1875 ret = -EINVAL;
1876 goto exit;
1877 }
1878 }
1879 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1880 {
1881 tANI_U32 remain_len;
1882
1883 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1884 {
1885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1886 "%s: Batch scan feature is not supported by FW", __func__);
1887 ret = -EINVAL;
1888 goto exit;
1889 }
1890
1891 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "Batch scan is not yet enabled could not return results"
1895 "Batch Scan state %d",
1896 pAdapter->batchScanState);
1897 ret = -EINVAL;
1898 goto exit;
1899 }
1900
1901 pPrivdata->used_len = 16;
1902 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1903 if (remain_len < pPrivdata->total_len)
1904 {
1905 /*Clear previous batch scan response data if any*/
1906 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1907 }
1908 else
1909 {
1910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1911 "Invalid total length from user space can't fetch batch"
1912 " scan response total_len %d used_len %d remain len %d",
1913 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1914 ret = -EINVAL;
1915 goto exit;
1916 }
1917 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1918 }
1919
1920exit:
1921
1922 return ret;
1923}
1924
1925
Rajeev79dbe4c2013-10-05 11:03:42 +05301926#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1927
c_hpothu92367912014-05-01 15:18:17 +05301928static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1929{
c_hpothu39eb1e32014-06-26 16:31:50 +05301930 bcnMissRateContext_t *pCBCtx;
1931
1932 if (NULL == data)
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1935 return;
1936 }
c_hpothu92367912014-05-01 15:18:17 +05301937
1938 /* there is a race condition that exists between this callback
1939 function and the caller since the caller could time out either
1940 before or while this code is executing. we use a spinlock to
1941 serialize these actions */
1942 spin_lock(&hdd_context_lock);
1943
c_hpothu39eb1e32014-06-26 16:31:50 +05301944 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301945 gbcnMissRate = -1;
1946
c_hpothu39eb1e32014-06-26 16:31:50 +05301947 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301950 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301951 spin_unlock(&hdd_context_lock);
1952 return ;
1953 }
1954
1955 if (VOS_STATUS_SUCCESS == status)
1956 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301957 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301958 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301959 else
1960 {
1961 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1962 }
1963
c_hpothu92367912014-05-01 15:18:17 +05301964 complete(&(pCBCtx->completion));
1965 spin_unlock(&hdd_context_lock);
1966
1967 return;
1968}
1969
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05301970static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
1971{
1972 int ret = 0;
1973
1974 if (!pCfg || !command || !extra || !len)
1975 {
1976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1977 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
1978 ret = -EINVAL;
1979 return ret;
1980 }
1981
1982 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
1983 {
1984 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
1985 (int)pCfg->nActiveMaxChnTime);
1986 return ret;
1987 }
1988 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
1989 {
1990 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
1991 (int)pCfg->nActiveMinChnTime);
1992 return ret;
1993 }
1994 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
1995 {
1996 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
1997 (int)pCfg->nPassiveMaxChnTime);
1998 return ret;
1999 }
2000 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2001 {
2002 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2003 (int)pCfg->nPassiveMinChnTime);
2004 return ret;
2005 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302006 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2007 {
2008 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2009 (int)pCfg->nActiveMaxChnTime);
2010 return ret;
2011 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302012 else
2013 {
2014 ret = -EINVAL;
2015 }
2016
2017 return ret;
2018}
2019
2020static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2021{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302022 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302023 hdd_config_t *pCfg;
2024 tANI_U8 *value = command;
2025 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302026 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302027
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302028 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2029 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302030 {
2031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2032 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2033 ret = -EINVAL;
2034 return ret;
2035 }
2036
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302037 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2038 sme_GetConfigParam(hHal, &smeConfig);
2039
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302040 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2041 {
2042 value = value + 24;
2043 temp = kstrtou32(value, 10, &val);
2044 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2045 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2046 {
2047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2048 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2049 ret = -EFAULT;
2050 return ret;
2051 }
2052 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302053 smeConfig.csrConfig.nActiveMaxChnTime = val;
2054 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302055 }
2056 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2057 {
2058 value = value + 24;
2059 temp = kstrtou32(value, 10, &val);
2060 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2061 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2062 {
2063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2064 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2065 ret = -EFAULT;
2066 return ret;
2067 }
2068 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302069 smeConfig.csrConfig.nActiveMinChnTime = val;
2070 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302071 }
2072 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2073 {
2074 value = value + 25;
2075 temp = kstrtou32(value, 10, &val);
2076 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2077 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2078 {
2079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2080 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2081 ret = -EFAULT;
2082 return ret;
2083 }
2084 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302085 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2086 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302087 }
2088 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2089 {
2090 value = value + 25;
2091 temp = kstrtou32(value, 10, &val);
2092 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2093 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2094 {
2095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2096 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2097 ret = -EFAULT;
2098 return ret;
2099 }
2100 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302101 smeConfig.csrConfig.nPassiveMinChnTime = val;
2102 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302103 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302104 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2105 {
2106 value = value + 13;
2107 temp = kstrtou32(value, 10, &val);
2108 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2109 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2110 {
2111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2112 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2113 ret = -EFAULT;
2114 return ret;
2115 }
2116 pCfg->nActiveMaxChnTime = val;
2117 smeConfig.csrConfig.nActiveMaxChnTime = val;
2118 sme_UpdateConfig(hHal, &smeConfig);
2119 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302120 else
2121 {
2122 ret = -EINVAL;
2123 }
2124
2125 return ret;
2126}
2127
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002128static int hdd_driver_command(hdd_adapter_t *pAdapter,
2129 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002130{
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 hdd_priv_data_t priv_data;
2132 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002133 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002134
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002135 /*
2136 * Note that valid pointers are provided by caller
2137 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002138
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002139 /* copy to local struct to avoid numerous changes to legacy code */
2140 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002141
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002142 if (priv_data.total_len <= 0 ||
2143 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002144 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002145 hddLog(VOS_TRACE_LEVEL_WARN,
2146 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2147 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002148 ret = -EINVAL;
2149 goto exit;
2150 }
2151
2152 /* Allocate +1 for '\0' */
2153 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002154 if (!command)
2155 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002156 hddLog(VOS_TRACE_LEVEL_ERROR,
2157 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002158 ret = -ENOMEM;
2159 goto exit;
2160 }
2161
2162 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2163 {
2164 ret = -EFAULT;
2165 goto exit;
2166 }
2167
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002168 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002169 command[priv_data.total_len] = '\0';
2170
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002171 /* at one time the following block of code was conditional. braces
2172 * have been retained to avoid re-indenting the legacy code
2173 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002174 {
2175 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2176
2177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002178 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002179
2180 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2181 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2183 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2184 pAdapter->sessionId, (unsigned)
2185 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2186 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2187 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2188 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002189 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2190 sizeof(tSirMacAddr)))
2191 {
2192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002193 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002194 ret = -EFAULT;
2195 }
2196 }
Amar Singhal0974e402013-02-12 14:27:46 -08002197 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002198 {
Amar Singhal0974e402013-02-12 14:27:46 -08002199 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002200
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002202
2203 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002206 "%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 -07002207 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002208 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302209 if(ret != 0)
2210 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002211 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002212 }
Kiet Lamf040f472013-11-20 21:15:23 +05302213 else if(strncmp(command, "SETWMMPS", 8) == 0)
2214 {
2215 tANI_U8 *ptr = command;
2216 ret = hdd_wmmps_helper(pAdapter, ptr);
2217 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002218 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2219 {
2220 char *country_code;
2221
2222 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002223
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002224 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002225 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002226#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302227 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002228#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002229 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2230 (void *)(tSmeChangeCountryCallback)
2231 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302232 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002233 if (eHAL_STATUS_SUCCESS == ret)
2234 {
2235 ret = wait_for_completion_interruptible_timeout(
2236 &pAdapter->change_country_code,
2237 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2238 if (0 >= ret)
2239 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302241 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002242 }
2243 }
2244 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002245 {
2246 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002247 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002248 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002249 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002250
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002251 }
2252 /*
2253 command should be a string having format
2254 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2255 */
Amar Singhal0974e402013-02-12 14:27:46 -08002256 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002257 {
Amar Singhal0974e402013-02-12 14:27:46 -08002258 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002259
2260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002261 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002262
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002263 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002264 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002265 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2266 {
2267 int suspend = 0;
2268 tANI_U8 *ptr = (tANI_U8*)command + 15;
2269
2270 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302271 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2272 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2273 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002274 hdd_set_wlan_suspend_mode(suspend);
2275 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002276#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2277 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2278 {
2279 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002280 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002281 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2282 eHalStatus status = eHAL_STATUS_SUCCESS;
2283
2284 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2285 value = value + 15;
2286
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002287 /* Convert the value from ascii to integer */
2288 ret = kstrtos8(value, 10, &rssi);
2289 if (ret < 0)
2290 {
2291 /* If the input value is greater than max value of datatype, then also
2292 kstrtou8 fails */
2293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2294 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002295 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002296 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2297 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2298 ret = -EINVAL;
2299 goto exit;
2300 }
2301
Srinivas Girigowdade697412013-02-14 16:31:48 -08002302 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002303
Srinivas Girigowdade697412013-02-14 16:31:48 -08002304 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2305 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2306 {
2307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2308 "Neighbor lookup threshold value %d is out of range"
2309 " (Min: %d Max: %d)", lookUpThreshold,
2310 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2311 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2312 ret = -EINVAL;
2313 goto exit;
2314 }
2315
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302316 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2317 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2318 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2320 "%s: Received Command to Set Roam trigger"
2321 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2322
2323 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2324 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2325 if (eHAL_STATUS_SUCCESS != status)
2326 {
2327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2328 "%s: Failed to set roam trigger, try again", __func__);
2329 ret = -EPERM;
2330 goto exit;
2331 }
2332
2333 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302334 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002335 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2336 }
2337 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2338 {
2339 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2340 int rssi = (-1) * lookUpThreshold;
2341 char extra[32];
2342 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302343 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2344 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2345 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002346 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002347 if (copy_to_user(priv_data.buf, &extra, len + 1))
2348 {
2349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2350 "%s: failed to copy data to user buffer", __func__);
2351 ret = -EFAULT;
2352 goto exit;
2353 }
2354 }
2355 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2356 {
2357 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002358 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002359 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002360
Srinivas Girigowdade697412013-02-14 16:31:48 -08002361 /* input refresh period is in terms of seconds */
2362 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2363 value = value + 18;
2364 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002365 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002366 if (ret < 0)
2367 {
2368 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002369 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002371 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002372 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002373 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2374 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002375 ret = -EINVAL;
2376 goto exit;
2377 }
2378
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002379 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2380 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002381 {
2382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002383 "Roam scan period value %d is out of range"
2384 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002385 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2386 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002387 ret = -EINVAL;
2388 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302389 }
2390 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2391 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2392 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002393 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002394
2395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2396 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002397 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002398
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002399 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2400 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002401 }
2402 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2403 {
2404 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2405 char extra[32];
2406 tANI_U8 len = 0;
2407
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302408 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2409 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2410 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002411 len = scnprintf(extra, sizeof(extra), "%s %d",
2412 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002413 /* Returned value is in units of seconds */
2414 if (copy_to_user(priv_data.buf, &extra, len + 1))
2415 {
2416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2417 "%s: failed to copy data to user buffer", __func__);
2418 ret = -EFAULT;
2419 goto exit;
2420 }
2421 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002422 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2423 {
2424 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002425 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002426 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002427
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002428 /* input refresh period is in terms of seconds */
2429 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2430 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002431
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002432 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002433 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002434 if (ret < 0)
2435 {
2436 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002437 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002439 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002440 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002441 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2442 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2443 ret = -EINVAL;
2444 goto exit;
2445 }
2446
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002447 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2448 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2449 {
2450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2451 "Neighbor scan results refresh period value %d is out of range"
2452 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2453 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2454 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2455 ret = -EINVAL;
2456 goto exit;
2457 }
2458 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2459
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2461 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002462 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002463
2464 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2465 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2466 }
2467 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2468 {
2469 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2470 char extra[32];
2471 tANI_U8 len = 0;
2472
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002473 len = scnprintf(extra, sizeof(extra), "%s %d",
2474 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002475 /* Returned value is in units of seconds */
2476 if (copy_to_user(priv_data.buf, &extra, len + 1))
2477 {
2478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2479 "%s: failed to copy data to user buffer", __func__);
2480 ret = -EFAULT;
2481 goto exit;
2482 }
2483 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002484#ifdef FEATURE_WLAN_LFR
2485 /* SETROAMMODE */
2486 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2487 {
2488 tANI_U8 *value = command;
2489 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2490
2491 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2492 value = value + SIZE_OF_SETROAMMODE + 1;
2493
2494 /* Convert the value from ascii to integer */
2495 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2496 if (ret < 0)
2497 {
2498 /* If the input value is greater than max value of datatype, then also
2499 kstrtou8 fails */
2500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2501 "%s: kstrtou8 failed range [%d - %d]", __func__,
2502 CFG_LFR_FEATURE_ENABLED_MIN,
2503 CFG_LFR_FEATURE_ENABLED_MAX);
2504 ret = -EINVAL;
2505 goto exit;
2506 }
2507 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2508 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2509 {
2510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2511 "Roam Mode value %d is out of range"
2512 " (Min: %d Max: %d)", roamMode,
2513 CFG_LFR_FEATURE_ENABLED_MIN,
2514 CFG_LFR_FEATURE_ENABLED_MAX);
2515 ret = -EINVAL;
2516 goto exit;
2517 }
2518
2519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2520 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2521 /*
2522 * Note that
2523 * SETROAMMODE 0 is to enable LFR while
2524 * SETROAMMODE 1 is to disable LFR, but
2525 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2526 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2527 */
2528 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2529 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2530 else
2531 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2532
2533 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2534 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2535 }
2536 /* GETROAMMODE */
2537 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2538 {
2539 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2540 char extra[32];
2541 tANI_U8 len = 0;
2542
2543 /*
2544 * roamMode value shall be inverted because the sementics is different.
2545 */
2546 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2547 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2548 else
2549 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2550
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002551 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002552 if (copy_to_user(priv_data.buf, &extra, len + 1))
2553 {
2554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2555 "%s: failed to copy data to user buffer", __func__);
2556 ret = -EFAULT;
2557 goto exit;
2558 }
2559 }
2560#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002561#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002562#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002563 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2564 {
2565 tANI_U8 *value = command;
2566 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2567
2568 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2569 value = value + 13;
2570 /* Convert the value from ascii to integer */
2571 ret = kstrtou8(value, 10, &roamRssiDiff);
2572 if (ret < 0)
2573 {
2574 /* If the input value is greater than max value of datatype, then also
2575 kstrtou8 fails */
2576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2577 "%s: kstrtou8 failed range [%d - %d]", __func__,
2578 CFG_ROAM_RSSI_DIFF_MIN,
2579 CFG_ROAM_RSSI_DIFF_MAX);
2580 ret = -EINVAL;
2581 goto exit;
2582 }
2583
2584 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2585 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2586 {
2587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2588 "Roam rssi diff value %d is out of range"
2589 " (Min: %d Max: %d)", roamRssiDiff,
2590 CFG_ROAM_RSSI_DIFF_MIN,
2591 CFG_ROAM_RSSI_DIFF_MAX);
2592 ret = -EINVAL;
2593 goto exit;
2594 }
2595
2596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2597 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2598
2599 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2600 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2601 }
2602 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2603 {
2604 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2605 char extra[32];
2606 tANI_U8 len = 0;
2607
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302608 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2609 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2610 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002611 len = scnprintf(extra, sizeof(extra), "%s %d",
2612 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002613 if (copy_to_user(priv_data.buf, &extra, len + 1))
2614 {
2615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2616 "%s: failed to copy data to user buffer", __func__);
2617 ret = -EFAULT;
2618 goto exit;
2619 }
2620 }
2621#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002622#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002623 else if (strncmp(command, "GETBAND", 7) == 0)
2624 {
2625 int band = -1;
2626 char extra[32];
2627 tANI_U8 len = 0;
2628 hdd_getBand_helper(pHddCtx, &band);
2629
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302630 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2631 TRACE_CODE_HDD_GETBAND_IOCTL,
2632 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002633 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002634 if (copy_to_user(priv_data.buf, &extra, len + 1))
2635 {
2636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2637 "%s: failed to copy data to user buffer", __func__);
2638 ret = -EFAULT;
2639 goto exit;
2640 }
2641 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002642 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2643 {
2644 tANI_U8 *value = command;
2645 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2646 tANI_U8 numChannels = 0;
2647 eHalStatus status = eHAL_STATUS_SUCCESS;
2648
2649 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2650 if (eHAL_STATUS_SUCCESS != status)
2651 {
2652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2653 "%s: Failed to parse channel list information", __func__);
2654 ret = -EINVAL;
2655 goto exit;
2656 }
2657
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302658 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2659 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2660 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002661 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2662 {
2663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2664 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2665 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2666 ret = -EINVAL;
2667 goto exit;
2668 }
2669 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2670 numChannels);
2671 if (eHAL_STATUS_SUCCESS != status)
2672 {
2673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2674 "%s: Failed to update channel list information", __func__);
2675 ret = -EINVAL;
2676 goto exit;
2677 }
2678 }
2679 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2680 {
2681 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2682 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002683 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002684 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002685 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002686
2687 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2688 ChannelList, &numChannels ))
2689 {
2690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2691 "%s: failed to get roam scan channel list", __func__);
2692 ret = -EFAULT;
2693 goto exit;
2694 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302695 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2696 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2697 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002698 /* output channel list is of the format
2699 [Number of roam scan channels][Channel1][Channel2]... */
2700 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002701 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002702 for (j = 0; (j < numChannels); j++)
2703 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002704 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2705 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002706 }
2707
2708 if (copy_to_user(priv_data.buf, &extra, len + 1))
2709 {
2710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2711 "%s: failed to copy data to user buffer", __func__);
2712 ret = -EFAULT;
2713 goto exit;
2714 }
2715 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002716 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2717 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002718 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002719 char extra[32];
2720 tANI_U8 len = 0;
2721
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002722 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002723 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002724 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002725 hdd_is_okc_mode_enabled(pHddCtx) &&
2726 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2727 {
2728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002729 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002730 " hence this operation is not permitted!", __func__);
2731 ret = -EPERM;
2732 goto exit;
2733 }
2734
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002735 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002736 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002737 if (copy_to_user(priv_data.buf, &extra, len + 1))
2738 {
2739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2740 "%s: failed to copy data to user buffer", __func__);
2741 ret = -EFAULT;
2742 goto exit;
2743 }
2744 }
2745 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2746 {
2747 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2748 char extra[32];
2749 tANI_U8 len = 0;
2750
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002751 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002752 then this operation is not permitted (return FAILURE) */
2753 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002754 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002755 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2756 {
2757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002758 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002759 " hence this operation is not permitted!", __func__);
2760 ret = -EPERM;
2761 goto exit;
2762 }
2763
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002764 len = scnprintf(extra, sizeof(extra), "%s %d",
2765 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002766 if (copy_to_user(priv_data.buf, &extra, len + 1))
2767 {
2768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2769 "%s: failed to copy data to user buffer", __func__);
2770 ret = -EFAULT;
2771 goto exit;
2772 }
2773 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002774 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002775 {
2776 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2777 char extra[32];
2778 tANI_U8 len = 0;
2779
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002780 len = scnprintf(extra, sizeof(extra), "%s %d",
2781 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002782 if (copy_to_user(priv_data.buf, &extra, len + 1))
2783 {
2784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2785 "%s: failed to copy data to user buffer", __func__);
2786 ret = -EFAULT;
2787 goto exit;
2788 }
2789 }
2790 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2791 {
2792 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2793 char extra[32];
2794 tANI_U8 len = 0;
2795
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002796 len = scnprintf(extra, sizeof(extra), "%s %d",
2797 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002798 if (copy_to_user(priv_data.buf, &extra, len + 1))
2799 {
2800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2801 "%s: failed to copy data to user buffer", __func__);
2802 ret = -EFAULT;
2803 goto exit;
2804 }
2805 }
2806 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2807 {
2808 tANI_U8 *value = command;
2809 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2810
2811 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2812 value = value + 26;
2813 /* Convert the value from ascii to integer */
2814 ret = kstrtou8(value, 10, &minTime);
2815 if (ret < 0)
2816 {
2817 /* If the input value is greater than max value of datatype, then also
2818 kstrtou8 fails */
2819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2820 "%s: kstrtou8 failed range [%d - %d]", __func__,
2821 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2822 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2823 ret = -EINVAL;
2824 goto exit;
2825 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002826 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2827 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2828 {
2829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2830 "scan min channel time value %d is out of range"
2831 " (Min: %d Max: %d)", minTime,
2832 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2833 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2834 ret = -EINVAL;
2835 goto exit;
2836 }
2837
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302838 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2839 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2840 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2842 "%s: Received Command to change channel min time = %d", __func__, minTime);
2843
2844 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2845 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2846 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002847 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2848 {
2849 tANI_U8 *value = command;
2850 tANI_U8 channel = 0;
2851 tANI_U8 dwellTime = 0;
2852 tANI_U8 bufLen = 0;
2853 tANI_U8 *buf = NULL;
2854 tSirMacAddr targetApBssid;
2855 eHalStatus status = eHAL_STATUS_SUCCESS;
2856 struct ieee80211_channel chan;
2857 tANI_U8 finalLen = 0;
2858 tANI_U8 *finalBuf = NULL;
2859 tANI_U8 temp = 0;
2860 u64 cookie;
2861 hdd_station_ctx_t *pHddStaCtx = NULL;
2862 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2863
2864 /* if not associated, no need to send action frame */
2865 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2866 {
2867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2868 ret = -EINVAL;
2869 goto exit;
2870 }
2871
2872 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2873 &dwellTime, &buf, &bufLen);
2874 if (eHAL_STATUS_SUCCESS != status)
2875 {
2876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2877 "%s: Failed to parse send action frame data", __func__);
2878 ret = -EINVAL;
2879 goto exit;
2880 }
2881
2882 /* if the target bssid is different from currently associated AP,
2883 then no need to send action frame */
2884 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2885 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2886 {
2887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2888 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002889 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002890 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002891 goto exit;
2892 }
2893
2894 /* if the channel number is different from operating channel then
2895 no need to send action frame */
2896 if (channel != pHddStaCtx->conn_info.operationChannel)
2897 {
2898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2899 "%s: channel(%d) is different from operating channel(%d)",
2900 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2901 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002902 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002903 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002904 goto exit;
2905 }
2906 chan.center_freq = sme_ChnToFreq(channel);
2907
2908 finalLen = bufLen + 24;
2909 finalBuf = vos_mem_malloc(finalLen);
2910 if (NULL == finalBuf)
2911 {
2912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2913 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002914 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002915 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002916 goto exit;
2917 }
2918 vos_mem_zero(finalBuf, finalLen);
2919
2920 /* Fill subtype */
2921 temp = SIR_MAC_MGMT_ACTION << 4;
2922 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2923
2924 /* Fill type */
2925 temp = SIR_MAC_MGMT_FRAME;
2926 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2927
2928 /* Fill destination address (bssid of the AP) */
2929 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2930
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002931 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002932 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2933
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002934 /* Fill BSSID (AP mac address) */
2935 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002936
2937 /* Fill received buffer from 24th address */
2938 vos_mem_copy(finalBuf + 24, buf, bufLen);
2939
Jeff Johnson11c33152013-04-16 17:52:40 -07002940 /* done with the parsed buffer */
2941 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002942 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002943
DARAM SUDHA39eede62014-02-12 11:16:40 +05302944 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2946 &(pAdapter->wdev),
2947#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002948 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002949#endif
2950 &chan, 0,
2951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2952 NL80211_CHAN_HT20, 1,
2953#endif
2954 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002955 1, &cookie );
2956 vos_mem_free(finalBuf);
2957 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002958 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2959 {
2960 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2961 char extra[32];
2962 tANI_U8 len = 0;
2963
2964 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002965 len = scnprintf(extra, sizeof(extra), "%s %d",
2966 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302967 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2968 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2969 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002970 if (copy_to_user(priv_data.buf, &extra, len + 1))
2971 {
2972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2973 "%s: failed to copy data to user buffer", __func__);
2974 ret = -EFAULT;
2975 goto exit;
2976 }
2977 }
2978 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2979 {
2980 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002981 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002982
2983 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2984 value = value + 19;
2985 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002986 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002987 if (ret < 0)
2988 {
2989 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002990 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002992 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002993 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2994 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2995 ret = -EINVAL;
2996 goto exit;
2997 }
2998
2999 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3000 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3001 {
3002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3003 "lfr mode value %d is out of range"
3004 " (Min: %d Max: %d)", maxTime,
3005 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3006 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3007 ret = -EINVAL;
3008 goto exit;
3009 }
3010
3011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3012 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3013
3014 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3015 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3016 }
3017 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3018 {
3019 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3020 char extra[32];
3021 tANI_U8 len = 0;
3022
3023 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003024 len = scnprintf(extra, sizeof(extra), "%s %d",
3025 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003026 if (copy_to_user(priv_data.buf, &extra, len + 1))
3027 {
3028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3029 "%s: failed to copy data to user buffer", __func__);
3030 ret = -EFAULT;
3031 goto exit;
3032 }
3033 }
3034 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3035 {
3036 tANI_U8 *value = command;
3037 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3038
3039 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3040 value = value + 16;
3041 /* Convert the value from ascii to integer */
3042 ret = kstrtou16(value, 10, &val);
3043 if (ret < 0)
3044 {
3045 /* If the input value is greater than max value of datatype, then also
3046 kstrtou16 fails */
3047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3048 "%s: kstrtou16 failed range [%d - %d]", __func__,
3049 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3050 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3051 ret = -EINVAL;
3052 goto exit;
3053 }
3054
3055 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3056 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3057 {
3058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3059 "scan home time value %d is out of range"
3060 " (Min: %d Max: %d)", val,
3061 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3062 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3063 ret = -EINVAL;
3064 goto exit;
3065 }
3066
3067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3068 "%s: Received Command to change scan home time = %d", __func__, val);
3069
3070 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3071 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3072 }
3073 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3074 {
3075 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3076 char extra[32];
3077 tANI_U8 len = 0;
3078
3079 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003080 len = scnprintf(extra, sizeof(extra), "%s %d",
3081 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003082 if (copy_to_user(priv_data.buf, &extra, len + 1))
3083 {
3084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3085 "%s: failed to copy data to user buffer", __func__);
3086 ret = -EFAULT;
3087 goto exit;
3088 }
3089 }
3090 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3091 {
3092 tANI_U8 *value = command;
3093 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3094
3095 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3096 value = value + 17;
3097 /* Convert the value from ascii to integer */
3098 ret = kstrtou8(value, 10, &val);
3099 if (ret < 0)
3100 {
3101 /* If the input value is greater than max value of datatype, then also
3102 kstrtou8 fails */
3103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3104 "%s: kstrtou8 failed range [%d - %d]", __func__,
3105 CFG_ROAM_INTRA_BAND_MIN,
3106 CFG_ROAM_INTRA_BAND_MAX);
3107 ret = -EINVAL;
3108 goto exit;
3109 }
3110
3111 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3112 (val > CFG_ROAM_INTRA_BAND_MAX))
3113 {
3114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3115 "intra band mode value %d is out of range"
3116 " (Min: %d Max: %d)", val,
3117 CFG_ROAM_INTRA_BAND_MIN,
3118 CFG_ROAM_INTRA_BAND_MAX);
3119 ret = -EINVAL;
3120 goto exit;
3121 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3123 "%s: Received Command to change intra band = %d", __func__, val);
3124
3125 pHddCtx->cfg_ini->nRoamIntraBand = val;
3126 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3127 }
3128 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3129 {
3130 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3131 char extra[32];
3132 tANI_U8 len = 0;
3133
3134 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003135 len = scnprintf(extra, sizeof(extra), "%s %d",
3136 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003137 if (copy_to_user(priv_data.buf, &extra, len + 1))
3138 {
3139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3140 "%s: failed to copy data to user buffer", __func__);
3141 ret = -EFAULT;
3142 goto exit;
3143 }
3144 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003145 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3146 {
3147 tANI_U8 *value = command;
3148 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3149
3150 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3151 value = value + 15;
3152 /* Convert the value from ascii to integer */
3153 ret = kstrtou8(value, 10, &nProbes);
3154 if (ret < 0)
3155 {
3156 /* If the input value is greater than max value of datatype, then also
3157 kstrtou8 fails */
3158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3159 "%s: kstrtou8 failed range [%d - %d]", __func__,
3160 CFG_ROAM_SCAN_N_PROBES_MIN,
3161 CFG_ROAM_SCAN_N_PROBES_MAX);
3162 ret = -EINVAL;
3163 goto exit;
3164 }
3165
3166 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3167 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3168 {
3169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3170 "NProbes value %d is out of range"
3171 " (Min: %d Max: %d)", nProbes,
3172 CFG_ROAM_SCAN_N_PROBES_MIN,
3173 CFG_ROAM_SCAN_N_PROBES_MAX);
3174 ret = -EINVAL;
3175 goto exit;
3176 }
3177
3178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3179 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3180
3181 pHddCtx->cfg_ini->nProbes = nProbes;
3182 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3183 }
3184 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3185 {
3186 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3187 char extra[32];
3188 tANI_U8 len = 0;
3189
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003190 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003191 if (copy_to_user(priv_data.buf, &extra, len + 1))
3192 {
3193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3194 "%s: failed to copy data to user buffer", __func__);
3195 ret = -EFAULT;
3196 goto exit;
3197 }
3198 }
3199 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3200 {
3201 tANI_U8 *value = command;
3202 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3203
3204 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3205 /* input value is in units of msec */
3206 value = value + 20;
3207 /* Convert the value from ascii to integer */
3208 ret = kstrtou16(value, 10, &homeAwayTime);
3209 if (ret < 0)
3210 {
3211 /* If the input value is greater than max value of datatype, then also
3212 kstrtou8 fails */
3213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3214 "%s: kstrtou8 failed range [%d - %d]", __func__,
3215 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3216 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3217 ret = -EINVAL;
3218 goto exit;
3219 }
3220
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003221 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3222 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3223 {
3224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3225 "homeAwayTime value %d is out of range"
3226 " (Min: %d Max: %d)", homeAwayTime,
3227 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3228 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3229 ret = -EINVAL;
3230 goto exit;
3231 }
3232
3233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3234 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003235 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3236 {
3237 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3238 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3239 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003240 }
3241 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3242 {
3243 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3244 char extra[32];
3245 tANI_U8 len = 0;
3246
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003247 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003248 if (copy_to_user(priv_data.buf, &extra, len + 1))
3249 {
3250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3251 "%s: failed to copy data to user buffer", __func__);
3252 ret = -EFAULT;
3253 goto exit;
3254 }
3255 }
3256 else if (strncmp(command, "REASSOC", 7) == 0)
3257 {
3258 tANI_U8 *value = command;
3259 tANI_U8 channel = 0;
3260 tSirMacAddr targetApBssid;
3261 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003262#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3263 tCsrHandoffRequest handoffInfo;
3264#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003265 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003266 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3267
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003268 /* if not associated, no need to proceed with reassoc */
3269 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3270 {
3271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3272 ret = -EINVAL;
3273 goto exit;
3274 }
3275
3276 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3277 if (eHAL_STATUS_SUCCESS != status)
3278 {
3279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3280 "%s: Failed to parse reassoc command data", __func__);
3281 ret = -EINVAL;
3282 goto exit;
3283 }
3284
3285 /* if the target bssid is same as currently associated AP,
3286 then no need to proceed with reassoc */
3287 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3288 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3289 {
3290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3291 ret = -EINVAL;
3292 goto exit;
3293 }
3294
3295 /* Check channel number is a valid channel number */
3296 if(VOS_STATUS_SUCCESS !=
3297 wlan_hdd_validate_operation_channel(pAdapter, channel))
3298 {
3299 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003300 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003301 return -EINVAL;
3302 }
3303
3304 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003305#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3306 handoffInfo.channel = channel;
3307 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3308 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3309#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003310 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003311 else if (strncmp(command, "SETWESMODE", 10) == 0)
3312 {
3313 tANI_U8 *value = command;
3314 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3315
3316 /* Move pointer to ahead of SETWESMODE<delimiter> */
3317 value = value + 11;
3318 /* Convert the value from ascii to integer */
3319 ret = kstrtou8(value, 10, &wesMode);
3320 if (ret < 0)
3321 {
3322 /* If the input value is greater than max value of datatype, then also
3323 kstrtou8 fails */
3324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3325 "%s: kstrtou8 failed range [%d - %d]", __func__,
3326 CFG_ENABLE_WES_MODE_NAME_MIN,
3327 CFG_ENABLE_WES_MODE_NAME_MAX);
3328 ret = -EINVAL;
3329 goto exit;
3330 }
3331
3332 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3333 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3334 {
3335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3336 "WES Mode value %d is out of range"
3337 " (Min: %d Max: %d)", wesMode,
3338 CFG_ENABLE_WES_MODE_NAME_MIN,
3339 CFG_ENABLE_WES_MODE_NAME_MAX);
3340 ret = -EINVAL;
3341 goto exit;
3342 }
3343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3344 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3345
3346 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3347 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3348 }
3349 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3350 {
3351 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3352 char extra[32];
3353 tANI_U8 len = 0;
3354
Arif Hussain826d9412013-11-12 16:44:54 -08003355 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003356 if (copy_to_user(priv_data.buf, &extra, len + 1))
3357 {
3358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3359 "%s: failed to copy data to user buffer", __func__);
3360 ret = -EFAULT;
3361 goto exit;
3362 }
3363 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003364#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003365#ifdef FEATURE_WLAN_LFR
3366 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3367 {
3368 tANI_U8 *value = command;
3369 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3370
3371 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3372 value = value + 12;
3373 /* Convert the value from ascii to integer */
3374 ret = kstrtou8(value, 10, &lfrMode);
3375 if (ret < 0)
3376 {
3377 /* If the input value is greater than max value of datatype, then also
3378 kstrtou8 fails */
3379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3380 "%s: kstrtou8 failed range [%d - %d]", __func__,
3381 CFG_LFR_FEATURE_ENABLED_MIN,
3382 CFG_LFR_FEATURE_ENABLED_MAX);
3383 ret = -EINVAL;
3384 goto exit;
3385 }
3386
3387 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3388 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3389 {
3390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3391 "lfr mode value %d is out of range"
3392 " (Min: %d Max: %d)", lfrMode,
3393 CFG_LFR_FEATURE_ENABLED_MIN,
3394 CFG_LFR_FEATURE_ENABLED_MAX);
3395 ret = -EINVAL;
3396 goto exit;
3397 }
3398
3399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3400 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3401
3402 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3403 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3404 }
3405#endif
3406#ifdef WLAN_FEATURE_VOWIFI_11R
3407 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3408 {
3409 tANI_U8 *value = command;
3410 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3411
3412 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3413 value = value + 18;
3414 /* Convert the value from ascii to integer */
3415 ret = kstrtou8(value, 10, &ft);
3416 if (ret < 0)
3417 {
3418 /* If the input value is greater than max value of datatype, then also
3419 kstrtou8 fails */
3420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3421 "%s: kstrtou8 failed range [%d - %d]", __func__,
3422 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3423 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3424 ret = -EINVAL;
3425 goto exit;
3426 }
3427
3428 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3429 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3430 {
3431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3432 "ft mode value %d is out of range"
3433 " (Min: %d Max: %d)", ft,
3434 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3435 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3436 ret = -EINVAL;
3437 goto exit;
3438 }
3439
3440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3441 "%s: Received Command to change ft mode = %d", __func__, ft);
3442
3443 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3444 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3445 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303446
3447 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3448 {
3449 tANI_U8 *value = command;
3450 tSirMacAddr targetApBssid;
3451 tANI_U8 trigger = 0;
3452 eHalStatus status = eHAL_STATUS_SUCCESS;
3453 hdd_station_ctx_t *pHddStaCtx = NULL;
3454 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3455
3456 /* if not associated, no need to proceed with reassoc */
3457 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3458 {
3459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3460 ret = -EINVAL;
3461 goto exit;
3462 }
3463
3464 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3465 if (eHAL_STATUS_SUCCESS != status)
3466 {
3467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3468 "%s: Failed to parse reassoc command data", __func__);
3469 ret = -EINVAL;
3470 goto exit;
3471 }
3472
3473 /* if the target bssid is same as currently associated AP,
3474 then no need to proceed with reassoc */
3475 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3476 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3477 {
3478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3479 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3480 __func__);
3481 ret = -EINVAL;
3482 goto exit;
3483 }
3484
3485 /* Proceed with scan/roam */
3486 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3487 &targetApBssid[0],
3488 (tSmeFastRoamTrigger)(trigger));
3489 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003490#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003491#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003492 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3493 {
3494 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003495 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003496
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003497 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003498 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003499 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003500 hdd_is_okc_mode_enabled(pHddCtx) &&
3501 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3502 {
3503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003504 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003505 " hence this operation is not permitted!", __func__);
3506 ret = -EPERM;
3507 goto exit;
3508 }
3509
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003510 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3511 value = value + 11;
3512 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003513 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003514 if (ret < 0)
3515 {
3516 /* If the input value is greater than max value of datatype, then also
3517 kstrtou8 fails */
3518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3519 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003520 CFG_ESE_FEATURE_ENABLED_MIN,
3521 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003522 ret = -EINVAL;
3523 goto exit;
3524 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003525 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3526 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003527 {
3528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003529 "Ese mode value %d is out of range"
3530 " (Min: %d Max: %d)", eseMode,
3531 CFG_ESE_FEATURE_ENABLED_MIN,
3532 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003533 ret = -EINVAL;
3534 goto exit;
3535 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003537 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003538
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003539 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3540 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003541 }
3542#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003543 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3544 {
3545 tANI_U8 *value = command;
3546 tANI_BOOLEAN roamScanControl = 0;
3547
3548 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3549 value = value + 19;
3550 /* Convert the value from ascii to integer */
3551 ret = kstrtou8(value, 10, &roamScanControl);
3552 if (ret < 0)
3553 {
3554 /* If the input value is greater than max value of datatype, then also
3555 kstrtou8 fails */
3556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3557 "%s: kstrtou8 failed ", __func__);
3558 ret = -EINVAL;
3559 goto exit;
3560 }
3561
3562 if (0 != roamScanControl)
3563 {
3564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3565 "roam scan control invalid value = %d",
3566 roamScanControl);
3567 ret = -EINVAL;
3568 goto exit;
3569 }
3570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3571 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3572
3573 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3574 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003575#ifdef FEATURE_WLAN_OKC
3576 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3577 {
3578 tANI_U8 *value = command;
3579 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3580
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003581 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003582 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003584 hdd_is_okc_mode_enabled(pHddCtx) &&
3585 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3586 {
3587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003588 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003589 " hence this operation is not permitted!", __func__);
3590 ret = -EPERM;
3591 goto exit;
3592 }
3593
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003594 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3595 value = value + 11;
3596 /* Convert the value from ascii to integer */
3597 ret = kstrtou8(value, 10, &okcMode);
3598 if (ret < 0)
3599 {
3600 /* If the input value is greater than max value of datatype, then also
3601 kstrtou8 fails */
3602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3603 "%s: kstrtou8 failed range [%d - %d]", __func__,
3604 CFG_OKC_FEATURE_ENABLED_MIN,
3605 CFG_OKC_FEATURE_ENABLED_MAX);
3606 ret = -EINVAL;
3607 goto exit;
3608 }
3609
3610 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3611 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3612 {
3613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3614 "Okc mode value %d is out of range"
3615 " (Min: %d Max: %d)", okcMode,
3616 CFG_OKC_FEATURE_ENABLED_MIN,
3617 CFG_OKC_FEATURE_ENABLED_MAX);
3618 ret = -EINVAL;
3619 goto exit;
3620 }
3621
3622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3623 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3624
3625 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3626 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003627#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003628 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3629 {
3630 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3631 char extra[32];
3632 tANI_U8 len = 0;
3633
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003634 len = scnprintf(extra, sizeof(extra), "%s %d",
3635 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003636 if (copy_to_user(priv_data.buf, &extra, len + 1))
3637 {
3638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3639 "%s: failed to copy data to user buffer", __func__);
3640 ret = -EFAULT;
3641 goto exit;
3642 }
3643 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303644#ifdef WLAN_FEATURE_PACKET_FILTERING
3645 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3646 {
3647 tANI_U8 filterType = 0;
3648 tANI_U8 *value = command;
3649
3650 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3651 value = value + 22;
3652
3653 /* Convert the value from ascii to integer */
3654 ret = kstrtou8(value, 10, &filterType);
3655 if (ret < 0)
3656 {
3657 /* If the input value is greater than max value of datatype,
3658 * then also kstrtou8 fails
3659 */
3660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3661 "%s: kstrtou8 failed range ", __func__);
3662 ret = -EINVAL;
3663 goto exit;
3664 }
3665
3666 if (filterType != 0 && filterType != 1)
3667 {
3668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3669 "%s: Accepted Values are 0 and 1 ", __func__);
3670 ret = -EINVAL;
3671 goto exit;
3672 }
3673 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3674 pAdapter->sessionId);
3675 }
3676#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303677 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3678 {
Kiet Lam94fd2922014-06-18 19:12:43 -07003679 char *bcMode;
3680 bcMode = command + 11;
3681 if ('1' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303682 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003684 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303685
3686 pHddCtx->btCoexModeSet = TRUE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303687 }
Kiet Lam94fd2922014-06-18 19:12:43 -07003688 else if ('2' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303689 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003691 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303692
3693 pHddCtx->btCoexModeSet = FALSE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303694 }
3695 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003696 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3697 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3699 FL("making default scan to ACTIVE"));
3700 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003701 }
3702 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3703 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3705 FL("making default scan to PASSIVE"));
3706 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003707 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303708 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3709 {
3710 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3711 char extra[32];
3712 tANI_U8 len = 0;
3713
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303714 memset(extra, 0, sizeof(extra));
3715 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3716 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303717 {
3718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3719 "%s: failed to copy data to user buffer", __func__);
3720 ret = -EFAULT;
3721 goto exit;
3722 }
3723 ret = len;
3724 }
3725 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3726 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303727 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303728 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003729 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3730 {
3731 tANI_U8 filterType = 0;
3732 tANI_U8 *value;
3733 value = command + 9;
3734
3735 /* Convert the value from ascii to integer */
3736 ret = kstrtou8(value, 10, &filterType);
3737 if (ret < 0)
3738 {
3739 /* If the input value is greater than max value of datatype,
3740 * then also kstrtou8 fails
3741 */
3742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3743 "%s: kstrtou8 failed range ", __func__);
3744 ret = -EINVAL;
3745 goto exit;
3746 }
3747 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3748 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3749 {
3750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3751 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3752 " 2-Sink ", __func__);
3753 ret = -EINVAL;
3754 goto exit;
3755 }
3756 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3757 pHddCtx->drvr_miracast = filterType;
3758 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3759 }
Leo Chang614d2072013-08-22 14:59:44 -07003760 else if (strncmp(command, "SETMCRATE", 9) == 0)
3761 {
Leo Chang614d2072013-08-22 14:59:44 -07003762 tANI_U8 *value = command;
3763 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003764 tSirRateUpdateInd *rateUpdate;
3765 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003766
3767 /* Only valid for SAP mode */
3768 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3769 {
3770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3771 "%s: SAP mode is not running", __func__);
3772 ret = -EFAULT;
3773 goto exit;
3774 }
3775
3776 /* Move pointer to ahead of SETMCRATE<delimiter> */
3777 /* input value is in units of hundred kbps */
3778 value = value + 10;
3779 /* Convert the value from ascii to integer, decimal base */
3780 ret = kstrtouint(value, 10, &targetRate);
3781
Leo Chang1f98cbd2013-10-17 15:03:52 -07003782 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3783 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003784 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003785 hddLog(VOS_TRACE_LEVEL_ERROR,
3786 "%s: SETMCRATE indication alloc fail", __func__);
3787 ret = -EFAULT;
3788 goto exit;
3789 }
3790 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3791
3792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3793 "MC Target rate %d", targetRate);
3794 /* Ignore unicast */
3795 rateUpdate->ucastDataRate = -1;
3796 rateUpdate->mcastDataRate24GHz = targetRate;
3797 rateUpdate->mcastDataRate5GHz = targetRate;
3798 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3799 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3800 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3801 if (eHAL_STATUS_SUCCESS != status)
3802 {
3803 hddLog(VOS_TRACE_LEVEL_ERROR,
3804 "%s: SET_MC_RATE failed", __func__);
3805 vos_mem_free(rateUpdate);
3806 ret = -EFAULT;
3807 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003808 }
3809 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303810#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003811 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303812 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003813 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303814 }
3815#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003816#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003817 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3818 {
3819 tANI_U8 *value = command;
3820 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3821 tANI_U8 numChannels = 0;
3822 eHalStatus status = eHAL_STATUS_SUCCESS;
3823
3824 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3825 if (eHAL_STATUS_SUCCESS != status)
3826 {
3827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3828 "%s: Failed to parse channel list information", __func__);
3829 ret = -EINVAL;
3830 goto exit;
3831 }
3832
3833 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3834 {
3835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3836 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3837 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3838 ret = -EINVAL;
3839 goto exit;
3840 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003841 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003842 ChannelList,
3843 numChannels);
3844 if (eHAL_STATUS_SUCCESS != status)
3845 {
3846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3847 "%s: Failed to update channel list information", __func__);
3848 ret = -EINVAL;
3849 goto exit;
3850 }
3851 }
3852 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3853 {
3854 tANI_U8 *value = command;
3855 char extra[128] = {0};
3856 int len = 0;
3857 tANI_U8 tid = 0;
3858 hdd_station_ctx_t *pHddStaCtx = NULL;
3859 tAniTrafStrmMetrics tsmMetrics;
3860 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3861
3862 /* if not associated, return error */
3863 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3864 {
3865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3866 ret = -EINVAL;
3867 goto exit;
3868 }
3869
3870 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3871 value = value + 12;
3872 /* Convert the value from ascii to integer */
3873 ret = kstrtou8(value, 10, &tid);
3874 if (ret < 0)
3875 {
3876 /* If the input value is greater than max value of datatype, then also
3877 kstrtou8 fails */
3878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3879 "%s: kstrtou8 failed range [%d - %d]", __func__,
3880 TID_MIN_VALUE,
3881 TID_MAX_VALUE);
3882 ret = -EINVAL;
3883 goto exit;
3884 }
3885
3886 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3887 {
3888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3889 "tid value %d is out of range"
3890 " (Min: %d Max: %d)", tid,
3891 TID_MIN_VALUE,
3892 TID_MAX_VALUE);
3893 ret = -EINVAL;
3894 goto exit;
3895 }
3896
3897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3898 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3899
3900 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3901 {
3902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3903 "%s: failed to get tsm stats", __func__);
3904 ret = -EFAULT;
3905 goto exit;
3906 }
3907
3908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3909 "UplinkPktQueueDly(%d)\n"
3910 "UplinkPktQueueDlyHist[0](%d)\n"
3911 "UplinkPktQueueDlyHist[1](%d)\n"
3912 "UplinkPktQueueDlyHist[2](%d)\n"
3913 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303914 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003915 "UplinkPktLoss(%d)\n"
3916 "UplinkPktCount(%d)\n"
3917 "RoamingCount(%d)\n"
3918 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3919 tsmMetrics.UplinkPktQueueDlyHist[0],
3920 tsmMetrics.UplinkPktQueueDlyHist[1],
3921 tsmMetrics.UplinkPktQueueDlyHist[2],
3922 tsmMetrics.UplinkPktQueueDlyHist[3],
3923 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3924 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3925
3926 /* Output TSM stats is of the format
3927 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3928 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003929 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003930 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3931 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3932 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3933 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3934 tsmMetrics.RoamingDly);
3935
3936 if (copy_to_user(priv_data.buf, &extra, len + 1))
3937 {
3938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3939 "%s: failed to copy data to user buffer", __func__);
3940 ret = -EFAULT;
3941 goto exit;
3942 }
3943 }
3944 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3945 {
3946 tANI_U8 *value = command;
3947 tANI_U8 *cckmIe = NULL;
3948 tANI_U8 cckmIeLen = 0;
3949 eHalStatus status = eHAL_STATUS_SUCCESS;
3950
3951 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3952 if (eHAL_STATUS_SUCCESS != status)
3953 {
3954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3955 "%s: Failed to parse cckm ie data", __func__);
3956 ret = -EINVAL;
3957 goto exit;
3958 }
3959
3960 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3961 {
3962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3963 "%s: CCKM Ie input length is more than max[%d]", __func__,
3964 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003965 vos_mem_free(cckmIe);
3966 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003967 ret = -EINVAL;
3968 goto exit;
3969 }
3970 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003971 vos_mem_free(cckmIe);
3972 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003973 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003974 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3975 {
3976 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003977 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003978 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003979
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003980 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003981 if (eHAL_STATUS_SUCCESS != status)
3982 {
3983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003984 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003985 ret = -EINVAL;
3986 goto exit;
3987 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003988 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
3989 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
3990 hdd_indicateEseBcnReportNoResults (pAdapter,
3991 eseBcnReq.bcnReq[0].measurementToken,
3992 0x02, //BIT(1) set for measurement done
3993 0); // no BSS
3994 goto exit;
3995 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003996
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003997 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3998 if (eHAL_STATUS_SUCCESS != status)
3999 {
4000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4001 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4002 ret = -EINVAL;
4003 goto exit;
4004 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004005 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004006#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304007 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4008 {
4009 eHalStatus status;
4010 char buf[32], len;
4011 long waitRet;
4012 bcnMissRateContext_t getBcnMissRateCtx;
4013
4014 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4015
4016 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_WARN,
4019 FL("GETBCNMISSRATE: STA is not in connected state"));
4020 ret = -1;
4021 goto exit;
4022 }
4023
4024 init_completion(&(getBcnMissRateCtx.completion));
4025 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4026
4027 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4028 pAdapter->sessionId,
4029 (void *)getBcnMissRateCB,
4030 (void *)(&getBcnMissRateCtx));
4031 if( eHAL_STATUS_SUCCESS != status)
4032 {
4033 hddLog(VOS_TRACE_LEVEL_INFO,
4034 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4035 ret = -EINVAL;
4036 goto exit;
4037 }
4038
4039 waitRet = wait_for_completion_interruptible_timeout
4040 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4041 if(waitRet <= 0)
4042 {
4043 hddLog(VOS_TRACE_LEVEL_ERROR,
4044 FL("failed to wait on bcnMissRateComp %d"), ret);
4045
4046 //Make magic number to zero so that callback is not called.
4047 spin_lock(&hdd_context_lock);
4048 getBcnMissRateCtx.magic = 0x0;
4049 spin_unlock(&hdd_context_lock);
4050 ret = -EINVAL;
4051 goto exit;
4052 }
4053
4054 hddLog(VOS_TRACE_LEVEL_INFO,
4055 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4056
4057 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4058 if (copy_to_user(priv_data.buf, &buf, len + 1))
4059 {
4060 hddLog(VOS_TRACE_LEVEL_ERROR,
4061 "%s: failed to copy data to user buffer", __func__);
4062 ret = -EFAULT;
4063 goto exit;
4064 }
4065 ret = len;
4066 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004067 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304068 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4069 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4070 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004071 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4072 __func__, command);
4073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004074 }
4075exit:
4076 if (command)
4077 {
4078 kfree(command);
4079 }
4080 return ret;
4081}
4082
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004083#ifdef CONFIG_COMPAT
4084static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4085{
4086 struct {
4087 compat_uptr_t buf;
4088 int used_len;
4089 int total_len;
4090 } compat_priv_data;
4091 hdd_priv_data_t priv_data;
4092 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004093
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004094 /*
4095 * Note that pAdapter and ifr have already been verified by caller,
4096 * and HDD context has also been validated
4097 */
4098 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4099 sizeof(compat_priv_data))) {
4100 ret = -EFAULT;
4101 goto exit;
4102 }
4103 priv_data.buf = compat_ptr(compat_priv_data.buf);
4104 priv_data.used_len = compat_priv_data.used_len;
4105 priv_data.total_len = compat_priv_data.total_len;
4106 ret = hdd_driver_command(pAdapter, &priv_data);
4107 exit:
4108 return ret;
4109}
4110#else /* CONFIG_COMPAT */
4111static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4112{
4113 /* will never be invoked */
4114 return 0;
4115}
4116#endif /* CONFIG_COMPAT */
4117
4118static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4119{
4120 hdd_priv_data_t priv_data;
4121 int ret = 0;
4122
4123 /*
4124 * Note that pAdapter and ifr have already been verified by caller,
4125 * and HDD context has also been validated
4126 */
4127 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4128 ret = -EFAULT;
4129 } else {
4130 ret = hdd_driver_command(pAdapter, &priv_data);
4131 }
4132 return ret;
4133}
4134
4135int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4136{
4137 hdd_adapter_t *pAdapter;
4138 hdd_context_t *pHddCtx;
4139 int ret;
4140
4141 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4142 if (NULL == pAdapter) {
4143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4144 "%s: HDD adapter context is Null", __func__);
4145 ret = -ENODEV;
4146 goto exit;
4147 }
4148 if (dev != pAdapter->dev) {
4149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4150 "%s: HDD adapter/dev inconsistency", __func__);
4151 ret = -ENODEV;
4152 goto exit;
4153 }
4154
4155 if ((!ifr) || (!ifr->ifr_data)) {
4156 ret = -EINVAL;
4157 goto exit;
4158 }
4159
4160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4161 ret = wlan_hdd_validate_context(pHddCtx);
4162 if (ret) {
4163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4164 "%s: invalid context", __func__);
4165 ret = -EBUSY;
4166 goto exit;
4167 }
4168
4169 switch (cmd) {
4170 case (SIOCDEVPRIVATE + 1):
4171 if (is_compat_task())
4172 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4173 else
4174 ret = hdd_driver_ioctl(pAdapter, ifr);
4175 break;
4176 default:
4177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4178 __func__, cmd);
4179 ret = -EINVAL;
4180 break;
4181 }
4182 exit:
4183 return ret;
4184}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004185
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004186#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004187/**---------------------------------------------------------------------------
4188
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004189 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004190
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004191 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004192 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4193 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4194 <space>Scan Mode N<space>Meas Duration N
4195 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4196 then take N.
4197 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4198 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4199 This function does not take care of removing duplicate channels from the list
4200
4201 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004202 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004203
4204 \return - 0 for success non-zero for failure
4205
4206 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004207static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4208 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004209{
4210 tANI_U8 *inPtr = pValue;
4211 int tempInt = 0;
4212 int j = 0, i = 0, v = 0;
4213 char buf[32];
4214
4215 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4216 /*no argument after the command*/
4217 if (NULL == inPtr)
4218 {
4219 return -EINVAL;
4220 }
4221 /*no space after the command*/
4222 else if (SPACE_ASCII_VALUE != *inPtr)
4223 {
4224 return -EINVAL;
4225 }
4226
4227 /*removing empty spaces*/
4228 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4229
4230 /*no argument followed by spaces*/
4231 if ('\0' == *inPtr) return -EINVAL;
4232
4233 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004234 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004235 if (1 != v) return -EINVAL;
4236
4237 v = kstrtos32(buf, 10, &tempInt);
4238 if ( v < 0) return -EINVAL;
4239
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004240 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004241
4242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004243 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004244
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004245 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004246 {
4247 for (i = 0; i < 4; i++)
4248 {
4249 /*inPtr pointing to the beginning of first space after number of ie fields*/
4250 inPtr = strpbrk( inPtr, " " );
4251 /*no ie data after the number of ie fields argument*/
4252 if (NULL == inPtr) return -EINVAL;
4253
4254 /*removing empty space*/
4255 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4256
4257 /*no ie data after the number of ie fields argument and spaces*/
4258 if ( '\0' == *inPtr ) return -EINVAL;
4259
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004260 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004261 if (1 != v) return -EINVAL;
4262
4263 v = kstrtos32(buf, 10, &tempInt);
4264 if (v < 0) return -EINVAL;
4265
4266 switch (i)
4267 {
4268 case 0: /* Measurement token */
4269 if (tempInt <= 0)
4270 {
4271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4272 "Invalid Measurement Token(%d)", tempInt);
4273 return -EINVAL;
4274 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004275 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004276 break;
4277
4278 case 1: /* Channel number */
4279 if ((tempInt <= 0) ||
4280 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4281 {
4282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4283 "Invalid Channel Number(%d)", tempInt);
4284 return -EINVAL;
4285 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004286 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004287 break;
4288
4289 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004290 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004291 {
4292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4293 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4294 return -EINVAL;
4295 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004296 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004297 break;
4298
4299 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004300 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4301 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004302 {
4303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4304 "Invalid Measurement Duration(%d)", tempInt);
4305 return -EINVAL;
4306 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004307 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004308 break;
4309 }
4310 }
4311 }
4312
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004313 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004314 {
4315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304316 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004317 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004318 pEseBcnReq->bcnReq[j].measurementToken,
4319 pEseBcnReq->bcnReq[j].channel,
4320 pEseBcnReq->bcnReq[j].scanMode,
4321 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004322 }
4323
4324 return VOS_STATUS_SUCCESS;
4325}
4326
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004327static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4328{
4329 struct statsContext *pStatsContext = NULL;
4330 hdd_adapter_t *pAdapter = NULL;
4331
4332 if (NULL == pContext)
4333 {
4334 hddLog(VOS_TRACE_LEVEL_ERROR,
4335 "%s: Bad param, pContext [%p]",
4336 __func__, pContext);
4337 return;
4338 }
4339
Jeff Johnson72a40512013-12-19 10:14:15 -08004340 /* there is a race condition that exists between this callback
4341 function and the caller since the caller could time out either
4342 before or while this code is executing. we use a spinlock to
4343 serialize these actions */
4344 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004345
4346 pStatsContext = pContext;
4347 pAdapter = pStatsContext->pAdapter;
4348 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4349 {
4350 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004351 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004352 hddLog(VOS_TRACE_LEVEL_WARN,
4353 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4354 __func__, pAdapter, pStatsContext->magic);
4355 return;
4356 }
4357
Jeff Johnson72a40512013-12-19 10:14:15 -08004358 /* context is valid so caller is still waiting */
4359
4360 /* paranoia: invalidate the magic */
4361 pStatsContext->magic = 0;
4362
4363 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004364 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4365 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4366 tsmMetrics.UplinkPktQueueDlyHist,
4367 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4368 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4369 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4370 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4371 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4372 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4373 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4374
Jeff Johnson72a40512013-12-19 10:14:15 -08004375 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004376 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004377
4378 /* serialization is complete */
4379 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004380}
4381
4382
4383
4384static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4385 tAniTrafStrmMetrics* pTsmMetrics)
4386{
4387 hdd_station_ctx_t *pHddStaCtx = NULL;
4388 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004389 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004390 long lrc;
4391 struct statsContext context;
4392 hdd_context_t *pHddCtx = NULL;
4393
4394 if (NULL == pAdapter)
4395 {
4396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4397 return VOS_STATUS_E_FAULT;
4398 }
4399
4400 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4401 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4402
4403 /* we are connected prepare our callback context */
4404 init_completion(&context.completion);
4405 context.pAdapter = pAdapter;
4406 context.magic = STATS_CONTEXT_MAGIC;
4407
4408 /* query tsm stats */
4409 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4410 pHddStaCtx->conn_info.staId[ 0 ],
4411 pHddStaCtx->conn_info.bssId,
4412 &context, pHddCtx->pvosContext, tid);
4413
4414 if (eHAL_STATUS_SUCCESS != hstatus)
4415 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4417 __func__);
4418 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004419 }
4420 else
4421 {
4422 /* request was sent -- wait for the response */
4423 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4424 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004425 if (lrc <= 0)
4426 {
4427 hddLog(VOS_TRACE_LEVEL_ERROR,
4428 "%s: SME %s while retrieving statistics",
4429 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004430 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004431 }
4432 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004433
Jeff Johnson72a40512013-12-19 10:14:15 -08004434 /* either we never sent a request, we sent a request and received a
4435 response or we sent a request and timed out. if we never sent a
4436 request or if we sent a request and got a response, we want to
4437 clear the magic out of paranoia. if we timed out there is a
4438 race condition such that the callback function could be
4439 executing at the same time we are. of primary concern is if the
4440 callback function had already verified the "magic" but had not
4441 yet set the completion variable when a timeout occurred. we
4442 serialize these activities by invalidating the magic while
4443 holding a shared spinlock which will cause us to block if the
4444 callback is currently executing */
4445 spin_lock(&hdd_context_lock);
4446 context.magic = 0;
4447 spin_unlock(&hdd_context_lock);
4448
4449 if (VOS_STATUS_SUCCESS == vstatus)
4450 {
4451 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4452 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4453 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4454 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4455 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4456 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4457 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4458 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4459 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4460 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4461 }
4462 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004463}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004464#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004465
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004466#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004467void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4468{
4469 eCsrBand band = -1;
4470 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4471 switch (band)
4472 {
4473 case eCSR_BAND_ALL:
4474 *pBand = WLAN_HDD_UI_BAND_AUTO;
4475 break;
4476
4477 case eCSR_BAND_24:
4478 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4479 break;
4480
4481 case eCSR_BAND_5G:
4482 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4483 break;
4484
4485 default:
4486 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4487 *pBand = -1;
4488 break;
4489 }
4490}
4491
4492/**---------------------------------------------------------------------------
4493
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004494 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4495
4496 This function parses the send action frame data passed in the format
4497 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4498
Srinivas Girigowda56076852013-08-20 14:00:50 -07004499 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004500 \param - pTargetApBssid Pointer to target Ap bssid
4501 \param - pChannel Pointer to the Target AP channel
4502 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4503 \param - pBuf Pointer to data
4504 \param - pBufLen Pointer to data length
4505
4506 \return - 0 for success non-zero for failure
4507
4508 --------------------------------------------------------------------------*/
4509VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4510 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4511{
4512 tANI_U8 *inPtr = pValue;
4513 tANI_U8 *dataEnd;
4514 int tempInt;
4515 int j = 0;
4516 int i = 0;
4517 int v = 0;
4518 tANI_U8 tempBuf[32];
4519 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004520 /* 12 hexa decimal digits, 5 ':' and '\0' */
4521 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004522
4523 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4524 /*no argument after the command*/
4525 if (NULL == inPtr)
4526 {
4527 return -EINVAL;
4528 }
4529
4530 /*no space after the command*/
4531 else if (SPACE_ASCII_VALUE != *inPtr)
4532 {
4533 return -EINVAL;
4534 }
4535
4536 /*removing empty spaces*/
4537 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4538
4539 /*no argument followed by spaces*/
4540 if ('\0' == *inPtr)
4541 {
4542 return -EINVAL;
4543 }
4544
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004545 v = sscanf(inPtr, "%17s", macAddress);
4546 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004547 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4549 "Invalid MAC address or All hex inputs are not read (%d)", v);
4550 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004551 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004552
4553 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4554 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4555 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4556 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4557 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4558 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004559
4560 /* point to the next argument */
4561 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4562 /*no argument after the command*/
4563 if (NULL == inPtr) return -EINVAL;
4564
4565 /*removing empty spaces*/
4566 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4567
4568 /*no argument followed by spaces*/
4569 if ('\0' == *inPtr)
4570 {
4571 return -EINVAL;
4572 }
4573
4574 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004575 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004576 if (1 != v) return -EINVAL;
4577
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004578 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304579 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304580 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004581
4582 *pChannel = tempInt;
4583
4584 /* point to the next argument */
4585 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4586 /*no argument after the command*/
4587 if (NULL == inPtr) return -EINVAL;
4588 /*removing empty spaces*/
4589 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4590
4591 /*no argument followed by spaces*/
4592 if ('\0' == *inPtr)
4593 {
4594 return -EINVAL;
4595 }
4596
4597 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004598 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004599 if (1 != v) return -EINVAL;
4600
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004601 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004602 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004603
4604 *pDwellTime = tempInt;
4605
4606 /* point to the next argument */
4607 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4608 /*no argument after the command*/
4609 if (NULL == inPtr) return -EINVAL;
4610 /*removing empty spaces*/
4611 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4612
4613 /*no argument followed by spaces*/
4614 if ('\0' == *inPtr)
4615 {
4616 return -EINVAL;
4617 }
4618
4619 /* find the length of data */
4620 dataEnd = inPtr;
4621 while(('\0' != *dataEnd) )
4622 {
4623 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004624 }
Kiet Lambe150c22013-11-21 16:30:32 +05304625 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004626 if ( *pBufLen <= 0) return -EINVAL;
4627
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004628 /* Allocate the number of bytes based on the number of input characters
4629 whether it is even or odd.
4630 if the number of input characters are even, then we need N/2 byte.
4631 if the number of input characters are odd, then we need do (N+1)/2 to
4632 compensate rounding off.
4633 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4634 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4635 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004636 if (NULL == *pBuf)
4637 {
4638 hddLog(VOS_TRACE_LEVEL_FATAL,
4639 "%s: vos_mem_alloc failed ", __func__);
4640 return -EINVAL;
4641 }
4642
4643 /* the buffer received from the upper layer is character buffer,
4644 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4645 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4646 and f0 in 3rd location */
4647 for (i = 0, j = 0; j < *pBufLen; j += 2)
4648 {
Kiet Lambe150c22013-11-21 16:30:32 +05304649 if( j+1 == *pBufLen)
4650 {
4651 tempByte = hdd_parse_hex(inPtr[j]);
4652 }
4653 else
4654 {
4655 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4656 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004657 (*pBuf)[i++] = tempByte;
4658 }
4659 *pBufLen = i;
4660 return VOS_STATUS_SUCCESS;
4661}
4662
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004663/**---------------------------------------------------------------------------
4664
Srinivas Girigowdade697412013-02-14 16:31:48 -08004665 \brief hdd_parse_channellist() - HDD Parse channel list
4666
4667 This function parses the channel list passed in the format
4668 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004669 if the Number of channels (N) does not match with the actual number of channels passed
4670 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4671 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4672 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4673 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004674
4675 \param - pValue Pointer to input channel list
4676 \param - ChannelList Pointer to local output array to record channel list
4677 \param - pNumChannels Pointer to number of roam scan channels
4678
4679 \return - 0 for success non-zero for failure
4680
4681 --------------------------------------------------------------------------*/
4682VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4683{
4684 tANI_U8 *inPtr = pValue;
4685 int tempInt;
4686 int j = 0;
4687 int v = 0;
4688 char buf[32];
4689
4690 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4691 /*no argument after the command*/
4692 if (NULL == inPtr)
4693 {
4694 return -EINVAL;
4695 }
4696
4697 /*no space after the command*/
4698 else if (SPACE_ASCII_VALUE != *inPtr)
4699 {
4700 return -EINVAL;
4701 }
4702
4703 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004704 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004705
4706 /*no argument followed by spaces*/
4707 if ('\0' == *inPtr)
4708 {
4709 return -EINVAL;
4710 }
4711
4712 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004713 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004714 if (1 != v) return -EINVAL;
4715
Srinivas Girigowdade697412013-02-14 16:31:48 -08004716 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004717 if ((v < 0) ||
4718 (tempInt <= 0) ||
4719 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4720 {
4721 return -EINVAL;
4722 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004723
4724 *pNumChannels = tempInt;
4725
4726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4727 "Number of channels are: %d", *pNumChannels);
4728
4729 for (j = 0; j < (*pNumChannels); j++)
4730 {
4731 /*inPtr pointing to the beginning of first space after number of channels*/
4732 inPtr = strpbrk( inPtr, " " );
4733 /*no channel list after the number of channels argument*/
4734 if (NULL == inPtr)
4735 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004736 if (0 != j)
4737 {
4738 *pNumChannels = j;
4739 return VOS_STATUS_SUCCESS;
4740 }
4741 else
4742 {
4743 return -EINVAL;
4744 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004745 }
4746
4747 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004748 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004749
4750 /*no channel list after the number of channels argument and spaces*/
4751 if ( '\0' == *inPtr )
4752 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004753 if (0 != j)
4754 {
4755 *pNumChannels = j;
4756 return VOS_STATUS_SUCCESS;
4757 }
4758 else
4759 {
4760 return -EINVAL;
4761 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004762 }
4763
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004764 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004765 if (1 != v) return -EINVAL;
4766
Srinivas Girigowdade697412013-02-14 16:31:48 -08004767 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004768 if ((v < 0) ||
4769 (tempInt <= 0) ||
4770 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4771 {
4772 return -EINVAL;
4773 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004774 pChannelList[j] = tempInt;
4775
4776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4777 "Channel %d added to preferred channel list",
4778 pChannelList[j] );
4779 }
4780
Srinivas Girigowdade697412013-02-14 16:31:48 -08004781 return VOS_STATUS_SUCCESS;
4782}
4783
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004784
4785/**---------------------------------------------------------------------------
4786
4787 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4788
4789 This function parses the reasoc command data passed in the format
4790 REASSOC<space><bssid><space><channel>
4791
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004792 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004793 \param - pTargetApBssid Pointer to target Ap bssid
4794 \param - pChannel Pointer to the Target AP channel
4795
4796 \return - 0 for success non-zero for failure
4797
4798 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004799VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4800 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004801{
4802 tANI_U8 *inPtr = pValue;
4803 int tempInt;
4804 int v = 0;
4805 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004806 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004807 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004808
4809 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4810 /*no argument after the command*/
4811 if (NULL == inPtr)
4812 {
4813 return -EINVAL;
4814 }
4815
4816 /*no space after the command*/
4817 else if (SPACE_ASCII_VALUE != *inPtr)
4818 {
4819 return -EINVAL;
4820 }
4821
4822 /*removing empty spaces*/
4823 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4824
4825 /*no argument followed by spaces*/
4826 if ('\0' == *inPtr)
4827 {
4828 return -EINVAL;
4829 }
4830
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004831 v = sscanf(inPtr, "%17s", macAddress);
4832 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004833 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4835 "Invalid MAC address or All hex inputs are not read (%d)", v);
4836 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004837 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004838
4839 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4840 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4841 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4842 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4843 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4844 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004845
4846 /* point to the next argument */
4847 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4848 /*no argument after the command*/
4849 if (NULL == inPtr) return -EINVAL;
4850
4851 /*removing empty spaces*/
4852 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4853
4854 /*no argument followed by spaces*/
4855 if ('\0' == *inPtr)
4856 {
4857 return -EINVAL;
4858 }
4859
4860 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004861 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004862 if (1 != v) return -EINVAL;
4863
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004864 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004865 if ((v < 0) ||
4866 (tempInt <= 0) ||
4867 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4868 {
4869 return -EINVAL;
4870 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004871
4872 *pChannel = tempInt;
4873 return VOS_STATUS_SUCCESS;
4874}
4875
4876#endif
4877
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004878#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004879/**---------------------------------------------------------------------------
4880
4881 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4882
4883 This function parses the SETCCKM IE command
4884 SETCCKMIE<space><ie data>
4885
4886 \param - pValue Pointer to input data
4887 \param - pCckmIe Pointer to output cckm Ie
4888 \param - pCckmIeLen Pointer to output cckm ie length
4889
4890 \return - 0 for success non-zero for failure
4891
4892 --------------------------------------------------------------------------*/
4893VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4894 tANI_U8 *pCckmIeLen)
4895{
4896 tANI_U8 *inPtr = pValue;
4897 tANI_U8 *dataEnd;
4898 int j = 0;
4899 int i = 0;
4900 tANI_U8 tempByte = 0;
4901
4902 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4903 /*no argument after the command*/
4904 if (NULL == inPtr)
4905 {
4906 return -EINVAL;
4907 }
4908
4909 /*no space after the command*/
4910 else if (SPACE_ASCII_VALUE != *inPtr)
4911 {
4912 return -EINVAL;
4913 }
4914
4915 /*removing empty spaces*/
4916 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4917
4918 /*no argument followed by spaces*/
4919 if ('\0' == *inPtr)
4920 {
4921 return -EINVAL;
4922 }
4923
4924 /* find the length of data */
4925 dataEnd = inPtr;
4926 while(('\0' != *dataEnd) )
4927 {
4928 dataEnd++;
4929 ++(*pCckmIeLen);
4930 }
4931 if ( *pCckmIeLen <= 0) return -EINVAL;
4932
4933 /* Allocate the number of bytes based on the number of input characters
4934 whether it is even or odd.
4935 if the number of input characters are even, then we need N/2 byte.
4936 if the number of input characters are odd, then we need do (N+1)/2 to
4937 compensate rounding off.
4938 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4939 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4940 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4941 if (NULL == *pCckmIe)
4942 {
4943 hddLog(VOS_TRACE_LEVEL_FATAL,
4944 "%s: vos_mem_alloc failed ", __func__);
4945 return -EINVAL;
4946 }
4947 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4948 /* the buffer received from the upper layer is character buffer,
4949 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4950 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4951 and f0 in 3rd location */
4952 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4953 {
4954 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4955 (*pCckmIe)[i++] = tempByte;
4956 }
4957 *pCckmIeLen = i;
4958
4959 return VOS_STATUS_SUCCESS;
4960}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004961#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004962
Jeff Johnson295189b2012-06-20 16:38:30 -07004963/**---------------------------------------------------------------------------
4964
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004965 \brief hdd_is_valid_mac_address() - Validate MAC address
4966
4967 This function validates whether the given MAC address is valid or not
4968 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4969 where X is the hexa decimal digit character and separated by ':'
4970 This algorithm works even if MAC address is not separated by ':'
4971
4972 This code checks given input string mac contains exactly 12 hexadecimal digits.
4973 and a separator colon : appears in the input string only after
4974 an even number of hex digits.
4975
4976 \param - pMacAddr pointer to the input MAC address
4977 \return - 1 for valid and 0 for invalid
4978
4979 --------------------------------------------------------------------------*/
4980
4981v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4982{
4983 int xdigit = 0;
4984 int separator = 0;
4985 while (*pMacAddr)
4986 {
4987 if (isxdigit(*pMacAddr))
4988 {
4989 xdigit++;
4990 }
4991 else if (':' == *pMacAddr)
4992 {
4993 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4994 break;
4995
4996 ++separator;
4997 }
4998 else
4999 {
5000 separator = -1;
5001 /* Invalid MAC found */
5002 return 0;
5003 }
5004 ++pMacAddr;
5005 }
5006 return (xdigit == 12 && (separator == 5 || separator == 0));
5007}
5008
5009/**---------------------------------------------------------------------------
5010
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 \brief hdd_open() - HDD Open function
5012
5013 This is called in response to ifconfig up
5014
5015 \param - dev Pointer to net_device structure
5016
5017 \return - 0 for success non-zero for failure
5018
5019 --------------------------------------------------------------------------*/
5020int hdd_open (struct net_device *dev)
5021{
5022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5023 hdd_context_t *pHddCtx;
5024 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5025 VOS_STATUS status;
5026 v_BOOL_t in_standby = TRUE;
5027
5028 if (NULL == pAdapter)
5029 {
5030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305031 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005032 return -ENODEV;
5033 }
5034
5035 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305036 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5037 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005038 if (NULL == pHddCtx)
5039 {
5040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005041 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005042 return -ENODEV;
5043 }
5044
5045 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5046 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5047 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005048 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5049 {
5050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305051 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005052 in_standby = FALSE;
5053 break;
5054 }
5055 else
5056 {
5057 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5058 pAdapterNode = pNext;
5059 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005060 }
5061
5062 if (TRUE == in_standby)
5063 {
5064 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5065 {
5066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5067 "wlan out of power save", __func__);
5068 return -EINVAL;
5069 }
5070 }
5071
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005072 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005073 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5074 {
5075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005076 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 /* Enable TX queues only when we are connected */
5078 netif_tx_start_all_queues(dev);
5079 }
5080
5081 return 0;
5082}
5083
5084int hdd_mon_open (struct net_device *dev)
5085{
5086 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5087
5088 if(pAdapter == NULL) {
5089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005090 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005091 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 }
5093
5094 netif_start_queue(dev);
5095
5096 return 0;
5097}
5098/**---------------------------------------------------------------------------
5099
5100 \brief hdd_stop() - HDD stop function
5101
5102 This is called in response to ifconfig down
5103
5104 \param - dev Pointer to net_device structure
5105
5106 \return - 0 for success non-zero for failure
5107
5108 --------------------------------------------------------------------------*/
5109
5110int hdd_stop (struct net_device *dev)
5111{
5112 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5113 hdd_context_t *pHddCtx;
5114 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5115 VOS_STATUS status;
5116 v_BOOL_t enter_standby = TRUE;
5117
5118 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005119 if (NULL == pAdapter)
5120 {
5121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305122 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005123 return -ENODEV;
5124 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305125 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5126 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005127 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5128 if (NULL == pHddCtx)
5129 {
5130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005131 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 return -ENODEV;
5133 }
5134
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305135 /* Nothing to be done if the interface is not opened */
5136 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5137 {
5138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5139 "%s: NETDEV Interface is not OPENED", __func__);
5140 return -ENODEV;
5141 }
5142
5143 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005144 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305146
5147 /* Disable TX on the interface, after this hard_start_xmit() will not
5148 * be called on that interface
5149 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305151
5152 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005153 netif_carrier_off(pAdapter->dev);
5154
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305155 /* The interface is marked as down for outside world (aka kernel)
5156 * But the driver is pretty much alive inside. The driver needs to
5157 * tear down the existing connection on the netdev (session)
5158 * cleanup the data pipes and wait until the control plane is stabilized
5159 * for this interface. The call also needs to wait until the above
5160 * mentioned actions are completed before returning to the caller.
5161 * Notice that the hdd_stop_adapter is requested not to close the session
5162 * That is intentional to be able to scan if it is a STA/P2P interface
5163 */
5164 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005165
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305166 /* DeInit the adapter. This ensures datapath cleanup as well */
5167 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005168 /* SoftAP ifaces should never go in power save mode
5169 making sure same here. */
5170 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5171 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005172 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005173 )
5174 {
5175 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5177 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005178 EXIT();
5179 return 0;
5180 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305181 /* Find if any iface is up. If any iface is up then can't put device to
5182 * sleep/power save mode
5183 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005184 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5185 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5186 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005187 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5188 {
5189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305190 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005191 enter_standby = FALSE;
5192 break;
5193 }
5194 else
5195 {
5196 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5197 pAdapterNode = pNext;
5198 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005199 }
5200
5201 if (TRUE == enter_standby)
5202 {
5203 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5204 "entering standby", __func__);
5205 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5206 {
5207 /*log and return success*/
5208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5209 "wlan in power save", __func__);
5210 }
5211 }
5212
5213 EXIT();
5214 return 0;
5215}
5216
5217/**---------------------------------------------------------------------------
5218
5219 \brief hdd_uninit() - HDD uninit function
5220
5221 This is called during the netdev unregister to uninitialize all data
5222associated with the device
5223
5224 \param - dev Pointer to net_device structure
5225
5226 \return - void
5227
5228 --------------------------------------------------------------------------*/
5229static void hdd_uninit (struct net_device *dev)
5230{
5231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5232
5233 ENTER();
5234
5235 do
5236 {
5237 if (NULL == pAdapter)
5238 {
5239 hddLog(VOS_TRACE_LEVEL_FATAL,
5240 "%s: NULL pAdapter", __func__);
5241 break;
5242 }
5243
5244 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5245 {
5246 hddLog(VOS_TRACE_LEVEL_FATAL,
5247 "%s: Invalid magic", __func__);
5248 break;
5249 }
5250
5251 if (NULL == pAdapter->pHddCtx)
5252 {
5253 hddLog(VOS_TRACE_LEVEL_FATAL,
5254 "%s: NULL pHddCtx", __func__);
5255 break;
5256 }
5257
5258 if (dev != pAdapter->dev)
5259 {
5260 hddLog(VOS_TRACE_LEVEL_FATAL,
5261 "%s: Invalid device reference", __func__);
5262 /* we haven't validated all cases so let this go for now */
5263 }
5264
5265 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5266
5267 /* after uninit our adapter structure will no longer be valid */
5268 pAdapter->dev = NULL;
5269 pAdapter->magic = 0;
5270 } while (0);
5271
5272 EXIT();
5273}
5274
5275/**---------------------------------------------------------------------------
5276
5277 \brief hdd_release_firmware() -
5278
5279 This function calls the release firmware API to free the firmware buffer.
5280
5281 \param - pFileName Pointer to the File Name.
5282 pCtx - Pointer to the adapter .
5283
5284
5285 \return - 0 for success, non zero for failure
5286
5287 --------------------------------------------------------------------------*/
5288
5289VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5290{
5291 VOS_STATUS status = VOS_STATUS_SUCCESS;
5292 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5293 ENTER();
5294
5295
5296 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5297
5298 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5299
5300 if(pHddCtx->fw) {
5301 release_firmware(pHddCtx->fw);
5302 pHddCtx->fw = NULL;
5303 }
5304 else
5305 status = VOS_STATUS_E_FAILURE;
5306 }
5307 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5308 if(pHddCtx->nv) {
5309 release_firmware(pHddCtx->nv);
5310 pHddCtx->nv = NULL;
5311 }
5312 else
5313 status = VOS_STATUS_E_FAILURE;
5314
5315 }
5316
5317 EXIT();
5318 return status;
5319}
5320
5321/**---------------------------------------------------------------------------
5322
5323 \brief hdd_request_firmware() -
5324
5325 This function reads the firmware file using the request firmware
5326 API and returns the the firmware data and the firmware file size.
5327
5328 \param - pfileName - Pointer to the file name.
5329 - pCtx - Pointer to the adapter .
5330 - ppfw_data - Pointer to the pointer of the firmware data.
5331 - pSize - Pointer to the file size.
5332
5333 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5334
5335 --------------------------------------------------------------------------*/
5336
5337
5338VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5339{
5340 int status;
5341 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5342 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5343 ENTER();
5344
5345 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5346
5347 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5348
5349 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5350 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5351 __func__, pfileName);
5352 retval = VOS_STATUS_E_FAILURE;
5353 }
5354
5355 else {
5356 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5357 *pSize = pHddCtx->fw->size;
5358 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5359 __func__, *pSize);
5360 }
5361 }
5362 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5363
5364 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5365
5366 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5367 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5368 __func__, pfileName);
5369 retval = VOS_STATUS_E_FAILURE;
5370 }
5371
5372 else {
5373 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5374 *pSize = pHddCtx->nv->size;
5375 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5376 __func__, *pSize);
5377 }
5378 }
5379
5380 EXIT();
5381 return retval;
5382}
5383/**---------------------------------------------------------------------------
5384 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5385
5386 This is the function invoked by SME to inform the result of a full power
5387 request issued by HDD
5388
5389 \param - callbackcontext - Pointer to cookie
5390 status - result of request
5391
5392 \return - None
5393
5394--------------------------------------------------------------------------*/
5395void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5396{
5397 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5398
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005399 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 if(&pHddCtx->full_pwr_comp_var)
5401 {
5402 complete(&pHddCtx->full_pwr_comp_var);
5403 }
5404}
5405
5406/**---------------------------------------------------------------------------
5407
5408 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5409
5410 This is the function invoked by SME to inform the result of BMPS
5411 request issued by HDD
5412
5413 \param - callbackcontext - Pointer to cookie
5414 status - result of request
5415
5416 \return - None
5417
5418--------------------------------------------------------------------------*/
5419void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5420{
5421
5422 struct completion *completion_var = (struct completion*) callbackContext;
5423
Arif Hussain6d2a3322013-11-17 19:50:10 -08005424 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 if(completion_var != NULL)
5426 {
5427 complete(completion_var);
5428 }
5429}
5430
5431/**---------------------------------------------------------------------------
5432
5433 \brief hdd_get_cfg_file_size() -
5434
5435 This function reads the configuration file using the request firmware
5436 API and returns the configuration file size.
5437
5438 \param - pCtx - Pointer to the adapter .
5439 - pFileName - Pointer to the file name.
5440 - pBufSize - Pointer to the buffer size.
5441
5442 \return - 0 for success, non zero for failure
5443
5444 --------------------------------------------------------------------------*/
5445
5446VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5447{
5448 int status;
5449 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5450
5451 ENTER();
5452
5453 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5454
5455 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5456 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5457 status = VOS_STATUS_E_FAILURE;
5458 }
5459 else {
5460 *pBufSize = pHddCtx->fw->size;
5461 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5462 release_firmware(pHddCtx->fw);
5463 pHddCtx->fw = NULL;
5464 }
5465
5466 EXIT();
5467 return VOS_STATUS_SUCCESS;
5468}
5469
5470/**---------------------------------------------------------------------------
5471
5472 \brief hdd_read_cfg_file() -
5473
5474 This function reads the configuration file using the request firmware
5475 API and returns the cfg data and the buffer size of the configuration file.
5476
5477 \param - pCtx - Pointer to the adapter .
5478 - pFileName - Pointer to the file name.
5479 - pBuffer - Pointer to the data buffer.
5480 - pBufSize - Pointer to the buffer size.
5481
5482 \return - 0 for success, non zero for failure
5483
5484 --------------------------------------------------------------------------*/
5485
5486VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5487 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5488{
5489 int status;
5490 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5491
5492 ENTER();
5493
5494 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5495
5496 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5497 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5498 return VOS_STATUS_E_FAILURE;
5499 }
5500 else {
5501 if(*pBufSize != pHddCtx->fw->size) {
5502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5503 "file size", __func__);
5504 release_firmware(pHddCtx->fw);
5505 pHddCtx->fw = NULL;
5506 return VOS_STATUS_E_FAILURE;
5507 }
5508 else {
5509 if(pBuffer) {
5510 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5511 }
5512 release_firmware(pHddCtx->fw);
5513 pHddCtx->fw = NULL;
5514 }
5515 }
5516
5517 EXIT();
5518
5519 return VOS_STATUS_SUCCESS;
5520}
5521
5522/**---------------------------------------------------------------------------
5523
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 \brief hdd_set_mac_address() -
5525
5526 This function sets the user specified mac address using
5527 the command ifconfig wlanX hw ether <mac adress>.
5528
5529 \param - dev - Pointer to the net device.
5530 - addr - Pointer to the sockaddr.
5531 \return - 0 for success, non zero for failure
5532
5533 --------------------------------------------------------------------------*/
5534
5535static int hdd_set_mac_address(struct net_device *dev, void *addr)
5536{
5537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5538 struct sockaddr *psta_mac_addr = addr;
5539 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5540
5541 ENTER();
5542
5543 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5545
5546 EXIT();
5547 return halStatus;
5548}
5549
5550tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5551{
5552 int i;
5553 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5554 {
Abhishek Singheb183782014-02-06 13:37:21 +05305555 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 break;
5557 }
5558
5559 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5560 return NULL;
5561
5562 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5563 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5564}
5565
5566void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5567{
5568 int i;
5569 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5570 {
5571 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5572 {
5573 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5574 break;
5575 }
5576 }
5577 return;
5578}
5579
5580#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5581 static struct net_device_ops wlan_drv_ops = {
5582 .ndo_open = hdd_open,
5583 .ndo_stop = hdd_stop,
5584 .ndo_uninit = hdd_uninit,
5585 .ndo_start_xmit = hdd_hard_start_xmit,
5586 .ndo_tx_timeout = hdd_tx_timeout,
5587 .ndo_get_stats = hdd_stats,
5588 .ndo_do_ioctl = hdd_ioctl,
5589 .ndo_set_mac_address = hdd_set_mac_address,
5590 .ndo_select_queue = hdd_select_queue,
5591#ifdef WLAN_FEATURE_PACKET_FILTERING
5592#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5593 .ndo_set_rx_mode = hdd_set_multicast_list,
5594#else
5595 .ndo_set_multicast_list = hdd_set_multicast_list,
5596#endif //LINUX_VERSION_CODE
5597#endif
5598 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 static struct net_device_ops wlan_mon_drv_ops = {
5600 .ndo_open = hdd_mon_open,
5601 .ndo_stop = hdd_stop,
5602 .ndo_uninit = hdd_uninit,
5603 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5604 .ndo_tx_timeout = hdd_tx_timeout,
5605 .ndo_get_stats = hdd_stats,
5606 .ndo_do_ioctl = hdd_ioctl,
5607 .ndo_set_mac_address = hdd_set_mac_address,
5608 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005609
5610#endif
5611
5612void hdd_set_station_ops( struct net_device *pWlanDev )
5613{
5614#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 pWlanDev->netdev_ops = &wlan_drv_ops;
5616#else
5617 pWlanDev->open = hdd_open;
5618 pWlanDev->stop = hdd_stop;
5619 pWlanDev->uninit = hdd_uninit;
5620 pWlanDev->hard_start_xmit = NULL;
5621 pWlanDev->tx_timeout = hdd_tx_timeout;
5622 pWlanDev->get_stats = hdd_stats;
5623 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 pWlanDev->set_mac_address = hdd_set_mac_address;
5625#endif
5626}
5627
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005628static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005629{
5630 struct net_device *pWlanDev = NULL;
5631 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 /*
5633 * cfg80211 initialization and registration....
5634 */
5635 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5636
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 if(pWlanDev != NULL)
5638 {
5639
5640 //Save the pointer to the net_device in the HDD adapter
5641 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5642
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5644
5645 pAdapter->dev = pWlanDev;
5646 pAdapter->pHddCtx = pHddCtx;
5647 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5648
5649 init_completion(&pAdapter->session_open_comp_var);
5650 init_completion(&pAdapter->session_close_comp_var);
5651 init_completion(&pAdapter->disconnect_comp_var);
5652 init_completion(&pAdapter->linkup_event_var);
5653 init_completion(&pAdapter->cancel_rem_on_chan_var);
5654 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305655 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5657 init_completion(&pAdapter->offchannel_tx_event);
5658#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005660#ifdef FEATURE_WLAN_TDLS
5661 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005662 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005663 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305664 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005665#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005666 init_completion(&pHddCtx->mc_sus_event_var);
5667 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305668 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005669 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005670 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005671
Rajeev79dbe4c2013-10-05 11:03:42 +05305672#ifdef FEATURE_WLAN_BATCH_SCAN
5673 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5674 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5675 pAdapter->pBatchScanRsp = NULL;
5676 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005677 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005678 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305679 mutex_init(&pAdapter->hdd_batch_scan_lock);
5680#endif
5681
Jeff Johnson295189b2012-06-20 16:38:30 -07005682 pAdapter->isLinkUpSvcNeeded = FALSE;
5683 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5684 //Init the net_device structure
5685 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5686
5687 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5688 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5689 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5690 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5691
5692 hdd_set_station_ops( pAdapter->dev );
5693
5694 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005695 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5696 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5697 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 /* set pWlanDev's parent to underlying device */
5699 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005700
5701 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 }
5703
5704 return pAdapter;
5705}
5706
5707VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5708{
5709 struct net_device *pWlanDev = pAdapter->dev;
5710 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5711 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5712 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5713
5714 if( rtnl_lock_held )
5715 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005716 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5718 {
5719 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5720 return VOS_STATUS_E_FAILURE;
5721 }
5722 }
5723 if (register_netdevice(pWlanDev))
5724 {
5725 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5726 return VOS_STATUS_E_FAILURE;
5727 }
5728 }
5729 else
5730 {
5731 if(register_netdev(pWlanDev))
5732 {
5733 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5734 return VOS_STATUS_E_FAILURE;
5735 }
5736 }
5737 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5738
5739 return VOS_STATUS_SUCCESS;
5740}
5741
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005742static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005743{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005744 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005745
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005746 if (NULL == pAdapter)
5747 {
5748 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5749 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005751
5752 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5753 {
5754 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5755 return eHAL_STATUS_NOT_INITIALIZED;
5756 }
5757
5758 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5759
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005760#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005761 /* need to make sure all of our scheduled work has completed.
5762 * This callback is called from MC thread context, so it is safe to
5763 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005764 *
5765 * Even though this is called from MC thread context, if there is a faulty
5766 * work item in the system, that can hang this call forever. So flushing
5767 * this global work queue is not safe; and now we make sure that
5768 * individual work queues are stopped correctly. But the cancel work queue
5769 * is a GPL only API, so the proprietary version of the driver would still
5770 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005771 */
5772 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005773#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005774
5775 /* We can be blocked while waiting for scheduled work to be
5776 * flushed, and the adapter structure can potentially be freed, in
5777 * which case the magic will have been reset. So make sure the
5778 * magic is still good, and hence the adapter structure is still
5779 * valid, before signaling completion */
5780 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5781 {
5782 complete(&pAdapter->session_close_comp_var);
5783 }
5784
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 return eHAL_STATUS_SUCCESS;
5786}
5787
5788VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5789{
5790 struct net_device *pWlanDev = pAdapter->dev;
5791 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5792 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5793 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5794 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305795 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005796
5797 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005798 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005799 //Open a SME session for future operation
5800 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005801 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5803 {
5804 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005805 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 halStatus, halStatus );
5807 status = VOS_STATUS_E_FAILURE;
5808 goto error_sme_open;
5809 }
5810
5811 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305812 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 &pAdapter->session_open_comp_var,
5814 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305815 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 {
5817 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305818 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 status = VOS_STATUS_E_FAILURE;
5820 goto error_sme_open;
5821 }
5822
5823 // Register wireless extensions
5824 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5825 {
5826 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005827 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 halStatus, halStatus );
5829 status = VOS_STATUS_E_FAILURE;
5830 goto error_register_wext;
5831 }
5832 //Safe to register the hard_start_xmit function again
5833#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5834 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5835#else
5836 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5837#endif
5838
5839 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305840 hddLog(VOS_TRACE_LEVEL_INFO,
5841 "%s: Set HDD connState to eConnectionState_NotConnected",
5842 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005843 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5844
5845 //Set the default operation channel
5846 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5847
5848 /* Make the default Auth Type as OPEN*/
5849 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5850
5851 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5852 {
5853 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005854 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 status, status );
5856 goto error_init_txrx;
5857 }
5858
5859 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5860
5861 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5862 {
5863 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005864 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 status, status );
5866 goto error_wmm_init;
5867 }
5868
5869 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5870
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005871#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305872 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005873 {
5874 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305875 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005876 goto error_tdls_init;
5877 }
5878 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5879#endif
5880
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 return VOS_STATUS_SUCCESS;
5882
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005883#ifdef FEATURE_WLAN_TDLS
5884error_tdls_init:
5885 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5886 hdd_wmm_adapter_close(pAdapter);
5887#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005888error_wmm_init:
5889 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5890 hdd_deinit_tx_rx(pAdapter);
5891error_init_txrx:
5892 hdd_UnregisterWext(pWlanDev);
5893error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005894 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 {
5896 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005897 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005899 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305901 unsigned long rc;
5902
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305904 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005906 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305907 if (rc <= 0)
5908 hddLog(VOS_TRACE_LEVEL_ERROR,
5909 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 }
5911}
5912error_sme_open:
5913 return status;
5914}
5915
Jeff Johnson295189b2012-06-20 16:38:30 -07005916void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5917{
5918 hdd_cfg80211_state_t *cfgState;
5919
5920 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5921
5922 if( NULL != cfgState->buf )
5923 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305924 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5926 rc = wait_for_completion_interruptible_timeout(
5927 &pAdapter->tx_action_cnf_event,
5928 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305929 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305932 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5933 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005934 }
5935 }
5936 return;
5937}
Jeff Johnson295189b2012-06-20 16:38:30 -07005938
5939void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5940{
5941 ENTER();
5942 switch ( pAdapter->device_mode )
5943 {
5944 case WLAN_HDD_INFRA_STATION:
5945 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005946 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005947 {
5948 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5949 {
5950 hdd_deinit_tx_rx( pAdapter );
5951 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5952 }
5953
5954 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5955 {
5956 hdd_wmm_adapter_close( pAdapter );
5957 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5958 }
5959
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005961#ifdef FEATURE_WLAN_TDLS
5962 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5963 {
5964 wlan_hdd_tdls_exit(pAdapter);
5965 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5966 }
5967#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005968
5969 break;
5970 }
5971
5972 case WLAN_HDD_SOFTAP:
5973 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305975
5976 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5977 {
5978 hdd_wmm_adapter_close( pAdapter );
5979 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5980 }
5981
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005983
5984 hdd_unregister_hostapd(pAdapter);
5985 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 break;
5988 }
5989
5990 case WLAN_HDD_MONITOR:
5991 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005992 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005993 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5994 {
5995 hdd_deinit_tx_rx( pAdapter );
5996 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5997 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005998 if(NULL != pAdapterforTx)
5999 {
6000 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 break;
6003 }
6004
6005
6006 default:
6007 break;
6008 }
6009
6010 EXIT();
6011}
6012
6013void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6014{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006015 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306016
6017 ENTER();
6018 if (NULL == pAdapter)
6019 {
6020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6021 "%s: HDD adapter is Null", __func__);
6022 return;
6023 }
6024
6025 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006026
Rajeev79dbe4c2013-10-05 11:03:42 +05306027#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306028 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6029 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006030 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306031 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6032 )
6033 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006034 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306035 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006036 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6037 {
6038 hdd_deinit_batch_scan(pAdapter);
6039 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306040 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006041 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306042#endif
6043
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6045 if( rtnl_held )
6046 {
6047 unregister_netdevice(pWlanDev);
6048 }
6049 else
6050 {
6051 unregister_netdev(pWlanDev);
6052 }
6053 // note that the pAdapter is no longer valid at this point
6054 // since the memory has been reclaimed
6055 }
6056
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306057 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006058}
6059
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006060void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6061{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306062 VOS_STATUS status;
6063 hdd_adapter_t *pAdapter = NULL;
6064 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006065
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306066 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006067
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306068 /*loop through all adapters.*/
6069 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006070 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306071 pAdapter = pAdapterNode->pAdapter;
6072 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6073 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006074
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306075 { // we skip this registration for modes other than STA and P2P client modes.
6076 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6077 pAdapterNode = pNext;
6078 continue;
6079 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006080
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306081 //Apply Dynamic DTIM For P2P
6082 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6083 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6084 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6085 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6086 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6087 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6088 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6089 (eConnectionState_Associated ==
6090 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6091 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6092 {
6093 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006094
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306095 powerRequest.uIgnoreDTIM = 1;
6096 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6097
6098 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6099 {
6100 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6101 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6102 }
6103 else
6104 {
6105 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6106 }
6107
6108 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6109 * specified during Enter/Exit BMPS when LCD off*/
6110 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6111 NULL, eANI_BOOLEAN_FALSE);
6112 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6113 NULL, eANI_BOOLEAN_FALSE);
6114
6115 /* switch to the DTIM specified in cfg.ini */
6116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6117 "Switch to DTIM %d", powerRequest.uListenInterval);
6118 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6119 break;
6120
6121 }
6122
6123 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6124 pAdapterNode = pNext;
6125 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006126}
6127
6128void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6129{
6130 /*Switch back to DTIM 1*/
6131 tSirSetPowerParamsReq powerRequest = { 0 };
6132
6133 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6134 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006135 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006136
6137 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6138 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6139 NULL, eANI_BOOLEAN_FALSE);
6140 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6141 NULL, eANI_BOOLEAN_FALSE);
6142
6143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6144 "Switch to DTIM%d",powerRequest.uListenInterval);
6145 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6146
6147}
6148
Jeff Johnson295189b2012-06-20 16:38:30 -07006149VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6150{
6151 VOS_STATUS status = VOS_STATUS_SUCCESS;
6152
6153 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6154 {
6155 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6156 }
6157
6158 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6159 {
6160 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6161 }
6162
6163 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6164 {
6165 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6166 }
6167
6168 return status;
6169}
6170
6171VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6172{
6173 hdd_adapter_t *pAdapter = NULL;
6174 eHalStatus halStatus;
6175 VOS_STATUS status = VOS_STATUS_E_INVAL;
6176 v_BOOL_t disableBmps = FALSE;
6177 v_BOOL_t disableImps = FALSE;
6178
6179 switch(session_type)
6180 {
6181 case WLAN_HDD_INFRA_STATION:
6182 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 case WLAN_HDD_P2P_CLIENT:
6184 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 //Exit BMPS -> Is Sta/P2P Client is already connected
6186 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6187 if((NULL != pAdapter)&&
6188 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6189 {
6190 disableBmps = TRUE;
6191 }
6192
6193 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6194 if((NULL != pAdapter)&&
6195 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6196 {
6197 disableBmps = TRUE;
6198 }
6199
6200 //Exit both Bmps and Imps incase of Go/SAP Mode
6201 if((WLAN_HDD_SOFTAP == session_type) ||
6202 (WLAN_HDD_P2P_GO == session_type))
6203 {
6204 disableBmps = TRUE;
6205 disableImps = TRUE;
6206 }
6207
6208 if(TRUE == disableImps)
6209 {
6210 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6211 {
6212 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6213 }
6214 }
6215
6216 if(TRUE == disableBmps)
6217 {
6218 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6219 {
6220 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6221
6222 if(eHAL_STATUS_SUCCESS != halStatus)
6223 {
6224 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006225 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 VOS_ASSERT(0);
6227 return status;
6228 }
6229 }
6230
6231 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6232 {
6233 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6234
6235 if(eHAL_STATUS_SUCCESS != halStatus)
6236 {
6237 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006238 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 VOS_ASSERT(0);
6240 return status;
6241 }
6242 }
6243 }
6244
6245 if((TRUE == disableBmps) ||
6246 (TRUE == disableImps))
6247 {
6248 /* Now, get the chip into Full Power now */
6249 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6250 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6251 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6252
6253 if(halStatus != eHAL_STATUS_SUCCESS)
6254 {
6255 if(halStatus == eHAL_STATUS_PMC_PENDING)
6256 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306257 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 ret = wait_for_completion_interruptible_timeout(
6260 &pHddCtx->full_pwr_comp_var,
6261 msecs_to_jiffies(1000));
6262 if (ret <= 0)
6263 {
6264 hddLog(VOS_TRACE_LEVEL_ERROR,
6265 "%s: wait on full_pwr_comp_var failed %ld",
6266 __func__, ret);
6267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 }
6269 else
6270 {
6271 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006272 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 VOS_ASSERT(0);
6274 return status;
6275 }
6276 }
6277
6278 status = VOS_STATUS_SUCCESS;
6279 }
6280
6281 break;
6282 }
6283 return status;
6284}
6285
6286hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006287 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 tANI_U8 rtnl_held )
6289{
6290 hdd_adapter_t *pAdapter = NULL;
6291 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6292 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6293 VOS_STATUS exitbmpsStatus;
6294
Arif Hussain6d2a3322013-11-17 19:50:10 -08006295 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006296
Nirav Shah436658f2014-02-28 17:05:45 +05306297 if(macAddr == NULL)
6298 {
6299 /* Not received valid macAddr */
6300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6301 "%s:Unable to add virtual intf: Not able to get"
6302 "valid mac address",__func__);
6303 return NULL;
6304 }
6305
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 //Disable BMPS incase of Concurrency
6307 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6308
6309 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6310 {
6311 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306312 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 VOS_ASSERT(0);
6314 return NULL;
6315 }
6316
6317 switch(session_type)
6318 {
6319 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006321 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 {
6323 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6324
6325 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306326 {
6327 hddLog(VOS_TRACE_LEVEL_FATAL,
6328 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306330 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006331
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306332#ifdef FEATURE_WLAN_TDLS
6333 /* A Mutex Lock is introduced while changing/initializing the mode to
6334 * protect the concurrent access for the Adapters by TDLS module.
6335 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306336 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306337#endif
6338
Jeff Johnsone7245742012-09-05 17:12:55 -07006339 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6340 NL80211_IFTYPE_P2P_CLIENT:
6341 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006342
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306344#ifdef FEATURE_WLAN_TDLS
6345 mutex_unlock(&pHddCtx->tdls_lock);
6346#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306347
6348 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 if( VOS_STATUS_SUCCESS != status )
6350 goto err_free_netdev;
6351
6352 status = hdd_register_interface( pAdapter, rtnl_held );
6353 if( VOS_STATUS_SUCCESS != status )
6354 {
6355 hdd_deinit_adapter(pHddCtx, pAdapter);
6356 goto err_free_netdev;
6357 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306358
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306359 // Workqueue which gets scheduled in IPv4 notification callback.
6360 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6361
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306362#ifdef WLAN_NS_OFFLOAD
6363 // Workqueue which gets scheduled in IPv6 notification callback.
6364 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6365#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 //Stop the Interface TX queue.
6367 netif_tx_disable(pAdapter->dev);
6368 //netif_tx_disable(pWlanDev);
6369 netif_carrier_off(pAdapter->dev);
6370
6371 break;
6372 }
6373
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 case WLAN_HDD_SOFTAP:
6376 {
6377 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6378 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306379 {
6380 hddLog(VOS_TRACE_LEVEL_FATAL,
6381 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306383 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006384
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6386 NL80211_IFTYPE_AP:
6387 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 pAdapter->device_mode = session_type;
6389
6390 status = hdd_init_ap_mode(pAdapter);
6391 if( VOS_STATUS_SUCCESS != status )
6392 goto err_free_netdev;
6393
6394 status = hdd_register_hostapd( pAdapter, rtnl_held );
6395 if( VOS_STATUS_SUCCESS != status )
6396 {
6397 hdd_deinit_adapter(pHddCtx, pAdapter);
6398 goto err_free_netdev;
6399 }
6400
6401 netif_tx_disable(pAdapter->dev);
6402 netif_carrier_off(pAdapter->dev);
6403
6404 hdd_set_conparam( 1 );
6405 break;
6406 }
6407 case WLAN_HDD_MONITOR:
6408 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6410 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306411 {
6412 hddLog(VOS_TRACE_LEVEL_FATAL,
6413 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306415 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006416
6417 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6418 pAdapter->device_mode = session_type;
6419 status = hdd_register_interface( pAdapter, rtnl_held );
6420#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6421 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6422#else
6423 pAdapter->dev->open = hdd_mon_open;
6424 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6425#endif
6426 hdd_init_tx_rx( pAdapter );
6427 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6428 //Set adapter to be used for data tx. It will use either GO or softap.
6429 pAdapter->sessionCtx.monitor.pAdapterForTx =
6430 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6432 {
6433 pAdapter->sessionCtx.monitor.pAdapterForTx =
6434 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6435 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 /* This workqueue will be used to transmit management packet over
6437 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006438 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6439 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6440 return NULL;
6441 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006442
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6444 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 }
6446 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 case WLAN_HDD_FTM:
6448 {
6449 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6450
6451 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306452 {
6453 hddLog(VOS_TRACE_LEVEL_FATAL,
6454 FL("failed to allocate adapter for session %d"), session_type);
6455 return NULL;
6456 }
6457
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6459 * message while loading driver in FTM mode. */
6460 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6461 pAdapter->device_mode = session_type;
6462 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306463
6464 hdd_init_tx_rx( pAdapter );
6465
6466 //Stop the Interface TX queue.
6467 netif_tx_disable(pAdapter->dev);
6468 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 }
6470 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 default:
6472 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306473 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6474 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 VOS_ASSERT(0);
6476 return NULL;
6477 }
6478 }
6479
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 if( VOS_STATUS_SUCCESS == status )
6481 {
6482 //Add it to the hdd's session list.
6483 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6484 if( NULL == pHddAdapterNode )
6485 {
6486 status = VOS_STATUS_E_NOMEM;
6487 }
6488 else
6489 {
6490 pHddAdapterNode->pAdapter = pAdapter;
6491 status = hdd_add_adapter_back ( pHddCtx,
6492 pHddAdapterNode );
6493 }
6494 }
6495
6496 if( VOS_STATUS_SUCCESS != status )
6497 {
6498 if( NULL != pAdapter )
6499 {
6500 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6501 pAdapter = NULL;
6502 }
6503 if( NULL != pHddAdapterNode )
6504 {
6505 vos_mem_free( pHddAdapterNode );
6506 }
6507
6508 goto resume_bmps;
6509 }
6510
6511 if(VOS_STATUS_SUCCESS == status)
6512 {
6513 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6514
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006515 //Initialize the WoWL service
6516 if(!hdd_init_wowl(pAdapter))
6517 {
6518 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6519 goto err_free_netdev;
6520 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006521 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006522 return pAdapter;
6523
6524err_free_netdev:
6525 free_netdev(pAdapter->dev);
6526 wlan_hdd_release_intf_addr( pHddCtx,
6527 pAdapter->macAddressCurrent.bytes );
6528
6529resume_bmps:
6530 //If bmps disabled enable it
6531 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6532 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306533 if (pHddCtx->hdd_wlan_suspended)
6534 {
6535 hdd_set_pwrparams(pHddCtx);
6536 }
6537 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 }
6539 return NULL;
6540}
6541
6542VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6543 tANI_U8 rtnl_held )
6544{
6545 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6546 VOS_STATUS status;
6547
6548 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6549 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306550 {
6551 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6552 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006553 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006555
6556 while ( pCurrent->pAdapter != pAdapter )
6557 {
6558 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6559 if( VOS_STATUS_SUCCESS != status )
6560 break;
6561
6562 pCurrent = pNext;
6563 }
6564 pAdapterNode = pCurrent;
6565 if( VOS_STATUS_SUCCESS == status )
6566 {
6567 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6568 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306569
6570#ifdef FEATURE_WLAN_TDLS
6571
6572 /* A Mutex Lock is introduced while changing/initializing the mode to
6573 * protect the concurrent access for the Adapters by TDLS module.
6574 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306575 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306576#endif
6577
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 hdd_remove_adapter( pHddCtx, pAdapterNode );
6579 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006580 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006581
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306582#ifdef FEATURE_WLAN_TDLS
6583 mutex_unlock(&pHddCtx->tdls_lock);
6584#endif
6585
Jeff Johnson295189b2012-06-20 16:38:30 -07006586
6587 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306588 if ((!vos_concurrent_open_sessions_running()) &&
6589 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6590 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006591 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306592 if (pHddCtx->hdd_wlan_suspended)
6593 {
6594 hdd_set_pwrparams(pHddCtx);
6595 }
6596 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006597 }
6598
6599 return VOS_STATUS_SUCCESS;
6600 }
6601
6602 return VOS_STATUS_E_FAILURE;
6603}
6604
6605VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6606{
6607 hdd_adapter_list_node_t *pHddAdapterNode;
6608 VOS_STATUS status;
6609
6610 ENTER();
6611
6612 do
6613 {
6614 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6615 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6616 {
6617 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6618 vos_mem_free( pHddAdapterNode );
6619 }
6620 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6621
6622 EXIT();
6623
6624 return VOS_STATUS_SUCCESS;
6625}
6626
6627void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6628{
6629 v_U8_t addIE[1] = {0};
6630
6631 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6632 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6633 eANI_BOOLEAN_FALSE) )
6634 {
6635 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006636 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006637 }
6638
6639 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6640 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6641 eANI_BOOLEAN_FALSE) )
6642 {
6643 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006644 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 }
6646
6647 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6648 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6649 eANI_BOOLEAN_FALSE) )
6650 {
6651 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006652 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 }
6654}
6655
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306656VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6657 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006658{
6659 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6660 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6661 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306662 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306663 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006664
6665 ENTER();
6666
6667 switch(pAdapter->device_mode)
6668 {
6669 case WLAN_HDD_INFRA_STATION:
6670 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006671 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306672 {
6673 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6674 if( hdd_connIsConnected(pstation) ||
6675 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 {
6677 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6678 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6679 pAdapter->sessionId,
6680 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6681 else
6682 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6683 pAdapter->sessionId,
6684 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6685 //success implies disconnect command got queued up successfully
6686 if(halStatus == eHAL_STATUS_SUCCESS)
6687 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306688 ret = wait_for_completion_interruptible_timeout(
6689 &pAdapter->disconnect_comp_var,
6690 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6691 if (ret <= 0)
6692 {
6693 hddLog(VOS_TRACE_LEVEL_ERROR,
6694 "%s: wait on disconnect_comp_var failed %ld",
6695 __func__, ret);
6696 }
6697 }
6698 else
6699 {
6700 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6701 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 }
6703 memset(&wrqu, '\0', sizeof(wrqu));
6704 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6705 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6706 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6707 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306708 else if(pstation->conn_info.connState ==
6709 eConnectionState_Disconnecting)
6710 {
6711 ret = wait_for_completion_interruptible_timeout(
6712 &pAdapter->disconnect_comp_var,
6713 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6714 if (ret <= 0)
6715 {
6716 hddLog(VOS_TRACE_LEVEL_ERROR,
6717 FL("wait on disconnect_comp_var failed %ld"), ret);
6718 }
6719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 else
6721 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306722 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6723 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306725 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6726 {
6727 while (pAdapter->is_roc_inprogress)
6728 {
6729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6730 "%s: ROC in progress for session %d!!!",
6731 __func__, pAdapter->sessionId);
6732 // waiting for ROC to expire
6733 msleep(500);
6734 /* In GO present case , if retry exceeds 3,
6735 it means something went wrong. */
6736 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6737 {
6738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6739 "%s: ROC completion is not received.!!!", __func__);
6740 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6741 pAdapter->sessionId);
6742 wait_for_completion_interruptible_timeout(
6743 &pAdapter->cancel_rem_on_chan_var,
6744 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6745 break;
6746 }
6747 }
6748 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306749#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306750#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306751 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6752#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306753 if (pAdapter->ipv6_notifier_registered)
6754 {
6755 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6756 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6757 pAdapter->ipv6_notifier_registered = false;
6758 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306759#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306760 if (pAdapter->ipv4_notifier_registered)
6761 {
6762 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6763 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6764 pAdapter->ipv4_notifier_registered = false;
6765 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306766#ifdef WLAN_OPEN_SOURCE
6767 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6768#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306769 /* It is possible that the caller of this function does not
6770 * wish to close the session
6771 */
6772 if (VOS_TRUE == bCloseSession &&
6773 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 {
6775 INIT_COMPLETION(pAdapter->session_close_comp_var);
6776 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306777 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6778 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306780 unsigned long ret;
6781
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306783 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306784 &pAdapter->session_close_comp_var,
6785 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306786 if ( 0 >= ret)
6787 {
6788 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306789 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 }
6792 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 break;
6795
6796 case WLAN_HDD_SOFTAP:
6797 case WLAN_HDD_P2P_GO:
6798 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306799 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6800 while (pAdapter->is_roc_inprogress) {
6801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6802 "%s: ROC in progress for session %d!!!",
6803 __func__, pAdapter->sessionId);
6804 msleep(500);
6805 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6807 "%s: ROC completion is not received.!!!", __func__);
6808 WLANSAP_CancelRemainOnChannel(
6809 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6810 wait_for_completion_interruptible_timeout(
6811 &pAdapter->cancel_rem_on_chan_var,
6812 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6813 break;
6814 }
6815 }
6816 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006817 mutex_lock(&pHddCtx->sap_lock);
6818 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6819 {
6820 VOS_STATUS status;
6821 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6822
6823 //Stop Bss.
6824 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6825 if (VOS_IS_STATUS_SUCCESS(status))
6826 {
6827 hdd_hostapd_state_t *pHostapdState =
6828 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6829
6830 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6831
6832 if (!VOS_IS_STATUS_SUCCESS(status))
6833 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306834 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6835 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006836 }
6837 }
6838 else
6839 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006840 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 }
6842 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306843 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006844
6845 if (eHAL_STATUS_FAILURE ==
6846 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6847 0, NULL, eANI_BOOLEAN_FALSE))
6848 {
6849 hddLog(LOGE,
6850 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006851 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006852 }
6853
6854 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6855 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6856 eANI_BOOLEAN_FALSE) )
6857 {
6858 hddLog(LOGE,
6859 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6860 }
6861
6862 // Reset WNI_CFG_PROBE_RSP Flags
6863 wlan_hdd_reset_prob_rspies(pAdapter);
6864 kfree(pAdapter->sessionCtx.ap.beacon);
6865 pAdapter->sessionCtx.ap.beacon = NULL;
6866 }
6867 mutex_unlock(&pHddCtx->sap_lock);
6868 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006869
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006871#ifdef WLAN_OPEN_SOURCE
6872 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6873#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006875
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 default:
6877 break;
6878 }
6879
6880 EXIT();
6881 return VOS_STATUS_SUCCESS;
6882}
6883
6884VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6885{
6886 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6887 VOS_STATUS status;
6888 hdd_adapter_t *pAdapter;
6889
6890 ENTER();
6891
6892 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6893
6894 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6895 {
6896 pAdapter = pAdapterNode->pAdapter;
6897 netif_tx_disable(pAdapter->dev);
6898 netif_carrier_off(pAdapter->dev);
6899
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306900 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006901
6902 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6903 pAdapterNode = pNext;
6904 }
6905
6906 EXIT();
6907
6908 return VOS_STATUS_SUCCESS;
6909}
6910
Rajeev Kumarf999e582014-01-09 17:33:29 -08006911
6912#ifdef FEATURE_WLAN_BATCH_SCAN
6913/**---------------------------------------------------------------------------
6914
6915 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6916 structures
6917
6918 \param - pAdapter Pointer to HDD adapter
6919
6920 \return - None
6921
6922 --------------------------------------------------------------------------*/
6923void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6924{
6925 tHddBatchScanRsp *pNode;
6926 tHddBatchScanRsp *pPrev;
6927
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306928 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006929 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306930 hddLog(VOS_TRACE_LEVEL_ERROR,
6931 "%s: Adapter context is Null", __func__);
6932 return;
6933 }
6934
6935 pNode = pAdapter->pBatchScanRsp;
6936 while (pNode)
6937 {
6938 pPrev = pNode;
6939 pNode = pNode->pNext;
6940 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006941 }
6942
6943 pAdapter->pBatchScanRsp = NULL;
6944 pAdapter->numScanList = 0;
6945 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6946 pAdapter->prev_batch_id = 0;
6947
6948 return;
6949}
6950#endif
6951
6952
Jeff Johnson295189b2012-06-20 16:38:30 -07006953VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6954{
6955 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6956 VOS_STATUS status;
6957 hdd_adapter_t *pAdapter;
6958
6959 ENTER();
6960
6961 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6962
6963 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6964 {
6965 pAdapter = pAdapterNode->pAdapter;
6966 netif_tx_disable(pAdapter->dev);
6967 netif_carrier_off(pAdapter->dev);
6968
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006969 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6970
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306972 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6973 {
6974 hdd_wmm_adapter_close( pAdapter );
6975 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6976 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006977
Rajeev Kumarf999e582014-01-09 17:33:29 -08006978#ifdef FEATURE_WLAN_BATCH_SCAN
6979 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6980 {
6981 hdd_deinit_batch_scan(pAdapter);
6982 }
6983#endif
6984
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6986 pAdapterNode = pNext;
6987 }
6988
6989 EXIT();
6990
6991 return VOS_STATUS_SUCCESS;
6992}
6993
6994VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6995{
6996 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6997 VOS_STATUS status;
6998 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306999 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007000
7001 ENTER();
7002
7003 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7004
7005 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7006 {
7007 pAdapter = pAdapterNode->pAdapter;
7008
Kumar Anand82c009f2014-05-29 00:29:42 -07007009 hdd_wmm_init( pAdapter );
7010
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 switch(pAdapter->device_mode)
7012 {
7013 case WLAN_HDD_INFRA_STATION:
7014 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007015 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307016
7017 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7018
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 hdd_init_station_mode(pAdapter);
7020 /* Open the gates for HDD to receive Wext commands */
7021 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007022 pHddCtx->scan_info.mScanPending = FALSE;
7023 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007024
7025 //Trigger the initial scan
7026 hdd_wlan_initial_scan(pAdapter);
7027
7028 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307029 if (eConnectionState_Associated == connState ||
7030 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 {
7032 union iwreq_data wrqu;
7033 memset(&wrqu, '\0', sizeof(wrqu));
7034 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7035 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7036 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007037 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007038
Jeff Johnson295189b2012-06-20 16:38:30 -07007039 /* indicate disconnected event to nl80211 */
7040 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7041 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307043 else if (eConnectionState_Connecting == connState)
7044 {
7045 /*
7046 * Indicate connect failure to supplicant if we were in the
7047 * process of connecting
7048 */
7049 cfg80211_connect_result(pAdapter->dev, NULL,
7050 NULL, 0, NULL, 0,
7051 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7052 GFP_KERNEL);
7053 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 break;
7055
7056 case WLAN_HDD_SOFTAP:
7057 /* softAP can handle SSR */
7058 break;
7059
7060 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007063 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 break;
7065
7066 case WLAN_HDD_MONITOR:
7067 /* monitor interface start */
7068 break;
7069 default:
7070 break;
7071 }
7072
7073 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7074 pAdapterNode = pNext;
7075 }
7076
7077 EXIT();
7078
7079 return VOS_STATUS_SUCCESS;
7080}
7081
7082VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7083{
7084 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7085 hdd_adapter_t *pAdapter;
7086 VOS_STATUS status;
7087 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307088 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007089
7090 ENTER();
7091
7092 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7093
7094 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7095 {
7096 pAdapter = pAdapterNode->pAdapter;
7097
7098 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7099 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7100 {
7101 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7102 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7103
Abhishek Singhf4669da2014-05-26 15:07:49 +05307104 hddLog(VOS_TRACE_LEVEL_INFO,
7105 "%s: Set HDD connState to eConnectionState_NotConnected",
7106 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7108 init_completion(&pAdapter->disconnect_comp_var);
7109 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7110 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7111
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307112 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 &pAdapter->disconnect_comp_var,
7114 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307115 if (0 >= ret)
7116 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7117 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007118
7119 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7120 pHddCtx->isAmpAllowed = VOS_FALSE;
7121 sme_RoamConnect(pHddCtx->hHal,
7122 pAdapter->sessionId, &(pWextState->roamProfile),
7123 &roamId);
7124 }
7125
7126 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7127 pAdapterNode = pNext;
7128 }
7129
7130 EXIT();
7131
7132 return VOS_STATUS_SUCCESS;
7133}
7134
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007135void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7136{
7137 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7138 VOS_STATUS status;
7139 hdd_adapter_t *pAdapter;
7140 hdd_station_ctx_t *pHddStaCtx;
7141 hdd_ap_ctx_t *pHddApCtx;
7142 hdd_hostapd_state_t * pHostapdState;
7143 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7144 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7145 const char *p2pMode = "DEV";
7146 const char *ccMode = "Standalone";
7147 int n;
7148
7149 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7150 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7151 {
7152 pAdapter = pAdapterNode->pAdapter;
7153 switch (pAdapter->device_mode) {
7154 case WLAN_HDD_INFRA_STATION:
7155 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7156 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7157 staChannel = pHddStaCtx->conn_info.operationChannel;
7158 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7159 }
7160 break;
7161 case WLAN_HDD_P2P_CLIENT:
7162 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7163 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7164 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7165 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7166 p2pMode = "CLI";
7167 }
7168 break;
7169 case WLAN_HDD_P2P_GO:
7170 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7171 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7172 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7173 p2pChannel = pHddApCtx->operatingChannel;
7174 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7175 }
7176 p2pMode = "GO";
7177 break;
7178 case WLAN_HDD_SOFTAP:
7179 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7180 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7181 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7182 apChannel = pHddApCtx->operatingChannel;
7183 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7184 }
7185 break;
7186 default:
7187 break;
7188 }
7189 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7190 pAdapterNode = pNext;
7191 }
7192 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7193 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7194 }
7195 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7196 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7197 if (p2pChannel > 0) {
7198 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7199 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7200 }
7201 if (apChannel > 0) {
7202 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7203 apChannel, MAC_ADDR_ARRAY(apBssid));
7204 }
7205
7206 if (p2pChannel > 0 && apChannel > 0) {
7207 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7208 }
7209}
7210
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007211bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007212{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007213 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007214}
7215
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007216/* Once SSR is disabled then it cannot be set. */
7217void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007218{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007219 if (HDD_SSR_DISABLED == isSsrRequired)
7220 return;
7221
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 isSsrRequired = value;
7223}
7224
7225VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7226 hdd_adapter_list_node_t** ppAdapterNode)
7227{
7228 VOS_STATUS status;
7229 spin_lock(&pHddCtx->hddAdapters.lock);
7230 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7231 (hdd_list_node_t**) ppAdapterNode );
7232 spin_unlock(&pHddCtx->hddAdapters.lock);
7233 return status;
7234}
7235
7236VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7237 hdd_adapter_list_node_t* pAdapterNode,
7238 hdd_adapter_list_node_t** pNextAdapterNode)
7239{
7240 VOS_STATUS status;
7241 spin_lock(&pHddCtx->hddAdapters.lock);
7242 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7243 (hdd_list_node_t*) pAdapterNode,
7244 (hdd_list_node_t**)pNextAdapterNode );
7245
7246 spin_unlock(&pHddCtx->hddAdapters.lock);
7247 return status;
7248}
7249
7250VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7251 hdd_adapter_list_node_t* pAdapterNode)
7252{
7253 VOS_STATUS status;
7254 spin_lock(&pHddCtx->hddAdapters.lock);
7255 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7256 &pAdapterNode->node );
7257 spin_unlock(&pHddCtx->hddAdapters.lock);
7258 return status;
7259}
7260
7261VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7262 hdd_adapter_list_node_t** ppAdapterNode)
7263{
7264 VOS_STATUS status;
7265 spin_lock(&pHddCtx->hddAdapters.lock);
7266 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7267 (hdd_list_node_t**) ppAdapterNode );
7268 spin_unlock(&pHddCtx->hddAdapters.lock);
7269 return status;
7270}
7271
7272VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7273 hdd_adapter_list_node_t* pAdapterNode)
7274{
7275 VOS_STATUS status;
7276 spin_lock(&pHddCtx->hddAdapters.lock);
7277 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7278 (hdd_list_node_t*) pAdapterNode );
7279 spin_unlock(&pHddCtx->hddAdapters.lock);
7280 return status;
7281}
7282
7283VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7284 hdd_adapter_list_node_t* pAdapterNode)
7285{
7286 VOS_STATUS status;
7287 spin_lock(&pHddCtx->hddAdapters.lock);
7288 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7289 (hdd_list_node_t*) pAdapterNode );
7290 spin_unlock(&pHddCtx->hddAdapters.lock);
7291 return status;
7292}
7293
7294hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7295 tSirMacAddr macAddr )
7296{
7297 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7298 hdd_adapter_t *pAdapter;
7299 VOS_STATUS status;
7300
7301 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7302
7303 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7304 {
7305 pAdapter = pAdapterNode->pAdapter;
7306
7307 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7308 macAddr, sizeof(tSirMacAddr) ) )
7309 {
7310 return pAdapter;
7311 }
7312 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7313 pAdapterNode = pNext;
7314 }
7315
7316 return NULL;
7317
7318}
7319
7320hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7321{
7322 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7323 hdd_adapter_t *pAdapter;
7324 VOS_STATUS status;
7325
7326 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7327
7328 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7329 {
7330 pAdapter = pAdapterNode->pAdapter;
7331
7332 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7333 IFNAMSIZ ) )
7334 {
7335 return pAdapter;
7336 }
7337 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7338 pAdapterNode = pNext;
7339 }
7340
7341 return NULL;
7342
7343}
7344
7345hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7346{
7347 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7348 hdd_adapter_t *pAdapter;
7349 VOS_STATUS status;
7350
7351 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7352
7353 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7354 {
7355 pAdapter = pAdapterNode->pAdapter;
7356
7357 if( pAdapter && (mode == pAdapter->device_mode) )
7358 {
7359 return pAdapter;
7360 }
7361 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7362 pAdapterNode = pNext;
7363 }
7364
7365 return NULL;
7366
7367}
7368
7369//Remove this function later
7370hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7371{
7372 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7373 hdd_adapter_t *pAdapter;
7374 VOS_STATUS status;
7375
7376 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7377
7378 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7379 {
7380 pAdapter = pAdapterNode->pAdapter;
7381
7382 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7383 {
7384 return pAdapter;
7385 }
7386
7387 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7388 pAdapterNode = pNext;
7389 }
7390
7391 return NULL;
7392
7393}
7394
Jeff Johnson295189b2012-06-20 16:38:30 -07007395/**---------------------------------------------------------------------------
7396
7397 \brief hdd_set_monitor_tx_adapter() -
7398
7399 This API initializes the adapter to be used while transmitting on monitor
7400 adapter.
7401
7402 \param - pHddCtx - Pointer to the HDD context.
7403 pAdapter - Adapter that will used for TX. This can be NULL.
7404 \return - None.
7405 --------------------------------------------------------------------------*/
7406void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7407{
7408 hdd_adapter_t *pMonAdapter;
7409
7410 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7411
7412 if( NULL != pMonAdapter )
7413 {
7414 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7415 }
7416}
Jeff Johnson295189b2012-06-20 16:38:30 -07007417/**---------------------------------------------------------------------------
7418
7419 \brief hdd_select_queue() -
7420
7421 This API returns the operating channel of the requested device mode
7422
7423 \param - pHddCtx - Pointer to the HDD context.
7424 - mode - Device mode for which operating channel is required
7425 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7426 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7427 \return - channel number. "0" id the requested device is not found OR it is not connected.
7428 --------------------------------------------------------------------------*/
7429v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7430{
7431 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7432 VOS_STATUS status;
7433 hdd_adapter_t *pAdapter;
7434 v_U8_t operatingChannel = 0;
7435
7436 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7437
7438 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7439 {
7440 pAdapter = pAdapterNode->pAdapter;
7441
7442 if( mode == pAdapter->device_mode )
7443 {
7444 switch(pAdapter->device_mode)
7445 {
7446 case WLAN_HDD_INFRA_STATION:
7447 case WLAN_HDD_P2P_CLIENT:
7448 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7449 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7450 break;
7451 case WLAN_HDD_SOFTAP:
7452 case WLAN_HDD_P2P_GO:
7453 /*softap connection info */
7454 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7455 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7456 break;
7457 default:
7458 break;
7459 }
7460
7461 break; //Found the device of interest. break the loop
7462 }
7463
7464 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7465 pAdapterNode = pNext;
7466 }
7467 return operatingChannel;
7468}
7469
7470#ifdef WLAN_FEATURE_PACKET_FILTERING
7471/**---------------------------------------------------------------------------
7472
7473 \brief hdd_set_multicast_list() -
7474
7475 This used to set the multicast address list.
7476
7477 \param - dev - Pointer to the WLAN device.
7478 - skb - Pointer to OS packet (sk_buff).
7479 \return - success/fail
7480
7481 --------------------------------------------------------------------------*/
7482static void hdd_set_multicast_list(struct net_device *dev)
7483{
7484 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 int mc_count;
7486 int i = 0;
7487 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307488
7489 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007490 {
7491 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307492 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 return;
7494 }
7495
7496 if (dev->flags & IFF_ALLMULTI)
7497 {
7498 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007499 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307500 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 }
7502 else
7503 {
7504 mc_count = netdev_mc_count(dev);
7505 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007506 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7508 {
7509 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007510 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307511 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 return;
7513 }
7514
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307515 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007516
7517 netdev_for_each_mc_addr(ha, dev) {
7518 if (i == mc_count)
7519 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307520 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7521 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007523 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307524 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007525 i++;
7526 }
7527 }
7528 return;
7529}
7530#endif
7531
7532/**---------------------------------------------------------------------------
7533
7534 \brief hdd_select_queue() -
7535
7536 This function is registered with the Linux OS for network
7537 core to decide which queue to use first.
7538
7539 \param - dev - Pointer to the WLAN device.
7540 - skb - Pointer to OS packet (sk_buff).
7541 \return - ac, Queue Index/access category corresponding to UP in IP header
7542
7543 --------------------------------------------------------------------------*/
7544v_U16_t hdd_select_queue(struct net_device *dev,
7545 struct sk_buff *skb)
7546{
7547 return hdd_wmm_select_queue(dev, skb);
7548}
7549
7550
7551/**---------------------------------------------------------------------------
7552
7553 \brief hdd_wlan_initial_scan() -
7554
7555 This function triggers the initial scan
7556
7557 \param - pAdapter - Pointer to the HDD adapter.
7558
7559 --------------------------------------------------------------------------*/
7560void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7561{
7562 tCsrScanRequest scanReq;
7563 tCsrChannelInfo channelInfo;
7564 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007565 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007566 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7567
7568 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7569 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7570 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7571
7572 if(sme_Is11dSupported(pHddCtx->hHal))
7573 {
7574 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7575 if ( HAL_STATUS_SUCCESS( halStatus ) )
7576 {
7577 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7578 if( !scanReq.ChannelInfo.ChannelList )
7579 {
7580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7581 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007582 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007583 return;
7584 }
7585 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7586 channelInfo.numOfChannels);
7587 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7588 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007589 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007590 }
7591
7592 scanReq.scanType = eSIR_PASSIVE_SCAN;
7593 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7594 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7595 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7596 }
7597 else
7598 {
7599 scanReq.scanType = eSIR_ACTIVE_SCAN;
7600 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7601 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7602 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7603 }
7604
7605 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7606 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7607 {
7608 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7609 __func__, halStatus );
7610 }
7611
7612 if(sme_Is11dSupported(pHddCtx->hHal))
7613 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7614}
7615
Jeff Johnson295189b2012-06-20 16:38:30 -07007616/**---------------------------------------------------------------------------
7617
7618 \brief hdd_full_power_callback() - HDD full power callback function
7619
7620 This is the function invoked by SME to inform the result of a full power
7621 request issued by HDD
7622
7623 \param - callbackcontext - Pointer to cookie
7624 \param - status - result of request
7625
7626 \return - None
7627
7628 --------------------------------------------------------------------------*/
7629static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7630{
Jeff Johnson72a40512013-12-19 10:14:15 -08007631 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007632
7633 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307634 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007635
7636 if (NULL == callbackContext)
7637 {
7638 hddLog(VOS_TRACE_LEVEL_ERROR,
7639 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007640 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 return;
7642 }
7643
Jeff Johnson72a40512013-12-19 10:14:15 -08007644 /* there is a race condition that exists between this callback
7645 function and the caller since the caller could time out either
7646 before or while this code is executing. we use a spinlock to
7647 serialize these actions */
7648 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007649
7650 if (POWER_CONTEXT_MAGIC != pContext->magic)
7651 {
7652 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007653 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007654 hddLog(VOS_TRACE_LEVEL_WARN,
7655 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007656 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 return;
7658 }
7659
Jeff Johnson72a40512013-12-19 10:14:15 -08007660 /* context is valid so caller is still waiting */
7661
7662 /* paranoia: invalidate the magic */
7663 pContext->magic = 0;
7664
7665 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007667
7668 /* serialization is complete */
7669 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007670}
7671
7672/**---------------------------------------------------------------------------
7673
7674 \brief hdd_wlan_exit() - HDD WLAN exit function
7675
7676 This is the driver exit point (invoked during rmmod)
7677
7678 \param - pHddCtx - Pointer to the HDD Context
7679
7680 \return - None
7681
7682 --------------------------------------------------------------------------*/
7683void hdd_wlan_exit(hdd_context_t *pHddCtx)
7684{
7685 eHalStatus halStatus;
7686 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7687 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307688 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007689 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007690 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307692 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007693
7694 ENTER();
7695
Jeff Johnson88ba7742013-02-27 14:36:02 -08007696 if (VOS_FTM_MODE != hdd_get_conparam())
7697 {
7698 // Unloading, restart logic is no more required.
7699 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007700
c_hpothu5ab05e92014-06-13 17:34:05 +05307701 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7702 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007703 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307704 pAdapter = pAdapterNode->pAdapter;
7705 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307707 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7708 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7709 {
7710 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7711 hdd_UnregisterWext(pAdapter->dev);
7712 }
7713 // Cancel any outstanding scan requests. We are about to close all
7714 // of our adapters, but an adapter structure is what SME passes back
7715 // to our callback function. Hence if there are any outstanding scan
7716 // requests then there is a race condition between when the adapter
7717 // is closed and when the callback is invoked.We try to resolve that
7718 // race condition here by canceling any outstanding scans before we
7719 // close the adapters.
7720 // Note that the scans may be cancelled in an asynchronous manner,
7721 // so ideally there needs to be some kind of synchronization. Rather
7722 // than introduce a new synchronization here, we will utilize the
7723 // fact that we are about to Request Full Power, and since that is
7724 // synchronized, the expectation is that by the time Request Full
7725 // Power has completed all scans will be cancelled.
7726 if (pHddCtx->scan_info.mScanPending)
7727 {
7728 hddLog(VOS_TRACE_LEVEL_INFO,
7729 FL("abort scan mode: %d sessionId: %d"),
7730 pAdapter->device_mode,
7731 pAdapter->sessionId);
7732 hdd_abort_mac_scan(pHddCtx,
7733 pAdapter->sessionId,
7734 eCSR_SCAN_ABORT_DEFAULT);
7735 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307737 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7738 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007739 }
7740 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307741 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007742 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307743 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007744 wlan_hdd_ftm_close(pHddCtx);
7745 goto free_hdd_ctx;
7746 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307747
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 /* DeRegister with platform driver as client for Suspend/Resume */
7749 vosStatus = hddDeregisterPmOps(pHddCtx);
7750 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7751 {
7752 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7753 VOS_ASSERT(0);
7754 }
7755
7756 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7757 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7758 {
7759 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7760 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007761
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007762 //Stop the traffic monitor timer
7763 if ( VOS_TIMER_STATE_RUNNING ==
7764 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7765 {
7766 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7767 }
7768
7769 // Destroy the traffic monitor timer
7770 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7771 &pHddCtx->tx_rx_trafficTmr)))
7772 {
7773 hddLog(VOS_TRACE_LEVEL_ERROR,
7774 "%s: Cannot deallocate Traffic monitor timer", __func__);
7775 }
7776
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 //Disable IMPS/BMPS as we do not want the device to enter any power
7778 //save mode during shutdown
7779 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7780 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7781 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7782
7783 //Ensure that device is in full power as we will touch H/W during vos_Stop
7784 init_completion(&powerContext.completion);
7785 powerContext.magic = POWER_CONTEXT_MAGIC;
7786
7787 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7788 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7789
7790 if (eHAL_STATUS_SUCCESS != halStatus)
7791 {
7792 if (eHAL_STATUS_PMC_PENDING == halStatus)
7793 {
7794 /* request was sent -- wait for the response */
7795 lrc = wait_for_completion_interruptible_timeout(
7796 &powerContext.completion,
7797 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007798 if (lrc <= 0)
7799 {
7800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007801 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007802 }
7803 }
7804 else
7805 {
7806 hddLog(VOS_TRACE_LEVEL_ERROR,
7807 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007808 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 /* continue -- need to clean up as much as possible */
7810 }
7811 }
7812
Jeff Johnson72a40512013-12-19 10:14:15 -08007813 /* either we never sent a request, we sent a request and received a
7814 response or we sent a request and timed out. if we never sent a
7815 request or if we sent a request and got a response, we want to
7816 clear the magic out of paranoia. if we timed out there is a
7817 race condition such that the callback function could be
7818 executing at the same time we are. of primary concern is if the
7819 callback function had already verified the "magic" but had not
7820 yet set the completion variable when a timeout occurred. we
7821 serialize these activities by invalidating the magic while
7822 holding a shared spinlock which will cause us to block if the
7823 callback is currently executing */
7824 spin_lock(&hdd_context_lock);
7825 powerContext.magic = 0;
7826 spin_unlock(&hdd_context_lock);
7827
Yue Ma0d4891e2013-08-06 17:01:45 -07007828 hdd_debugfs_exit(pHddCtx);
7829
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 // Unregister the Net Device Notifier
7831 unregister_netdevice_notifier(&hdd_netdev_notifier);
7832
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 hdd_stop_all_adapters( pHddCtx );
7834
Jeff Johnson295189b2012-06-20 16:38:30 -07007835#ifdef WLAN_BTAMP_FEATURE
7836 vosStatus = WLANBAP_Stop(pVosContext);
7837 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7838 {
7839 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7840 "%s: Failed to stop BAP",__func__);
7841 }
7842#endif //WLAN_BTAMP_FEATURE
7843
7844 //Stop all the modules
7845 vosStatus = vos_stop( pVosContext );
7846 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7847 {
7848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7849 "%s: Failed to stop VOSS",__func__);
7850 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7851 }
7852
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 //Assert Deep sleep signal now to put Libra HW in lowest power state
7854 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7855 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7856
7857 //Vote off any PMIC voltage supplies
7858 vos_chipPowerDown(NULL, NULL, NULL);
7859
7860 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7861
Leo Chang59cdc7e2013-07-10 10:08:21 -07007862
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007865
7866 //Close the scheduler before calling vos_close to make sure no thread is
7867 // scheduled after the each module close is called i.e after all the data
7868 // structures are freed.
7869 vosStatus = vos_sched_close( pVosContext );
7870 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7871 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7872 "%s: Failed to close VOSS Scheduler",__func__);
7873 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7874 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007875#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007876#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7877 /* Destroy the wake lock */
7878 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7879#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007880 /* Destroy the wake lock */
7881 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007882#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007883
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307884#ifdef CONFIG_ENABLE_LINUX_REG
7885 vosStatus = vos_nv_close();
7886 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7887 {
7888 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7889 "%s: Failed to close NV", __func__);
7890 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7891 }
7892#endif
7893
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 //Close VOSS
7895 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7896 vos_close(pVosContext);
7897
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 //Close Watchdog
7899 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7900 vos_watchdog_close(pVosContext);
7901
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307902 //Clean up HDD Nlink Service
7903 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007904#ifdef WLAN_KD_READY_NOTIFIER
7905 nl_srv_exit(pHddCtx->ptt_pid);
7906#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307907 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007908#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307909
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307910#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307911 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307912 {
7913 wlan_logging_sock_deactivate_svc();
7914 }
7915#endif
7916
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 /* Cancel the vote for XO Core ON.
7918 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7919 * exited at this point
7920 */
7921 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007922 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7924 {
7925 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7926 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007927 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007928 }
7929
7930 hdd_close_all_adapters( pHddCtx );
7931
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 /* free the power on lock from platform driver */
7933 if (free_riva_power_on_lock("wlan"))
7934 {
7935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7936 __func__);
7937 }
7938
Jeff Johnson88ba7742013-02-27 14:36:02 -08007939free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307940
7941 //Free up dynamically allocated members inside HDD Adapter
7942 if (pHddCtx->cfg_ini)
7943 {
7944 kfree(pHddCtx->cfg_ini);
7945 pHddCtx->cfg_ini= NULL;
7946 }
7947
Leo Changf04ddad2013-09-18 13:46:38 -07007948 /* FTM mode, WIPHY did not registered
7949 If un-register here, system crash will happen */
7950 if (VOS_FTM_MODE != hdd_get_conparam())
7951 {
7952 wiphy_unregister(wiphy) ;
7953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 if (hdd_is_ssr_required())
7956 {
7957 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007958 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 msleep(5000);
7960 }
7961 hdd_set_ssr_required (VOS_FALSE);
7962}
7963
7964
7965/**---------------------------------------------------------------------------
7966
7967 \brief hdd_update_config_from_nv() - Function to update the contents of
7968 the running configuration with parameters taken from NV storage
7969
7970 \param - pHddCtx - Pointer to the HDD global context
7971
7972 \return - VOS_STATUS_SUCCESS if successful
7973
7974 --------------------------------------------------------------------------*/
7975static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7976{
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 v_BOOL_t itemIsValid = VOS_FALSE;
7978 VOS_STATUS status;
7979 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7980 v_U8_t macLoop;
7981
7982 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7983 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7984 if(status != VOS_STATUS_SUCCESS)
7985 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007986 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 return VOS_STATUS_E_FAILURE;
7988 }
7989
7990 if (itemIsValid == VOS_TRUE)
7991 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007992 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7994 VOS_MAX_CONCURRENCY_PERSONA);
7995 if(status != VOS_STATUS_SUCCESS)
7996 {
7997 /* Get MAC from NV fail, not update CFG info
7998 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007999 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008000 return VOS_STATUS_E_FAILURE;
8001 }
8002
8003 /* If first MAC is not valid, treat all others are not valid
8004 * Then all MACs will be got from ini file */
8005 if(vos_is_macaddr_zero(&macFromNV[0]))
8006 {
8007 /* MAC address in NV file is not configured yet */
8008 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8009 return VOS_STATUS_E_INVAL;
8010 }
8011
8012 /* Get MAC address from NV, update CFG info */
8013 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8014 {
8015 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8016 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308017 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 /* This MAC is not valid, skip it
8019 * This MAC will be got from ini file */
8020 }
8021 else
8022 {
8023 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8024 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8025 VOS_MAC_ADDR_SIZE);
8026 }
8027 }
8028 }
8029 else
8030 {
8031 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8032 return VOS_STATUS_E_FAILURE;
8033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008034
Jeff Johnson295189b2012-06-20 16:38:30 -07008035
8036 return VOS_STATUS_SUCCESS;
8037}
8038
8039/**---------------------------------------------------------------------------
8040
8041 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8042
8043 \param - pAdapter - Pointer to the HDD
8044
8045 \return - None
8046
8047 --------------------------------------------------------------------------*/
8048VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8049{
8050 eHalStatus halStatus;
8051 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308052 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008053
Jeff Johnson295189b2012-06-20 16:38:30 -07008054
8055 // Send ready indication to the HDD. This will kick off the MAC
8056 // into a 'running' state and should kick off an initial scan.
8057 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8058 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8059 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308060 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 "code %08d [x%08x]",__func__, halStatus, halStatus );
8062 return VOS_STATUS_E_FAILURE;
8063 }
8064
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308065 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8067 // And RIVA will crash
8068 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8069 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308070 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8071 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8072
8073
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 return VOS_STATUS_SUCCESS;
8075}
8076
Jeff Johnson295189b2012-06-20 16:38:30 -07008077/* wake lock APIs for HDD */
8078void hdd_prevent_suspend(void)
8079{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008080#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008082#else
8083 wcnss_prevent_suspend();
8084#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008085}
8086
8087void hdd_allow_suspend(void)
8088{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008089#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008091#else
8092 wcnss_allow_suspend();
8093#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008094}
8095
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308096void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008097{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008098#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008099 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008100#else
8101 /* Do nothing as there is no API in wcnss for timeout*/
8102#endif
8103}
8104
Jeff Johnson295189b2012-06-20 16:38:30 -07008105/**---------------------------------------------------------------------------
8106
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008107 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8108 information between Host and Riva
8109
8110 This function gets reported version of FW
8111 It also finds the version of Riva headers used to compile the host
8112 It compares the above two and prints a warning if they are different
8113 It gets the SW and HW version string
8114 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8115 indicating the features they support through a bitmap
8116
8117 \param - pHddCtx - Pointer to HDD context
8118
8119 \return - void
8120
8121 --------------------------------------------------------------------------*/
8122
8123void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8124{
8125
8126 tSirVersionType versionCompiled;
8127 tSirVersionType versionReported;
8128 tSirVersionString versionString;
8129 tANI_U8 fwFeatCapsMsgSupported = 0;
8130 VOS_STATUS vstatus;
8131
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008132 memset(&versionCompiled, 0, sizeof(versionCompiled));
8133 memset(&versionReported, 0, sizeof(versionReported));
8134
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008135 /* retrieve and display WCNSS version information */
8136 do {
8137
8138 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8139 &versionCompiled);
8140 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8141 {
8142 hddLog(VOS_TRACE_LEVEL_FATAL,
8143 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008144 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008145 break;
8146 }
8147
8148 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8149 &versionReported);
8150 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8151 {
8152 hddLog(VOS_TRACE_LEVEL_FATAL,
8153 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008154 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008155 break;
8156 }
8157
8158 if ((versionCompiled.major != versionReported.major) ||
8159 (versionCompiled.minor != versionReported.minor) ||
8160 (versionCompiled.version != versionReported.version) ||
8161 (versionCompiled.revision != versionReported.revision))
8162 {
8163 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8164 "Host expected %u.%u.%u.%u\n",
8165 WLAN_MODULE_NAME,
8166 (int)versionReported.major,
8167 (int)versionReported.minor,
8168 (int)versionReported.version,
8169 (int)versionReported.revision,
8170 (int)versionCompiled.major,
8171 (int)versionCompiled.minor,
8172 (int)versionCompiled.version,
8173 (int)versionCompiled.revision);
8174 }
8175 else
8176 {
8177 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8178 WLAN_MODULE_NAME,
8179 (int)versionReported.major,
8180 (int)versionReported.minor,
8181 (int)versionReported.version,
8182 (int)versionReported.revision);
8183 }
8184
8185 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8186 versionString,
8187 sizeof(versionString));
8188 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8189 {
8190 hddLog(VOS_TRACE_LEVEL_FATAL,
8191 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008192 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008193 break;
8194 }
8195
8196 pr_info("%s: WCNSS software version %s\n",
8197 WLAN_MODULE_NAME, versionString);
8198
8199 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8200 versionString,
8201 sizeof(versionString));
8202 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8203 {
8204 hddLog(VOS_TRACE_LEVEL_FATAL,
8205 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008206 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008207 break;
8208 }
8209
8210 pr_info("%s: WCNSS hardware version %s\n",
8211 WLAN_MODULE_NAME, versionString);
8212
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008213 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8214 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008215 send the message only if it the riva is 1.1
8216 minor numbers for different riva branches:
8217 0 -> (1.0)Mainline Build
8218 1 -> (1.1)Mainline Build
8219 2->(1.04) Stability Build
8220 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008221 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008222 ((versionReported.minor>=1) && (versionReported.version>=1)))
8223 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8224 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008225
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008226 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008227 {
8228#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8229 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8230 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8231#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008232 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8233 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8234 {
8235 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8236 }
8237
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008238 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008239 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008240
8241 } while (0);
8242
8243}
8244
8245/**---------------------------------------------------------------------------
8246
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308247 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8248
8249 \param - pHddCtx - Pointer to the hdd context
8250
8251 \return - true if hardware supports 5GHz
8252
8253 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308254boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308255{
8256 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8257 * then hardware support 5Ghz.
8258 */
8259 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8260 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308261 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308262 return true;
8263 }
8264 else
8265 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308266 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308267 __func__);
8268 return false;
8269 }
8270}
8271
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308272/**---------------------------------------------------------------------------
8273
8274 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8275 generate function
8276
8277 This is generate the random mac address for WLAN interface
8278
8279 \param - pHddCtx - Pointer to HDD context
8280 idx - Start interface index to get auto
8281 generated mac addr.
8282 mac_addr - Mac address
8283
8284 \return - 0 for success, < 0 for failure
8285
8286 --------------------------------------------------------------------------*/
8287
8288static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8289 int idx, v_MACADDR_t mac_addr)
8290{
8291 int i;
8292 unsigned int serialno;
8293 serialno = wcnss_get_serial_number();
8294
8295 if (0 != serialno)
8296 {
8297 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8298 bytes of the serial number that can be used to generate
8299 the other 3 bytes of the MAC address. Mask off all but
8300 the lower 3 bytes (this will also make sure we don't
8301 overflow in the next step) */
8302 serialno &= 0x00FFFFFF;
8303
8304 /* we need a unique address for each session */
8305 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8306
8307 /* autogen other Mac addresses */
8308 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8309 {
8310 /* start with the entire default address */
8311 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8312 /* then replace the lower 3 bytes */
8313 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8314 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8315 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8316
8317 serialno++;
8318 hddLog(VOS_TRACE_LEVEL_ERROR,
8319 "%s: Derived Mac Addr: "
8320 MAC_ADDRESS_STR, __func__,
8321 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8322 }
8323
8324 }
8325 else
8326 {
8327 hddLog(LOGE, FL("Failed to Get Serial NO"));
8328 return -1;
8329 }
8330 return 0;
8331}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308332
8333/**---------------------------------------------------------------------------
8334
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308335 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8336 completed to flush out the scan results
8337
8338 11d scan is done during driver load and is a passive scan on all
8339 channels supported by the device, 11d scans may find some APs on
8340 frequencies which are forbidden to be used in the regulatory domain
8341 the device is operating in. If these APs are notified to the supplicant
8342 it may try to connect to these APs, thus flush out all the scan results
8343 which are present in SME after 11d scan is done.
8344
8345 \return - eHalStatus
8346
8347 --------------------------------------------------------------------------*/
8348static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8349 tANI_U32 scanId, eCsrScanStatus status)
8350{
8351 ENTER();
8352
8353 sme_ScanFlushResult(halHandle, 0);
8354
8355 EXIT();
8356
8357 return eHAL_STATUS_SUCCESS;
8358}
8359
8360/**---------------------------------------------------------------------------
8361
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 \brief hdd_wlan_startup() - HDD init function
8363
8364 This is the driver startup code executed once a WLAN device has been detected
8365
8366 \param - dev - Pointer to the underlying device
8367
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008368 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008369
8370 --------------------------------------------------------------------------*/
8371
8372int hdd_wlan_startup(struct device *dev )
8373{
8374 VOS_STATUS status;
8375 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008376 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 hdd_context_t *pHddCtx = NULL;
8378 v_CONTEXT_t pVosContext= NULL;
8379#ifdef WLAN_BTAMP_FEATURE
8380 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8381 WLANBAP_ConfigType btAmpConfig;
8382 hdd_config_t *pConfig;
8383#endif
8384 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008385 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308386 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008387
8388 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 /*
8390 * cfg80211: wiphy allocation
8391 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308392 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008393
8394 if(wiphy == NULL)
8395 {
8396 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008397 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 }
8399
8400 pHddCtx = wiphy_priv(wiphy);
8401
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 //Initialize the adapter context to zeros.
8403 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8404
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308407 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008408
8409 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8410
8411 /*Get vos context here bcoz vos_open requires it*/
8412 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8413
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008414 if(pVosContext == NULL)
8415 {
8416 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8417 goto err_free_hdd_context;
8418 }
8419
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 //Save the Global VOSS context in adapter context for future.
8421 pHddCtx->pvosContext = pVosContext;
8422
8423 //Save the adapter context in global context for future.
8424 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8425
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 pHddCtx->parent_dev = dev;
8427
8428 init_completion(&pHddCtx->full_pwr_comp_var);
8429 init_completion(&pHddCtx->standby_comp_var);
8430 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008431 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008432 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308433 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308434 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008435
8436#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008437 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008438#else
8439 init_completion(&pHddCtx->driver_crda_req);
8440#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008441
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308442 spin_lock_init(&pHddCtx->schedScan_lock);
8443
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8445
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308446#ifdef FEATURE_WLAN_TDLS
8447 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8448 * invoked by other instances also) to protect the concurrent
8449 * access for the Adapters by TDLS module.
8450 */
8451 mutex_init(&pHddCtx->tdls_lock);
8452#endif
Agarwal Ashish1f422872014-07-22 00:11:55 +05308453 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308454
Agarwal Ashish1f422872014-07-22 00:11:55 +05308455 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 // Load all config first as TL config is needed during vos_open
8457 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8458 if(pHddCtx->cfg_ini == NULL)
8459 {
8460 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8461 goto err_free_hdd_context;
8462 }
8463
8464 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8465
8466 // Read and parse the qcom_cfg.ini file
8467 status = hdd_parse_config_ini( pHddCtx );
8468 if ( VOS_STATUS_SUCCESS != status )
8469 {
8470 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8471 __func__, WLAN_INI_FILE);
8472 goto err_config;
8473 }
Arif Hussaind5218912013-12-05 01:10:55 -08008474#ifdef MEMORY_DEBUG
8475 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8476 vos_mem_init();
8477
8478 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8479 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8480#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008481
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308482 /* INI has been read, initialise the configuredMcastBcastFilter with
8483 * INI value as this will serve as the default value
8484 */
8485 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8486 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8487 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308488
8489 if (false == hdd_is_5g_supported(pHddCtx))
8490 {
8491 //5Ghz is not supported.
8492 if (1 != pHddCtx->cfg_ini->nBandCapability)
8493 {
8494 hddLog(VOS_TRACE_LEVEL_INFO,
8495 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8496 pHddCtx->cfg_ini->nBandCapability = 1;
8497 }
8498 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308499
8500 /* If SNR Monitoring is enabled, FW has to parse all beacons
8501 * for calcaluting and storing the average SNR, so set Nth beacon
8502 * filter to 1 to enable FW to parse all the beaocons
8503 */
8504 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8505 {
8506 /* The log level is deliberately set to WARN as overriding
8507 * nthBeaconFilter to 1 will increase power cosumption and this
8508 * might just prove helpful to detect the power issue.
8509 */
8510 hddLog(VOS_TRACE_LEVEL_WARN,
8511 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8512 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008514 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308515 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008517 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008519 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8520 {
8521 hddLog(VOS_TRACE_LEVEL_FATAL,
8522 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8523 goto err_config;
8524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008526
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008527 // Update VOS trace levels based upon the cfg.ini
8528 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8529 pHddCtx->cfg_ini->vosTraceEnableBAP);
8530 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8531 pHddCtx->cfg_ini->vosTraceEnableTL);
8532 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8533 pHddCtx->cfg_ini->vosTraceEnableWDI);
8534 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8535 pHddCtx->cfg_ini->vosTraceEnableHDD);
8536 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8537 pHddCtx->cfg_ini->vosTraceEnableSME);
8538 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8539 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308540 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8541 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008542 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8543 pHddCtx->cfg_ini->vosTraceEnableWDA);
8544 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8545 pHddCtx->cfg_ini->vosTraceEnableSYS);
8546 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8547 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008548 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8549 pHddCtx->cfg_ini->vosTraceEnableSAP);
8550 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8551 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008552
Jeff Johnson295189b2012-06-20 16:38:30 -07008553 // Update WDI trace levels based upon the cfg.ini
8554 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8555 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8556 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8557 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8558 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8559 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8560 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8561 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008562
Jeff Johnson88ba7742013-02-27 14:36:02 -08008563 if (VOS_FTM_MODE == hdd_get_conparam())
8564 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8566 {
8567 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8568 goto err_free_hdd_context;
8569 }
8570 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308571
8572 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008574 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008575
Jeff Johnson88ba7742013-02-27 14:36:02 -08008576 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8578 {
8579 status = vos_watchdog_open(pVosContext,
8580 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8581
8582 if(!VOS_IS_STATUS_SUCCESS( status ))
8583 {
8584 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308585 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 }
8587 }
8588
8589 pHddCtx->isLogpInProgress = FALSE;
8590 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8591
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8593 if(!VOS_IS_STATUS_SUCCESS(status))
8594 {
8595 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008596 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 }
8598
Amar Singhala49cbc52013-10-08 18:37:44 -07008599#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008600 /* initialize the NV module. This is required so that
8601 we can initialize the channel information in wiphy
8602 from the NV.bin data. The channel information in
8603 wiphy needs to be initialized before wiphy registration */
8604
8605 status = vos_nv_open();
8606 if (!VOS_IS_STATUS_SUCCESS(status))
8607 {
8608 /* NV module cannot be initialized */
8609 hddLog( VOS_TRACE_LEVEL_FATAL,
8610 "%s: vos_nv_open failed", __func__);
8611 goto err_clkvote;
8612 }
8613
8614 status = vos_init_wiphy_from_nv_bin();
8615 if (!VOS_IS_STATUS_SUCCESS(status))
8616 {
8617 /* NV module cannot be initialized */
8618 hddLog( VOS_TRACE_LEVEL_FATAL,
8619 "%s: vos_init_wiphy failed", __func__);
8620 goto err_vos_nv_close;
8621 }
8622
Amar Singhala49cbc52013-10-08 18:37:44 -07008623#endif
8624
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308625 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 if ( !VOS_IS_STATUS_SUCCESS( status ))
8627 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008628 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308629 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 }
8631
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8633
8634 if ( NULL == pHddCtx->hHal )
8635 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008636 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 goto err_vosclose;
8638 }
8639
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008640 status = vos_preStart( pHddCtx->pvosContext );
8641 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8642 {
8643 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308644 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008645 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008646
Arif Hussaineaf68602013-12-30 23:10:44 -08008647 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8648 {
8649 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8650 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8651 __func__, enable_dfs_chan_scan);
8652 }
8653 if (0 == enable_11d || 1 == enable_11d)
8654 {
8655 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8656 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8657 __func__, enable_11d);
8658 }
8659
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008660 /* Note that the vos_preStart() sequence triggers the cfg download.
8661 The cfg download must occur before we update the SME config
8662 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 status = hdd_set_sme_config( pHddCtx );
8664
8665 if ( VOS_STATUS_SUCCESS != status )
8666 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008667 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308668 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008670
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 /* In the integrated architecture we update the configuration from
8672 the INI file and from NV before vOSS has been started so that
8673 the final contents are available to send down to the cCPU */
8674
8675 // Apply the cfg.ini to cfg.dat
8676 if (FALSE == hdd_update_config_dat(pHddCtx))
8677 {
8678 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308679 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 }
8681
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308682 // Get mac addr from platform driver
8683 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8684
8685 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308687 /* Store the mac addr for first interface */
8688 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8689
8690 hddLog(VOS_TRACE_LEVEL_ERROR,
8691 "%s: WLAN Mac Addr: "
8692 MAC_ADDRESS_STR, __func__,
8693 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8694
8695 /* Here, passing Arg2 as 1 because we do not want to change the
8696 last 3 bytes (means non OUI bytes) of first interface mac
8697 addr.
8698 */
8699 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8700 {
8701 hddLog(VOS_TRACE_LEVEL_ERROR,
8702 "%s: Failed to generate wlan interface mac addr "
8703 "using MAC from ini file ", __func__);
8704 }
8705 }
8706 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8707 {
8708 // Apply the NV to cfg.dat
8709 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008710#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8711 /* There was not a valid set of MAC Addresses in NV. See if the
8712 default addresses were modified by the cfg.ini settings. If so,
8713 we'll use them, but if not, we'll autogenerate a set of MAC
8714 addresses based upon the device serial number */
8715
8716 static const v_MACADDR_t default_address =
8717 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008718
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308719 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8720 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 {
8722 /* cfg.ini has the default address, invoke autogen logic */
8723
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308724 /* Here, passing Arg2 as 0 because we want to change the
8725 last 3 bytes (means non OUI bytes) of all the interfaces
8726 mac addr.
8727 */
8728 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8729 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308731 hddLog(VOS_TRACE_LEVEL_ERROR,
8732 "%s: Failed to generate wlan interface mac addr "
8733 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8734 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 }
8737 else
8738#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8739 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008740 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 "%s: Invalid MAC address in NV, using MAC from ini file "
8742 MAC_ADDRESS_STR, __func__,
8743 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8744 }
8745 }
8746 {
8747 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308748
8749 /* Set the MAC Address Currently this is used by HAL to
8750 * add self sta. Remove this once self sta is added as
8751 * part of session open.
8752 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8754 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8755 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308756
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 if (!HAL_STATUS_SUCCESS( halStatus ))
8758 {
8759 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8760 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308761 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 }
8763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008764
8765 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8766 Note: Firmware image will be read and downloaded inside vos_start API */
8767 status = vos_start( pHddCtx->pvosContext );
8768 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8769 {
8770 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308771 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 }
8773
Leo Chang6cec3e22014-01-21 15:33:49 -08008774#ifdef FEATURE_WLAN_CH_AVOID
8775 /* Plug in avoid channel notification callback
8776 * This should happen before ADD_SELF_STA
8777 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308778
8779 /* check the Channel Avoidance is enabled */
8780 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8781 {
8782 sme_AddChAvoidCallback(pHddCtx->hHal,
8783 hdd_hostapd_ch_avoid_cb);
8784 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008785#endif /* FEATURE_WLAN_CH_AVOID */
8786
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008787 /* Exchange capability info between Host and FW and also get versioning info from FW */
8788 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008789
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308790#ifdef CONFIG_ENABLE_LINUX_REG
8791 status = wlan_hdd_init_channels(pHddCtx);
8792 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8793 {
8794 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8795 __func__);
8796 goto err_vosstop;
8797 }
8798#endif
8799
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 status = hdd_post_voss_start_config( pHddCtx );
8801 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8802 {
8803 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8804 __func__);
8805 goto err_vosstop;
8806 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008807
8808#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308809 wlan_hdd_cfg80211_update_reg_info( wiphy );
8810
8811 /* registration of wiphy dev with cfg80211 */
8812 if (0 > wlan_hdd_cfg80211_register(wiphy))
8813 {
8814 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8815 goto err_vosstop;
8816 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008817#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008818
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308819#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308820 /* registration of wiphy dev with cfg80211 */
8821 if (0 > wlan_hdd_cfg80211_register(wiphy))
8822 {
8823 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8824 goto err_vosstop;
8825 }
8826
8827 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8828 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8829 {
8830 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8831 __func__);
8832 goto err_unregister_wiphy;
8833 }
8834#endif
8835
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8837 {
8838 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8839 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8840 }
8841 else
8842 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8844 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8845 if (pAdapter != NULL)
8846 {
kaidde69982014-06-18 13:23:21 +08008847 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308849 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8850 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8851 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008852
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308853 /* Generate the P2P Device Address. This consists of the device's
8854 * primary MAC address with the locally administered bit set.
8855 */
8856 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008857 }
8858 else
8859 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308860 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8861 if (p2p_dev_addr != NULL)
8862 {
8863 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8864 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8865 }
8866 else
8867 {
8868 hddLog(VOS_TRACE_LEVEL_FATAL,
8869 "%s: Failed to allocate mac_address for p2p_device",
8870 __func__);
8871 goto err_close_adapter;
8872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008874
8875 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8876 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8877 if ( NULL == pP2pAdapter )
8878 {
8879 hddLog(VOS_TRACE_LEVEL_FATAL,
8880 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008881 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008882 goto err_close_adapter;
8883 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008884 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008885 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008886
8887 if( pAdapter == NULL )
8888 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8890 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008892
Arif Hussain66559122013-11-21 10:11:40 -08008893 if (country_code)
8894 {
8895 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008896 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008897 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8898#ifndef CONFIG_ENABLE_LINUX_REG
8899 hdd_checkandupdate_phymode(pAdapter, country_code);
8900#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008901 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8902 (void *)(tSmeChangeCountryCallback)
8903 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008904 country_code,
8905 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308906 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008907 if (eHAL_STATUS_SUCCESS == ret)
8908 {
Arif Hussaincb607082013-12-20 11:57:42 -08008909 ret = wait_for_completion_interruptible_timeout(
8910 &pAdapter->change_country_code,
8911 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8912
8913 if (0 >= ret)
8914 {
8915 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8916 "%s: SME while setting country code timed out", __func__);
8917 }
Arif Hussain66559122013-11-21 10:11:40 -08008918 }
8919 else
8920 {
Arif Hussaincb607082013-12-20 11:57:42 -08008921 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8922 "%s: SME Change Country code from module param fail ret=%d",
8923 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008924 }
8925 }
8926
Jeff Johnson295189b2012-06-20 16:38:30 -07008927#ifdef WLAN_BTAMP_FEATURE
8928 vStatus = WLANBAP_Open(pVosContext);
8929 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8930 {
8931 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8932 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008933 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 }
8935
8936 vStatus = BSL_Init(pVosContext);
8937 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8938 {
8939 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8940 "%s: Failed to Init BSL",__func__);
8941 goto err_bap_close;
8942 }
8943 vStatus = WLANBAP_Start(pVosContext);
8944 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8945 {
8946 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8947 "%s: Failed to start TL",__func__);
8948 goto err_bap_close;
8949 }
8950
8951 pConfig = pHddCtx->cfg_ini;
8952 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8953 status = WLANBAP_SetConfig(&btAmpConfig);
8954
8955#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008956
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008957#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8958 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8959 {
8960 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8961 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8962 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8963 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8964 }
8965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008966
Agarwal Ashish4b87f922014-06-18 03:03:21 +05308967 wlan_hdd_tdls_init(pHddCtx);
8968
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308969 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8970
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 /* Register with platform driver as client for Suspend/Resume */
8972 status = hddRegisterPmOps(pHddCtx);
8973 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8974 {
8975 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8976#ifdef WLAN_BTAMP_FEATURE
8977 goto err_bap_stop;
8978#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008979 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008980#endif //WLAN_BTAMP_FEATURE
8981 }
8982
Yue Ma0d4891e2013-08-06 17:01:45 -07008983 /* Open debugfs interface */
8984 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8985 {
8986 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8987 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008988 }
8989
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 /* Register TM level change handler function to the platform */
8991 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8992 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8993 {
8994 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8995 goto err_unregister_pmops;
8996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008997
8998 /* register for riva power on lock to platform driver */
8999 if (req_riva_power_on_lock("wlan"))
9000 {
9001 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9002 __func__);
9003 goto err_unregister_pmops;
9004 }
9005
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 // register net device notifier for device change notification
9007 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9008
9009 if(ret < 0)
9010 {
9011 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9012 goto err_free_power_on_lock;
9013 }
9014
9015 //Initialize the nlink service
9016 if(nl_srv_init() != 0)
9017 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309018 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 goto err_reg_netdev;
9020 }
9021
Leo Chang4ce1cc52013-10-21 18:27:15 -07009022#ifdef WLAN_KD_READY_NOTIFIER
9023 pHddCtx->kd_nl_init = 1;
9024#endif /* WLAN_KD_READY_NOTIFIER */
9025
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 //Initialize the BTC service
9027 if(btc_activate_service(pHddCtx) != 0)
9028 {
9029 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9030 goto err_nl_srv;
9031 }
9032
9033#ifdef PTT_SOCK_SVC_ENABLE
9034 //Initialize the PTT service
9035 if(ptt_sock_activate_svc(pHddCtx) != 0)
9036 {
9037 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9038 goto err_nl_srv;
9039 }
9040#endif
9041
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309042#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9043 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9044 {
9045 if(wlan_logging_sock_activate_svc(
9046 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9047 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9048 {
9049 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9050 " failed", __func__);
9051 goto err_nl_srv;
9052 }
9053 }
9054#endif
9055
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009059 /* Action frame registered in one adapter which will
9060 * applicable to all interfaces
9061 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309062 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009064
9065 mutex_init(&pHddCtx->sap_lock);
9066
Jeff Johnson295189b2012-06-20 16:38:30 -07009067
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009068#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009069#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9070 /* Initialize the wake lcok */
9071 wake_lock_init(&pHddCtx->rx_wake_lock,
9072 WAKE_LOCK_SUSPEND,
9073 "qcom_rx_wakelock");
9074#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009075 /* Initialize the wake lcok */
9076 wake_lock_init(&pHddCtx->sap_wake_lock,
9077 WAKE_LOCK_SUSPEND,
9078 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009079#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009080
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009081 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9082 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009083
Katya Nigam5c306ea2014-06-19 15:39:54 +05309084 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9086 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309087
9088#ifdef FEATURE_WLAN_SCAN_PNO
9089 /*SME must send channel update configuration to RIVA*/
9090 sme_UpdateChannelConfig(pHddCtx->hHal);
9091#endif
9092
Abhishek Singha306a442013-11-07 18:39:01 +05309093#ifndef CONFIG_ENABLE_LINUX_REG
9094 /*updating wiphy so that regulatory user hints can be processed*/
9095 if (wiphy)
9096 {
9097 regulatory_hint(wiphy, "00");
9098 }
9099#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009100 // Initialize the restart logic
9101 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309102
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009103 //Register the traffic monitor timer now
9104 if ( pHddCtx->cfg_ini->dynSplitscan)
9105 {
9106 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9107 VOS_TIMER_TYPE_SW,
9108 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9109 (void *)pHddCtx);
9110 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309111#ifdef WLAN_FEATURE_EXTSCAN
9112 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9113 wlan_hdd_cfg80211_extscan_callback,
9114 pHddCtx);
9115#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 goto success;
9117
9118err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009119#ifdef WLAN_KD_READY_NOTIFIER
9120 nl_srv_exit(pHddCtx->ptt_pid);
9121#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009122 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009123#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009124err_reg_netdev:
9125 unregister_netdevice_notifier(&hdd_netdev_notifier);
9126
9127err_free_power_on_lock:
9128 free_riva_power_on_lock("wlan");
9129
9130err_unregister_pmops:
9131 hddDevTmUnregisterNotifyCallback(pHddCtx);
9132 hddDeregisterPmOps(pHddCtx);
9133
Yue Ma0d4891e2013-08-06 17:01:45 -07009134 hdd_debugfs_exit(pHddCtx);
9135
Jeff Johnson295189b2012-06-20 16:38:30 -07009136#ifdef WLAN_BTAMP_FEATURE
9137err_bap_stop:
9138 WLANBAP_Stop(pVosContext);
9139#endif
9140
9141#ifdef WLAN_BTAMP_FEATURE
9142err_bap_close:
9143 WLANBAP_Close(pVosContext);
9144#endif
9145
Jeff Johnson295189b2012-06-20 16:38:30 -07009146err_close_adapter:
9147 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309148#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309149err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309150#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309151 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009152err_vosstop:
9153 vos_stop(pVosContext);
9154
Amar Singhala49cbc52013-10-08 18:37:44 -07009155err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 status = vos_sched_close( pVosContext );
9157 if (!VOS_IS_STATUS_SUCCESS(status)) {
9158 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9159 "%s: Failed to close VOSS Scheduler", __func__);
9160 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9161 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009162 vos_close(pVosContext );
9163
Amar Singhal0a402232013-10-11 20:57:16 -07009164err_vos_nv_close:
9165
c_hpothue6a36282014-03-19 12:27:38 +05309166#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009167 vos_nv_close();
9168
Jeff Johnson295189b2012-06-20 16:38:30 -07009169err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309170#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009171 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009172
9173err_wdclose:
9174 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9175 vos_watchdog_close(pVosContext);
9176
Jeff Johnson295189b2012-06-20 16:38:30 -07009177err_config:
9178 kfree(pHddCtx->cfg_ini);
9179 pHddCtx->cfg_ini= NULL;
9180
9181err_free_hdd_context:
9182 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009183 wiphy_free(wiphy) ;
9184 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 VOS_BUG(1);
9186
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009187 if (hdd_is_ssr_required())
9188 {
9189 /* WDI timeout had happened during load, so SSR is needed here */
9190 subsystem_restart("wcnss");
9191 msleep(5000);
9192 }
9193 hdd_set_ssr_required (VOS_FALSE);
9194
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009195 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
9197success:
9198 EXIT();
9199 return 0;
9200}
9201
9202/**---------------------------------------------------------------------------
9203
Jeff Johnson32d95a32012-09-10 13:15:23 -07009204 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009205
Jeff Johnson32d95a32012-09-10 13:15:23 -07009206 This is the driver entry point - called in different timeline depending
9207 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009208
9209 \param - None
9210
9211 \return - 0 for success, non zero for failure
9212
9213 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009214static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009215{
9216 VOS_STATUS status;
9217 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009218 struct device *dev = NULL;
9219 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009220#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9221 int max_retries = 0;
9222#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009223
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309224#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9225 wlan_logging_sock_init_svc();
9226#endif
9227
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 ENTER();
9229
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009230#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009231 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009232#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309234 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9236 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9237
9238 //Power Up Libra WLAN card first if not already powered up
9239 status = vos_chipPowerUp(NULL,NULL,NULL);
9240 if (!VOS_IS_STATUS_SUCCESS(status))
9241 {
9242 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9243 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309244#ifdef WLAN_OPEN_SOURCE
9245 wake_lock_destroy(&wlan_wake_lock);
9246#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309247
9248#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9249 wlan_logging_sock_deinit_svc();
9250#endif
9251
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009252 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 }
9254
Jeff Johnson295189b2012-06-20 16:38:30 -07009255#ifdef ANI_BUS_TYPE_PCI
9256
9257 dev = wcnss_wlan_get_device();
9258
9259#endif // ANI_BUS_TYPE_PCI
9260
9261#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009262
9263#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9264 /* wait until WCNSS driver downloads NV */
9265 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9266 msleep(1000);
9267 }
9268 if (max_retries >= 5) {
9269 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309270#ifdef WLAN_OPEN_SOURCE
9271 wake_lock_destroy(&wlan_wake_lock);
9272#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309273
9274#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9275 wlan_logging_sock_deinit_svc();
9276#endif
9277
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009278 return -ENODEV;
9279 }
9280#endif
9281
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 dev = wcnss_wlan_get_device();
9283#endif // ANI_BUS_TYPE_PLATFORM
9284
9285
9286 do {
9287 if (NULL == dev) {
9288 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9289 ret_status = -1;
9290 break;
9291 }
9292
Jeff Johnson295189b2012-06-20 16:38:30 -07009293#ifdef TIMER_MANAGER
9294 vos_timer_manager_init();
9295#endif
9296
9297 /* Preopen VOSS so that it is ready to start at least SAL */
9298 status = vos_preOpen(&pVosContext);
9299
9300 if (!VOS_IS_STATUS_SUCCESS(status))
9301 {
9302 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9303 ret_status = -1;
9304 break;
9305 }
9306
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009307#ifndef MODULE
9308 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9309 */
9310 hdd_set_conparam((v_UINT_t)con_mode);
9311#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009312
9313 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009314 if (hdd_wlan_startup(dev))
9315 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009317 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 vos_preClose( &pVosContext );
9319 ret_status = -1;
9320 break;
9321 }
9322
9323 /* Cancel the vote for XO Core ON
9324 * This is done here for safety purposes in case we re-initialize without turning
9325 * it OFF in any error scenario.
9326 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009327 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009329 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9331 {
9332 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009333 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 }
9335 } while (0);
9336
9337 if (0 != ret_status)
9338 {
9339 //Assert Deep sleep signal now to put Libra HW in lowest power state
9340 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9341 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9342
9343 //Vote off any PMIC voltage supplies
9344 vos_chipPowerDown(NULL, NULL, NULL);
9345#ifdef TIMER_MANAGER
9346 vos_timer_exit();
9347#endif
9348#ifdef MEMORY_DEBUG
9349 vos_mem_exit();
9350#endif
9351
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009352#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009354#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309355
9356#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9357 wlan_logging_sock_deinit_svc();
9358#endif
9359
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9361 }
9362 else
9363 {
9364 //Send WLAN UP indication to Nlink Service
9365 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9366
9367 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 }
9369
9370 EXIT();
9371
9372 return ret_status;
9373}
9374
Jeff Johnson32d95a32012-09-10 13:15:23 -07009375/**---------------------------------------------------------------------------
9376
9377 \brief hdd_module_init() - Init Function
9378
9379 This is the driver entry point (invoked when module is loaded using insmod)
9380
9381 \param - None
9382
9383 \return - 0 for success, non zero for failure
9384
9385 --------------------------------------------------------------------------*/
9386#ifdef MODULE
9387static int __init hdd_module_init ( void)
9388{
9389 return hdd_driver_init();
9390}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009391#else /* #ifdef MODULE */
9392static int __init hdd_module_init ( void)
9393{
9394 /* Driver initialization is delayed to fwpath_changed_handler */
9395 return 0;
9396}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009397#endif /* #ifdef MODULE */
9398
Jeff Johnson295189b2012-06-20 16:38:30 -07009399
9400/**---------------------------------------------------------------------------
9401
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009402 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009403
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009404 This is the driver exit point (invoked when module is unloaded using rmmod
9405 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009406
9407 \param - None
9408
9409 \return - None
9410
9411 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009412static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009413{
9414 hdd_context_t *pHddCtx = NULL;
9415 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309416 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309417 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009418
9419 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9420
9421 //Get the global vos context
9422 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9423
9424 if(!pVosContext)
9425 {
9426 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9427 goto done;
9428 }
9429
9430 //Get the HDD context.
9431 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9432
9433 if(!pHddCtx)
9434 {
9435 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9436 }
9437 else
9438 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309439 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9440
9441 if (pHddCtx->isLogpInProgress)
9442 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309444 "%s:SSR in Progress; block rmmod !!!", __func__);
9445 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9446 msecs_to_jiffies(30000));
9447 if(!rc)
9448 {
9449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9450 "%s:SSR timedout, fatal error", __func__);
9451 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009452 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309453 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009454
Mihir Shete18156292014-03-11 15:38:30 +05309455 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9457
Agarwal Ashish5e414792014-06-08 15:25:23 +05309458 if (eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
9459 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority )
9460 {
9461 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9462 }
9463
Jeff Johnson295189b2012-06-20 16:38:30 -07009464 //Do all the cleanup before deregistering the driver
9465 hdd_wlan_exit(pHddCtx);
9466 }
9467
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 vos_preClose( &pVosContext );
9469
9470#ifdef TIMER_MANAGER
9471 vos_timer_exit();
9472#endif
9473#ifdef MEMORY_DEBUG
9474 vos_mem_exit();
9475#endif
9476
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309477#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9478 wlan_logging_sock_deinit_svc();
9479#endif
9480
Jeff Johnson295189b2012-06-20 16:38:30 -07009481done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009482#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009484#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309485
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9487}
9488
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009489/**---------------------------------------------------------------------------
9490
9491 \brief hdd_module_exit() - Exit function
9492
9493 This is the driver exit point (invoked when module is unloaded using rmmod)
9494
9495 \param - None
9496
9497 \return - None
9498
9499 --------------------------------------------------------------------------*/
9500static void __exit hdd_module_exit(void)
9501{
9502 hdd_driver_exit();
9503}
9504
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009505#ifdef MODULE
9506static int fwpath_changed_handler(const char *kmessage,
9507 struct kernel_param *kp)
9508{
Jeff Johnson76052702013-04-16 13:55:05 -07009509 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009510}
9511
9512static int con_mode_handler(const char *kmessage,
9513 struct kernel_param *kp)
9514{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009515 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009516}
9517#else /* #ifdef MODULE */
9518/**---------------------------------------------------------------------------
9519
Jeff Johnson76052702013-04-16 13:55:05 -07009520 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009521
Jeff Johnson76052702013-04-16 13:55:05 -07009522 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009523 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009524 - invoked when module parameter fwpath is modified from userspace to signal
9525 initializing the WLAN driver or when con_mode is modified from userspace
9526 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009527
9528 \return - 0 for success, non zero for failure
9529
9530 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009531static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009532{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009533 int ret_status;
9534
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009535 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009536 ret_status = hdd_driver_init();
9537 wlan_hdd_inited = ret_status ? 0 : 1;
9538 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009539 }
9540
9541 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009542
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009543 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009544
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009545 ret_status = hdd_driver_init();
9546 wlan_hdd_inited = ret_status ? 0 : 1;
9547 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009548}
9549
Jeff Johnson295189b2012-06-20 16:38:30 -07009550/**---------------------------------------------------------------------------
9551
Jeff Johnson76052702013-04-16 13:55:05 -07009552 \brief fwpath_changed_handler() - Handler Function
9553
9554 Handle changes to the fwpath parameter
9555
9556 \return - 0 for success, non zero for failure
9557
9558 --------------------------------------------------------------------------*/
9559static int fwpath_changed_handler(const char *kmessage,
9560 struct kernel_param *kp)
9561{
9562 int ret;
9563
9564 ret = param_set_copystring(kmessage, kp);
9565 if (0 == ret)
9566 ret = kickstart_driver();
9567 return ret;
9568}
9569
9570/**---------------------------------------------------------------------------
9571
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009572 \brief con_mode_handler() -
9573
9574 Handler function for module param con_mode when it is changed by userspace
9575 Dynamically linked - do nothing
9576 Statically linked - exit and init driver, as in rmmod and insmod
9577
Jeff Johnson76052702013-04-16 13:55:05 -07009578 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009579
Jeff Johnson76052702013-04-16 13:55:05 -07009580 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009581
9582 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009583static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009584{
Jeff Johnson76052702013-04-16 13:55:05 -07009585 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009586
Jeff Johnson76052702013-04-16 13:55:05 -07009587 ret = param_set_int(kmessage, kp);
9588 if (0 == ret)
9589 ret = kickstart_driver();
9590 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009591}
9592#endif /* #ifdef MODULE */
9593
9594/**---------------------------------------------------------------------------
9595
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 \brief hdd_get_conparam() -
9597
9598 This is the driver exit point (invoked when module is unloaded using rmmod)
9599
9600 \param - None
9601
9602 \return - tVOS_CON_MODE
9603
9604 --------------------------------------------------------------------------*/
9605tVOS_CON_MODE hdd_get_conparam ( void )
9606{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009607#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009609#else
9610 return (tVOS_CON_MODE)curr_con_mode;
9611#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009612}
9613void hdd_set_conparam ( v_UINT_t newParam )
9614{
9615 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009616#ifndef MODULE
9617 curr_con_mode = con_mode;
9618#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009619}
9620/**---------------------------------------------------------------------------
9621
9622 \brief hdd_softap_sta_deauth() - function
9623
9624 This to take counter measure to handle deauth req from HDD
9625
9626 \param - pAdapter - Pointer to the HDD
9627
9628 \param - enable - boolean value
9629
9630 \return - None
9631
9632 --------------------------------------------------------------------------*/
9633
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009634VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009635{
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009637 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009638
9639 ENTER();
9640
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009641 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9642 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009643
9644 //Ignore request to deauth bcmc station
9645 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009646 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009647
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009648 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009649
9650 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009651 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009652}
9653
9654/**---------------------------------------------------------------------------
9655
9656 \brief hdd_softap_sta_disassoc() - function
9657
9658 This to take counter measure to handle deauth req from HDD
9659
9660 \param - pAdapter - Pointer to the HDD
9661
9662 \param - enable - boolean value
9663
9664 \return - None
9665
9666 --------------------------------------------------------------------------*/
9667
9668void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9669{
9670 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9671
9672 ENTER();
9673
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309674 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009675
9676 //Ignore request to disassoc bcmc station
9677 if( pDestMacAddress[0] & 0x1 )
9678 return;
9679
9680 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9681}
9682
9683void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9684{
9685 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9686
9687 ENTER();
9688
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309689 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009690
9691 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9692}
9693
Jeff Johnson295189b2012-06-20 16:38:30 -07009694/**---------------------------------------------------------------------------
9695 *
9696 * \brief hdd_get__concurrency_mode() -
9697 *
9698 *
9699 * \param - None
9700 *
9701 * \return - CONCURRENCY MODE
9702 *
9703 * --------------------------------------------------------------------------*/
9704tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9705{
9706 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9707 hdd_context_t *pHddCtx;
9708
9709 if (NULL != pVosContext)
9710 {
9711 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9712 if (NULL != pHddCtx)
9713 {
9714 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9715 }
9716 }
9717
9718 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009719 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 return VOS_STA;
9721}
9722
9723/* Decide whether to allow/not the apps power collapse.
9724 * Allow apps power collapse if we are in connected state.
9725 * if not, allow only if we are in IMPS */
9726v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9727{
9728 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009729 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009730 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9732 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9733 hdd_adapter_t *pAdapter = NULL;
9734 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009735 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009736
Jeff Johnson295189b2012-06-20 16:38:30 -07009737 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9738 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009739
Yathish9f22e662012-12-10 14:21:35 -08009740 concurrent_state = hdd_get_concurrency_mode();
9741
9742#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9743 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9744 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9745 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9746 return TRUE;
9747#endif
9748
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 /*loop through all adapters. TBD fix for Concurrency */
9750 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9751 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9752 {
9753 pAdapter = pAdapterNode->pAdapter;
9754 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9755 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9756 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009757 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309758 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009759 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009760 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9761 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009763 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009764 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9765 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 return FALSE;
9767 }
9768 }
9769 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9770 pAdapterNode = pNext;
9771 }
9772 return TRUE;
9773}
9774
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009775/* Decides whether to send suspend notification to Riva
9776 * if any adapter is in BMPS; then it is required */
9777v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9778{
9779 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9780 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9781
9782 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9783 {
9784 return TRUE;
9785 }
9786 return FALSE;
9787}
9788
Jeff Johnson295189b2012-06-20 16:38:30 -07009789void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9790{
9791 switch(mode)
9792 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009793 case VOS_STA_MODE:
9794 case VOS_P2P_CLIENT_MODE:
9795 case VOS_P2P_GO_MODE:
9796 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009797 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309798 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 break;
9800 default:
9801 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309803 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9804 "Number of open sessions for mode %d = %d"),
9805 pHddCtx->concurrency_mode, mode,
9806 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009807}
9808
9809
9810void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9811{
9812 switch(mode)
9813 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009814 case VOS_STA_MODE:
9815 case VOS_P2P_CLIENT_MODE:
9816 case VOS_P2P_GO_MODE:
9817 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +05309818 pHddCtx->no_of_open_sessions[mode]--;
9819 if (!(pHddCtx->no_of_open_sessions[mode]))
9820 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 break;
9822 default:
9823 break;
9824 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309825 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9826 "Number of open sessions for mode %d = %d"),
9827 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
9828
9829}
9830/**---------------------------------------------------------------------------
9831 *
9832 * \brief wlan_hdd_incr_active_session()
9833 *
9834 * This function increments the number of active sessions
9835 * maintained per device mode
9836 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
9837 * Incase of SAP/P2P GO upon bss start it is incremented
9838 *
9839 * \param pHddCtx - HDD Context
9840 * \param mode - device mode
9841 *
9842 * \return - None
9843 *
9844 * --------------------------------------------------------------------------*/
9845void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9846{
9847 switch (mode) {
9848 case VOS_STA_MODE:
9849 case VOS_P2P_CLIENT_MODE:
9850 case VOS_P2P_GO_MODE:
9851 case VOS_STA_SAP_MODE:
9852 pHddCtx->no_of_active_sessions[mode]++;
9853 break;
9854 default:
9855 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9856 break;
9857 }
9858 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9859 mode,
9860 pHddCtx->no_of_active_sessions[mode]);
9861}
9862
9863/**---------------------------------------------------------------------------
9864 *
9865 * \brief wlan_hdd_decr_active_session()
9866 *
9867 * This function decrements the number of active sessions
9868 * maintained per device mode
9869 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
9870 * Incase of SAP/P2P GO upon bss stop it is decremented
9871 *
9872 * \param pHddCtx - HDD Context
9873 * \param mode - device mode
9874 *
9875 * \return - None
9876 *
9877 * --------------------------------------------------------------------------*/
9878void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9879{
9880 switch (mode) {
9881 case VOS_STA_MODE:
9882 case VOS_P2P_CLIENT_MODE:
9883 case VOS_P2P_GO_MODE:
9884 case VOS_STA_SAP_MODE:
9885 pHddCtx->no_of_active_sessions[mode]--;
9886 break;
9887 default:
9888 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9889 break;
9890 }
9891 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9892 mode,
9893 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009894}
9895
Jeff Johnsone7245742012-09-05 17:12:55 -07009896/**---------------------------------------------------------------------------
9897 *
9898 * \brief wlan_hdd_restart_init
9899 *
9900 * This function initalizes restart timer/flag. An internal function.
9901 *
9902 * \param - pHddCtx
9903 *
9904 * \return - None
9905 *
9906 * --------------------------------------------------------------------------*/
9907
9908static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9909{
9910 /* Initialize */
9911 pHddCtx->hdd_restart_retries = 0;
9912 atomic_set(&pHddCtx->isRestartInProgress, 0);
9913 vos_timer_init(&pHddCtx->hdd_restart_timer,
9914 VOS_TIMER_TYPE_SW,
9915 wlan_hdd_restart_timer_cb,
9916 pHddCtx);
9917}
9918/**---------------------------------------------------------------------------
9919 *
9920 * \brief wlan_hdd_restart_deinit
9921 *
9922 * This function cleans up the resources used. An internal function.
9923 *
9924 * \param - pHddCtx
9925 *
9926 * \return - None
9927 *
9928 * --------------------------------------------------------------------------*/
9929
9930static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9931{
9932
9933 VOS_STATUS vos_status;
9934 /* Block any further calls */
9935 atomic_set(&pHddCtx->isRestartInProgress, 1);
9936 /* Cleanup */
9937 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9938 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309939 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009940 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9941 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309942 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009943
9944}
9945
9946/**---------------------------------------------------------------------------
9947 *
9948 * \brief wlan_hdd_framework_restart
9949 *
9950 * This function uses a cfg80211 API to start a framework initiated WLAN
9951 * driver module unload/load.
9952 *
9953 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9954 *
9955 *
9956 * \param - pHddCtx
9957 *
9958 * \return - VOS_STATUS_SUCCESS: Success
9959 * VOS_STATUS_E_EMPTY: Adapter is Empty
9960 * VOS_STATUS_E_NOMEM: No memory
9961
9962 * --------------------------------------------------------------------------*/
9963
9964static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9965{
9966 VOS_STATUS status = VOS_STATUS_SUCCESS;
9967 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009968 int len = (sizeof (struct ieee80211_mgmt));
9969 struct ieee80211_mgmt *mgmt = NULL;
9970
9971 /* Prepare the DEAUTH managment frame with reason code */
9972 mgmt = kzalloc(len, GFP_KERNEL);
9973 if(mgmt == NULL)
9974 {
9975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9976 "%s: memory allocation failed (%d bytes)", __func__, len);
9977 return VOS_STATUS_E_NOMEM;
9978 }
9979 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009980
9981 /* Iterate over all adapters/devices */
9982 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9983 do
9984 {
9985 if( (status == VOS_STATUS_SUCCESS) &&
9986 pAdapterNode &&
9987 pAdapterNode->pAdapter)
9988 {
9989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9990 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9991 pAdapterNode->pAdapter->dev->name,
9992 pAdapterNode->pAdapter->device_mode,
9993 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009994 /*
9995 * CFG80211 event to restart the driver
9996 *
9997 * 'cfg80211_send_unprot_deauth' sends a
9998 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9999 * of SME(Linux Kernel) state machine.
10000 *
10001 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10002 * the driver.
10003 *
10004 */
10005
10006 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010007 }
10008 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10009 pAdapterNode = pNext;
10010 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10011
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010012
10013 /* Free the allocated management frame */
10014 kfree(mgmt);
10015
Jeff Johnsone7245742012-09-05 17:12:55 -070010016 /* Retry until we unload or reach max count */
10017 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10018 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10019
10020 return status;
10021
10022}
10023/**---------------------------------------------------------------------------
10024 *
10025 * \brief wlan_hdd_restart_timer_cb
10026 *
10027 * Restart timer callback. An internal function.
10028 *
10029 * \param - User data:
10030 *
10031 * \return - None
10032 *
10033 * --------------------------------------------------------------------------*/
10034
10035void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10036{
10037 hdd_context_t *pHddCtx = usrDataForCallback;
10038 wlan_hdd_framework_restart(pHddCtx);
10039 return;
10040
10041}
10042
10043
10044/**---------------------------------------------------------------------------
10045 *
10046 * \brief wlan_hdd_restart_driver
10047 *
10048 * This function sends an event to supplicant to restart the WLAN driver.
10049 *
10050 * This function is called from vos_wlanRestart.
10051 *
10052 * \param - pHddCtx
10053 *
10054 * \return - VOS_STATUS_SUCCESS: Success
10055 * VOS_STATUS_E_EMPTY: Adapter is Empty
10056 * VOS_STATUS_E_ALREADY: Request already in progress
10057
10058 * --------------------------------------------------------------------------*/
10059VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10060{
10061 VOS_STATUS status = VOS_STATUS_SUCCESS;
10062
10063 /* A tight check to make sure reentrancy */
10064 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10065 {
Mihir Shetefd528652014-06-23 19:07:50 +053010066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010067 "%s: WLAN restart is already in progress", __func__);
10068
10069 return VOS_STATUS_E_ALREADY;
10070 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010071 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010072#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010073 wcnss_reset_intr();
10074#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010075
Jeff Johnsone7245742012-09-05 17:12:55 -070010076 return status;
10077}
10078
Mihir Shetee1093ba2014-01-21 20:13:32 +053010079/**---------------------------------------------------------------------------
10080 *
10081 * \brief wlan_hdd_init_channels
10082 *
10083 * This function is used to initialize the channel list in CSR
10084 *
10085 * This function is called from hdd_wlan_startup
10086 *
10087 * \param - pHddCtx: HDD context
10088 *
10089 * \return - VOS_STATUS_SUCCESS: Success
10090 * VOS_STATUS_E_FAULT: Failure reported by SME
10091
10092 * --------------------------------------------------------------------------*/
10093static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10094{
10095 eHalStatus status;
10096
10097 status = sme_InitChannels(pHddCtx->hHal);
10098 if (HAL_STATUS_SUCCESS(status))
10099 {
10100 return VOS_STATUS_SUCCESS;
10101 }
10102 else
10103 {
10104 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10105 __func__, status);
10106 return VOS_STATUS_E_FAULT;
10107 }
10108}
10109
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010110static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
10111{
10112 eHalStatus status;
10113
10114 status = sme_InitChannelsForCC(pHddCtx->hHal);
10115 if (HAL_STATUS_SUCCESS(status))
10116 {
10117 return VOS_STATUS_SUCCESS;
10118 }
10119 else
10120 {
10121 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10122 __func__, status);
10123 return VOS_STATUS_E_FAULT;
10124 }
10125}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010126/*
10127 * API to find if there is any STA or P2P-Client is connected
10128 */
10129VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10130{
10131 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10132}
Jeff Johnsone7245742012-09-05 17:12:55 -070010133
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010134int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10135{
10136 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10137 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010138 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010139
10140 pScanInfo = &pHddCtx->scan_info;
10141 if (pScanInfo->mScanPending)
10142 {
10143 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10144 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10145 eCSR_SCAN_ABORT_DEFAULT);
10146
10147 status = wait_for_completion_interruptible_timeout(
10148 &pScanInfo->abortscan_event_var,
10149 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010150 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010151 {
10152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010153 "%s: Timeout or Interrupt occurred while waiting for abort"
10154 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010155 return -ETIMEDOUT;
10156 }
10157 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010158 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010159}
10160
Jeff Johnson295189b2012-06-20 16:38:30 -070010161//Register the module init/exit functions
10162module_init(hdd_module_init);
10163module_exit(hdd_module_exit);
10164
10165MODULE_LICENSE("Dual BSD/GPL");
10166MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10167MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10168
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010169module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10170 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010171
Jeff Johnson76052702013-04-16 13:55:05 -070010172module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010173 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010174
10175module_param(enable_dfs_chan_scan, int,
10176 S_IRUSR | S_IRGRP | S_IROTH);
10177
10178module_param(enable_11d, int,
10179 S_IRUSR | S_IRGRP | S_IROTH);
10180
10181module_param(country_code, charp,
10182 S_IRUSR | S_IRGRP | S_IROTH);