blob: 15039af71f595c5fc6bee18c44f4e4d58c118a30 [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 }
2006 else
2007 {
2008 ret = -EINVAL;
2009 }
2010
2011 return ret;
2012}
2013
2014static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2015{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302016 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302017 hdd_config_t *pCfg;
2018 tANI_U8 *value = command;
2019 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302020 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302021
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302022 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2023 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302024 {
2025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2026 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2027 ret = -EINVAL;
2028 return ret;
2029 }
2030
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302031 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2032 sme_GetConfigParam(hHal, &smeConfig);
2033
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302034 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2035 {
2036 value = value + 24;
2037 temp = kstrtou32(value, 10, &val);
2038 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2039 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2040 {
2041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2042 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2043 ret = -EFAULT;
2044 return ret;
2045 }
2046 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302047 smeConfig.csrConfig.nActiveMaxChnTime = val;
2048 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302049 }
2050 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2051 {
2052 value = value + 24;
2053 temp = kstrtou32(value, 10, &val);
2054 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2055 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2056 {
2057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2058 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2059 ret = -EFAULT;
2060 return ret;
2061 }
2062 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302063 smeConfig.csrConfig.nActiveMinChnTime = val;
2064 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302065 }
2066 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2067 {
2068 value = value + 25;
2069 temp = kstrtou32(value, 10, &val);
2070 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2071 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2072 {
2073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2074 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2075 ret = -EFAULT;
2076 return ret;
2077 }
2078 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302079 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2080 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302081 }
2082 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2083 {
2084 value = value + 25;
2085 temp = kstrtou32(value, 10, &val);
2086 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2087 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2088 {
2089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2090 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2091 ret = -EFAULT;
2092 return ret;
2093 }
2094 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302095 smeConfig.csrConfig.nPassiveMinChnTime = val;
2096 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302097 }
2098 else
2099 {
2100 ret = -EINVAL;
2101 }
2102
2103 return ret;
2104}
2105
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002106static int hdd_driver_command(hdd_adapter_t *pAdapter,
2107 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002108{
Jeff Johnson295189b2012-06-20 16:38:30 -07002109 hdd_priv_data_t priv_data;
2110 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002111 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002112
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002113 /*
2114 * Note that valid pointers are provided by caller
2115 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002116
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002117 /* copy to local struct to avoid numerous changes to legacy code */
2118 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002119
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002120 if (priv_data.total_len <= 0 ||
2121 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002122 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002123 hddLog(VOS_TRACE_LEVEL_WARN,
2124 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2125 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002126 ret = -EINVAL;
2127 goto exit;
2128 }
2129
2130 /* Allocate +1 for '\0' */
2131 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 if (!command)
2133 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002134 hddLog(VOS_TRACE_LEVEL_ERROR,
2135 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002136 ret = -ENOMEM;
2137 goto exit;
2138 }
2139
2140 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2141 {
2142 ret = -EFAULT;
2143 goto exit;
2144 }
2145
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002146 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002147 command[priv_data.total_len] = '\0';
2148
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002149 /* at one time the following block of code was conditional. braces
2150 * have been retained to avoid re-indenting the legacy code
2151 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002152 {
2153 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2154
2155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002156 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002157
2158 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2159 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302160 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2161 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2162 pAdapter->sessionId, (unsigned)
2163 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2164 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2165 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2166 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002167 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2168 sizeof(tSirMacAddr)))
2169 {
2170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002171 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002172 ret = -EFAULT;
2173 }
2174 }
Amar Singhal0974e402013-02-12 14:27:46 -08002175 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 {
Amar Singhal0974e402013-02-12 14:27:46 -08002177 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002178
Jeff Johnson295189b2012-06-20 16:38:30 -07002179 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002180
2181 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002182 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002184 "%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 -07002185 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002186 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302187 if(ret != 0)
2188 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002189 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002190 }
Kiet Lamf040f472013-11-20 21:15:23 +05302191 else if(strncmp(command, "SETWMMPS", 8) == 0)
2192 {
2193 tANI_U8 *ptr = command;
2194 ret = hdd_wmmps_helper(pAdapter, ptr);
2195 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002196 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2197 {
2198 char *country_code;
2199
2200 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002201
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002202 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002203 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002204#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302205 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002206#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002207 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2208 (void *)(tSmeChangeCountryCallback)
2209 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302210 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002211 if (eHAL_STATUS_SUCCESS == ret)
2212 {
2213 ret = wait_for_completion_interruptible_timeout(
2214 &pAdapter->change_country_code,
2215 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2216 if (0 >= ret)
2217 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302219 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002220 }
2221 }
2222 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002223 {
2224 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002225 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002226 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002227 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002228
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002229 }
2230 /*
2231 command should be a string having format
2232 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2233 */
Amar Singhal0974e402013-02-12 14:27:46 -08002234 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002235 {
Amar Singhal0974e402013-02-12 14:27:46 -08002236 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002237
2238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002239 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002240
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002241 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002242 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002243 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2244 {
2245 int suspend = 0;
2246 tANI_U8 *ptr = (tANI_U8*)command + 15;
2247
2248 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302249 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2250 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2251 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002252 hdd_set_wlan_suspend_mode(suspend);
2253 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002254#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2255 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2256 {
2257 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002258 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002259 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2260 eHalStatus status = eHAL_STATUS_SUCCESS;
2261
2262 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2263 value = value + 15;
2264
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002265 /* Convert the value from ascii to integer */
2266 ret = kstrtos8(value, 10, &rssi);
2267 if (ret < 0)
2268 {
2269 /* If the input value is greater than max value of datatype, then also
2270 kstrtou8 fails */
2271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2272 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002273 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002274 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2275 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2276 ret = -EINVAL;
2277 goto exit;
2278 }
2279
Srinivas Girigowdade697412013-02-14 16:31:48 -08002280 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002281
Srinivas Girigowdade697412013-02-14 16:31:48 -08002282 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2283 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2284 {
2285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2286 "Neighbor lookup threshold value %d is out of range"
2287 " (Min: %d Max: %d)", lookUpThreshold,
2288 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2289 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2290 ret = -EINVAL;
2291 goto exit;
2292 }
2293
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302294 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2295 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2296 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2298 "%s: Received Command to Set Roam trigger"
2299 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2300
2301 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2302 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2303 if (eHAL_STATUS_SUCCESS != status)
2304 {
2305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2306 "%s: Failed to set roam trigger, try again", __func__);
2307 ret = -EPERM;
2308 goto exit;
2309 }
2310
2311 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302312 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002313 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2314 }
2315 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2316 {
2317 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2318 int rssi = (-1) * lookUpThreshold;
2319 char extra[32];
2320 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302321 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2322 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2323 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002324 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002325 if (copy_to_user(priv_data.buf, &extra, len + 1))
2326 {
2327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2328 "%s: failed to copy data to user buffer", __func__);
2329 ret = -EFAULT;
2330 goto exit;
2331 }
2332 }
2333 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2334 {
2335 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002336 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002337 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002338
Srinivas Girigowdade697412013-02-14 16:31:48 -08002339 /* input refresh period is in terms of seconds */
2340 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2341 value = value + 18;
2342 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002343 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002344 if (ret < 0)
2345 {
2346 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002347 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002349 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002350 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002351 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2352 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002353 ret = -EINVAL;
2354 goto exit;
2355 }
2356
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002357 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2358 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002359 {
2360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002361 "Roam scan period value %d is out of range"
2362 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002363 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2364 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002365 ret = -EINVAL;
2366 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302367 }
2368 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2369 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2370 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002371 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002372
2373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2374 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002375 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002376
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002377 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2378 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002379 }
2380 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2381 {
2382 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2383 char extra[32];
2384 tANI_U8 len = 0;
2385
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302386 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2387 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2388 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002389 len = scnprintf(extra, sizeof(extra), "%s %d",
2390 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002391 /* Returned value is in units of seconds */
2392 if (copy_to_user(priv_data.buf, &extra, len + 1))
2393 {
2394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2395 "%s: failed to copy data to user buffer", __func__);
2396 ret = -EFAULT;
2397 goto exit;
2398 }
2399 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002400 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2401 {
2402 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002403 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002404 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002405
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002406 /* input refresh period is in terms of seconds */
2407 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2408 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002409
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002410 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002411 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002412 if (ret < 0)
2413 {
2414 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002415 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002417 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002418 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002419 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2420 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2421 ret = -EINVAL;
2422 goto exit;
2423 }
2424
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002425 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2426 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2427 {
2428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2429 "Neighbor scan results refresh period value %d is out of range"
2430 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2431 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2432 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2433 ret = -EINVAL;
2434 goto exit;
2435 }
2436 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2437
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2439 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002441
2442 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2443 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2444 }
2445 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2446 {
2447 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2448 char extra[32];
2449 tANI_U8 len = 0;
2450
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002451 len = scnprintf(extra, sizeof(extra), "%s %d",
2452 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002453 /* Returned value is in units of seconds */
2454 if (copy_to_user(priv_data.buf, &extra, len + 1))
2455 {
2456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2457 "%s: failed to copy data to user buffer", __func__);
2458 ret = -EFAULT;
2459 goto exit;
2460 }
2461 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002462#ifdef FEATURE_WLAN_LFR
2463 /* SETROAMMODE */
2464 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2465 {
2466 tANI_U8 *value = command;
2467 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2468
2469 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2470 value = value + SIZE_OF_SETROAMMODE + 1;
2471
2472 /* Convert the value from ascii to integer */
2473 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2474 if (ret < 0)
2475 {
2476 /* If the input value is greater than max value of datatype, then also
2477 kstrtou8 fails */
2478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2479 "%s: kstrtou8 failed range [%d - %d]", __func__,
2480 CFG_LFR_FEATURE_ENABLED_MIN,
2481 CFG_LFR_FEATURE_ENABLED_MAX);
2482 ret = -EINVAL;
2483 goto exit;
2484 }
2485 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2486 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2487 {
2488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2489 "Roam Mode value %d is out of range"
2490 " (Min: %d Max: %d)", roamMode,
2491 CFG_LFR_FEATURE_ENABLED_MIN,
2492 CFG_LFR_FEATURE_ENABLED_MAX);
2493 ret = -EINVAL;
2494 goto exit;
2495 }
2496
2497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2498 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2499 /*
2500 * Note that
2501 * SETROAMMODE 0 is to enable LFR while
2502 * SETROAMMODE 1 is to disable LFR, but
2503 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2504 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2505 */
2506 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2507 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2508 else
2509 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2510
2511 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2512 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2513 }
2514 /* GETROAMMODE */
2515 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2516 {
2517 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2518 char extra[32];
2519 tANI_U8 len = 0;
2520
2521 /*
2522 * roamMode value shall be inverted because the sementics is different.
2523 */
2524 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2525 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2526 else
2527 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2528
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002529 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002530 if (copy_to_user(priv_data.buf, &extra, len + 1))
2531 {
2532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2533 "%s: failed to copy data to user buffer", __func__);
2534 ret = -EFAULT;
2535 goto exit;
2536 }
2537 }
2538#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002539#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002540#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002541 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2542 {
2543 tANI_U8 *value = command;
2544 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2545
2546 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2547 value = value + 13;
2548 /* Convert the value from ascii to integer */
2549 ret = kstrtou8(value, 10, &roamRssiDiff);
2550 if (ret < 0)
2551 {
2552 /* If the input value is greater than max value of datatype, then also
2553 kstrtou8 fails */
2554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2555 "%s: kstrtou8 failed range [%d - %d]", __func__,
2556 CFG_ROAM_RSSI_DIFF_MIN,
2557 CFG_ROAM_RSSI_DIFF_MAX);
2558 ret = -EINVAL;
2559 goto exit;
2560 }
2561
2562 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2563 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2564 {
2565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2566 "Roam rssi diff value %d is out of range"
2567 " (Min: %d Max: %d)", roamRssiDiff,
2568 CFG_ROAM_RSSI_DIFF_MIN,
2569 CFG_ROAM_RSSI_DIFF_MAX);
2570 ret = -EINVAL;
2571 goto exit;
2572 }
2573
2574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2575 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2576
2577 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2578 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2579 }
2580 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2581 {
2582 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2583 char extra[32];
2584 tANI_U8 len = 0;
2585
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302586 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2587 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2588 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002589 len = scnprintf(extra, sizeof(extra), "%s %d",
2590 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002591 if (copy_to_user(priv_data.buf, &extra, len + 1))
2592 {
2593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2594 "%s: failed to copy data to user buffer", __func__);
2595 ret = -EFAULT;
2596 goto exit;
2597 }
2598 }
2599#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002600#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002601 else if (strncmp(command, "GETBAND", 7) == 0)
2602 {
2603 int band = -1;
2604 char extra[32];
2605 tANI_U8 len = 0;
2606 hdd_getBand_helper(pHddCtx, &band);
2607
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302608 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2609 TRACE_CODE_HDD_GETBAND_IOCTL,
2610 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002611 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002612 if (copy_to_user(priv_data.buf, &extra, len + 1))
2613 {
2614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2615 "%s: failed to copy data to user buffer", __func__);
2616 ret = -EFAULT;
2617 goto exit;
2618 }
2619 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002620 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2621 {
2622 tANI_U8 *value = command;
2623 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2624 tANI_U8 numChannels = 0;
2625 eHalStatus status = eHAL_STATUS_SUCCESS;
2626
2627 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2628 if (eHAL_STATUS_SUCCESS != status)
2629 {
2630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2631 "%s: Failed to parse channel list information", __func__);
2632 ret = -EINVAL;
2633 goto exit;
2634 }
2635
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2637 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2638 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002639 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2640 {
2641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2642 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2643 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2644 ret = -EINVAL;
2645 goto exit;
2646 }
2647 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2648 numChannels);
2649 if (eHAL_STATUS_SUCCESS != status)
2650 {
2651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2652 "%s: Failed to update channel list information", __func__);
2653 ret = -EINVAL;
2654 goto exit;
2655 }
2656 }
2657 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2658 {
2659 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2660 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002661 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002662 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002663 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002664
2665 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2666 ChannelList, &numChannels ))
2667 {
2668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2669 "%s: failed to get roam scan channel list", __func__);
2670 ret = -EFAULT;
2671 goto exit;
2672 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2674 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2675 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002676 /* output channel list is of the format
2677 [Number of roam scan channels][Channel1][Channel2]... */
2678 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002679 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 for (j = 0; (j < numChannels); j++)
2681 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002682 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2683 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002684 }
2685
2686 if (copy_to_user(priv_data.buf, &extra, len + 1))
2687 {
2688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2689 "%s: failed to copy data to user buffer", __func__);
2690 ret = -EFAULT;
2691 goto exit;
2692 }
2693 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002694 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2695 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002696 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002697 char extra[32];
2698 tANI_U8 len = 0;
2699
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002700 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002701 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002702 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002703 hdd_is_okc_mode_enabled(pHddCtx) &&
2704 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2705 {
2706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002707 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002708 " hence this operation is not permitted!", __func__);
2709 ret = -EPERM;
2710 goto exit;
2711 }
2712
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002713 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002714 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002715 if (copy_to_user(priv_data.buf, &extra, len + 1))
2716 {
2717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2718 "%s: failed to copy data to user buffer", __func__);
2719 ret = -EFAULT;
2720 goto exit;
2721 }
2722 }
2723 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2724 {
2725 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2726 char extra[32];
2727 tANI_U8 len = 0;
2728
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002729 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002730 then this operation is not permitted (return FAILURE) */
2731 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002732 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002733 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2734 {
2735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002736 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002737 " hence this operation is not permitted!", __func__);
2738 ret = -EPERM;
2739 goto exit;
2740 }
2741
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002742 len = scnprintf(extra, sizeof(extra), "%s %d",
2743 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002744 if (copy_to_user(priv_data.buf, &extra, len + 1))
2745 {
2746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2747 "%s: failed to copy data to user buffer", __func__);
2748 ret = -EFAULT;
2749 goto exit;
2750 }
2751 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002752 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002753 {
2754 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2755 char extra[32];
2756 tANI_U8 len = 0;
2757
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002758 len = scnprintf(extra, sizeof(extra), "%s %d",
2759 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002760 if (copy_to_user(priv_data.buf, &extra, len + 1))
2761 {
2762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2763 "%s: failed to copy data to user buffer", __func__);
2764 ret = -EFAULT;
2765 goto exit;
2766 }
2767 }
2768 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2769 {
2770 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2771 char extra[32];
2772 tANI_U8 len = 0;
2773
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002774 len = scnprintf(extra, sizeof(extra), "%s %d",
2775 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002776 if (copy_to_user(priv_data.buf, &extra, len + 1))
2777 {
2778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2779 "%s: failed to copy data to user buffer", __func__);
2780 ret = -EFAULT;
2781 goto exit;
2782 }
2783 }
2784 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2785 {
2786 tANI_U8 *value = command;
2787 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2788
2789 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2790 value = value + 26;
2791 /* Convert the value from ascii to integer */
2792 ret = kstrtou8(value, 10, &minTime);
2793 if (ret < 0)
2794 {
2795 /* If the input value is greater than max value of datatype, then also
2796 kstrtou8 fails */
2797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2798 "%s: kstrtou8 failed range [%d - %d]", __func__,
2799 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2800 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2801 ret = -EINVAL;
2802 goto exit;
2803 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002804 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2805 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2808 "scan min channel time value %d is out of range"
2809 " (Min: %d Max: %d)", minTime,
2810 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2811 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2812 ret = -EINVAL;
2813 goto exit;
2814 }
2815
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2817 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2818 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2820 "%s: Received Command to change channel min time = %d", __func__, minTime);
2821
2822 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2823 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2824 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002825 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2826 {
2827 tANI_U8 *value = command;
2828 tANI_U8 channel = 0;
2829 tANI_U8 dwellTime = 0;
2830 tANI_U8 bufLen = 0;
2831 tANI_U8 *buf = NULL;
2832 tSirMacAddr targetApBssid;
2833 eHalStatus status = eHAL_STATUS_SUCCESS;
2834 struct ieee80211_channel chan;
2835 tANI_U8 finalLen = 0;
2836 tANI_U8 *finalBuf = NULL;
2837 tANI_U8 temp = 0;
2838 u64 cookie;
2839 hdd_station_ctx_t *pHddStaCtx = NULL;
2840 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2841
2842 /* if not associated, no need to send action frame */
2843 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2844 {
2845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2846 ret = -EINVAL;
2847 goto exit;
2848 }
2849
2850 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2851 &dwellTime, &buf, &bufLen);
2852 if (eHAL_STATUS_SUCCESS != status)
2853 {
2854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2855 "%s: Failed to parse send action frame data", __func__);
2856 ret = -EINVAL;
2857 goto exit;
2858 }
2859
2860 /* if the target bssid is different from currently associated AP,
2861 then no need to send action frame */
2862 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2863 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2864 {
2865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2866 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002867 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002868 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002869 goto exit;
2870 }
2871
2872 /* if the channel number is different from operating channel then
2873 no need to send action frame */
2874 if (channel != pHddStaCtx->conn_info.operationChannel)
2875 {
2876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2877 "%s: channel(%d) is different from operating channel(%d)",
2878 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2879 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002880 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002881 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002882 goto exit;
2883 }
2884 chan.center_freq = sme_ChnToFreq(channel);
2885
2886 finalLen = bufLen + 24;
2887 finalBuf = vos_mem_malloc(finalLen);
2888 if (NULL == finalBuf)
2889 {
2890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2891 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002892 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002893 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002894 goto exit;
2895 }
2896 vos_mem_zero(finalBuf, finalLen);
2897
2898 /* Fill subtype */
2899 temp = SIR_MAC_MGMT_ACTION << 4;
2900 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2901
2902 /* Fill type */
2903 temp = SIR_MAC_MGMT_FRAME;
2904 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2905
2906 /* Fill destination address (bssid of the AP) */
2907 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2908
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002909 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002910 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2911
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002912 /* Fill BSSID (AP mac address) */
2913 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002914
2915 /* Fill received buffer from 24th address */
2916 vos_mem_copy(finalBuf + 24, buf, bufLen);
2917
Jeff Johnson11c33152013-04-16 17:52:40 -07002918 /* done with the parsed buffer */
2919 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002920 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002921
DARAM SUDHA39eede62014-02-12 11:16:40 +05302922 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002923#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2924 &(pAdapter->wdev),
2925#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002926 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002927#endif
2928 &chan, 0,
2929#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2930 NL80211_CHAN_HT20, 1,
2931#endif
2932 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002933 1, &cookie );
2934 vos_mem_free(finalBuf);
2935 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002936 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2937 {
2938 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2939 char extra[32];
2940 tANI_U8 len = 0;
2941
2942 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002943 len = scnprintf(extra, sizeof(extra), "%s %d",
2944 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302945 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2946 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2947 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002948 if (copy_to_user(priv_data.buf, &extra, len + 1))
2949 {
2950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2951 "%s: failed to copy data to user buffer", __func__);
2952 ret = -EFAULT;
2953 goto exit;
2954 }
2955 }
2956 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2957 {
2958 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002959 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002960
2961 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2962 value = value + 19;
2963 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002964 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002965 if (ret < 0)
2966 {
2967 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002968 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002970 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002971 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2972 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2973 ret = -EINVAL;
2974 goto exit;
2975 }
2976
2977 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2978 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2979 {
2980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2981 "lfr mode value %d is out of range"
2982 " (Min: %d Max: %d)", maxTime,
2983 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2984 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2985 ret = -EINVAL;
2986 goto exit;
2987 }
2988
2989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2990 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2991
2992 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2993 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2994 }
2995 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2996 {
2997 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2998 char extra[32];
2999 tANI_U8 len = 0;
3000
3001 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003002 len = scnprintf(extra, sizeof(extra), "%s %d",
3003 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003004 if (copy_to_user(priv_data.buf, &extra, len + 1))
3005 {
3006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3007 "%s: failed to copy data to user buffer", __func__);
3008 ret = -EFAULT;
3009 goto exit;
3010 }
3011 }
3012 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3013 {
3014 tANI_U8 *value = command;
3015 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3016
3017 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3018 value = value + 16;
3019 /* Convert the value from ascii to integer */
3020 ret = kstrtou16(value, 10, &val);
3021 if (ret < 0)
3022 {
3023 /* If the input value is greater than max value of datatype, then also
3024 kstrtou16 fails */
3025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3026 "%s: kstrtou16 failed range [%d - %d]", __func__,
3027 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3028 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3029 ret = -EINVAL;
3030 goto exit;
3031 }
3032
3033 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3034 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3035 {
3036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3037 "scan home time value %d is out of range"
3038 " (Min: %d Max: %d)", val,
3039 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3040 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3041 ret = -EINVAL;
3042 goto exit;
3043 }
3044
3045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3046 "%s: Received Command to change scan home time = %d", __func__, val);
3047
3048 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3049 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3050 }
3051 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3052 {
3053 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3054 char extra[32];
3055 tANI_U8 len = 0;
3056
3057 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003058 len = scnprintf(extra, sizeof(extra), "%s %d",
3059 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003060 if (copy_to_user(priv_data.buf, &extra, len + 1))
3061 {
3062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3063 "%s: failed to copy data to user buffer", __func__);
3064 ret = -EFAULT;
3065 goto exit;
3066 }
3067 }
3068 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3069 {
3070 tANI_U8 *value = command;
3071 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3072
3073 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3074 value = value + 17;
3075 /* Convert the value from ascii to integer */
3076 ret = kstrtou8(value, 10, &val);
3077 if (ret < 0)
3078 {
3079 /* If the input value is greater than max value of datatype, then also
3080 kstrtou8 fails */
3081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3082 "%s: kstrtou8 failed range [%d - %d]", __func__,
3083 CFG_ROAM_INTRA_BAND_MIN,
3084 CFG_ROAM_INTRA_BAND_MAX);
3085 ret = -EINVAL;
3086 goto exit;
3087 }
3088
3089 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3090 (val > CFG_ROAM_INTRA_BAND_MAX))
3091 {
3092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3093 "intra band mode value %d is out of range"
3094 " (Min: %d Max: %d)", val,
3095 CFG_ROAM_INTRA_BAND_MIN,
3096 CFG_ROAM_INTRA_BAND_MAX);
3097 ret = -EINVAL;
3098 goto exit;
3099 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3101 "%s: Received Command to change intra band = %d", __func__, val);
3102
3103 pHddCtx->cfg_ini->nRoamIntraBand = val;
3104 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3105 }
3106 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3107 {
3108 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3109 char extra[32];
3110 tANI_U8 len = 0;
3111
3112 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003113 len = scnprintf(extra, sizeof(extra), "%s %d",
3114 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003115 if (copy_to_user(priv_data.buf, &extra, len + 1))
3116 {
3117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3118 "%s: failed to copy data to user buffer", __func__);
3119 ret = -EFAULT;
3120 goto exit;
3121 }
3122 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003123 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3124 {
3125 tANI_U8 *value = command;
3126 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3127
3128 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3129 value = value + 15;
3130 /* Convert the value from ascii to integer */
3131 ret = kstrtou8(value, 10, &nProbes);
3132 if (ret < 0)
3133 {
3134 /* If the input value is greater than max value of datatype, then also
3135 kstrtou8 fails */
3136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3137 "%s: kstrtou8 failed range [%d - %d]", __func__,
3138 CFG_ROAM_SCAN_N_PROBES_MIN,
3139 CFG_ROAM_SCAN_N_PROBES_MAX);
3140 ret = -EINVAL;
3141 goto exit;
3142 }
3143
3144 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3145 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3146 {
3147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3148 "NProbes value %d is out of range"
3149 " (Min: %d Max: %d)", nProbes,
3150 CFG_ROAM_SCAN_N_PROBES_MIN,
3151 CFG_ROAM_SCAN_N_PROBES_MAX);
3152 ret = -EINVAL;
3153 goto exit;
3154 }
3155
3156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3157 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3158
3159 pHddCtx->cfg_ini->nProbes = nProbes;
3160 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3161 }
3162 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3163 {
3164 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3165 char extra[32];
3166 tANI_U8 len = 0;
3167
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003168 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003169 if (copy_to_user(priv_data.buf, &extra, len + 1))
3170 {
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "%s: failed to copy data to user buffer", __func__);
3173 ret = -EFAULT;
3174 goto exit;
3175 }
3176 }
3177 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3178 {
3179 tANI_U8 *value = command;
3180 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3181
3182 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3183 /* input value is in units of msec */
3184 value = value + 20;
3185 /* Convert the value from ascii to integer */
3186 ret = kstrtou16(value, 10, &homeAwayTime);
3187 if (ret < 0)
3188 {
3189 /* If the input value is greater than max value of datatype, then also
3190 kstrtou8 fails */
3191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3192 "%s: kstrtou8 failed range [%d - %d]", __func__,
3193 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3194 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3195 ret = -EINVAL;
3196 goto exit;
3197 }
3198
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003199 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3200 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3201 {
3202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3203 "homeAwayTime value %d is out of range"
3204 " (Min: %d Max: %d)", homeAwayTime,
3205 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3206 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3207 ret = -EINVAL;
3208 goto exit;
3209 }
3210
3211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3212 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003213 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3214 {
3215 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3216 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3217 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003218 }
3219 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3220 {
3221 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3222 char extra[32];
3223 tANI_U8 len = 0;
3224
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003225 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003226 if (copy_to_user(priv_data.buf, &extra, len + 1))
3227 {
3228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3229 "%s: failed to copy data to user buffer", __func__);
3230 ret = -EFAULT;
3231 goto exit;
3232 }
3233 }
3234 else if (strncmp(command, "REASSOC", 7) == 0)
3235 {
3236 tANI_U8 *value = command;
3237 tANI_U8 channel = 0;
3238 tSirMacAddr targetApBssid;
3239 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003240#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3241 tCsrHandoffRequest handoffInfo;
3242#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003243 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003244 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3245
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003246 /* if not associated, no need to proceed with reassoc */
3247 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3248 {
3249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3250 ret = -EINVAL;
3251 goto exit;
3252 }
3253
3254 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3255 if (eHAL_STATUS_SUCCESS != status)
3256 {
3257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3258 "%s: Failed to parse reassoc command data", __func__);
3259 ret = -EINVAL;
3260 goto exit;
3261 }
3262
3263 /* if the target bssid is same as currently associated AP,
3264 then no need to proceed with reassoc */
3265 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3266 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3267 {
3268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3269 ret = -EINVAL;
3270 goto exit;
3271 }
3272
3273 /* Check channel number is a valid channel number */
3274 if(VOS_STATUS_SUCCESS !=
3275 wlan_hdd_validate_operation_channel(pAdapter, channel))
3276 {
3277 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003278 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003279 return -EINVAL;
3280 }
3281
3282 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003283#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3284 handoffInfo.channel = channel;
3285 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3286 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3287#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003288 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003289 else if (strncmp(command, "SETWESMODE", 10) == 0)
3290 {
3291 tANI_U8 *value = command;
3292 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3293
3294 /* Move pointer to ahead of SETWESMODE<delimiter> */
3295 value = value + 11;
3296 /* Convert the value from ascii to integer */
3297 ret = kstrtou8(value, 10, &wesMode);
3298 if (ret < 0)
3299 {
3300 /* If the input value is greater than max value of datatype, then also
3301 kstrtou8 fails */
3302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3303 "%s: kstrtou8 failed range [%d - %d]", __func__,
3304 CFG_ENABLE_WES_MODE_NAME_MIN,
3305 CFG_ENABLE_WES_MODE_NAME_MAX);
3306 ret = -EINVAL;
3307 goto exit;
3308 }
3309
3310 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3311 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3312 {
3313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3314 "WES Mode value %d is out of range"
3315 " (Min: %d Max: %d)", wesMode,
3316 CFG_ENABLE_WES_MODE_NAME_MIN,
3317 CFG_ENABLE_WES_MODE_NAME_MAX);
3318 ret = -EINVAL;
3319 goto exit;
3320 }
3321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3322 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3323
3324 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3325 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3326 }
3327 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3328 {
3329 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3330 char extra[32];
3331 tANI_U8 len = 0;
3332
Arif Hussain826d9412013-11-12 16:44:54 -08003333 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003334 if (copy_to_user(priv_data.buf, &extra, len + 1))
3335 {
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3337 "%s: failed to copy data to user buffer", __func__);
3338 ret = -EFAULT;
3339 goto exit;
3340 }
3341 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003342#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003343#ifdef FEATURE_WLAN_LFR
3344 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3345 {
3346 tANI_U8 *value = command;
3347 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3348
3349 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3350 value = value + 12;
3351 /* Convert the value from ascii to integer */
3352 ret = kstrtou8(value, 10, &lfrMode);
3353 if (ret < 0)
3354 {
3355 /* If the input value is greater than max value of datatype, then also
3356 kstrtou8 fails */
3357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3358 "%s: kstrtou8 failed range [%d - %d]", __func__,
3359 CFG_LFR_FEATURE_ENABLED_MIN,
3360 CFG_LFR_FEATURE_ENABLED_MAX);
3361 ret = -EINVAL;
3362 goto exit;
3363 }
3364
3365 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3366 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3367 {
3368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3369 "lfr mode value %d is out of range"
3370 " (Min: %d Max: %d)", lfrMode,
3371 CFG_LFR_FEATURE_ENABLED_MIN,
3372 CFG_LFR_FEATURE_ENABLED_MAX);
3373 ret = -EINVAL;
3374 goto exit;
3375 }
3376
3377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3378 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3379
3380 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3381 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3382 }
3383#endif
3384#ifdef WLAN_FEATURE_VOWIFI_11R
3385 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3386 {
3387 tANI_U8 *value = command;
3388 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3389
3390 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3391 value = value + 18;
3392 /* Convert the value from ascii to integer */
3393 ret = kstrtou8(value, 10, &ft);
3394 if (ret < 0)
3395 {
3396 /* If the input value is greater than max value of datatype, then also
3397 kstrtou8 fails */
3398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3399 "%s: kstrtou8 failed range [%d - %d]", __func__,
3400 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3401 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3402 ret = -EINVAL;
3403 goto exit;
3404 }
3405
3406 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3407 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3408 {
3409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3410 "ft mode value %d is out of range"
3411 " (Min: %d Max: %d)", ft,
3412 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3413 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3414 ret = -EINVAL;
3415 goto exit;
3416 }
3417
3418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3419 "%s: Received Command to change ft mode = %d", __func__, ft);
3420
3421 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3422 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3423 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303424
3425 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3426 {
3427 tANI_U8 *value = command;
3428 tSirMacAddr targetApBssid;
3429 tANI_U8 trigger = 0;
3430 eHalStatus status = eHAL_STATUS_SUCCESS;
3431 hdd_station_ctx_t *pHddStaCtx = NULL;
3432 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3433
3434 /* if not associated, no need to proceed with reassoc */
3435 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3436 {
3437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3438 ret = -EINVAL;
3439 goto exit;
3440 }
3441
3442 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3443 if (eHAL_STATUS_SUCCESS != status)
3444 {
3445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3446 "%s: Failed to parse reassoc command data", __func__);
3447 ret = -EINVAL;
3448 goto exit;
3449 }
3450
3451 /* if the target bssid is same as currently associated AP,
3452 then no need to proceed with reassoc */
3453 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3454 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3455 {
3456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3457 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3458 __func__);
3459 ret = -EINVAL;
3460 goto exit;
3461 }
3462
3463 /* Proceed with scan/roam */
3464 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3465 &targetApBssid[0],
3466 (tSmeFastRoamTrigger)(trigger));
3467 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003468#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003469#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003470 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3471 {
3472 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003473 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003474
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003475 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003476 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003477 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003478 hdd_is_okc_mode_enabled(pHddCtx) &&
3479 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3480 {
3481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003482 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003483 " hence this operation is not permitted!", __func__);
3484 ret = -EPERM;
3485 goto exit;
3486 }
3487
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003488 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3489 value = value + 11;
3490 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003491 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003492 if (ret < 0)
3493 {
3494 /* If the input value is greater than max value of datatype, then also
3495 kstrtou8 fails */
3496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3497 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003498 CFG_ESE_FEATURE_ENABLED_MIN,
3499 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003500 ret = -EINVAL;
3501 goto exit;
3502 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003503 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3504 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003505 {
3506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003507 "Ese mode value %d is out of range"
3508 " (Min: %d Max: %d)", eseMode,
3509 CFG_ESE_FEATURE_ENABLED_MIN,
3510 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003511 ret = -EINVAL;
3512 goto exit;
3513 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003515 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003516
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003517 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3518 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003519 }
3520#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003521 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3522 {
3523 tANI_U8 *value = command;
3524 tANI_BOOLEAN roamScanControl = 0;
3525
3526 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3527 value = value + 19;
3528 /* Convert the value from ascii to integer */
3529 ret = kstrtou8(value, 10, &roamScanControl);
3530 if (ret < 0)
3531 {
3532 /* If the input value is greater than max value of datatype, then also
3533 kstrtou8 fails */
3534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3535 "%s: kstrtou8 failed ", __func__);
3536 ret = -EINVAL;
3537 goto exit;
3538 }
3539
3540 if (0 != roamScanControl)
3541 {
3542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3543 "roam scan control invalid value = %d",
3544 roamScanControl);
3545 ret = -EINVAL;
3546 goto exit;
3547 }
3548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3549 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3550
3551 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3552 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003553#ifdef FEATURE_WLAN_OKC
3554 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3555 {
3556 tANI_U8 *value = command;
3557 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3558
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003559 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003560 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003561 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003562 hdd_is_okc_mode_enabled(pHddCtx) &&
3563 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3564 {
3565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003566 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003567 " hence this operation is not permitted!", __func__);
3568 ret = -EPERM;
3569 goto exit;
3570 }
3571
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003572 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3573 value = value + 11;
3574 /* Convert the value from ascii to integer */
3575 ret = kstrtou8(value, 10, &okcMode);
3576 if (ret < 0)
3577 {
3578 /* If the input value is greater than max value of datatype, then also
3579 kstrtou8 fails */
3580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3581 "%s: kstrtou8 failed range [%d - %d]", __func__,
3582 CFG_OKC_FEATURE_ENABLED_MIN,
3583 CFG_OKC_FEATURE_ENABLED_MAX);
3584 ret = -EINVAL;
3585 goto exit;
3586 }
3587
3588 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3589 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3590 {
3591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3592 "Okc mode value %d is out of range"
3593 " (Min: %d Max: %d)", okcMode,
3594 CFG_OKC_FEATURE_ENABLED_MIN,
3595 CFG_OKC_FEATURE_ENABLED_MAX);
3596 ret = -EINVAL;
3597 goto exit;
3598 }
3599
3600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3601 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3602
3603 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3604 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003605#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003606 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3607 {
3608 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3609 char extra[32];
3610 tANI_U8 len = 0;
3611
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003612 len = scnprintf(extra, sizeof(extra), "%s %d",
3613 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003614 if (copy_to_user(priv_data.buf, &extra, len + 1))
3615 {
3616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3617 "%s: failed to copy data to user buffer", __func__);
3618 ret = -EFAULT;
3619 goto exit;
3620 }
3621 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303622#ifdef WLAN_FEATURE_PACKET_FILTERING
3623 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3624 {
3625 tANI_U8 filterType = 0;
3626 tANI_U8 *value = command;
3627
3628 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3629 value = value + 22;
3630
3631 /* Convert the value from ascii to integer */
3632 ret = kstrtou8(value, 10, &filterType);
3633 if (ret < 0)
3634 {
3635 /* If the input value is greater than max value of datatype,
3636 * then also kstrtou8 fails
3637 */
3638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3639 "%s: kstrtou8 failed range ", __func__);
3640 ret = -EINVAL;
3641 goto exit;
3642 }
3643
3644 if (filterType != 0 && filterType != 1)
3645 {
3646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3647 "%s: Accepted Values are 0 and 1 ", __func__);
3648 ret = -EINVAL;
3649 goto exit;
3650 }
3651 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3652 pAdapter->sessionId);
3653 }
3654#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303655 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3656 {
Kiet Lam94fd2922014-06-18 19:12:43 -07003657 char *bcMode;
3658 bcMode = command + 11;
3659 if ('1' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303660 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003662 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303663
3664 pHddCtx->btCoexModeSet = TRUE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303665 }
Kiet Lam94fd2922014-06-18 19:12:43 -07003666 else if ('2' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303667 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003669 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303670
3671 pHddCtx->btCoexModeSet = FALSE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303672 }
3673 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003674 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3675 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3677 FL("making default scan to ACTIVE"));
3678 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003679 }
3680 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3681 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3683 FL("making default scan to PASSIVE"));
3684 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003685 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303686 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3687 {
3688 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3689 char extra[32];
3690 tANI_U8 len = 0;
3691
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303692 memset(extra, 0, sizeof(extra));
3693 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3694 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303695 {
3696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3697 "%s: failed to copy data to user buffer", __func__);
3698 ret = -EFAULT;
3699 goto exit;
3700 }
3701 ret = len;
3702 }
3703 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3704 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303705 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303706 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003707 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3708 {
3709 tANI_U8 filterType = 0;
3710 tANI_U8 *value;
3711 value = command + 9;
3712
3713 /* Convert the value from ascii to integer */
3714 ret = kstrtou8(value, 10, &filterType);
3715 if (ret < 0)
3716 {
3717 /* If the input value is greater than max value of datatype,
3718 * then also kstrtou8 fails
3719 */
3720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3721 "%s: kstrtou8 failed range ", __func__);
3722 ret = -EINVAL;
3723 goto exit;
3724 }
3725 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3726 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3727 {
3728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3729 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3730 " 2-Sink ", __func__);
3731 ret = -EINVAL;
3732 goto exit;
3733 }
3734 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3735 pHddCtx->drvr_miracast = filterType;
3736 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3737 }
Leo Chang614d2072013-08-22 14:59:44 -07003738 else if (strncmp(command, "SETMCRATE", 9) == 0)
3739 {
Leo Chang614d2072013-08-22 14:59:44 -07003740 tANI_U8 *value = command;
3741 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003742 tSirRateUpdateInd *rateUpdate;
3743 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003744
3745 /* Only valid for SAP mode */
3746 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3747 {
3748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3749 "%s: SAP mode is not running", __func__);
3750 ret = -EFAULT;
3751 goto exit;
3752 }
3753
3754 /* Move pointer to ahead of SETMCRATE<delimiter> */
3755 /* input value is in units of hundred kbps */
3756 value = value + 10;
3757 /* Convert the value from ascii to integer, decimal base */
3758 ret = kstrtouint(value, 10, &targetRate);
3759
Leo Chang1f98cbd2013-10-17 15:03:52 -07003760 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3761 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003762 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003763 hddLog(VOS_TRACE_LEVEL_ERROR,
3764 "%s: SETMCRATE indication alloc fail", __func__);
3765 ret = -EFAULT;
3766 goto exit;
3767 }
3768 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3769
3770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3771 "MC Target rate %d", targetRate);
3772 /* Ignore unicast */
3773 rateUpdate->ucastDataRate = -1;
3774 rateUpdate->mcastDataRate24GHz = targetRate;
3775 rateUpdate->mcastDataRate5GHz = targetRate;
3776 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3777 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3778 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3779 if (eHAL_STATUS_SUCCESS != status)
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR,
3782 "%s: SET_MC_RATE failed", __func__);
3783 vos_mem_free(rateUpdate);
3784 ret = -EFAULT;
3785 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003786 }
3787 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303788#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003789 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303790 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003791 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303792 }
3793#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003794#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003795 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3796 {
3797 tANI_U8 *value = command;
3798 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3799 tANI_U8 numChannels = 0;
3800 eHalStatus status = eHAL_STATUS_SUCCESS;
3801
3802 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3803 if (eHAL_STATUS_SUCCESS != status)
3804 {
3805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3806 "%s: Failed to parse channel list information", __func__);
3807 ret = -EINVAL;
3808 goto exit;
3809 }
3810
3811 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3812 {
3813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3814 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3815 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3816 ret = -EINVAL;
3817 goto exit;
3818 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003819 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003820 ChannelList,
3821 numChannels);
3822 if (eHAL_STATUS_SUCCESS != status)
3823 {
3824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3825 "%s: Failed to update channel list information", __func__);
3826 ret = -EINVAL;
3827 goto exit;
3828 }
3829 }
3830 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3831 {
3832 tANI_U8 *value = command;
3833 char extra[128] = {0};
3834 int len = 0;
3835 tANI_U8 tid = 0;
3836 hdd_station_ctx_t *pHddStaCtx = NULL;
3837 tAniTrafStrmMetrics tsmMetrics;
3838 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3839
3840 /* if not associated, return error */
3841 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3842 {
3843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3844 ret = -EINVAL;
3845 goto exit;
3846 }
3847
3848 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3849 value = value + 12;
3850 /* Convert the value from ascii to integer */
3851 ret = kstrtou8(value, 10, &tid);
3852 if (ret < 0)
3853 {
3854 /* If the input value is greater than max value of datatype, then also
3855 kstrtou8 fails */
3856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3857 "%s: kstrtou8 failed range [%d - %d]", __func__,
3858 TID_MIN_VALUE,
3859 TID_MAX_VALUE);
3860 ret = -EINVAL;
3861 goto exit;
3862 }
3863
3864 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3865 {
3866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3867 "tid value %d is out of range"
3868 " (Min: %d Max: %d)", tid,
3869 TID_MIN_VALUE,
3870 TID_MAX_VALUE);
3871 ret = -EINVAL;
3872 goto exit;
3873 }
3874
3875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3876 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3877
3878 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3879 {
3880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3881 "%s: failed to get tsm stats", __func__);
3882 ret = -EFAULT;
3883 goto exit;
3884 }
3885
3886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3887 "UplinkPktQueueDly(%d)\n"
3888 "UplinkPktQueueDlyHist[0](%d)\n"
3889 "UplinkPktQueueDlyHist[1](%d)\n"
3890 "UplinkPktQueueDlyHist[2](%d)\n"
3891 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303892 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003893 "UplinkPktLoss(%d)\n"
3894 "UplinkPktCount(%d)\n"
3895 "RoamingCount(%d)\n"
3896 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3897 tsmMetrics.UplinkPktQueueDlyHist[0],
3898 tsmMetrics.UplinkPktQueueDlyHist[1],
3899 tsmMetrics.UplinkPktQueueDlyHist[2],
3900 tsmMetrics.UplinkPktQueueDlyHist[3],
3901 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3902 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3903
3904 /* Output TSM stats is of the format
3905 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3906 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003907 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003908 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3909 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3910 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3911 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3912 tsmMetrics.RoamingDly);
3913
3914 if (copy_to_user(priv_data.buf, &extra, len + 1))
3915 {
3916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3917 "%s: failed to copy data to user buffer", __func__);
3918 ret = -EFAULT;
3919 goto exit;
3920 }
3921 }
3922 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3923 {
3924 tANI_U8 *value = command;
3925 tANI_U8 *cckmIe = NULL;
3926 tANI_U8 cckmIeLen = 0;
3927 eHalStatus status = eHAL_STATUS_SUCCESS;
3928
3929 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3930 if (eHAL_STATUS_SUCCESS != status)
3931 {
3932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3933 "%s: Failed to parse cckm ie data", __func__);
3934 ret = -EINVAL;
3935 goto exit;
3936 }
3937
3938 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3939 {
3940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3941 "%s: CCKM Ie input length is more than max[%d]", __func__,
3942 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003943 vos_mem_free(cckmIe);
3944 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003945 ret = -EINVAL;
3946 goto exit;
3947 }
3948 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003949 vos_mem_free(cckmIe);
3950 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003951 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003952 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3953 {
3954 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003955 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003956 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003957
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003958 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003959 if (eHAL_STATUS_SUCCESS != status)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003962 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003963 ret = -EINVAL;
3964 goto exit;
3965 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003966 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
3967 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
3968 hdd_indicateEseBcnReportNoResults (pAdapter,
3969 eseBcnReq.bcnReq[0].measurementToken,
3970 0x02, //BIT(1) set for measurement done
3971 0); // no BSS
3972 goto exit;
3973 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003974
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003975 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3976 if (eHAL_STATUS_SUCCESS != status)
3977 {
3978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3979 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3980 ret = -EINVAL;
3981 goto exit;
3982 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003983 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003984#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05303985 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
3986 {
3987 eHalStatus status;
3988 char buf[32], len;
3989 long waitRet;
3990 bcnMissRateContext_t getBcnMissRateCtx;
3991
3992 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3993
3994 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3995 {
3996 hddLog(VOS_TRACE_LEVEL_WARN,
3997 FL("GETBCNMISSRATE: STA is not in connected state"));
3998 ret = -1;
3999 goto exit;
4000 }
4001
4002 init_completion(&(getBcnMissRateCtx.completion));
4003 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4004
4005 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4006 pAdapter->sessionId,
4007 (void *)getBcnMissRateCB,
4008 (void *)(&getBcnMissRateCtx));
4009 if( eHAL_STATUS_SUCCESS != status)
4010 {
4011 hddLog(VOS_TRACE_LEVEL_INFO,
4012 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4013 ret = -EINVAL;
4014 goto exit;
4015 }
4016
4017 waitRet = wait_for_completion_interruptible_timeout
4018 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4019 if(waitRet <= 0)
4020 {
4021 hddLog(VOS_TRACE_LEVEL_ERROR,
4022 FL("failed to wait on bcnMissRateComp %d"), ret);
4023
4024 //Make magic number to zero so that callback is not called.
4025 spin_lock(&hdd_context_lock);
4026 getBcnMissRateCtx.magic = 0x0;
4027 spin_unlock(&hdd_context_lock);
4028 ret = -EINVAL;
4029 goto exit;
4030 }
4031
4032 hddLog(VOS_TRACE_LEVEL_INFO,
4033 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4034
4035 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4036 if (copy_to_user(priv_data.buf, &buf, len + 1))
4037 {
4038 hddLog(VOS_TRACE_LEVEL_ERROR,
4039 "%s: failed to copy data to user buffer", __func__);
4040 ret = -EFAULT;
4041 goto exit;
4042 }
4043 ret = len;
4044 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004045 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4047 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4048 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004049 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4050 __func__, command);
4051 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004052 }
4053exit:
4054 if (command)
4055 {
4056 kfree(command);
4057 }
4058 return ret;
4059}
4060
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004061#ifdef CONFIG_COMPAT
4062static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4063{
4064 struct {
4065 compat_uptr_t buf;
4066 int used_len;
4067 int total_len;
4068 } compat_priv_data;
4069 hdd_priv_data_t priv_data;
4070 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004071
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004072 /*
4073 * Note that pAdapter and ifr have already been verified by caller,
4074 * and HDD context has also been validated
4075 */
4076 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4077 sizeof(compat_priv_data))) {
4078 ret = -EFAULT;
4079 goto exit;
4080 }
4081 priv_data.buf = compat_ptr(compat_priv_data.buf);
4082 priv_data.used_len = compat_priv_data.used_len;
4083 priv_data.total_len = compat_priv_data.total_len;
4084 ret = hdd_driver_command(pAdapter, &priv_data);
4085 exit:
4086 return ret;
4087}
4088#else /* CONFIG_COMPAT */
4089static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4090{
4091 /* will never be invoked */
4092 return 0;
4093}
4094#endif /* CONFIG_COMPAT */
4095
4096static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4097{
4098 hdd_priv_data_t priv_data;
4099 int ret = 0;
4100
4101 /*
4102 * Note that pAdapter and ifr have already been verified by caller,
4103 * and HDD context has also been validated
4104 */
4105 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4106 ret = -EFAULT;
4107 } else {
4108 ret = hdd_driver_command(pAdapter, &priv_data);
4109 }
4110 return ret;
4111}
4112
4113int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4114{
4115 hdd_adapter_t *pAdapter;
4116 hdd_context_t *pHddCtx;
4117 int ret;
4118
4119 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4120 if (NULL == pAdapter) {
4121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4122 "%s: HDD adapter context is Null", __func__);
4123 ret = -ENODEV;
4124 goto exit;
4125 }
4126 if (dev != pAdapter->dev) {
4127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4128 "%s: HDD adapter/dev inconsistency", __func__);
4129 ret = -ENODEV;
4130 goto exit;
4131 }
4132
4133 if ((!ifr) || (!ifr->ifr_data)) {
4134 ret = -EINVAL;
4135 goto exit;
4136 }
4137
4138 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4139 ret = wlan_hdd_validate_context(pHddCtx);
4140 if (ret) {
4141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4142 "%s: invalid context", __func__);
4143 ret = -EBUSY;
4144 goto exit;
4145 }
4146
4147 switch (cmd) {
4148 case (SIOCDEVPRIVATE + 1):
4149 if (is_compat_task())
4150 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4151 else
4152 ret = hdd_driver_ioctl(pAdapter, ifr);
4153 break;
4154 default:
4155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4156 __func__, cmd);
4157 ret = -EINVAL;
4158 break;
4159 }
4160 exit:
4161 return ret;
4162}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004163
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004164#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004165/**---------------------------------------------------------------------------
4166
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004167 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004168
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004169 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004170 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4171 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4172 <space>Scan Mode N<space>Meas Duration N
4173 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4174 then take N.
4175 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4176 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4177 This function does not take care of removing duplicate channels from the list
4178
4179 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004180 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004181
4182 \return - 0 for success non-zero for failure
4183
4184 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004185static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4186 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004187{
4188 tANI_U8 *inPtr = pValue;
4189 int tempInt = 0;
4190 int j = 0, i = 0, v = 0;
4191 char buf[32];
4192
4193 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4194 /*no argument after the command*/
4195 if (NULL == inPtr)
4196 {
4197 return -EINVAL;
4198 }
4199 /*no space after the command*/
4200 else if (SPACE_ASCII_VALUE != *inPtr)
4201 {
4202 return -EINVAL;
4203 }
4204
4205 /*removing empty spaces*/
4206 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4207
4208 /*no argument followed by spaces*/
4209 if ('\0' == *inPtr) return -EINVAL;
4210
4211 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004212 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004213 if (1 != v) return -EINVAL;
4214
4215 v = kstrtos32(buf, 10, &tempInt);
4216 if ( v < 0) return -EINVAL;
4217
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004218 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004219
4220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004221 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004222
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004223 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004224 {
4225 for (i = 0; i < 4; i++)
4226 {
4227 /*inPtr pointing to the beginning of first space after number of ie fields*/
4228 inPtr = strpbrk( inPtr, " " );
4229 /*no ie data after the number of ie fields argument*/
4230 if (NULL == inPtr) return -EINVAL;
4231
4232 /*removing empty space*/
4233 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4234
4235 /*no ie data after the number of ie fields argument and spaces*/
4236 if ( '\0' == *inPtr ) return -EINVAL;
4237
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004238 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004239 if (1 != v) return -EINVAL;
4240
4241 v = kstrtos32(buf, 10, &tempInt);
4242 if (v < 0) return -EINVAL;
4243
4244 switch (i)
4245 {
4246 case 0: /* Measurement token */
4247 if (tempInt <= 0)
4248 {
4249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4250 "Invalid Measurement Token(%d)", tempInt);
4251 return -EINVAL;
4252 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004253 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004254 break;
4255
4256 case 1: /* Channel number */
4257 if ((tempInt <= 0) ||
4258 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4259 {
4260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4261 "Invalid Channel Number(%d)", tempInt);
4262 return -EINVAL;
4263 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004264 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004265 break;
4266
4267 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004268 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004269 {
4270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4271 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4272 return -EINVAL;
4273 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004274 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004275 break;
4276
4277 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004278 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4279 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004280 {
4281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4282 "Invalid Measurement Duration(%d)", tempInt);
4283 return -EINVAL;
4284 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004285 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004286 break;
4287 }
4288 }
4289 }
4290
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004291 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004292 {
4293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304294 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004295 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004296 pEseBcnReq->bcnReq[j].measurementToken,
4297 pEseBcnReq->bcnReq[j].channel,
4298 pEseBcnReq->bcnReq[j].scanMode,
4299 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004300 }
4301
4302 return VOS_STATUS_SUCCESS;
4303}
4304
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004305static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4306{
4307 struct statsContext *pStatsContext = NULL;
4308 hdd_adapter_t *pAdapter = NULL;
4309
4310 if (NULL == pContext)
4311 {
4312 hddLog(VOS_TRACE_LEVEL_ERROR,
4313 "%s: Bad param, pContext [%p]",
4314 __func__, pContext);
4315 return;
4316 }
4317
Jeff Johnson72a40512013-12-19 10:14:15 -08004318 /* there is a race condition that exists between this callback
4319 function and the caller since the caller could time out either
4320 before or while this code is executing. we use a spinlock to
4321 serialize these actions */
4322 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004323
4324 pStatsContext = pContext;
4325 pAdapter = pStatsContext->pAdapter;
4326 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4327 {
4328 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004329 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004330 hddLog(VOS_TRACE_LEVEL_WARN,
4331 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4332 __func__, pAdapter, pStatsContext->magic);
4333 return;
4334 }
4335
Jeff Johnson72a40512013-12-19 10:14:15 -08004336 /* context is valid so caller is still waiting */
4337
4338 /* paranoia: invalidate the magic */
4339 pStatsContext->magic = 0;
4340
4341 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004342 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4343 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4344 tsmMetrics.UplinkPktQueueDlyHist,
4345 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4346 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4347 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4348 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4349 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4350 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4351 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4352
Jeff Johnson72a40512013-12-19 10:14:15 -08004353 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004354 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004355
4356 /* serialization is complete */
4357 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004358}
4359
4360
4361
4362static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4363 tAniTrafStrmMetrics* pTsmMetrics)
4364{
4365 hdd_station_ctx_t *pHddStaCtx = NULL;
4366 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004367 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004368 long lrc;
4369 struct statsContext context;
4370 hdd_context_t *pHddCtx = NULL;
4371
4372 if (NULL == pAdapter)
4373 {
4374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4375 return VOS_STATUS_E_FAULT;
4376 }
4377
4378 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4379 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4380
4381 /* we are connected prepare our callback context */
4382 init_completion(&context.completion);
4383 context.pAdapter = pAdapter;
4384 context.magic = STATS_CONTEXT_MAGIC;
4385
4386 /* query tsm stats */
4387 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4388 pHddStaCtx->conn_info.staId[ 0 ],
4389 pHddStaCtx->conn_info.bssId,
4390 &context, pHddCtx->pvosContext, tid);
4391
4392 if (eHAL_STATUS_SUCCESS != hstatus)
4393 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4395 __func__);
4396 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004397 }
4398 else
4399 {
4400 /* request was sent -- wait for the response */
4401 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4402 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004403 if (lrc <= 0)
4404 {
4405 hddLog(VOS_TRACE_LEVEL_ERROR,
4406 "%s: SME %s while retrieving statistics",
4407 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004408 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004409 }
4410 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004411
Jeff Johnson72a40512013-12-19 10:14:15 -08004412 /* either we never sent a request, we sent a request and received a
4413 response or we sent a request and timed out. if we never sent a
4414 request or if we sent a request and got a response, we want to
4415 clear the magic out of paranoia. if we timed out there is a
4416 race condition such that the callback function could be
4417 executing at the same time we are. of primary concern is if the
4418 callback function had already verified the "magic" but had not
4419 yet set the completion variable when a timeout occurred. we
4420 serialize these activities by invalidating the magic while
4421 holding a shared spinlock which will cause us to block if the
4422 callback is currently executing */
4423 spin_lock(&hdd_context_lock);
4424 context.magic = 0;
4425 spin_unlock(&hdd_context_lock);
4426
4427 if (VOS_STATUS_SUCCESS == vstatus)
4428 {
4429 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4430 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4431 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4432 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4433 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4434 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4435 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4436 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4437 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4438 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4439 }
4440 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004441}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004442#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004443
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004444#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004445void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4446{
4447 eCsrBand band = -1;
4448 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4449 switch (band)
4450 {
4451 case eCSR_BAND_ALL:
4452 *pBand = WLAN_HDD_UI_BAND_AUTO;
4453 break;
4454
4455 case eCSR_BAND_24:
4456 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4457 break;
4458
4459 case eCSR_BAND_5G:
4460 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4461 break;
4462
4463 default:
4464 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4465 *pBand = -1;
4466 break;
4467 }
4468}
4469
4470/**---------------------------------------------------------------------------
4471
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004472 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4473
4474 This function parses the send action frame data passed in the format
4475 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4476
Srinivas Girigowda56076852013-08-20 14:00:50 -07004477 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004478 \param - pTargetApBssid Pointer to target Ap bssid
4479 \param - pChannel Pointer to the Target AP channel
4480 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4481 \param - pBuf Pointer to data
4482 \param - pBufLen Pointer to data length
4483
4484 \return - 0 for success non-zero for failure
4485
4486 --------------------------------------------------------------------------*/
4487VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4488 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4489{
4490 tANI_U8 *inPtr = pValue;
4491 tANI_U8 *dataEnd;
4492 int tempInt;
4493 int j = 0;
4494 int i = 0;
4495 int v = 0;
4496 tANI_U8 tempBuf[32];
4497 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004498 /* 12 hexa decimal digits, 5 ':' and '\0' */
4499 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004500
4501 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4502 /*no argument after the command*/
4503 if (NULL == inPtr)
4504 {
4505 return -EINVAL;
4506 }
4507
4508 /*no space after the command*/
4509 else if (SPACE_ASCII_VALUE != *inPtr)
4510 {
4511 return -EINVAL;
4512 }
4513
4514 /*removing empty spaces*/
4515 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4516
4517 /*no argument followed by spaces*/
4518 if ('\0' == *inPtr)
4519 {
4520 return -EINVAL;
4521 }
4522
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004523 v = sscanf(inPtr, "%17s", macAddress);
4524 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004525 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4527 "Invalid MAC address or All hex inputs are not read (%d)", v);
4528 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004529 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004530
4531 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4532 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4533 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4534 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4535 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4536 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004537
4538 /* point to the next argument */
4539 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4540 /*no argument after the command*/
4541 if (NULL == inPtr) return -EINVAL;
4542
4543 /*removing empty spaces*/
4544 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4545
4546 /*no argument followed by spaces*/
4547 if ('\0' == *inPtr)
4548 {
4549 return -EINVAL;
4550 }
4551
4552 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004553 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004554 if (1 != v) return -EINVAL;
4555
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004556 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304557 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304558 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004559
4560 *pChannel = tempInt;
4561
4562 /* point to the next argument */
4563 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4564 /*no argument after the command*/
4565 if (NULL == inPtr) return -EINVAL;
4566 /*removing empty spaces*/
4567 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4568
4569 /*no argument followed by spaces*/
4570 if ('\0' == *inPtr)
4571 {
4572 return -EINVAL;
4573 }
4574
4575 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004576 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004577 if (1 != v) return -EINVAL;
4578
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004579 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004580 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004581
4582 *pDwellTime = 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 /* find the length of data */
4598 dataEnd = inPtr;
4599 while(('\0' != *dataEnd) )
4600 {
4601 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004602 }
Kiet Lambe150c22013-11-21 16:30:32 +05304603 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004604 if ( *pBufLen <= 0) return -EINVAL;
4605
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004606 /* Allocate the number of bytes based on the number of input characters
4607 whether it is even or odd.
4608 if the number of input characters are even, then we need N/2 byte.
4609 if the number of input characters are odd, then we need do (N+1)/2 to
4610 compensate rounding off.
4611 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4612 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4613 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004614 if (NULL == *pBuf)
4615 {
4616 hddLog(VOS_TRACE_LEVEL_FATAL,
4617 "%s: vos_mem_alloc failed ", __func__);
4618 return -EINVAL;
4619 }
4620
4621 /* the buffer received from the upper layer is character buffer,
4622 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4623 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4624 and f0 in 3rd location */
4625 for (i = 0, j = 0; j < *pBufLen; j += 2)
4626 {
Kiet Lambe150c22013-11-21 16:30:32 +05304627 if( j+1 == *pBufLen)
4628 {
4629 tempByte = hdd_parse_hex(inPtr[j]);
4630 }
4631 else
4632 {
4633 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4634 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004635 (*pBuf)[i++] = tempByte;
4636 }
4637 *pBufLen = i;
4638 return VOS_STATUS_SUCCESS;
4639}
4640
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004641/**---------------------------------------------------------------------------
4642
Srinivas Girigowdade697412013-02-14 16:31:48 -08004643 \brief hdd_parse_channellist() - HDD Parse channel list
4644
4645 This function parses the channel list passed in the format
4646 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004647 if the Number of channels (N) does not match with the actual number of channels passed
4648 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4649 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4650 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4651 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004652
4653 \param - pValue Pointer to input channel list
4654 \param - ChannelList Pointer to local output array to record channel list
4655 \param - pNumChannels Pointer to number of roam scan channels
4656
4657 \return - 0 for success non-zero for failure
4658
4659 --------------------------------------------------------------------------*/
4660VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4661{
4662 tANI_U8 *inPtr = pValue;
4663 int tempInt;
4664 int j = 0;
4665 int v = 0;
4666 char buf[32];
4667
4668 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4669 /*no argument after the command*/
4670 if (NULL == inPtr)
4671 {
4672 return -EINVAL;
4673 }
4674
4675 /*no space after the command*/
4676 else if (SPACE_ASCII_VALUE != *inPtr)
4677 {
4678 return -EINVAL;
4679 }
4680
4681 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004682 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004683
4684 /*no argument followed by spaces*/
4685 if ('\0' == *inPtr)
4686 {
4687 return -EINVAL;
4688 }
4689
4690 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004691 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004692 if (1 != v) return -EINVAL;
4693
Srinivas Girigowdade697412013-02-14 16:31:48 -08004694 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004695 if ((v < 0) ||
4696 (tempInt <= 0) ||
4697 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4698 {
4699 return -EINVAL;
4700 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004701
4702 *pNumChannels = tempInt;
4703
4704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4705 "Number of channels are: %d", *pNumChannels);
4706
4707 for (j = 0; j < (*pNumChannels); j++)
4708 {
4709 /*inPtr pointing to the beginning of first space after number of channels*/
4710 inPtr = strpbrk( inPtr, " " );
4711 /*no channel list after the number of channels argument*/
4712 if (NULL == inPtr)
4713 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004714 if (0 != j)
4715 {
4716 *pNumChannels = j;
4717 return VOS_STATUS_SUCCESS;
4718 }
4719 else
4720 {
4721 return -EINVAL;
4722 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004723 }
4724
4725 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004726 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004727
4728 /*no channel list after the number of channels argument and spaces*/
4729 if ( '\0' == *inPtr )
4730 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004731 if (0 != j)
4732 {
4733 *pNumChannels = j;
4734 return VOS_STATUS_SUCCESS;
4735 }
4736 else
4737 {
4738 return -EINVAL;
4739 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004740 }
4741
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004742 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004743 if (1 != v) return -EINVAL;
4744
Srinivas Girigowdade697412013-02-14 16:31:48 -08004745 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004746 if ((v < 0) ||
4747 (tempInt <= 0) ||
4748 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4749 {
4750 return -EINVAL;
4751 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004752 pChannelList[j] = tempInt;
4753
4754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4755 "Channel %d added to preferred channel list",
4756 pChannelList[j] );
4757 }
4758
Srinivas Girigowdade697412013-02-14 16:31:48 -08004759 return VOS_STATUS_SUCCESS;
4760}
4761
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004762
4763/**---------------------------------------------------------------------------
4764
4765 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4766
4767 This function parses the reasoc command data passed in the format
4768 REASSOC<space><bssid><space><channel>
4769
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004770 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004771 \param - pTargetApBssid Pointer to target Ap bssid
4772 \param - pChannel Pointer to the Target AP channel
4773
4774 \return - 0 for success non-zero for failure
4775
4776 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004777VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4778 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004779{
4780 tANI_U8 *inPtr = pValue;
4781 int tempInt;
4782 int v = 0;
4783 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004784 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004785 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004786
4787 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4788 /*no argument after the command*/
4789 if (NULL == inPtr)
4790 {
4791 return -EINVAL;
4792 }
4793
4794 /*no space after the command*/
4795 else if (SPACE_ASCII_VALUE != *inPtr)
4796 {
4797 return -EINVAL;
4798 }
4799
4800 /*removing empty spaces*/
4801 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4802
4803 /*no argument followed by spaces*/
4804 if ('\0' == *inPtr)
4805 {
4806 return -EINVAL;
4807 }
4808
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004809 v = sscanf(inPtr, "%17s", macAddress);
4810 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004811 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4813 "Invalid MAC address or All hex inputs are not read (%d)", v);
4814 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004815 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004816
4817 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4818 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4819 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4820 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4821 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4822 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004823
4824 /* point to the next argument */
4825 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4826 /*no argument after the command*/
4827 if (NULL == inPtr) return -EINVAL;
4828
4829 /*removing empty spaces*/
4830 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4831
4832 /*no argument followed by spaces*/
4833 if ('\0' == *inPtr)
4834 {
4835 return -EINVAL;
4836 }
4837
4838 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004839 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004840 if (1 != v) return -EINVAL;
4841
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004842 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004843 if ((v < 0) ||
4844 (tempInt <= 0) ||
4845 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4846 {
4847 return -EINVAL;
4848 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004849
4850 *pChannel = tempInt;
4851 return VOS_STATUS_SUCCESS;
4852}
4853
4854#endif
4855
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004856#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004857/**---------------------------------------------------------------------------
4858
4859 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4860
4861 This function parses the SETCCKM IE command
4862 SETCCKMIE<space><ie data>
4863
4864 \param - pValue Pointer to input data
4865 \param - pCckmIe Pointer to output cckm Ie
4866 \param - pCckmIeLen Pointer to output cckm ie length
4867
4868 \return - 0 for success non-zero for failure
4869
4870 --------------------------------------------------------------------------*/
4871VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4872 tANI_U8 *pCckmIeLen)
4873{
4874 tANI_U8 *inPtr = pValue;
4875 tANI_U8 *dataEnd;
4876 int j = 0;
4877 int i = 0;
4878 tANI_U8 tempByte = 0;
4879
4880 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4881 /*no argument after the command*/
4882 if (NULL == inPtr)
4883 {
4884 return -EINVAL;
4885 }
4886
4887 /*no space after the command*/
4888 else if (SPACE_ASCII_VALUE != *inPtr)
4889 {
4890 return -EINVAL;
4891 }
4892
4893 /*removing empty spaces*/
4894 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4895
4896 /*no argument followed by spaces*/
4897 if ('\0' == *inPtr)
4898 {
4899 return -EINVAL;
4900 }
4901
4902 /* find the length of data */
4903 dataEnd = inPtr;
4904 while(('\0' != *dataEnd) )
4905 {
4906 dataEnd++;
4907 ++(*pCckmIeLen);
4908 }
4909 if ( *pCckmIeLen <= 0) return -EINVAL;
4910
4911 /* Allocate the number of bytes based on the number of input characters
4912 whether it is even or odd.
4913 if the number of input characters are even, then we need N/2 byte.
4914 if the number of input characters are odd, then we need do (N+1)/2 to
4915 compensate rounding off.
4916 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4917 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4918 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4919 if (NULL == *pCckmIe)
4920 {
4921 hddLog(VOS_TRACE_LEVEL_FATAL,
4922 "%s: vos_mem_alloc failed ", __func__);
4923 return -EINVAL;
4924 }
4925 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4926 /* the buffer received from the upper layer is character buffer,
4927 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4928 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4929 and f0 in 3rd location */
4930 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4931 {
4932 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4933 (*pCckmIe)[i++] = tempByte;
4934 }
4935 *pCckmIeLen = i;
4936
4937 return VOS_STATUS_SUCCESS;
4938}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004939#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004940
Jeff Johnson295189b2012-06-20 16:38:30 -07004941/**---------------------------------------------------------------------------
4942
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004943 \brief hdd_is_valid_mac_address() - Validate MAC address
4944
4945 This function validates whether the given MAC address is valid or not
4946 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4947 where X is the hexa decimal digit character and separated by ':'
4948 This algorithm works even if MAC address is not separated by ':'
4949
4950 This code checks given input string mac contains exactly 12 hexadecimal digits.
4951 and a separator colon : appears in the input string only after
4952 an even number of hex digits.
4953
4954 \param - pMacAddr pointer to the input MAC address
4955 \return - 1 for valid and 0 for invalid
4956
4957 --------------------------------------------------------------------------*/
4958
4959v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4960{
4961 int xdigit = 0;
4962 int separator = 0;
4963 while (*pMacAddr)
4964 {
4965 if (isxdigit(*pMacAddr))
4966 {
4967 xdigit++;
4968 }
4969 else if (':' == *pMacAddr)
4970 {
4971 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4972 break;
4973
4974 ++separator;
4975 }
4976 else
4977 {
4978 separator = -1;
4979 /* Invalid MAC found */
4980 return 0;
4981 }
4982 ++pMacAddr;
4983 }
4984 return (xdigit == 12 && (separator == 5 || separator == 0));
4985}
4986
4987/**---------------------------------------------------------------------------
4988
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 \brief hdd_open() - HDD Open function
4990
4991 This is called in response to ifconfig up
4992
4993 \param - dev Pointer to net_device structure
4994
4995 \return - 0 for success non-zero for failure
4996
4997 --------------------------------------------------------------------------*/
4998int hdd_open (struct net_device *dev)
4999{
5000 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5001 hdd_context_t *pHddCtx;
5002 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5003 VOS_STATUS status;
5004 v_BOOL_t in_standby = TRUE;
5005
5006 if (NULL == pAdapter)
5007 {
5008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305009 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005010 return -ENODEV;
5011 }
5012
5013 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305014 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5015 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005016 if (NULL == pHddCtx)
5017 {
5018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005019 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 return -ENODEV;
5021 }
5022
5023 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5024 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5025 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005026 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5027 {
5028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305029 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005030 in_standby = FALSE;
5031 break;
5032 }
5033 else
5034 {
5035 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5036 pAdapterNode = pNext;
5037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005038 }
5039
5040 if (TRUE == in_standby)
5041 {
5042 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5043 {
5044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5045 "wlan out of power save", __func__);
5046 return -EINVAL;
5047 }
5048 }
5049
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005050 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5052 {
5053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005054 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 /* Enable TX queues only when we are connected */
5056 netif_tx_start_all_queues(dev);
5057 }
5058
5059 return 0;
5060}
5061
5062int hdd_mon_open (struct net_device *dev)
5063{
5064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5065
5066 if(pAdapter == NULL) {
5067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005068 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005069 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 }
5071
5072 netif_start_queue(dev);
5073
5074 return 0;
5075}
5076/**---------------------------------------------------------------------------
5077
5078 \brief hdd_stop() - HDD stop function
5079
5080 This is called in response to ifconfig down
5081
5082 \param - dev Pointer to net_device structure
5083
5084 \return - 0 for success non-zero for failure
5085
5086 --------------------------------------------------------------------------*/
5087
5088int hdd_stop (struct net_device *dev)
5089{
5090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5091 hdd_context_t *pHddCtx;
5092 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5093 VOS_STATUS status;
5094 v_BOOL_t enter_standby = TRUE;
5095
5096 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 if (NULL == pAdapter)
5098 {
5099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305100 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 return -ENODEV;
5102 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305103 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5104 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5106 if (NULL == pHddCtx)
5107 {
5108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005109 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 return -ENODEV;
5111 }
5112
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305113 /* Nothing to be done if the interface is not opened */
5114 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5115 {
5116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5117 "%s: NETDEV Interface is not OPENED", __func__);
5118 return -ENODEV;
5119 }
5120
5121 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005122 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005123 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305124
5125 /* Disable TX on the interface, after this hard_start_xmit() will not
5126 * be called on that interface
5127 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005128 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305129
5130 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005131 netif_carrier_off(pAdapter->dev);
5132
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305133 /* The interface is marked as down for outside world (aka kernel)
5134 * But the driver is pretty much alive inside. The driver needs to
5135 * tear down the existing connection on the netdev (session)
5136 * cleanup the data pipes and wait until the control plane is stabilized
5137 * for this interface. The call also needs to wait until the above
5138 * mentioned actions are completed before returning to the caller.
5139 * Notice that the hdd_stop_adapter is requested not to close the session
5140 * That is intentional to be able to scan if it is a STA/P2P interface
5141 */
5142 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005143
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305144 /* DeInit the adapter. This ensures datapath cleanup as well */
5145 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005146 /* SoftAP ifaces should never go in power save mode
5147 making sure same here. */
5148 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5149 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005151 )
5152 {
5153 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5155 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005156 EXIT();
5157 return 0;
5158 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305159 /* Find if any iface is up. If any iface is up then can't put device to
5160 * sleep/power save mode
5161 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005162 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5163 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5164 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005165 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5166 {
5167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305168 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005169 enter_standby = FALSE;
5170 break;
5171 }
5172 else
5173 {
5174 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5175 pAdapterNode = pNext;
5176 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005177 }
5178
5179 if (TRUE == enter_standby)
5180 {
5181 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5182 "entering standby", __func__);
5183 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5184 {
5185 /*log and return success*/
5186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5187 "wlan in power save", __func__);
5188 }
5189 }
5190
5191 EXIT();
5192 return 0;
5193}
5194
5195/**---------------------------------------------------------------------------
5196
5197 \brief hdd_uninit() - HDD uninit function
5198
5199 This is called during the netdev unregister to uninitialize all data
5200associated with the device
5201
5202 \param - dev Pointer to net_device structure
5203
5204 \return - void
5205
5206 --------------------------------------------------------------------------*/
5207static void hdd_uninit (struct net_device *dev)
5208{
5209 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5210
5211 ENTER();
5212
5213 do
5214 {
5215 if (NULL == pAdapter)
5216 {
5217 hddLog(VOS_TRACE_LEVEL_FATAL,
5218 "%s: NULL pAdapter", __func__);
5219 break;
5220 }
5221
5222 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5223 {
5224 hddLog(VOS_TRACE_LEVEL_FATAL,
5225 "%s: Invalid magic", __func__);
5226 break;
5227 }
5228
5229 if (NULL == pAdapter->pHddCtx)
5230 {
5231 hddLog(VOS_TRACE_LEVEL_FATAL,
5232 "%s: NULL pHddCtx", __func__);
5233 break;
5234 }
5235
5236 if (dev != pAdapter->dev)
5237 {
5238 hddLog(VOS_TRACE_LEVEL_FATAL,
5239 "%s: Invalid device reference", __func__);
5240 /* we haven't validated all cases so let this go for now */
5241 }
5242
5243 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5244
5245 /* after uninit our adapter structure will no longer be valid */
5246 pAdapter->dev = NULL;
5247 pAdapter->magic = 0;
5248 } while (0);
5249
5250 EXIT();
5251}
5252
5253/**---------------------------------------------------------------------------
5254
5255 \brief hdd_release_firmware() -
5256
5257 This function calls the release firmware API to free the firmware buffer.
5258
5259 \param - pFileName Pointer to the File Name.
5260 pCtx - Pointer to the adapter .
5261
5262
5263 \return - 0 for success, non zero for failure
5264
5265 --------------------------------------------------------------------------*/
5266
5267VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5268{
5269 VOS_STATUS status = VOS_STATUS_SUCCESS;
5270 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5271 ENTER();
5272
5273
5274 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5275
5276 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5277
5278 if(pHddCtx->fw) {
5279 release_firmware(pHddCtx->fw);
5280 pHddCtx->fw = NULL;
5281 }
5282 else
5283 status = VOS_STATUS_E_FAILURE;
5284 }
5285 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5286 if(pHddCtx->nv) {
5287 release_firmware(pHddCtx->nv);
5288 pHddCtx->nv = NULL;
5289 }
5290 else
5291 status = VOS_STATUS_E_FAILURE;
5292
5293 }
5294
5295 EXIT();
5296 return status;
5297}
5298
5299/**---------------------------------------------------------------------------
5300
5301 \brief hdd_request_firmware() -
5302
5303 This function reads the firmware file using the request firmware
5304 API and returns the the firmware data and the firmware file size.
5305
5306 \param - pfileName - Pointer to the file name.
5307 - pCtx - Pointer to the adapter .
5308 - ppfw_data - Pointer to the pointer of the firmware data.
5309 - pSize - Pointer to the file size.
5310
5311 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5312
5313 --------------------------------------------------------------------------*/
5314
5315
5316VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5317{
5318 int status;
5319 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5320 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5321 ENTER();
5322
5323 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5324
5325 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5326
5327 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5328 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5329 __func__, pfileName);
5330 retval = VOS_STATUS_E_FAILURE;
5331 }
5332
5333 else {
5334 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5335 *pSize = pHddCtx->fw->size;
5336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5337 __func__, *pSize);
5338 }
5339 }
5340 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5341
5342 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5343
5344 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5345 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5346 __func__, pfileName);
5347 retval = VOS_STATUS_E_FAILURE;
5348 }
5349
5350 else {
5351 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5352 *pSize = pHddCtx->nv->size;
5353 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5354 __func__, *pSize);
5355 }
5356 }
5357
5358 EXIT();
5359 return retval;
5360}
5361/**---------------------------------------------------------------------------
5362 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5363
5364 This is the function invoked by SME to inform the result of a full power
5365 request issued by HDD
5366
5367 \param - callbackcontext - Pointer to cookie
5368 status - result of request
5369
5370 \return - None
5371
5372--------------------------------------------------------------------------*/
5373void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5374{
5375 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5376
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005377 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005378 if(&pHddCtx->full_pwr_comp_var)
5379 {
5380 complete(&pHddCtx->full_pwr_comp_var);
5381 }
5382}
5383
5384/**---------------------------------------------------------------------------
5385
5386 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5387
5388 This is the function invoked by SME to inform the result of BMPS
5389 request issued by HDD
5390
5391 \param - callbackcontext - Pointer to cookie
5392 status - result of request
5393
5394 \return - None
5395
5396--------------------------------------------------------------------------*/
5397void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5398{
5399
5400 struct completion *completion_var = (struct completion*) callbackContext;
5401
Arif Hussain6d2a3322013-11-17 19:50:10 -08005402 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 if(completion_var != NULL)
5404 {
5405 complete(completion_var);
5406 }
5407}
5408
5409/**---------------------------------------------------------------------------
5410
5411 \brief hdd_get_cfg_file_size() -
5412
5413 This function reads the configuration file using the request firmware
5414 API and returns the configuration file size.
5415
5416 \param - pCtx - Pointer to the adapter .
5417 - pFileName - Pointer to the file name.
5418 - pBufSize - Pointer to the buffer size.
5419
5420 \return - 0 for success, non zero for failure
5421
5422 --------------------------------------------------------------------------*/
5423
5424VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5425{
5426 int status;
5427 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5428
5429 ENTER();
5430
5431 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5432
5433 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5434 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5435 status = VOS_STATUS_E_FAILURE;
5436 }
5437 else {
5438 *pBufSize = pHddCtx->fw->size;
5439 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5440 release_firmware(pHddCtx->fw);
5441 pHddCtx->fw = NULL;
5442 }
5443
5444 EXIT();
5445 return VOS_STATUS_SUCCESS;
5446}
5447
5448/**---------------------------------------------------------------------------
5449
5450 \brief hdd_read_cfg_file() -
5451
5452 This function reads the configuration file using the request firmware
5453 API and returns the cfg data and the buffer size of the configuration file.
5454
5455 \param - pCtx - Pointer to the adapter .
5456 - pFileName - Pointer to the file name.
5457 - pBuffer - Pointer to the data buffer.
5458 - pBufSize - Pointer to the buffer size.
5459
5460 \return - 0 for success, non zero for failure
5461
5462 --------------------------------------------------------------------------*/
5463
5464VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5465 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5466{
5467 int status;
5468 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5469
5470 ENTER();
5471
5472 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5473
5474 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5475 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5476 return VOS_STATUS_E_FAILURE;
5477 }
5478 else {
5479 if(*pBufSize != pHddCtx->fw->size) {
5480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5481 "file size", __func__);
5482 release_firmware(pHddCtx->fw);
5483 pHddCtx->fw = NULL;
5484 return VOS_STATUS_E_FAILURE;
5485 }
5486 else {
5487 if(pBuffer) {
5488 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5489 }
5490 release_firmware(pHddCtx->fw);
5491 pHddCtx->fw = NULL;
5492 }
5493 }
5494
5495 EXIT();
5496
5497 return VOS_STATUS_SUCCESS;
5498}
5499
5500/**---------------------------------------------------------------------------
5501
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 \brief hdd_set_mac_address() -
5503
5504 This function sets the user specified mac address using
5505 the command ifconfig wlanX hw ether <mac adress>.
5506
5507 \param - dev - Pointer to the net device.
5508 - addr - Pointer to the sockaddr.
5509 \return - 0 for success, non zero for failure
5510
5511 --------------------------------------------------------------------------*/
5512
5513static int hdd_set_mac_address(struct net_device *dev, void *addr)
5514{
5515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5516 struct sockaddr *psta_mac_addr = addr;
5517 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5518
5519 ENTER();
5520
5521 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5523
5524 EXIT();
5525 return halStatus;
5526}
5527
5528tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5529{
5530 int i;
5531 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5532 {
Abhishek Singheb183782014-02-06 13:37:21 +05305533 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 break;
5535 }
5536
5537 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5538 return NULL;
5539
5540 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5541 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5542}
5543
5544void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5545{
5546 int i;
5547 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5548 {
5549 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5550 {
5551 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5552 break;
5553 }
5554 }
5555 return;
5556}
5557
5558#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5559 static struct net_device_ops wlan_drv_ops = {
5560 .ndo_open = hdd_open,
5561 .ndo_stop = hdd_stop,
5562 .ndo_uninit = hdd_uninit,
5563 .ndo_start_xmit = hdd_hard_start_xmit,
5564 .ndo_tx_timeout = hdd_tx_timeout,
5565 .ndo_get_stats = hdd_stats,
5566 .ndo_do_ioctl = hdd_ioctl,
5567 .ndo_set_mac_address = hdd_set_mac_address,
5568 .ndo_select_queue = hdd_select_queue,
5569#ifdef WLAN_FEATURE_PACKET_FILTERING
5570#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5571 .ndo_set_rx_mode = hdd_set_multicast_list,
5572#else
5573 .ndo_set_multicast_list = hdd_set_multicast_list,
5574#endif //LINUX_VERSION_CODE
5575#endif
5576 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 static struct net_device_ops wlan_mon_drv_ops = {
5578 .ndo_open = hdd_mon_open,
5579 .ndo_stop = hdd_stop,
5580 .ndo_uninit = hdd_uninit,
5581 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5582 .ndo_tx_timeout = hdd_tx_timeout,
5583 .ndo_get_stats = hdd_stats,
5584 .ndo_do_ioctl = hdd_ioctl,
5585 .ndo_set_mac_address = hdd_set_mac_address,
5586 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005587
5588#endif
5589
5590void hdd_set_station_ops( struct net_device *pWlanDev )
5591{
5592#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 pWlanDev->netdev_ops = &wlan_drv_ops;
5594#else
5595 pWlanDev->open = hdd_open;
5596 pWlanDev->stop = hdd_stop;
5597 pWlanDev->uninit = hdd_uninit;
5598 pWlanDev->hard_start_xmit = NULL;
5599 pWlanDev->tx_timeout = hdd_tx_timeout;
5600 pWlanDev->get_stats = hdd_stats;
5601 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 pWlanDev->set_mac_address = hdd_set_mac_address;
5603#endif
5604}
5605
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005606static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005607{
5608 struct net_device *pWlanDev = NULL;
5609 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 /*
5611 * cfg80211 initialization and registration....
5612 */
5613 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5614
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 if(pWlanDev != NULL)
5616 {
5617
5618 //Save the pointer to the net_device in the HDD adapter
5619 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5620
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5622
5623 pAdapter->dev = pWlanDev;
5624 pAdapter->pHddCtx = pHddCtx;
5625 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5626
5627 init_completion(&pAdapter->session_open_comp_var);
5628 init_completion(&pAdapter->session_close_comp_var);
5629 init_completion(&pAdapter->disconnect_comp_var);
5630 init_completion(&pAdapter->linkup_event_var);
5631 init_completion(&pAdapter->cancel_rem_on_chan_var);
5632 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305633 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005634#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5635 init_completion(&pAdapter->offchannel_tx_event);
5636#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005638#ifdef FEATURE_WLAN_TDLS
5639 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005640 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005641 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305642 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005643#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 init_completion(&pHddCtx->mc_sus_event_var);
5645 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305646 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005647 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005648 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005649
Rajeev79dbe4c2013-10-05 11:03:42 +05305650#ifdef FEATURE_WLAN_BATCH_SCAN
5651 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5652 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5653 pAdapter->pBatchScanRsp = NULL;
5654 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005655 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005656 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305657 mutex_init(&pAdapter->hdd_batch_scan_lock);
5658#endif
5659
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 pAdapter->isLinkUpSvcNeeded = FALSE;
5661 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5662 //Init the net_device structure
5663 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5664
5665 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5666 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5667 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5668 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5669
5670 hdd_set_station_ops( pAdapter->dev );
5671
5672 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005673 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5674 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5675 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005676 /* set pWlanDev's parent to underlying device */
5677 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005678
5679 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005680 }
5681
5682 return pAdapter;
5683}
5684
5685VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5686{
5687 struct net_device *pWlanDev = pAdapter->dev;
5688 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5689 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5690 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5691
5692 if( rtnl_lock_held )
5693 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005694 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005695 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5696 {
5697 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5698 return VOS_STATUS_E_FAILURE;
5699 }
5700 }
5701 if (register_netdevice(pWlanDev))
5702 {
5703 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5704 return VOS_STATUS_E_FAILURE;
5705 }
5706 }
5707 else
5708 {
5709 if(register_netdev(pWlanDev))
5710 {
5711 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5712 return VOS_STATUS_E_FAILURE;
5713 }
5714 }
5715 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5716
5717 return VOS_STATUS_SUCCESS;
5718}
5719
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005720static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005721{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005722 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005723
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005724 if (NULL == pAdapter)
5725 {
5726 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5727 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005729
5730 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5731 {
5732 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5733 return eHAL_STATUS_NOT_INITIALIZED;
5734 }
5735
5736 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5737
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005738#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005739 /* need to make sure all of our scheduled work has completed.
5740 * This callback is called from MC thread context, so it is safe to
5741 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005742 *
5743 * Even though this is called from MC thread context, if there is a faulty
5744 * work item in the system, that can hang this call forever. So flushing
5745 * this global work queue is not safe; and now we make sure that
5746 * individual work queues are stopped correctly. But the cancel work queue
5747 * is a GPL only API, so the proprietary version of the driver would still
5748 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005749 */
5750 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005751#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005752
5753 /* We can be blocked while waiting for scheduled work to be
5754 * flushed, and the adapter structure can potentially be freed, in
5755 * which case the magic will have been reset. So make sure the
5756 * magic is still good, and hence the adapter structure is still
5757 * valid, before signaling completion */
5758 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5759 {
5760 complete(&pAdapter->session_close_comp_var);
5761 }
5762
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 return eHAL_STATUS_SUCCESS;
5764}
5765
5766VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5767{
5768 struct net_device *pWlanDev = pAdapter->dev;
5769 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5770 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5771 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5772 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305773 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005774
5775 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005776 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005777 //Open a SME session for future operation
5778 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005779 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5781 {
5782 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005783 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005784 halStatus, halStatus );
5785 status = VOS_STATUS_E_FAILURE;
5786 goto error_sme_open;
5787 }
5788
5789 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305790 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 &pAdapter->session_open_comp_var,
5792 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305793 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005794 {
5795 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305796 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 status = VOS_STATUS_E_FAILURE;
5798 goto error_sme_open;
5799 }
5800
5801 // Register wireless extensions
5802 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5803 {
5804 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005805 "hdd_register_wext() 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_register_wext;
5809 }
5810 //Safe to register the hard_start_xmit function again
5811#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5812 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5813#else
5814 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5815#endif
5816
5817 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305818 hddLog(VOS_TRACE_LEVEL_INFO,
5819 "%s: Set HDD connState to eConnectionState_NotConnected",
5820 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5822
5823 //Set the default operation channel
5824 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5825
5826 /* Make the default Auth Type as OPEN*/
5827 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5828
5829 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5830 {
5831 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005832 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 status, status );
5834 goto error_init_txrx;
5835 }
5836
5837 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5838
5839 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5840 {
5841 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005842 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005843 status, status );
5844 goto error_wmm_init;
5845 }
5846
5847 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5848
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005849#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305850 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005851 {
5852 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305853 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005854 goto error_tdls_init;
5855 }
5856 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5857#endif
5858
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 return VOS_STATUS_SUCCESS;
5860
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005861#ifdef FEATURE_WLAN_TDLS
5862error_tdls_init:
5863 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5864 hdd_wmm_adapter_close(pAdapter);
5865#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005866error_wmm_init:
5867 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5868 hdd_deinit_tx_rx(pAdapter);
5869error_init_txrx:
5870 hdd_UnregisterWext(pWlanDev);
5871error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005872 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 {
5874 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005875 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005877 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305879 unsigned long rc;
5880
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305882 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005884 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305885 if (rc <= 0)
5886 hddLog(VOS_TRACE_LEVEL_ERROR,
5887 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 }
5889}
5890error_sme_open:
5891 return status;
5892}
5893
Jeff Johnson295189b2012-06-20 16:38:30 -07005894void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5895{
5896 hdd_cfg80211_state_t *cfgState;
5897
5898 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5899
5900 if( NULL != cfgState->buf )
5901 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305902 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5904 rc = wait_for_completion_interruptible_timeout(
5905 &pAdapter->tx_action_cnf_event,
5906 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305907 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305910 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5911 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 }
5913 }
5914 return;
5915}
Jeff Johnson295189b2012-06-20 16:38:30 -07005916
5917void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5918{
5919 ENTER();
5920 switch ( pAdapter->device_mode )
5921 {
5922 case WLAN_HDD_INFRA_STATION:
5923 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005924 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 {
5926 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5927 {
5928 hdd_deinit_tx_rx( pAdapter );
5929 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5930 }
5931
5932 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5933 {
5934 hdd_wmm_adapter_close( pAdapter );
5935 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5936 }
5937
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005939#ifdef FEATURE_WLAN_TDLS
5940 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5941 {
5942 wlan_hdd_tdls_exit(pAdapter);
5943 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5944 }
5945#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005946
5947 break;
5948 }
5949
5950 case WLAN_HDD_SOFTAP:
5951 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305953
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);
Jeff Johnson295189b2012-06-20 16:38:30 -07005961
5962 hdd_unregister_hostapd(pAdapter);
5963 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005964 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 break;
5966 }
5967
5968 case WLAN_HDD_MONITOR:
5969 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005971 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5972 {
5973 hdd_deinit_tx_rx( pAdapter );
5974 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 if(NULL != pAdapterforTx)
5977 {
5978 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 break;
5981 }
5982
5983
5984 default:
5985 break;
5986 }
5987
5988 EXIT();
5989}
5990
5991void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5992{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005993 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305994
5995 ENTER();
5996 if (NULL == pAdapter)
5997 {
5998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5999 "%s: HDD adapter is Null", __func__);
6000 return;
6001 }
6002
6003 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006004
Rajeev79dbe4c2013-10-05 11:03:42 +05306005#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306006 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6007 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006008 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306009 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6010 )
6011 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006012 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306013 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006014 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6015 {
6016 hdd_deinit_batch_scan(pAdapter);
6017 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306018 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006019 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306020#endif
6021
Jeff Johnson295189b2012-06-20 16:38:30 -07006022 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6023 if( rtnl_held )
6024 {
6025 unregister_netdevice(pWlanDev);
6026 }
6027 else
6028 {
6029 unregister_netdev(pWlanDev);
6030 }
6031 // note that the pAdapter is no longer valid at this point
6032 // since the memory has been reclaimed
6033 }
6034
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306035 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006036}
6037
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006038void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6039{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306040 VOS_STATUS status;
6041 hdd_adapter_t *pAdapter = NULL;
6042 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006043
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306044 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006045
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306046 /*loop through all adapters.*/
6047 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006048 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306049 pAdapter = pAdapterNode->pAdapter;
6050 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6051 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006052
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306053 { // we skip this registration for modes other than STA and P2P client modes.
6054 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6055 pAdapterNode = pNext;
6056 continue;
6057 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006058
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306059 //Apply Dynamic DTIM For P2P
6060 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6061 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6062 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6063 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6064 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6065 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6066 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6067 (eConnectionState_Associated ==
6068 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6069 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6070 {
6071 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006072
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306073 powerRequest.uIgnoreDTIM = 1;
6074 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6075
6076 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6077 {
6078 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6079 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6080 }
6081 else
6082 {
6083 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6084 }
6085
6086 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6087 * specified during Enter/Exit BMPS when LCD off*/
6088 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6089 NULL, eANI_BOOLEAN_FALSE);
6090 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6091 NULL, eANI_BOOLEAN_FALSE);
6092
6093 /* switch to the DTIM specified in cfg.ini */
6094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6095 "Switch to DTIM %d", powerRequest.uListenInterval);
6096 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6097 break;
6098
6099 }
6100
6101 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6102 pAdapterNode = pNext;
6103 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006104}
6105
6106void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6107{
6108 /*Switch back to DTIM 1*/
6109 tSirSetPowerParamsReq powerRequest = { 0 };
6110
6111 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6112 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006113 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006114
6115 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6116 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6117 NULL, eANI_BOOLEAN_FALSE);
6118 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6119 NULL, eANI_BOOLEAN_FALSE);
6120
6121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6122 "Switch to DTIM%d",powerRequest.uListenInterval);
6123 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6124
6125}
6126
Jeff Johnson295189b2012-06-20 16:38:30 -07006127VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6128{
6129 VOS_STATUS status = VOS_STATUS_SUCCESS;
6130
6131 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6132 {
6133 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6134 }
6135
6136 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6137 {
6138 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6139 }
6140
6141 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6142 {
6143 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6144 }
6145
6146 return status;
6147}
6148
6149VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6150{
6151 hdd_adapter_t *pAdapter = NULL;
6152 eHalStatus halStatus;
6153 VOS_STATUS status = VOS_STATUS_E_INVAL;
6154 v_BOOL_t disableBmps = FALSE;
6155 v_BOOL_t disableImps = FALSE;
6156
6157 switch(session_type)
6158 {
6159 case WLAN_HDD_INFRA_STATION:
6160 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006161 case WLAN_HDD_P2P_CLIENT:
6162 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006163 //Exit BMPS -> Is Sta/P2P Client is already connected
6164 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6165 if((NULL != pAdapter)&&
6166 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6167 {
6168 disableBmps = TRUE;
6169 }
6170
6171 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6172 if((NULL != pAdapter)&&
6173 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6174 {
6175 disableBmps = TRUE;
6176 }
6177
6178 //Exit both Bmps and Imps incase of Go/SAP Mode
6179 if((WLAN_HDD_SOFTAP == session_type) ||
6180 (WLAN_HDD_P2P_GO == session_type))
6181 {
6182 disableBmps = TRUE;
6183 disableImps = TRUE;
6184 }
6185
6186 if(TRUE == disableImps)
6187 {
6188 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6189 {
6190 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6191 }
6192 }
6193
6194 if(TRUE == disableBmps)
6195 {
6196 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6197 {
6198 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6199
6200 if(eHAL_STATUS_SUCCESS != halStatus)
6201 {
6202 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006203 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006204 VOS_ASSERT(0);
6205 return status;
6206 }
6207 }
6208
6209 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6210 {
6211 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6212
6213 if(eHAL_STATUS_SUCCESS != halStatus)
6214 {
6215 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006216 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 VOS_ASSERT(0);
6218 return status;
6219 }
6220 }
6221 }
6222
6223 if((TRUE == disableBmps) ||
6224 (TRUE == disableImps))
6225 {
6226 /* Now, get the chip into Full Power now */
6227 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6228 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6229 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6230
6231 if(halStatus != eHAL_STATUS_SUCCESS)
6232 {
6233 if(halStatus == eHAL_STATUS_PMC_PENDING)
6234 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306235 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306237 ret = wait_for_completion_interruptible_timeout(
6238 &pHddCtx->full_pwr_comp_var,
6239 msecs_to_jiffies(1000));
6240 if (ret <= 0)
6241 {
6242 hddLog(VOS_TRACE_LEVEL_ERROR,
6243 "%s: wait on full_pwr_comp_var failed %ld",
6244 __func__, ret);
6245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 }
6247 else
6248 {
6249 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006250 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 VOS_ASSERT(0);
6252 return status;
6253 }
6254 }
6255
6256 status = VOS_STATUS_SUCCESS;
6257 }
6258
6259 break;
6260 }
6261 return status;
6262}
6263
6264hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006265 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 tANI_U8 rtnl_held )
6267{
6268 hdd_adapter_t *pAdapter = NULL;
6269 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6270 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6271 VOS_STATUS exitbmpsStatus;
6272
Arif Hussain6d2a3322013-11-17 19:50:10 -08006273 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006274
Nirav Shah436658f2014-02-28 17:05:45 +05306275 if(macAddr == NULL)
6276 {
6277 /* Not received valid macAddr */
6278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6279 "%s:Unable to add virtual intf: Not able to get"
6280 "valid mac address",__func__);
6281 return NULL;
6282 }
6283
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 //Disable BMPS incase of Concurrency
6285 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6286
6287 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6288 {
6289 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306290 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 VOS_ASSERT(0);
6292 return NULL;
6293 }
6294
6295 switch(session_type)
6296 {
6297 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006299 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 {
6301 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6302
6303 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306304 {
6305 hddLog(VOS_TRACE_LEVEL_FATAL,
6306 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306308 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006309
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306310#ifdef FEATURE_WLAN_TDLS
6311 /* A Mutex Lock is introduced while changing/initializing the mode to
6312 * protect the concurrent access for the Adapters by TDLS module.
6313 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306314 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306315#endif
6316
Jeff Johnsone7245742012-09-05 17:12:55 -07006317 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6318 NL80211_IFTYPE_P2P_CLIENT:
6319 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006320
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306322#ifdef FEATURE_WLAN_TDLS
6323 mutex_unlock(&pHddCtx->tdls_lock);
6324#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306325
6326 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 if( VOS_STATUS_SUCCESS != status )
6328 goto err_free_netdev;
6329
6330 status = hdd_register_interface( pAdapter, rtnl_held );
6331 if( VOS_STATUS_SUCCESS != status )
6332 {
6333 hdd_deinit_adapter(pHddCtx, pAdapter);
6334 goto err_free_netdev;
6335 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306336
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306337 // Workqueue which gets scheduled in IPv4 notification callback.
6338 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6339
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306340#ifdef WLAN_NS_OFFLOAD
6341 // Workqueue which gets scheduled in IPv6 notification callback.
6342 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6343#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006344 //Stop the Interface TX queue.
6345 netif_tx_disable(pAdapter->dev);
6346 //netif_tx_disable(pWlanDev);
6347 netif_carrier_off(pAdapter->dev);
6348
6349 break;
6350 }
6351
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 case WLAN_HDD_SOFTAP:
6354 {
6355 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6356 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306357 {
6358 hddLog(VOS_TRACE_LEVEL_FATAL,
6359 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006362
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6364 NL80211_IFTYPE_AP:
6365 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 pAdapter->device_mode = session_type;
6367
6368 status = hdd_init_ap_mode(pAdapter);
6369 if( VOS_STATUS_SUCCESS != status )
6370 goto err_free_netdev;
6371
6372 status = hdd_register_hostapd( pAdapter, rtnl_held );
6373 if( VOS_STATUS_SUCCESS != status )
6374 {
6375 hdd_deinit_adapter(pHddCtx, pAdapter);
6376 goto err_free_netdev;
6377 }
6378
6379 netif_tx_disable(pAdapter->dev);
6380 netif_carrier_off(pAdapter->dev);
6381
6382 hdd_set_conparam( 1 );
6383 break;
6384 }
6385 case WLAN_HDD_MONITOR:
6386 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6388 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306389 {
6390 hddLog(VOS_TRACE_LEVEL_FATAL,
6391 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006394
6395 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6396 pAdapter->device_mode = session_type;
6397 status = hdd_register_interface( pAdapter, rtnl_held );
6398#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6399 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6400#else
6401 pAdapter->dev->open = hdd_mon_open;
6402 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6403#endif
6404 hdd_init_tx_rx( pAdapter );
6405 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6406 //Set adapter to be used for data tx. It will use either GO or softap.
6407 pAdapter->sessionCtx.monitor.pAdapterForTx =
6408 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6410 {
6411 pAdapter->sessionCtx.monitor.pAdapterForTx =
6412 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 /* This workqueue will be used to transmit management packet over
6415 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006416 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6417 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6418 return NULL;
6419 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006420
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6422 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 }
6424 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 case WLAN_HDD_FTM:
6426 {
6427 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6428
6429 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306430 {
6431 hddLog(VOS_TRACE_LEVEL_FATAL,
6432 FL("failed to allocate adapter for session %d"), session_type);
6433 return NULL;
6434 }
6435
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6437 * message while loading driver in FTM mode. */
6438 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6439 pAdapter->device_mode = session_type;
6440 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306441
6442 hdd_init_tx_rx( pAdapter );
6443
6444 //Stop the Interface TX queue.
6445 netif_tx_disable(pAdapter->dev);
6446 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 }
6448 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 default:
6450 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306451 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6452 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 VOS_ASSERT(0);
6454 return NULL;
6455 }
6456 }
6457
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 if( VOS_STATUS_SUCCESS == status )
6459 {
6460 //Add it to the hdd's session list.
6461 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6462 if( NULL == pHddAdapterNode )
6463 {
6464 status = VOS_STATUS_E_NOMEM;
6465 }
6466 else
6467 {
6468 pHddAdapterNode->pAdapter = pAdapter;
6469 status = hdd_add_adapter_back ( pHddCtx,
6470 pHddAdapterNode );
6471 }
6472 }
6473
6474 if( VOS_STATUS_SUCCESS != status )
6475 {
6476 if( NULL != pAdapter )
6477 {
6478 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6479 pAdapter = NULL;
6480 }
6481 if( NULL != pHddAdapterNode )
6482 {
6483 vos_mem_free( pHddAdapterNode );
6484 }
6485
6486 goto resume_bmps;
6487 }
6488
6489 if(VOS_STATUS_SUCCESS == status)
6490 {
6491 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6492
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006493 //Initialize the WoWL service
6494 if(!hdd_init_wowl(pAdapter))
6495 {
6496 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6497 goto err_free_netdev;
6498 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 return pAdapter;
6501
6502err_free_netdev:
6503 free_netdev(pAdapter->dev);
6504 wlan_hdd_release_intf_addr( pHddCtx,
6505 pAdapter->macAddressCurrent.bytes );
6506
6507resume_bmps:
6508 //If bmps disabled enable it
6509 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6510 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306511 if (pHddCtx->hdd_wlan_suspended)
6512 {
6513 hdd_set_pwrparams(pHddCtx);
6514 }
6515 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 }
6517 return NULL;
6518}
6519
6520VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6521 tANI_U8 rtnl_held )
6522{
6523 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6524 VOS_STATUS status;
6525
6526 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6527 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306528 {
6529 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6530 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006531 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006533
6534 while ( pCurrent->pAdapter != pAdapter )
6535 {
6536 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6537 if( VOS_STATUS_SUCCESS != status )
6538 break;
6539
6540 pCurrent = pNext;
6541 }
6542 pAdapterNode = pCurrent;
6543 if( VOS_STATUS_SUCCESS == status )
6544 {
6545 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6546 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306547
6548#ifdef FEATURE_WLAN_TDLS
6549
6550 /* A Mutex Lock is introduced while changing/initializing the mode to
6551 * protect the concurrent access for the Adapters by TDLS module.
6552 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306553 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306554#endif
6555
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 hdd_remove_adapter( pHddCtx, pAdapterNode );
6557 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006558 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006559
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306560#ifdef FEATURE_WLAN_TDLS
6561 mutex_unlock(&pHddCtx->tdls_lock);
6562#endif
6563
Jeff Johnson295189b2012-06-20 16:38:30 -07006564
6565 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306566 if ((!vos_concurrent_open_sessions_running()) &&
6567 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6568 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306570 if (pHddCtx->hdd_wlan_suspended)
6571 {
6572 hdd_set_pwrparams(pHddCtx);
6573 }
6574 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006575 }
6576
6577 return VOS_STATUS_SUCCESS;
6578 }
6579
6580 return VOS_STATUS_E_FAILURE;
6581}
6582
6583VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6584{
6585 hdd_adapter_list_node_t *pHddAdapterNode;
6586 VOS_STATUS status;
6587
6588 ENTER();
6589
6590 do
6591 {
6592 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6593 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6594 {
6595 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6596 vos_mem_free( pHddAdapterNode );
6597 }
6598 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6599
6600 EXIT();
6601
6602 return VOS_STATUS_SUCCESS;
6603}
6604
6605void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6606{
6607 v_U8_t addIE[1] = {0};
6608
6609 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6610 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6611 eANI_BOOLEAN_FALSE) )
6612 {
6613 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006614 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 }
6616
6617 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6618 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6619 eANI_BOOLEAN_FALSE) )
6620 {
6621 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006622 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 }
6624
6625 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6626 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6627 eANI_BOOLEAN_FALSE) )
6628 {
6629 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006630 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 }
6632}
6633
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306634VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6635 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006636{
6637 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6638 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6639 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306640 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306641 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006642
6643 ENTER();
6644
6645 switch(pAdapter->device_mode)
6646 {
6647 case WLAN_HDD_INFRA_STATION:
6648 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006649 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306650 {
6651 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6652 if( hdd_connIsConnected(pstation) ||
6653 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006654 {
6655 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6656 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6657 pAdapter->sessionId,
6658 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6659 else
6660 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6661 pAdapter->sessionId,
6662 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6663 //success implies disconnect command got queued up successfully
6664 if(halStatus == eHAL_STATUS_SUCCESS)
6665 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306666 ret = wait_for_completion_interruptible_timeout(
6667 &pAdapter->disconnect_comp_var,
6668 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6669 if (ret <= 0)
6670 {
6671 hddLog(VOS_TRACE_LEVEL_ERROR,
6672 "%s: wait on disconnect_comp_var failed %ld",
6673 __func__, ret);
6674 }
6675 }
6676 else
6677 {
6678 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6679 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006680 }
6681 memset(&wrqu, '\0', sizeof(wrqu));
6682 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6683 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6684 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6685 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306686 else if(pstation->conn_info.connState ==
6687 eConnectionState_Disconnecting)
6688 {
6689 ret = wait_for_completion_interruptible_timeout(
6690 &pAdapter->disconnect_comp_var,
6691 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6692 if (ret <= 0)
6693 {
6694 hddLog(VOS_TRACE_LEVEL_ERROR,
6695 FL("wait on disconnect_comp_var failed %ld"), ret);
6696 }
6697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 else
6699 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306700 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6701 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306703 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6704 {
6705 while (pAdapter->is_roc_inprogress)
6706 {
6707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6708 "%s: ROC in progress for session %d!!!",
6709 __func__, pAdapter->sessionId);
6710 // waiting for ROC to expire
6711 msleep(500);
6712 /* In GO present case , if retry exceeds 3,
6713 it means something went wrong. */
6714 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6715 {
6716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6717 "%s: ROC completion is not received.!!!", __func__);
6718 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6719 pAdapter->sessionId);
6720 wait_for_completion_interruptible_timeout(
6721 &pAdapter->cancel_rem_on_chan_var,
6722 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6723 break;
6724 }
6725 }
6726 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306727#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306728#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306729 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6730#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306731 if (pAdapter->ipv6_notifier_registered)
6732 {
6733 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6734 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6735 pAdapter->ipv6_notifier_registered = false;
6736 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306737#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306738 if (pAdapter->ipv4_notifier_registered)
6739 {
6740 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6741 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6742 pAdapter->ipv4_notifier_registered = false;
6743 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306744#ifdef WLAN_OPEN_SOURCE
6745 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6746#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306747 /* It is possible that the caller of this function does not
6748 * wish to close the session
6749 */
6750 if (VOS_TRUE == bCloseSession &&
6751 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 {
6753 INIT_COMPLETION(pAdapter->session_close_comp_var);
6754 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306755 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6756 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306758 unsigned long ret;
6759
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306761 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306762 &pAdapter->session_close_comp_var,
6763 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306764 if ( 0 >= ret)
6765 {
6766 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306767 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306768 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 }
6770 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306771 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 break;
6773
6774 case WLAN_HDD_SOFTAP:
6775 case WLAN_HDD_P2P_GO:
6776 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306777 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6778 while (pAdapter->is_roc_inprogress) {
6779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6780 "%s: ROC in progress for session %d!!!",
6781 __func__, pAdapter->sessionId);
6782 msleep(500);
6783 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6785 "%s: ROC completion is not received.!!!", __func__);
6786 WLANSAP_CancelRemainOnChannel(
6787 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6788 wait_for_completion_interruptible_timeout(
6789 &pAdapter->cancel_rem_on_chan_var,
6790 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6791 break;
6792 }
6793 }
6794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 mutex_lock(&pHddCtx->sap_lock);
6796 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6797 {
6798 VOS_STATUS status;
6799 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6800
6801 //Stop Bss.
6802 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6803 if (VOS_IS_STATUS_SUCCESS(status))
6804 {
6805 hdd_hostapd_state_t *pHostapdState =
6806 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6807
6808 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6809
6810 if (!VOS_IS_STATUS_SUCCESS(status))
6811 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306812 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6813 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 }
6815 }
6816 else
6817 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006818 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006819 }
6820 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306821 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006822
6823 if (eHAL_STATUS_FAILURE ==
6824 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6825 0, NULL, eANI_BOOLEAN_FALSE))
6826 {
6827 hddLog(LOGE,
6828 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006829 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 }
6831
6832 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6833 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6834 eANI_BOOLEAN_FALSE) )
6835 {
6836 hddLog(LOGE,
6837 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6838 }
6839
6840 // Reset WNI_CFG_PROBE_RSP Flags
6841 wlan_hdd_reset_prob_rspies(pAdapter);
6842 kfree(pAdapter->sessionCtx.ap.beacon);
6843 pAdapter->sessionCtx.ap.beacon = NULL;
6844 }
6845 mutex_unlock(&pHddCtx->sap_lock);
6846 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006847
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006849#ifdef WLAN_OPEN_SOURCE
6850 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6851#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006852 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006853
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 default:
6855 break;
6856 }
6857
6858 EXIT();
6859 return VOS_STATUS_SUCCESS;
6860}
6861
6862VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6863{
6864 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6865 VOS_STATUS status;
6866 hdd_adapter_t *pAdapter;
6867
6868 ENTER();
6869
6870 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6871
6872 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6873 {
6874 pAdapter = pAdapterNode->pAdapter;
6875 netif_tx_disable(pAdapter->dev);
6876 netif_carrier_off(pAdapter->dev);
6877
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306878 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006879
6880 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6881 pAdapterNode = pNext;
6882 }
6883
6884 EXIT();
6885
6886 return VOS_STATUS_SUCCESS;
6887}
6888
Rajeev Kumarf999e582014-01-09 17:33:29 -08006889
6890#ifdef FEATURE_WLAN_BATCH_SCAN
6891/**---------------------------------------------------------------------------
6892
6893 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6894 structures
6895
6896 \param - pAdapter Pointer to HDD adapter
6897
6898 \return - None
6899
6900 --------------------------------------------------------------------------*/
6901void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6902{
6903 tHddBatchScanRsp *pNode;
6904 tHddBatchScanRsp *pPrev;
6905
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306906 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006907 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306908 hddLog(VOS_TRACE_LEVEL_ERROR,
6909 "%s: Adapter context is Null", __func__);
6910 return;
6911 }
6912
6913 pNode = pAdapter->pBatchScanRsp;
6914 while (pNode)
6915 {
6916 pPrev = pNode;
6917 pNode = pNode->pNext;
6918 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006919 }
6920
6921 pAdapter->pBatchScanRsp = NULL;
6922 pAdapter->numScanList = 0;
6923 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6924 pAdapter->prev_batch_id = 0;
6925
6926 return;
6927}
6928#endif
6929
6930
Jeff Johnson295189b2012-06-20 16:38:30 -07006931VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6932{
6933 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6934 VOS_STATUS status;
6935 hdd_adapter_t *pAdapter;
6936
6937 ENTER();
6938
6939 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6940
6941 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6942 {
6943 pAdapter = pAdapterNode->pAdapter;
6944 netif_tx_disable(pAdapter->dev);
6945 netif_carrier_off(pAdapter->dev);
6946
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006947 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6948
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306950 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6951 {
6952 hdd_wmm_adapter_close( pAdapter );
6953 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6954 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006955
Rajeev Kumarf999e582014-01-09 17:33:29 -08006956#ifdef FEATURE_WLAN_BATCH_SCAN
6957 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6958 {
6959 hdd_deinit_batch_scan(pAdapter);
6960 }
6961#endif
6962
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6964 pAdapterNode = pNext;
6965 }
6966
6967 EXIT();
6968
6969 return VOS_STATUS_SUCCESS;
6970}
6971
6972VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6973{
6974 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6975 VOS_STATUS status;
6976 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306977 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006978
6979 ENTER();
6980
6981 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6982
6983 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6984 {
6985 pAdapter = pAdapterNode->pAdapter;
6986
Kumar Anand82c009f2014-05-29 00:29:42 -07006987 hdd_wmm_init( pAdapter );
6988
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 switch(pAdapter->device_mode)
6990 {
6991 case WLAN_HDD_INFRA_STATION:
6992 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006993 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306994
6995 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6996
Jeff Johnson295189b2012-06-20 16:38:30 -07006997 hdd_init_station_mode(pAdapter);
6998 /* Open the gates for HDD to receive Wext commands */
6999 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007000 pHddCtx->scan_info.mScanPending = FALSE;
7001 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007002
7003 //Trigger the initial scan
7004 hdd_wlan_initial_scan(pAdapter);
7005
7006 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307007 if (eConnectionState_Associated == connState ||
7008 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 {
7010 union iwreq_data wrqu;
7011 memset(&wrqu, '\0', sizeof(wrqu));
7012 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7013 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7014 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007015 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007016
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 /* indicate disconnected event to nl80211 */
7018 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7019 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307021 else if (eConnectionState_Connecting == connState)
7022 {
7023 /*
7024 * Indicate connect failure to supplicant if we were in the
7025 * process of connecting
7026 */
7027 cfg80211_connect_result(pAdapter->dev, NULL,
7028 NULL, 0, NULL, 0,
7029 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7030 GFP_KERNEL);
7031 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 break;
7033
7034 case WLAN_HDD_SOFTAP:
7035 /* softAP can handle SSR */
7036 break;
7037
7038 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007041 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 break;
7043
7044 case WLAN_HDD_MONITOR:
7045 /* monitor interface start */
7046 break;
7047 default:
7048 break;
7049 }
7050
7051 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7052 pAdapterNode = pNext;
7053 }
7054
7055 EXIT();
7056
7057 return VOS_STATUS_SUCCESS;
7058}
7059
7060VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7061{
7062 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7063 hdd_adapter_t *pAdapter;
7064 VOS_STATUS status;
7065 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307066 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007067
7068 ENTER();
7069
7070 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7071
7072 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7073 {
7074 pAdapter = pAdapterNode->pAdapter;
7075
7076 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7077 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7078 {
7079 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7080 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7081
Abhishek Singhf4669da2014-05-26 15:07:49 +05307082 hddLog(VOS_TRACE_LEVEL_INFO,
7083 "%s: Set HDD connState to eConnectionState_NotConnected",
7084 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7086 init_completion(&pAdapter->disconnect_comp_var);
7087 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7088 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7089
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307090 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 &pAdapter->disconnect_comp_var,
7092 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307093 if (0 >= ret)
7094 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7095 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007096
7097 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7098 pHddCtx->isAmpAllowed = VOS_FALSE;
7099 sme_RoamConnect(pHddCtx->hHal,
7100 pAdapter->sessionId, &(pWextState->roamProfile),
7101 &roamId);
7102 }
7103
7104 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7105 pAdapterNode = pNext;
7106 }
7107
7108 EXIT();
7109
7110 return VOS_STATUS_SUCCESS;
7111}
7112
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007113void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7114{
7115 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7116 VOS_STATUS status;
7117 hdd_adapter_t *pAdapter;
7118 hdd_station_ctx_t *pHddStaCtx;
7119 hdd_ap_ctx_t *pHddApCtx;
7120 hdd_hostapd_state_t * pHostapdState;
7121 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7122 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7123 const char *p2pMode = "DEV";
7124 const char *ccMode = "Standalone";
7125 int n;
7126
7127 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7128 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7129 {
7130 pAdapter = pAdapterNode->pAdapter;
7131 switch (pAdapter->device_mode) {
7132 case WLAN_HDD_INFRA_STATION:
7133 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7134 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7135 staChannel = pHddStaCtx->conn_info.operationChannel;
7136 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7137 }
7138 break;
7139 case WLAN_HDD_P2P_CLIENT:
7140 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7141 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7142 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7143 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7144 p2pMode = "CLI";
7145 }
7146 break;
7147 case WLAN_HDD_P2P_GO:
7148 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7149 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7150 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7151 p2pChannel = pHddApCtx->operatingChannel;
7152 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7153 }
7154 p2pMode = "GO";
7155 break;
7156 case WLAN_HDD_SOFTAP:
7157 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7158 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7159 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7160 apChannel = pHddApCtx->operatingChannel;
7161 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7162 }
7163 break;
7164 default:
7165 break;
7166 }
7167 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7168 pAdapterNode = pNext;
7169 }
7170 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7171 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7172 }
7173 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7174 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7175 if (p2pChannel > 0) {
7176 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7177 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7178 }
7179 if (apChannel > 0) {
7180 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7181 apChannel, MAC_ADDR_ARRAY(apBssid));
7182 }
7183
7184 if (p2pChannel > 0 && apChannel > 0) {
7185 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7186 }
7187}
7188
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007189bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007190{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007191 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007192}
7193
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007194/* Once SSR is disabled then it cannot be set. */
7195void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007196{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007197 if (HDD_SSR_DISABLED == isSsrRequired)
7198 return;
7199
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 isSsrRequired = value;
7201}
7202
7203VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7204 hdd_adapter_list_node_t** ppAdapterNode)
7205{
7206 VOS_STATUS status;
7207 spin_lock(&pHddCtx->hddAdapters.lock);
7208 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7209 (hdd_list_node_t**) ppAdapterNode );
7210 spin_unlock(&pHddCtx->hddAdapters.lock);
7211 return status;
7212}
7213
7214VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7215 hdd_adapter_list_node_t* pAdapterNode,
7216 hdd_adapter_list_node_t** pNextAdapterNode)
7217{
7218 VOS_STATUS status;
7219 spin_lock(&pHddCtx->hddAdapters.lock);
7220 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7221 (hdd_list_node_t*) pAdapterNode,
7222 (hdd_list_node_t**)pNextAdapterNode );
7223
7224 spin_unlock(&pHddCtx->hddAdapters.lock);
7225 return status;
7226}
7227
7228VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7229 hdd_adapter_list_node_t* pAdapterNode)
7230{
7231 VOS_STATUS status;
7232 spin_lock(&pHddCtx->hddAdapters.lock);
7233 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7234 &pAdapterNode->node );
7235 spin_unlock(&pHddCtx->hddAdapters.lock);
7236 return status;
7237}
7238
7239VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7240 hdd_adapter_list_node_t** ppAdapterNode)
7241{
7242 VOS_STATUS status;
7243 spin_lock(&pHddCtx->hddAdapters.lock);
7244 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7245 (hdd_list_node_t**) ppAdapterNode );
7246 spin_unlock(&pHddCtx->hddAdapters.lock);
7247 return status;
7248}
7249
7250VOS_STATUS hdd_add_adapter_back( 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_insert_back ( &pHddCtx->hddAdapters,
7256 (hdd_list_node_t*) pAdapterNode );
7257 spin_unlock(&pHddCtx->hddAdapters.lock);
7258 return status;
7259}
7260
7261VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7262 hdd_adapter_list_node_t* pAdapterNode)
7263{
7264 VOS_STATUS status;
7265 spin_lock(&pHddCtx->hddAdapters.lock);
7266 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7267 (hdd_list_node_t*) pAdapterNode );
7268 spin_unlock(&pHddCtx->hddAdapters.lock);
7269 return status;
7270}
7271
7272hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7273 tSirMacAddr macAddr )
7274{
7275 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7276 hdd_adapter_t *pAdapter;
7277 VOS_STATUS status;
7278
7279 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7280
7281 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7282 {
7283 pAdapter = pAdapterNode->pAdapter;
7284
7285 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7286 macAddr, sizeof(tSirMacAddr) ) )
7287 {
7288 return pAdapter;
7289 }
7290 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7291 pAdapterNode = pNext;
7292 }
7293
7294 return NULL;
7295
7296}
7297
7298hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7299{
7300 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7301 hdd_adapter_t *pAdapter;
7302 VOS_STATUS status;
7303
7304 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7305
7306 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7307 {
7308 pAdapter = pAdapterNode->pAdapter;
7309
7310 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7311 IFNAMSIZ ) )
7312 {
7313 return pAdapter;
7314 }
7315 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7316 pAdapterNode = pNext;
7317 }
7318
7319 return NULL;
7320
7321}
7322
7323hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7324{
7325 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7326 hdd_adapter_t *pAdapter;
7327 VOS_STATUS status;
7328
7329 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7330
7331 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7332 {
7333 pAdapter = pAdapterNode->pAdapter;
7334
7335 if( pAdapter && (mode == pAdapter->device_mode) )
7336 {
7337 return pAdapter;
7338 }
7339 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7340 pAdapterNode = pNext;
7341 }
7342
7343 return NULL;
7344
7345}
7346
7347//Remove this function later
7348hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7349{
7350 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7351 hdd_adapter_t *pAdapter;
7352 VOS_STATUS status;
7353
7354 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7355
7356 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7357 {
7358 pAdapter = pAdapterNode->pAdapter;
7359
7360 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7361 {
7362 return pAdapter;
7363 }
7364
7365 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7366 pAdapterNode = pNext;
7367 }
7368
7369 return NULL;
7370
7371}
7372
Jeff Johnson295189b2012-06-20 16:38:30 -07007373/**---------------------------------------------------------------------------
7374
7375 \brief hdd_set_monitor_tx_adapter() -
7376
7377 This API initializes the adapter to be used while transmitting on monitor
7378 adapter.
7379
7380 \param - pHddCtx - Pointer to the HDD context.
7381 pAdapter - Adapter that will used for TX. This can be NULL.
7382 \return - None.
7383 --------------------------------------------------------------------------*/
7384void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7385{
7386 hdd_adapter_t *pMonAdapter;
7387
7388 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7389
7390 if( NULL != pMonAdapter )
7391 {
7392 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7393 }
7394}
Jeff Johnson295189b2012-06-20 16:38:30 -07007395/**---------------------------------------------------------------------------
7396
7397 \brief hdd_select_queue() -
7398
7399 This API returns the operating channel of the requested device mode
7400
7401 \param - pHddCtx - Pointer to the HDD context.
7402 - mode - Device mode for which operating channel is required
7403 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7404 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7405 \return - channel number. "0" id the requested device is not found OR it is not connected.
7406 --------------------------------------------------------------------------*/
7407v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7408{
7409 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7410 VOS_STATUS status;
7411 hdd_adapter_t *pAdapter;
7412 v_U8_t operatingChannel = 0;
7413
7414 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7415
7416 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7417 {
7418 pAdapter = pAdapterNode->pAdapter;
7419
7420 if( mode == pAdapter->device_mode )
7421 {
7422 switch(pAdapter->device_mode)
7423 {
7424 case WLAN_HDD_INFRA_STATION:
7425 case WLAN_HDD_P2P_CLIENT:
7426 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7427 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7428 break;
7429 case WLAN_HDD_SOFTAP:
7430 case WLAN_HDD_P2P_GO:
7431 /*softap connection info */
7432 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7433 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7434 break;
7435 default:
7436 break;
7437 }
7438
7439 break; //Found the device of interest. break the loop
7440 }
7441
7442 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7443 pAdapterNode = pNext;
7444 }
7445 return operatingChannel;
7446}
7447
7448#ifdef WLAN_FEATURE_PACKET_FILTERING
7449/**---------------------------------------------------------------------------
7450
7451 \brief hdd_set_multicast_list() -
7452
7453 This used to set the multicast address list.
7454
7455 \param - dev - Pointer to the WLAN device.
7456 - skb - Pointer to OS packet (sk_buff).
7457 \return - success/fail
7458
7459 --------------------------------------------------------------------------*/
7460static void hdd_set_multicast_list(struct net_device *dev)
7461{
7462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007463 int mc_count;
7464 int i = 0;
7465 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307466
7467 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 {
7469 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307470 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007471 return;
7472 }
7473
7474 if (dev->flags & IFF_ALLMULTI)
7475 {
7476 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007477 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307478 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 }
7480 else
7481 {
7482 mc_count = netdev_mc_count(dev);
7483 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007484 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7486 {
7487 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007488 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307489 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007490 return;
7491 }
7492
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307493 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007494
7495 netdev_for_each_mc_addr(ha, dev) {
7496 if (i == mc_count)
7497 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307498 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7499 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007500 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307502 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 i++;
7504 }
7505 }
7506 return;
7507}
7508#endif
7509
7510/**---------------------------------------------------------------------------
7511
7512 \brief hdd_select_queue() -
7513
7514 This function is registered with the Linux OS for network
7515 core to decide which queue to use first.
7516
7517 \param - dev - Pointer to the WLAN device.
7518 - skb - Pointer to OS packet (sk_buff).
7519 \return - ac, Queue Index/access category corresponding to UP in IP header
7520
7521 --------------------------------------------------------------------------*/
7522v_U16_t hdd_select_queue(struct net_device *dev,
7523 struct sk_buff *skb)
7524{
7525 return hdd_wmm_select_queue(dev, skb);
7526}
7527
7528
7529/**---------------------------------------------------------------------------
7530
7531 \brief hdd_wlan_initial_scan() -
7532
7533 This function triggers the initial scan
7534
7535 \param - pAdapter - Pointer to the HDD adapter.
7536
7537 --------------------------------------------------------------------------*/
7538void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7539{
7540 tCsrScanRequest scanReq;
7541 tCsrChannelInfo channelInfo;
7542 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007543 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7545
7546 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7547 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7548 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7549
7550 if(sme_Is11dSupported(pHddCtx->hHal))
7551 {
7552 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7553 if ( HAL_STATUS_SUCCESS( halStatus ) )
7554 {
7555 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7556 if( !scanReq.ChannelInfo.ChannelList )
7557 {
7558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7559 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007560 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 return;
7562 }
7563 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7564 channelInfo.numOfChannels);
7565 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7566 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007567 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007568 }
7569
7570 scanReq.scanType = eSIR_PASSIVE_SCAN;
7571 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7572 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7573 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7574 }
7575 else
7576 {
7577 scanReq.scanType = eSIR_ACTIVE_SCAN;
7578 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7579 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7580 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7581 }
7582
7583 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7584 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7585 {
7586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7587 __func__, halStatus );
7588 }
7589
7590 if(sme_Is11dSupported(pHddCtx->hHal))
7591 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7592}
7593
Jeff Johnson295189b2012-06-20 16:38:30 -07007594/**---------------------------------------------------------------------------
7595
7596 \brief hdd_full_power_callback() - HDD full power callback function
7597
7598 This is the function invoked by SME to inform the result of a full power
7599 request issued by HDD
7600
7601 \param - callbackcontext - Pointer to cookie
7602 \param - status - result of request
7603
7604 \return - None
7605
7606 --------------------------------------------------------------------------*/
7607static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7608{
Jeff Johnson72a40512013-12-19 10:14:15 -08007609 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007610
7611 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307612 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007613
7614 if (NULL == callbackContext)
7615 {
7616 hddLog(VOS_TRACE_LEVEL_ERROR,
7617 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007618 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 return;
7620 }
7621
Jeff Johnson72a40512013-12-19 10:14:15 -08007622 /* there is a race condition that exists between this callback
7623 function and the caller since the caller could time out either
7624 before or while this code is executing. we use a spinlock to
7625 serialize these actions */
7626 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007627
7628 if (POWER_CONTEXT_MAGIC != pContext->magic)
7629 {
7630 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007631 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 hddLog(VOS_TRACE_LEVEL_WARN,
7633 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007634 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 return;
7636 }
7637
Jeff Johnson72a40512013-12-19 10:14:15 -08007638 /* context is valid so caller is still waiting */
7639
7640 /* paranoia: invalidate the magic */
7641 pContext->magic = 0;
7642
7643 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007645
7646 /* serialization is complete */
7647 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007648}
7649
7650/**---------------------------------------------------------------------------
7651
7652 \brief hdd_wlan_exit() - HDD WLAN exit function
7653
7654 This is the driver exit point (invoked during rmmod)
7655
7656 \param - pHddCtx - Pointer to the HDD Context
7657
7658 \return - None
7659
7660 --------------------------------------------------------------------------*/
7661void hdd_wlan_exit(hdd_context_t *pHddCtx)
7662{
7663 eHalStatus halStatus;
7664 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7665 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307666 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007667 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007668 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307670 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007671
7672 ENTER();
7673
Jeff Johnson88ba7742013-02-27 14:36:02 -08007674 if (VOS_FTM_MODE != hdd_get_conparam())
7675 {
7676 // Unloading, restart logic is no more required.
7677 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007678
c_hpothu5ab05e92014-06-13 17:34:05 +05307679 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7680 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307682 pAdapter = pAdapterNode->pAdapter;
7683 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307685 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7686 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7687 {
7688 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7689 hdd_UnregisterWext(pAdapter->dev);
7690 }
7691 // Cancel any outstanding scan requests. We are about to close all
7692 // of our adapters, but an adapter structure is what SME passes back
7693 // to our callback function. Hence if there are any outstanding scan
7694 // requests then there is a race condition between when the adapter
7695 // is closed and when the callback is invoked.We try to resolve that
7696 // race condition here by canceling any outstanding scans before we
7697 // close the adapters.
7698 // Note that the scans may be cancelled in an asynchronous manner,
7699 // so ideally there needs to be some kind of synchronization. Rather
7700 // than introduce a new synchronization here, we will utilize the
7701 // fact that we are about to Request Full Power, and since that is
7702 // synchronized, the expectation is that by the time Request Full
7703 // Power has completed all scans will be cancelled.
7704 if (pHddCtx->scan_info.mScanPending)
7705 {
7706 hddLog(VOS_TRACE_LEVEL_INFO,
7707 FL("abort scan mode: %d sessionId: %d"),
7708 pAdapter->device_mode,
7709 pAdapter->sessionId);
7710 hdd_abort_mac_scan(pHddCtx,
7711 pAdapter->sessionId,
7712 eCSR_SCAN_ABORT_DEFAULT);
7713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307715 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7716 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 }
7718 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307719 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007720 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307721 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007722 wlan_hdd_ftm_close(pHddCtx);
7723 goto free_hdd_ctx;
7724 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307725
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 /* DeRegister with platform driver as client for Suspend/Resume */
7727 vosStatus = hddDeregisterPmOps(pHddCtx);
7728 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7729 {
7730 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7731 VOS_ASSERT(0);
7732 }
7733
7734 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7735 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7736 {
7737 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7738 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007739
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007740 //Stop the traffic monitor timer
7741 if ( VOS_TIMER_STATE_RUNNING ==
7742 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7743 {
7744 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7745 }
7746
7747 // Destroy the traffic monitor timer
7748 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7749 &pHddCtx->tx_rx_trafficTmr)))
7750 {
7751 hddLog(VOS_TRACE_LEVEL_ERROR,
7752 "%s: Cannot deallocate Traffic monitor timer", __func__);
7753 }
7754
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 //Disable IMPS/BMPS as we do not want the device to enter any power
7756 //save mode during shutdown
7757 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7758 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7759 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7760
7761 //Ensure that device is in full power as we will touch H/W during vos_Stop
7762 init_completion(&powerContext.completion);
7763 powerContext.magic = POWER_CONTEXT_MAGIC;
7764
7765 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7766 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7767
7768 if (eHAL_STATUS_SUCCESS != halStatus)
7769 {
7770 if (eHAL_STATUS_PMC_PENDING == halStatus)
7771 {
7772 /* request was sent -- wait for the response */
7773 lrc = wait_for_completion_interruptible_timeout(
7774 &powerContext.completion,
7775 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 if (lrc <= 0)
7777 {
7778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007779 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 }
7781 }
7782 else
7783 {
7784 hddLog(VOS_TRACE_LEVEL_ERROR,
7785 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007786 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 /* continue -- need to clean up as much as possible */
7788 }
7789 }
7790
Jeff Johnson72a40512013-12-19 10:14:15 -08007791 /* either we never sent a request, we sent a request and received a
7792 response or we sent a request and timed out. if we never sent a
7793 request or if we sent a request and got a response, we want to
7794 clear the magic out of paranoia. if we timed out there is a
7795 race condition such that the callback function could be
7796 executing at the same time we are. of primary concern is if the
7797 callback function had already verified the "magic" but had not
7798 yet set the completion variable when a timeout occurred. we
7799 serialize these activities by invalidating the magic while
7800 holding a shared spinlock which will cause us to block if the
7801 callback is currently executing */
7802 spin_lock(&hdd_context_lock);
7803 powerContext.magic = 0;
7804 spin_unlock(&hdd_context_lock);
7805
Yue Ma0d4891e2013-08-06 17:01:45 -07007806 hdd_debugfs_exit(pHddCtx);
7807
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 // Unregister the Net Device Notifier
7809 unregister_netdevice_notifier(&hdd_netdev_notifier);
7810
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 hdd_stop_all_adapters( pHddCtx );
7812
Jeff Johnson295189b2012-06-20 16:38:30 -07007813#ifdef WLAN_BTAMP_FEATURE
7814 vosStatus = WLANBAP_Stop(pVosContext);
7815 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7816 {
7817 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7818 "%s: Failed to stop BAP",__func__);
7819 }
7820#endif //WLAN_BTAMP_FEATURE
7821
7822 //Stop all the modules
7823 vosStatus = vos_stop( pVosContext );
7824 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7825 {
7826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7827 "%s: Failed to stop VOSS",__func__);
7828 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7829 }
7830
Jeff Johnson295189b2012-06-20 16:38:30 -07007831 //Assert Deep sleep signal now to put Libra HW in lowest power state
7832 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7833 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7834
7835 //Vote off any PMIC voltage supplies
7836 vos_chipPowerDown(NULL, NULL, NULL);
7837
7838 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7839
Leo Chang59cdc7e2013-07-10 10:08:21 -07007840
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007843
7844 //Close the scheduler before calling vos_close to make sure no thread is
7845 // scheduled after the each module close is called i.e after all the data
7846 // structures are freed.
7847 vosStatus = vos_sched_close( pVosContext );
7848 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7849 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7850 "%s: Failed to close VOSS Scheduler",__func__);
7851 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7852 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007853#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007854#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7855 /* Destroy the wake lock */
7856 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7857#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007858 /* Destroy the wake lock */
7859 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007860#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007861
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307862#ifdef CONFIG_ENABLE_LINUX_REG
7863 vosStatus = vos_nv_close();
7864 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7865 {
7866 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7867 "%s: Failed to close NV", __func__);
7868 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7869 }
7870#endif
7871
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 //Close VOSS
7873 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7874 vos_close(pVosContext);
7875
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 //Close Watchdog
7877 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7878 vos_watchdog_close(pVosContext);
7879
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307880 //Clean up HDD Nlink Service
7881 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007882#ifdef WLAN_KD_READY_NOTIFIER
7883 nl_srv_exit(pHddCtx->ptt_pid);
7884#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307885 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007886#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307887
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307888#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307889 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307890 {
7891 wlan_logging_sock_deactivate_svc();
7892 }
7893#endif
7894
Jeff Johnson295189b2012-06-20 16:38:30 -07007895 /* Cancel the vote for XO Core ON.
7896 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7897 * exited at this point
7898 */
7899 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007900 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7902 {
7903 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7904 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007905 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 }
7907
7908 hdd_close_all_adapters( pHddCtx );
7909
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 /* free the power on lock from platform driver */
7911 if (free_riva_power_on_lock("wlan"))
7912 {
7913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7914 __func__);
7915 }
7916
Jeff Johnson88ba7742013-02-27 14:36:02 -08007917free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307918
7919 //Free up dynamically allocated members inside HDD Adapter
7920 if (pHddCtx->cfg_ini)
7921 {
7922 kfree(pHddCtx->cfg_ini);
7923 pHddCtx->cfg_ini= NULL;
7924 }
7925
Leo Changf04ddad2013-09-18 13:46:38 -07007926 /* FTM mode, WIPHY did not registered
7927 If un-register here, system crash will happen */
7928 if (VOS_FTM_MODE != hdd_get_conparam())
7929 {
7930 wiphy_unregister(wiphy) ;
7931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007933 if (hdd_is_ssr_required())
7934 {
7935 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007936 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007937 msleep(5000);
7938 }
7939 hdd_set_ssr_required (VOS_FALSE);
7940}
7941
7942
7943/**---------------------------------------------------------------------------
7944
7945 \brief hdd_update_config_from_nv() - Function to update the contents of
7946 the running configuration with parameters taken from NV storage
7947
7948 \param - pHddCtx - Pointer to the HDD global context
7949
7950 \return - VOS_STATUS_SUCCESS if successful
7951
7952 --------------------------------------------------------------------------*/
7953static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7954{
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 v_BOOL_t itemIsValid = VOS_FALSE;
7956 VOS_STATUS status;
7957 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7958 v_U8_t macLoop;
7959
7960 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7961 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7962 if(status != VOS_STATUS_SUCCESS)
7963 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007964 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007965 return VOS_STATUS_E_FAILURE;
7966 }
7967
7968 if (itemIsValid == VOS_TRUE)
7969 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007970 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7972 VOS_MAX_CONCURRENCY_PERSONA);
7973 if(status != VOS_STATUS_SUCCESS)
7974 {
7975 /* Get MAC from NV fail, not update CFG info
7976 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007977 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007978 return VOS_STATUS_E_FAILURE;
7979 }
7980
7981 /* If first MAC is not valid, treat all others are not valid
7982 * Then all MACs will be got from ini file */
7983 if(vos_is_macaddr_zero(&macFromNV[0]))
7984 {
7985 /* MAC address in NV file is not configured yet */
7986 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7987 return VOS_STATUS_E_INVAL;
7988 }
7989
7990 /* Get MAC address from NV, update CFG info */
7991 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7992 {
7993 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7994 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307995 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 /* This MAC is not valid, skip it
7997 * This MAC will be got from ini file */
7998 }
7999 else
8000 {
8001 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8002 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8003 VOS_MAC_ADDR_SIZE);
8004 }
8005 }
8006 }
8007 else
8008 {
8009 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8010 return VOS_STATUS_E_FAILURE;
8011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008012
Jeff Johnson295189b2012-06-20 16:38:30 -07008013
8014 return VOS_STATUS_SUCCESS;
8015}
8016
8017/**---------------------------------------------------------------------------
8018
8019 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8020
8021 \param - pAdapter - Pointer to the HDD
8022
8023 \return - None
8024
8025 --------------------------------------------------------------------------*/
8026VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8027{
8028 eHalStatus halStatus;
8029 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308030 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008031
Jeff Johnson295189b2012-06-20 16:38:30 -07008032
8033 // Send ready indication to the HDD. This will kick off the MAC
8034 // into a 'running' state and should kick off an initial scan.
8035 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8036 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8037 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308038 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 "code %08d [x%08x]",__func__, halStatus, halStatus );
8040 return VOS_STATUS_E_FAILURE;
8041 }
8042
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308043 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8045 // And RIVA will crash
8046 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8047 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308048 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8049 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8050
8051
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 return VOS_STATUS_SUCCESS;
8053}
8054
Jeff Johnson295189b2012-06-20 16:38:30 -07008055/* wake lock APIs for HDD */
8056void hdd_prevent_suspend(void)
8057{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008058#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008059 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008060#else
8061 wcnss_prevent_suspend();
8062#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008063}
8064
8065void hdd_allow_suspend(void)
8066{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008067#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008069#else
8070 wcnss_allow_suspend();
8071#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008072}
8073
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308074void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008075{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008076#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008077 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008078#else
8079 /* Do nothing as there is no API in wcnss for timeout*/
8080#endif
8081}
8082
Jeff Johnson295189b2012-06-20 16:38:30 -07008083/**---------------------------------------------------------------------------
8084
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008085 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8086 information between Host and Riva
8087
8088 This function gets reported version of FW
8089 It also finds the version of Riva headers used to compile the host
8090 It compares the above two and prints a warning if they are different
8091 It gets the SW and HW version string
8092 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8093 indicating the features they support through a bitmap
8094
8095 \param - pHddCtx - Pointer to HDD context
8096
8097 \return - void
8098
8099 --------------------------------------------------------------------------*/
8100
8101void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8102{
8103
8104 tSirVersionType versionCompiled;
8105 tSirVersionType versionReported;
8106 tSirVersionString versionString;
8107 tANI_U8 fwFeatCapsMsgSupported = 0;
8108 VOS_STATUS vstatus;
8109
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008110 memset(&versionCompiled, 0, sizeof(versionCompiled));
8111 memset(&versionReported, 0, sizeof(versionReported));
8112
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008113 /* retrieve and display WCNSS version information */
8114 do {
8115
8116 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8117 &versionCompiled);
8118 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8119 {
8120 hddLog(VOS_TRACE_LEVEL_FATAL,
8121 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008122 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008123 break;
8124 }
8125
8126 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8127 &versionReported);
8128 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8129 {
8130 hddLog(VOS_TRACE_LEVEL_FATAL,
8131 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008132 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008133 break;
8134 }
8135
8136 if ((versionCompiled.major != versionReported.major) ||
8137 (versionCompiled.minor != versionReported.minor) ||
8138 (versionCompiled.version != versionReported.version) ||
8139 (versionCompiled.revision != versionReported.revision))
8140 {
8141 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8142 "Host expected %u.%u.%u.%u\n",
8143 WLAN_MODULE_NAME,
8144 (int)versionReported.major,
8145 (int)versionReported.minor,
8146 (int)versionReported.version,
8147 (int)versionReported.revision,
8148 (int)versionCompiled.major,
8149 (int)versionCompiled.minor,
8150 (int)versionCompiled.version,
8151 (int)versionCompiled.revision);
8152 }
8153 else
8154 {
8155 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8156 WLAN_MODULE_NAME,
8157 (int)versionReported.major,
8158 (int)versionReported.minor,
8159 (int)versionReported.version,
8160 (int)versionReported.revision);
8161 }
8162
8163 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8164 versionString,
8165 sizeof(versionString));
8166 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8167 {
8168 hddLog(VOS_TRACE_LEVEL_FATAL,
8169 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008170 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008171 break;
8172 }
8173
8174 pr_info("%s: WCNSS software version %s\n",
8175 WLAN_MODULE_NAME, versionString);
8176
8177 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8178 versionString,
8179 sizeof(versionString));
8180 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8181 {
8182 hddLog(VOS_TRACE_LEVEL_FATAL,
8183 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008184 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008185 break;
8186 }
8187
8188 pr_info("%s: WCNSS hardware version %s\n",
8189 WLAN_MODULE_NAME, versionString);
8190
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008191 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8192 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008193 send the message only if it the riva is 1.1
8194 minor numbers for different riva branches:
8195 0 -> (1.0)Mainline Build
8196 1 -> (1.1)Mainline Build
8197 2->(1.04) Stability Build
8198 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008199 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008200 ((versionReported.minor>=1) && (versionReported.version>=1)))
8201 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8202 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008203
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008204 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008205 {
8206#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8207 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8208 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8209#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008210 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8211 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8212 {
8213 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8214 }
8215
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008216 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008217 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008218
8219 } while (0);
8220
8221}
8222
8223/**---------------------------------------------------------------------------
8224
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308225 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8226
8227 \param - pHddCtx - Pointer to the hdd context
8228
8229 \return - true if hardware supports 5GHz
8230
8231 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308232boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308233{
8234 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8235 * then hardware support 5Ghz.
8236 */
8237 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8238 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308240 return true;
8241 }
8242 else
8243 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308244 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308245 __func__);
8246 return false;
8247 }
8248}
8249
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308250/**---------------------------------------------------------------------------
8251
8252 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8253 generate function
8254
8255 This is generate the random mac address for WLAN interface
8256
8257 \param - pHddCtx - Pointer to HDD context
8258 idx - Start interface index to get auto
8259 generated mac addr.
8260 mac_addr - Mac address
8261
8262 \return - 0 for success, < 0 for failure
8263
8264 --------------------------------------------------------------------------*/
8265
8266static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8267 int idx, v_MACADDR_t mac_addr)
8268{
8269 int i;
8270 unsigned int serialno;
8271 serialno = wcnss_get_serial_number();
8272
8273 if (0 != serialno)
8274 {
8275 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8276 bytes of the serial number that can be used to generate
8277 the other 3 bytes of the MAC address. Mask off all but
8278 the lower 3 bytes (this will also make sure we don't
8279 overflow in the next step) */
8280 serialno &= 0x00FFFFFF;
8281
8282 /* we need a unique address for each session */
8283 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8284
8285 /* autogen other Mac addresses */
8286 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8287 {
8288 /* start with the entire default address */
8289 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8290 /* then replace the lower 3 bytes */
8291 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8292 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8293 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8294
8295 serialno++;
8296 hddLog(VOS_TRACE_LEVEL_ERROR,
8297 "%s: Derived Mac Addr: "
8298 MAC_ADDRESS_STR, __func__,
8299 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8300 }
8301
8302 }
8303 else
8304 {
8305 hddLog(LOGE, FL("Failed to Get Serial NO"));
8306 return -1;
8307 }
8308 return 0;
8309}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308310
8311/**---------------------------------------------------------------------------
8312
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308313 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8314 completed to flush out the scan results
8315
8316 11d scan is done during driver load and is a passive scan on all
8317 channels supported by the device, 11d scans may find some APs on
8318 frequencies which are forbidden to be used in the regulatory domain
8319 the device is operating in. If these APs are notified to the supplicant
8320 it may try to connect to these APs, thus flush out all the scan results
8321 which are present in SME after 11d scan is done.
8322
8323 \return - eHalStatus
8324
8325 --------------------------------------------------------------------------*/
8326static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8327 tANI_U32 scanId, eCsrScanStatus status)
8328{
8329 ENTER();
8330
8331 sme_ScanFlushResult(halHandle, 0);
8332
8333 EXIT();
8334
8335 return eHAL_STATUS_SUCCESS;
8336}
8337
8338/**---------------------------------------------------------------------------
8339
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 \brief hdd_wlan_startup() - HDD init function
8341
8342 This is the driver startup code executed once a WLAN device has been detected
8343
8344 \param - dev - Pointer to the underlying device
8345
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008346 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008347
8348 --------------------------------------------------------------------------*/
8349
8350int hdd_wlan_startup(struct device *dev )
8351{
8352 VOS_STATUS status;
8353 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008354 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 hdd_context_t *pHddCtx = NULL;
8356 v_CONTEXT_t pVosContext= NULL;
8357#ifdef WLAN_BTAMP_FEATURE
8358 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8359 WLANBAP_ConfigType btAmpConfig;
8360 hdd_config_t *pConfig;
8361#endif
8362 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308364 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008365
8366 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 /*
8368 * cfg80211: wiphy allocation
8369 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308370 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008371
8372 if(wiphy == NULL)
8373 {
8374 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008375 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 }
8377
8378 pHddCtx = wiphy_priv(wiphy);
8379
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 //Initialize the adapter context to zeros.
8381 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8382
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008384 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308385 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008386
8387 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8388
8389 /*Get vos context here bcoz vos_open requires it*/
8390 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8391
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008392 if(pVosContext == NULL)
8393 {
8394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8395 goto err_free_hdd_context;
8396 }
8397
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 //Save the Global VOSS context in adapter context for future.
8399 pHddCtx->pvosContext = pVosContext;
8400
8401 //Save the adapter context in global context for future.
8402 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8403
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 pHddCtx->parent_dev = dev;
8405
8406 init_completion(&pHddCtx->full_pwr_comp_var);
8407 init_completion(&pHddCtx->standby_comp_var);
8408 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008409 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008410 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308411 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308412 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008413
8414#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008415 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008416#else
8417 init_completion(&pHddCtx->driver_crda_req);
8418#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008419
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308420 spin_lock_init(&pHddCtx->schedScan_lock);
8421
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8423
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308424#ifdef FEATURE_WLAN_TDLS
8425 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8426 * invoked by other instances also) to protect the concurrent
8427 * access for the Adapters by TDLS module.
8428 */
8429 mutex_init(&pHddCtx->tdls_lock);
8430#endif
8431
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308432 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 // Load all config first as TL config is needed during vos_open
8434 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8435 if(pHddCtx->cfg_ini == NULL)
8436 {
8437 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8438 goto err_free_hdd_context;
8439 }
8440
8441 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8442
8443 // Read and parse the qcom_cfg.ini file
8444 status = hdd_parse_config_ini( pHddCtx );
8445 if ( VOS_STATUS_SUCCESS != status )
8446 {
8447 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8448 __func__, WLAN_INI_FILE);
8449 goto err_config;
8450 }
Arif Hussaind5218912013-12-05 01:10:55 -08008451#ifdef MEMORY_DEBUG
8452 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8453 vos_mem_init();
8454
8455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8456 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8457#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008458
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308459 /* INI has been read, initialise the configuredMcastBcastFilter with
8460 * INI value as this will serve as the default value
8461 */
8462 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8463 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8464 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308465
8466 if (false == hdd_is_5g_supported(pHddCtx))
8467 {
8468 //5Ghz is not supported.
8469 if (1 != pHddCtx->cfg_ini->nBandCapability)
8470 {
8471 hddLog(VOS_TRACE_LEVEL_INFO,
8472 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8473 pHddCtx->cfg_ini->nBandCapability = 1;
8474 }
8475 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308476
8477 /* If SNR Monitoring is enabled, FW has to parse all beacons
8478 * for calcaluting and storing the average SNR, so set Nth beacon
8479 * filter to 1 to enable FW to parse all the beaocons
8480 */
8481 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8482 {
8483 /* The log level is deliberately set to WARN as overriding
8484 * nthBeaconFilter to 1 will increase power cosumption and this
8485 * might just prove helpful to detect the power issue.
8486 */
8487 hddLog(VOS_TRACE_LEVEL_WARN,
8488 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8489 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008491 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308492 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008494 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008496 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8497 {
8498 hddLog(VOS_TRACE_LEVEL_FATAL,
8499 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8500 goto err_config;
8501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008503
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008504 // Update VOS trace levels based upon the cfg.ini
8505 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8506 pHddCtx->cfg_ini->vosTraceEnableBAP);
8507 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8508 pHddCtx->cfg_ini->vosTraceEnableTL);
8509 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8510 pHddCtx->cfg_ini->vosTraceEnableWDI);
8511 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8512 pHddCtx->cfg_ini->vosTraceEnableHDD);
8513 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8514 pHddCtx->cfg_ini->vosTraceEnableSME);
8515 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8516 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308517 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8518 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008519 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8520 pHddCtx->cfg_ini->vosTraceEnableWDA);
8521 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8522 pHddCtx->cfg_ini->vosTraceEnableSYS);
8523 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8524 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008525 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8526 pHddCtx->cfg_ini->vosTraceEnableSAP);
8527 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8528 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008529
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 // Update WDI trace levels based upon the cfg.ini
8531 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8532 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8533 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8534 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8535 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8536 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8537 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8538 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008539
Jeff Johnson88ba7742013-02-27 14:36:02 -08008540 if (VOS_FTM_MODE == hdd_get_conparam())
8541 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008542 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8543 {
8544 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8545 goto err_free_hdd_context;
8546 }
8547 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308548
8549 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008551 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008552
Jeff Johnson88ba7742013-02-27 14:36:02 -08008553 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008554 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8555 {
8556 status = vos_watchdog_open(pVosContext,
8557 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8558
8559 if(!VOS_IS_STATUS_SUCCESS( status ))
8560 {
8561 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308562 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008563 }
8564 }
8565
8566 pHddCtx->isLogpInProgress = FALSE;
8567 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8568
Jeff Johnson295189b2012-06-20 16:38:30 -07008569 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8570 if(!VOS_IS_STATUS_SUCCESS(status))
8571 {
8572 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 }
8575
Amar Singhala49cbc52013-10-08 18:37:44 -07008576#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008577 /* initialize the NV module. This is required so that
8578 we can initialize the channel information in wiphy
8579 from the NV.bin data. The channel information in
8580 wiphy needs to be initialized before wiphy registration */
8581
8582 status = vos_nv_open();
8583 if (!VOS_IS_STATUS_SUCCESS(status))
8584 {
8585 /* NV module cannot be initialized */
8586 hddLog( VOS_TRACE_LEVEL_FATAL,
8587 "%s: vos_nv_open failed", __func__);
8588 goto err_clkvote;
8589 }
8590
8591 status = vos_init_wiphy_from_nv_bin();
8592 if (!VOS_IS_STATUS_SUCCESS(status))
8593 {
8594 /* NV module cannot be initialized */
8595 hddLog( VOS_TRACE_LEVEL_FATAL,
8596 "%s: vos_init_wiphy failed", __func__);
8597 goto err_vos_nv_close;
8598 }
8599
Amar Singhala49cbc52013-10-08 18:37:44 -07008600#endif
8601
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308602 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 if ( !VOS_IS_STATUS_SUCCESS( status ))
8604 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008605 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308606 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008607 }
8608
Jeff Johnson295189b2012-06-20 16:38:30 -07008609 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8610
8611 if ( NULL == pHddCtx->hHal )
8612 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008613 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008614 goto err_vosclose;
8615 }
8616
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008617 status = vos_preStart( pHddCtx->pvosContext );
8618 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8619 {
8620 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308621 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008622 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008623
Arif Hussaineaf68602013-12-30 23:10:44 -08008624 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8625 {
8626 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8627 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8628 __func__, enable_dfs_chan_scan);
8629 }
8630 if (0 == enable_11d || 1 == enable_11d)
8631 {
8632 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8633 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8634 __func__, enable_11d);
8635 }
8636
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008637 /* Note that the vos_preStart() sequence triggers the cfg download.
8638 The cfg download must occur before we update the SME config
8639 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008640 status = hdd_set_sme_config( pHddCtx );
8641
8642 if ( VOS_STATUS_SUCCESS != status )
8643 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008644 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308645 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008647
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 /* In the integrated architecture we update the configuration from
8649 the INI file and from NV before vOSS has been started so that
8650 the final contents are available to send down to the cCPU */
8651
8652 // Apply the cfg.ini to cfg.dat
8653 if (FALSE == hdd_update_config_dat(pHddCtx))
8654 {
8655 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308656 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 }
8658
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308659 // Get mac addr from platform driver
8660 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8661
8662 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308664 /* Store the mac addr for first interface */
8665 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8666
8667 hddLog(VOS_TRACE_LEVEL_ERROR,
8668 "%s: WLAN Mac Addr: "
8669 MAC_ADDRESS_STR, __func__,
8670 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8671
8672 /* Here, passing Arg2 as 1 because we do not want to change the
8673 last 3 bytes (means non OUI bytes) of first interface mac
8674 addr.
8675 */
8676 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8677 {
8678 hddLog(VOS_TRACE_LEVEL_ERROR,
8679 "%s: Failed to generate wlan interface mac addr "
8680 "using MAC from ini file ", __func__);
8681 }
8682 }
8683 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8684 {
8685 // Apply the NV to cfg.dat
8686 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008687#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8688 /* There was not a valid set of MAC Addresses in NV. See if the
8689 default addresses were modified by the cfg.ini settings. If so,
8690 we'll use them, but if not, we'll autogenerate a set of MAC
8691 addresses based upon the device serial number */
8692
8693 static const v_MACADDR_t default_address =
8694 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008695
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308696 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8697 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 {
8699 /* cfg.ini has the default address, invoke autogen logic */
8700
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308701 /* Here, passing Arg2 as 0 because we want to change the
8702 last 3 bytes (means non OUI bytes) of all the interfaces
8703 mac addr.
8704 */
8705 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8706 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308708 hddLog(VOS_TRACE_LEVEL_ERROR,
8709 "%s: Failed to generate wlan interface mac addr "
8710 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8711 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 }
8714 else
8715#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8716 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008717 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 "%s: Invalid MAC address in NV, using MAC from ini file "
8719 MAC_ADDRESS_STR, __func__,
8720 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8721 }
8722 }
8723 {
8724 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308725
8726 /* Set the MAC Address Currently this is used by HAL to
8727 * add self sta. Remove this once self sta is added as
8728 * part of session open.
8729 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8731 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8732 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308733
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 if (!HAL_STATUS_SUCCESS( halStatus ))
8735 {
8736 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8737 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308738 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 }
8740 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008741
8742 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8743 Note: Firmware image will be read and downloaded inside vos_start API */
8744 status = vos_start( pHddCtx->pvosContext );
8745 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8746 {
8747 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308748 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 }
8750
Leo Chang6cec3e22014-01-21 15:33:49 -08008751#ifdef FEATURE_WLAN_CH_AVOID
8752 /* Plug in avoid channel notification callback
8753 * This should happen before ADD_SELF_STA
8754 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308755
8756 /* check the Channel Avoidance is enabled */
8757 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8758 {
8759 sme_AddChAvoidCallback(pHddCtx->hHal,
8760 hdd_hostapd_ch_avoid_cb);
8761 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008762#endif /* FEATURE_WLAN_CH_AVOID */
8763
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008764 /* Exchange capability info between Host and FW and also get versioning info from FW */
8765 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008766
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308767#ifdef CONFIG_ENABLE_LINUX_REG
8768 status = wlan_hdd_init_channels(pHddCtx);
8769 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8770 {
8771 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8772 __func__);
8773 goto err_vosstop;
8774 }
8775#endif
8776
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 status = hdd_post_voss_start_config( pHddCtx );
8778 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8779 {
8780 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8781 __func__);
8782 goto err_vosstop;
8783 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008784
8785#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308786 wlan_hdd_cfg80211_update_reg_info( wiphy );
8787
8788 /* registration of wiphy dev with cfg80211 */
8789 if (0 > wlan_hdd_cfg80211_register(wiphy))
8790 {
8791 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8792 goto err_vosstop;
8793 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008794#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008795
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308796#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308797 /* registration of wiphy dev with cfg80211 */
8798 if (0 > wlan_hdd_cfg80211_register(wiphy))
8799 {
8800 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8801 goto err_vosstop;
8802 }
8803
8804 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8805 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8806 {
8807 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8808 __func__);
8809 goto err_unregister_wiphy;
8810 }
8811#endif
8812
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8814 {
8815 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8816 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8817 }
8818 else
8819 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8821 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8822 if (pAdapter != NULL)
8823 {
kaidde69982014-06-18 13:23:21 +08008824 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308826 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8827 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8828 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008829
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308830 /* Generate the P2P Device Address. This consists of the device's
8831 * primary MAC address with the locally administered bit set.
8832 */
8833 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008834 }
8835 else
8836 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308837 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8838 if (p2p_dev_addr != NULL)
8839 {
8840 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8841 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8842 }
8843 else
8844 {
8845 hddLog(VOS_TRACE_LEVEL_FATAL,
8846 "%s: Failed to allocate mac_address for p2p_device",
8847 __func__);
8848 goto err_close_adapter;
8849 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008850 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008851
8852 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8853 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8854 if ( NULL == pP2pAdapter )
8855 {
8856 hddLog(VOS_TRACE_LEVEL_FATAL,
8857 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008858 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008859 goto err_close_adapter;
8860 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008861 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008863
8864 if( pAdapter == NULL )
8865 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8867 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008869
Arif Hussain66559122013-11-21 10:11:40 -08008870 if (country_code)
8871 {
8872 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008873 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008874 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8875#ifndef CONFIG_ENABLE_LINUX_REG
8876 hdd_checkandupdate_phymode(pAdapter, country_code);
8877#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008878 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8879 (void *)(tSmeChangeCountryCallback)
8880 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008881 country_code,
8882 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308883 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008884 if (eHAL_STATUS_SUCCESS == ret)
8885 {
Arif Hussaincb607082013-12-20 11:57:42 -08008886 ret = wait_for_completion_interruptible_timeout(
8887 &pAdapter->change_country_code,
8888 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8889
8890 if (0 >= ret)
8891 {
8892 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8893 "%s: SME while setting country code timed out", __func__);
8894 }
Arif Hussain66559122013-11-21 10:11:40 -08008895 }
8896 else
8897 {
Arif Hussaincb607082013-12-20 11:57:42 -08008898 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8899 "%s: SME Change Country code from module param fail ret=%d",
8900 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008901 }
8902 }
8903
Jeff Johnson295189b2012-06-20 16:38:30 -07008904#ifdef WLAN_BTAMP_FEATURE
8905 vStatus = WLANBAP_Open(pVosContext);
8906 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8907 {
8908 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8909 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008910 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 }
8912
8913 vStatus = BSL_Init(pVosContext);
8914 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8915 {
8916 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8917 "%s: Failed to Init BSL",__func__);
8918 goto err_bap_close;
8919 }
8920 vStatus = WLANBAP_Start(pVosContext);
8921 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8922 {
8923 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8924 "%s: Failed to start TL",__func__);
8925 goto err_bap_close;
8926 }
8927
8928 pConfig = pHddCtx->cfg_ini;
8929 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8930 status = WLANBAP_SetConfig(&btAmpConfig);
8931
8932#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008933
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008934#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8935 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8936 {
8937 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8938 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8939 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8940 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8941 }
8942#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008943
Agarwal Ashish4b87f922014-06-18 03:03:21 +05308944 wlan_hdd_tdls_init(pHddCtx);
8945
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308946 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8947
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 /* Register with platform driver as client for Suspend/Resume */
8949 status = hddRegisterPmOps(pHddCtx);
8950 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8951 {
8952 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8953#ifdef WLAN_BTAMP_FEATURE
8954 goto err_bap_stop;
8955#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008956 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008957#endif //WLAN_BTAMP_FEATURE
8958 }
8959
Yue Ma0d4891e2013-08-06 17:01:45 -07008960 /* Open debugfs interface */
8961 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8962 {
8963 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8964 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008965 }
8966
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 /* Register TM level change handler function to the platform */
8968 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8969 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8970 {
8971 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8972 goto err_unregister_pmops;
8973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008974
8975 /* register for riva power on lock to platform driver */
8976 if (req_riva_power_on_lock("wlan"))
8977 {
8978 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8979 __func__);
8980 goto err_unregister_pmops;
8981 }
8982
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 // register net device notifier for device change notification
8984 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8985
8986 if(ret < 0)
8987 {
8988 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8989 goto err_free_power_on_lock;
8990 }
8991
8992 //Initialize the nlink service
8993 if(nl_srv_init() != 0)
8994 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308995 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 goto err_reg_netdev;
8997 }
8998
Leo Chang4ce1cc52013-10-21 18:27:15 -07008999#ifdef WLAN_KD_READY_NOTIFIER
9000 pHddCtx->kd_nl_init = 1;
9001#endif /* WLAN_KD_READY_NOTIFIER */
9002
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 //Initialize the BTC service
9004 if(btc_activate_service(pHddCtx) != 0)
9005 {
9006 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9007 goto err_nl_srv;
9008 }
9009
9010#ifdef PTT_SOCK_SVC_ENABLE
9011 //Initialize the PTT service
9012 if(ptt_sock_activate_svc(pHddCtx) != 0)
9013 {
9014 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9015 goto err_nl_srv;
9016 }
9017#endif
9018
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309019#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9020 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9021 {
9022 if(wlan_logging_sock_activate_svc(
9023 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9024 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9025 {
9026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9027 " failed", __func__);
9028 goto err_nl_srv;
9029 }
9030 }
9031#endif
9032
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009036 /* Action frame registered in one adapter which will
9037 * applicable to all interfaces
9038 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309039 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009041
9042 mutex_init(&pHddCtx->sap_lock);
9043
Jeff Johnson295189b2012-06-20 16:38:30 -07009044
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009045#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009046#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9047 /* Initialize the wake lcok */
9048 wake_lock_init(&pHddCtx->rx_wake_lock,
9049 WAKE_LOCK_SUSPEND,
9050 "qcom_rx_wakelock");
9051#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009052 /* Initialize the wake lcok */
9053 wake_lock_init(&pHddCtx->sap_wake_lock,
9054 WAKE_LOCK_SUSPEND,
9055 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009056#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009057
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009058 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9059 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009060
Katya Nigam5c306ea2014-06-19 15:39:54 +05309061 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9063 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309064
9065#ifdef FEATURE_WLAN_SCAN_PNO
9066 /*SME must send channel update configuration to RIVA*/
9067 sme_UpdateChannelConfig(pHddCtx->hHal);
9068#endif
9069
Abhishek Singha306a442013-11-07 18:39:01 +05309070#ifndef CONFIG_ENABLE_LINUX_REG
9071 /*updating wiphy so that regulatory user hints can be processed*/
9072 if (wiphy)
9073 {
9074 regulatory_hint(wiphy, "00");
9075 }
9076#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009077 // Initialize the restart logic
9078 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309079
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009080 //Register the traffic monitor timer now
9081 if ( pHddCtx->cfg_ini->dynSplitscan)
9082 {
9083 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9084 VOS_TIMER_TYPE_SW,
9085 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9086 (void *)pHddCtx);
9087 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309088#ifdef WLAN_FEATURE_EXTSCAN
9089 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9090 wlan_hdd_cfg80211_extscan_callback,
9091 pHddCtx);
9092#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009093 goto success;
9094
9095err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009096#ifdef WLAN_KD_READY_NOTIFIER
9097 nl_srv_exit(pHddCtx->ptt_pid);
9098#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009099 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009100#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009101err_reg_netdev:
9102 unregister_netdevice_notifier(&hdd_netdev_notifier);
9103
9104err_free_power_on_lock:
9105 free_riva_power_on_lock("wlan");
9106
9107err_unregister_pmops:
9108 hddDevTmUnregisterNotifyCallback(pHddCtx);
9109 hddDeregisterPmOps(pHddCtx);
9110
Yue Ma0d4891e2013-08-06 17:01:45 -07009111 hdd_debugfs_exit(pHddCtx);
9112
Jeff Johnson295189b2012-06-20 16:38:30 -07009113#ifdef WLAN_BTAMP_FEATURE
9114err_bap_stop:
9115 WLANBAP_Stop(pVosContext);
9116#endif
9117
9118#ifdef WLAN_BTAMP_FEATURE
9119err_bap_close:
9120 WLANBAP_Close(pVosContext);
9121#endif
9122
Jeff Johnson295189b2012-06-20 16:38:30 -07009123err_close_adapter:
9124 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309125err_unregister_wiphy:
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309126 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009127err_vosstop:
9128 vos_stop(pVosContext);
9129
Amar Singhala49cbc52013-10-08 18:37:44 -07009130err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 status = vos_sched_close( pVosContext );
9132 if (!VOS_IS_STATUS_SUCCESS(status)) {
9133 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9134 "%s: Failed to close VOSS Scheduler", __func__);
9135 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9136 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009137 vos_close(pVosContext );
9138
Amar Singhal0a402232013-10-11 20:57:16 -07009139err_vos_nv_close:
9140
c_hpothue6a36282014-03-19 12:27:38 +05309141#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009142 vos_nv_close();
9143
Jeff Johnson295189b2012-06-20 16:38:30 -07009144err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309145#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009146 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009147
9148err_wdclose:
9149 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9150 vos_watchdog_close(pVosContext);
9151
Jeff Johnson295189b2012-06-20 16:38:30 -07009152err_config:
9153 kfree(pHddCtx->cfg_ini);
9154 pHddCtx->cfg_ini= NULL;
9155
9156err_free_hdd_context:
9157 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 wiphy_free(wiphy) ;
9159 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 VOS_BUG(1);
9161
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009162 if (hdd_is_ssr_required())
9163 {
9164 /* WDI timeout had happened during load, so SSR is needed here */
9165 subsystem_restart("wcnss");
9166 msleep(5000);
9167 }
9168 hdd_set_ssr_required (VOS_FALSE);
9169
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009170 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009171
9172success:
9173 EXIT();
9174 return 0;
9175}
9176
9177/**---------------------------------------------------------------------------
9178
Jeff Johnson32d95a32012-09-10 13:15:23 -07009179 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009180
Jeff Johnson32d95a32012-09-10 13:15:23 -07009181 This is the driver entry point - called in different timeline depending
9182 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009183
9184 \param - None
9185
9186 \return - 0 for success, non zero for failure
9187
9188 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009189static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009190{
9191 VOS_STATUS status;
9192 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 struct device *dev = NULL;
9194 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009195#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9196 int max_retries = 0;
9197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009198
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309199#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9200 wlan_logging_sock_init_svc();
9201#endif
9202
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 ENTER();
9204
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009205#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009207#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009208
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309209 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009210 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9211 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9212
9213 //Power Up Libra WLAN card first if not already powered up
9214 status = vos_chipPowerUp(NULL,NULL,NULL);
9215 if (!VOS_IS_STATUS_SUCCESS(status))
9216 {
9217 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9218 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309219#ifdef WLAN_OPEN_SOURCE
9220 wake_lock_destroy(&wlan_wake_lock);
9221#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309222
9223#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9224 wlan_logging_sock_deinit_svc();
9225#endif
9226
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009227 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 }
9229
Jeff Johnson295189b2012-06-20 16:38:30 -07009230#ifdef ANI_BUS_TYPE_PCI
9231
9232 dev = wcnss_wlan_get_device();
9233
9234#endif // ANI_BUS_TYPE_PCI
9235
9236#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009237
9238#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9239 /* wait until WCNSS driver downloads NV */
9240 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9241 msleep(1000);
9242 }
9243 if (max_retries >= 5) {
9244 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309245#ifdef WLAN_OPEN_SOURCE
9246 wake_lock_destroy(&wlan_wake_lock);
9247#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309248
9249#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9250 wlan_logging_sock_deinit_svc();
9251#endif
9252
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009253 return -ENODEV;
9254 }
9255#endif
9256
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 dev = wcnss_wlan_get_device();
9258#endif // ANI_BUS_TYPE_PLATFORM
9259
9260
9261 do {
9262 if (NULL == dev) {
9263 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9264 ret_status = -1;
9265 break;
9266 }
9267
Jeff Johnson295189b2012-06-20 16:38:30 -07009268#ifdef TIMER_MANAGER
9269 vos_timer_manager_init();
9270#endif
9271
9272 /* Preopen VOSS so that it is ready to start at least SAL */
9273 status = vos_preOpen(&pVosContext);
9274
9275 if (!VOS_IS_STATUS_SUCCESS(status))
9276 {
9277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9278 ret_status = -1;
9279 break;
9280 }
9281
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009282#ifndef MODULE
9283 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9284 */
9285 hdd_set_conparam((v_UINT_t)con_mode);
9286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009287
9288 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009289 if (hdd_wlan_startup(dev))
9290 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009292 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 vos_preClose( &pVosContext );
9294 ret_status = -1;
9295 break;
9296 }
9297
9298 /* Cancel the vote for XO Core ON
9299 * This is done here for safety purposes in case we re-initialize without turning
9300 * it OFF in any error scenario.
9301 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009302 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009304 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9306 {
9307 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009308 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 }
9310 } while (0);
9311
9312 if (0 != ret_status)
9313 {
9314 //Assert Deep sleep signal now to put Libra HW in lowest power state
9315 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9316 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9317
9318 //Vote off any PMIC voltage supplies
9319 vos_chipPowerDown(NULL, NULL, NULL);
9320#ifdef TIMER_MANAGER
9321 vos_timer_exit();
9322#endif
9323#ifdef MEMORY_DEBUG
9324 vos_mem_exit();
9325#endif
9326
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009327#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009329#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309330
9331#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9332 wlan_logging_sock_deinit_svc();
9333#endif
9334
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9336 }
9337 else
9338 {
9339 //Send WLAN UP indication to Nlink Service
9340 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9341
9342 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 }
9344
9345 EXIT();
9346
9347 return ret_status;
9348}
9349
Jeff Johnson32d95a32012-09-10 13:15:23 -07009350/**---------------------------------------------------------------------------
9351
9352 \brief hdd_module_init() - Init Function
9353
9354 This is the driver entry point (invoked when module is loaded using insmod)
9355
9356 \param - None
9357
9358 \return - 0 for success, non zero for failure
9359
9360 --------------------------------------------------------------------------*/
9361#ifdef MODULE
9362static int __init hdd_module_init ( void)
9363{
9364 return hdd_driver_init();
9365}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009366#else /* #ifdef MODULE */
9367static int __init hdd_module_init ( void)
9368{
9369 /* Driver initialization is delayed to fwpath_changed_handler */
9370 return 0;
9371}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009372#endif /* #ifdef MODULE */
9373
Jeff Johnson295189b2012-06-20 16:38:30 -07009374
9375/**---------------------------------------------------------------------------
9376
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009377 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009378
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009379 This is the driver exit point (invoked when module is unloaded using rmmod
9380 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009381
9382 \param - None
9383
9384 \return - None
9385
9386 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009387static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009388{
9389 hdd_context_t *pHddCtx = NULL;
9390 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309391 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309392 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009393
9394 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9395
9396 //Get the global vos context
9397 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9398
9399 if(!pVosContext)
9400 {
9401 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9402 goto done;
9403 }
9404
9405 //Get the HDD context.
9406 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9407
9408 if(!pHddCtx)
9409 {
9410 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9411 }
9412 else
9413 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309414 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9415
9416 if (pHddCtx->isLogpInProgress)
9417 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309419 "%s:SSR in Progress; block rmmod !!!", __func__);
9420 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9421 msecs_to_jiffies(30000));
9422 if(!rc)
9423 {
9424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9425 "%s:SSR timedout, fatal error", __func__);
9426 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009427 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309428 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009429
Mihir Shete18156292014-03-11 15:38:30 +05309430 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9432
Agarwal Ashish5e414792014-06-08 15:25:23 +05309433 if (eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
9434 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority )
9435 {
9436 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9437 }
9438
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 //Do all the cleanup before deregistering the driver
9440 hdd_wlan_exit(pHddCtx);
9441 }
9442
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 vos_preClose( &pVosContext );
9444
9445#ifdef TIMER_MANAGER
9446 vos_timer_exit();
9447#endif
9448#ifdef MEMORY_DEBUG
9449 vos_mem_exit();
9450#endif
9451
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309452#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9453 wlan_logging_sock_deinit_svc();
9454#endif
9455
Jeff Johnson295189b2012-06-20 16:38:30 -07009456done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009457#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009459#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309460
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9462}
9463
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009464/**---------------------------------------------------------------------------
9465
9466 \brief hdd_module_exit() - Exit function
9467
9468 This is the driver exit point (invoked when module is unloaded using rmmod)
9469
9470 \param - None
9471
9472 \return - None
9473
9474 --------------------------------------------------------------------------*/
9475static void __exit hdd_module_exit(void)
9476{
9477 hdd_driver_exit();
9478}
9479
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009480#ifdef MODULE
9481static int fwpath_changed_handler(const char *kmessage,
9482 struct kernel_param *kp)
9483{
Jeff Johnson76052702013-04-16 13:55:05 -07009484 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009485}
9486
9487static int con_mode_handler(const char *kmessage,
9488 struct kernel_param *kp)
9489{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009490 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009491}
9492#else /* #ifdef MODULE */
9493/**---------------------------------------------------------------------------
9494
Jeff Johnson76052702013-04-16 13:55:05 -07009495 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009496
Jeff Johnson76052702013-04-16 13:55:05 -07009497 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009498 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009499 - invoked when module parameter fwpath is modified from userspace to signal
9500 initializing the WLAN driver or when con_mode is modified from userspace
9501 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009502
9503 \return - 0 for success, non zero for failure
9504
9505 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009506static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009507{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009508 int ret_status;
9509
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009510 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009511 ret_status = hdd_driver_init();
9512 wlan_hdd_inited = ret_status ? 0 : 1;
9513 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009514 }
9515
9516 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009517
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009518 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009519
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009520 ret_status = hdd_driver_init();
9521 wlan_hdd_inited = ret_status ? 0 : 1;
9522 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009523}
9524
Jeff Johnson295189b2012-06-20 16:38:30 -07009525/**---------------------------------------------------------------------------
9526
Jeff Johnson76052702013-04-16 13:55:05 -07009527 \brief fwpath_changed_handler() - Handler Function
9528
9529 Handle changes to the fwpath parameter
9530
9531 \return - 0 for success, non zero for failure
9532
9533 --------------------------------------------------------------------------*/
9534static int fwpath_changed_handler(const char *kmessage,
9535 struct kernel_param *kp)
9536{
9537 int ret;
9538
9539 ret = param_set_copystring(kmessage, kp);
9540 if (0 == ret)
9541 ret = kickstart_driver();
9542 return ret;
9543}
9544
9545/**---------------------------------------------------------------------------
9546
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009547 \brief con_mode_handler() -
9548
9549 Handler function for module param con_mode when it is changed by userspace
9550 Dynamically linked - do nothing
9551 Statically linked - exit and init driver, as in rmmod and insmod
9552
Jeff Johnson76052702013-04-16 13:55:05 -07009553 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009554
Jeff Johnson76052702013-04-16 13:55:05 -07009555 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009556
9557 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009558static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009559{
Jeff Johnson76052702013-04-16 13:55:05 -07009560 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009561
Jeff Johnson76052702013-04-16 13:55:05 -07009562 ret = param_set_int(kmessage, kp);
9563 if (0 == ret)
9564 ret = kickstart_driver();
9565 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009566}
9567#endif /* #ifdef MODULE */
9568
9569/**---------------------------------------------------------------------------
9570
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 \brief hdd_get_conparam() -
9572
9573 This is the driver exit point (invoked when module is unloaded using rmmod)
9574
9575 \param - None
9576
9577 \return - tVOS_CON_MODE
9578
9579 --------------------------------------------------------------------------*/
9580tVOS_CON_MODE hdd_get_conparam ( void )
9581{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009582#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009584#else
9585 return (tVOS_CON_MODE)curr_con_mode;
9586#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009587}
9588void hdd_set_conparam ( v_UINT_t newParam )
9589{
9590 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009591#ifndef MODULE
9592 curr_con_mode = con_mode;
9593#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009594}
9595/**---------------------------------------------------------------------------
9596
9597 \brief hdd_softap_sta_deauth() - function
9598
9599 This to take counter measure to handle deauth req from HDD
9600
9601 \param - pAdapter - Pointer to the HDD
9602
9603 \param - enable - boolean value
9604
9605 \return - None
9606
9607 --------------------------------------------------------------------------*/
9608
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009609VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009610{
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009612 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009613
9614 ENTER();
9615
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009616 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9617 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009618
9619 //Ignore request to deauth bcmc station
9620 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009621 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009622
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009623 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009624
9625 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009626 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009627}
9628
9629/**---------------------------------------------------------------------------
9630
9631 \brief hdd_softap_sta_disassoc() - function
9632
9633 This to take counter measure to handle deauth req from HDD
9634
9635 \param - pAdapter - Pointer to the HDD
9636
9637 \param - enable - boolean value
9638
9639 \return - None
9640
9641 --------------------------------------------------------------------------*/
9642
9643void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9644{
9645 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9646
9647 ENTER();
9648
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309649 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009650
9651 //Ignore request to disassoc bcmc station
9652 if( pDestMacAddress[0] & 0x1 )
9653 return;
9654
9655 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9656}
9657
9658void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9659{
9660 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9661
9662 ENTER();
9663
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309664 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009665
9666 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9667}
9668
Jeff Johnson295189b2012-06-20 16:38:30 -07009669/**---------------------------------------------------------------------------
9670 *
9671 * \brief hdd_get__concurrency_mode() -
9672 *
9673 *
9674 * \param - None
9675 *
9676 * \return - CONCURRENCY MODE
9677 *
9678 * --------------------------------------------------------------------------*/
9679tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9680{
9681 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9682 hdd_context_t *pHddCtx;
9683
9684 if (NULL != pVosContext)
9685 {
9686 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9687 if (NULL != pHddCtx)
9688 {
9689 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9690 }
9691 }
9692
9693 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009694 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 return VOS_STA;
9696}
9697
9698/* Decide whether to allow/not the apps power collapse.
9699 * Allow apps power collapse if we are in connected state.
9700 * if not, allow only if we are in IMPS */
9701v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9702{
9703 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009704 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009705 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9707 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9708 hdd_adapter_t *pAdapter = NULL;
9709 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009710 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009711
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9713 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009714
Yathish9f22e662012-12-10 14:21:35 -08009715 concurrent_state = hdd_get_concurrency_mode();
9716
9717#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9718 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9719 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9720 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9721 return TRUE;
9722#endif
9723
Jeff Johnson295189b2012-06-20 16:38:30 -07009724 /*loop through all adapters. TBD fix for Concurrency */
9725 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9726 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9727 {
9728 pAdapter = pAdapterNode->pAdapter;
9729 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9730 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9731 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009732 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309733 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009734 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009735 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9736 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009737 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009738 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009739 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9740 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 return FALSE;
9742 }
9743 }
9744 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9745 pAdapterNode = pNext;
9746 }
9747 return TRUE;
9748}
9749
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009750/* Decides whether to send suspend notification to Riva
9751 * if any adapter is in BMPS; then it is required */
9752v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9753{
9754 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9755 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9756
9757 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9758 {
9759 return TRUE;
9760 }
9761 return FALSE;
9762}
9763
Jeff Johnson295189b2012-06-20 16:38:30 -07009764void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9765{
9766 switch(mode)
9767 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009768 case VOS_STA_MODE:
9769 case VOS_P2P_CLIENT_MODE:
9770 case VOS_P2P_GO_MODE:
9771 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009772 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309773 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 break;
9775 default:
9776 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309778 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9779 "Number of open sessions for mode %d = %d"),
9780 pHddCtx->concurrency_mode, mode,
9781 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009782}
9783
9784
9785void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9786{
9787 switch(mode)
9788 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009789 case VOS_STA_MODE:
9790 case VOS_P2P_CLIENT_MODE:
9791 case VOS_P2P_GO_MODE:
9792 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +05309793 pHddCtx->no_of_open_sessions[mode]--;
9794 if (!(pHddCtx->no_of_open_sessions[mode]))
9795 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 break;
9797 default:
9798 break;
9799 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309800 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9801 "Number of open sessions for mode %d = %d"),
9802 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
9803
9804}
9805/**---------------------------------------------------------------------------
9806 *
9807 * \brief wlan_hdd_incr_active_session()
9808 *
9809 * This function increments the number of active sessions
9810 * maintained per device mode
9811 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
9812 * Incase of SAP/P2P GO upon bss start it is incremented
9813 *
9814 * \param pHddCtx - HDD Context
9815 * \param mode - device mode
9816 *
9817 * \return - None
9818 *
9819 * --------------------------------------------------------------------------*/
9820void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9821{
9822 switch (mode) {
9823 case VOS_STA_MODE:
9824 case VOS_P2P_CLIENT_MODE:
9825 case VOS_P2P_GO_MODE:
9826 case VOS_STA_SAP_MODE:
9827 pHddCtx->no_of_active_sessions[mode]++;
9828 break;
9829 default:
9830 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9831 break;
9832 }
9833 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9834 mode,
9835 pHddCtx->no_of_active_sessions[mode]);
9836}
9837
9838/**---------------------------------------------------------------------------
9839 *
9840 * \brief wlan_hdd_decr_active_session()
9841 *
9842 * This function decrements the number of active sessions
9843 * maintained per device mode
9844 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
9845 * Incase of SAP/P2P GO upon bss stop it is decremented
9846 *
9847 * \param pHddCtx - HDD Context
9848 * \param mode - device mode
9849 *
9850 * \return - None
9851 *
9852 * --------------------------------------------------------------------------*/
9853void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9854{
9855 switch (mode) {
9856 case VOS_STA_MODE:
9857 case VOS_P2P_CLIENT_MODE:
9858 case VOS_P2P_GO_MODE:
9859 case VOS_STA_SAP_MODE:
9860 pHddCtx->no_of_active_sessions[mode]--;
9861 break;
9862 default:
9863 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9864 break;
9865 }
9866 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9867 mode,
9868 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009869}
9870
Jeff Johnsone7245742012-09-05 17:12:55 -07009871/**---------------------------------------------------------------------------
9872 *
9873 * \brief wlan_hdd_restart_init
9874 *
9875 * This function initalizes restart timer/flag. An internal function.
9876 *
9877 * \param - pHddCtx
9878 *
9879 * \return - None
9880 *
9881 * --------------------------------------------------------------------------*/
9882
9883static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9884{
9885 /* Initialize */
9886 pHddCtx->hdd_restart_retries = 0;
9887 atomic_set(&pHddCtx->isRestartInProgress, 0);
9888 vos_timer_init(&pHddCtx->hdd_restart_timer,
9889 VOS_TIMER_TYPE_SW,
9890 wlan_hdd_restart_timer_cb,
9891 pHddCtx);
9892}
9893/**---------------------------------------------------------------------------
9894 *
9895 * \brief wlan_hdd_restart_deinit
9896 *
9897 * This function cleans up the resources used. An internal function.
9898 *
9899 * \param - pHddCtx
9900 *
9901 * \return - None
9902 *
9903 * --------------------------------------------------------------------------*/
9904
9905static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9906{
9907
9908 VOS_STATUS vos_status;
9909 /* Block any further calls */
9910 atomic_set(&pHddCtx->isRestartInProgress, 1);
9911 /* Cleanup */
9912 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9913 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309914 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009915 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9916 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309917 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009918
9919}
9920
9921/**---------------------------------------------------------------------------
9922 *
9923 * \brief wlan_hdd_framework_restart
9924 *
9925 * This function uses a cfg80211 API to start a framework initiated WLAN
9926 * driver module unload/load.
9927 *
9928 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9929 *
9930 *
9931 * \param - pHddCtx
9932 *
9933 * \return - VOS_STATUS_SUCCESS: Success
9934 * VOS_STATUS_E_EMPTY: Adapter is Empty
9935 * VOS_STATUS_E_NOMEM: No memory
9936
9937 * --------------------------------------------------------------------------*/
9938
9939static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9940{
9941 VOS_STATUS status = VOS_STATUS_SUCCESS;
9942 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009943 int len = (sizeof (struct ieee80211_mgmt));
9944 struct ieee80211_mgmt *mgmt = NULL;
9945
9946 /* Prepare the DEAUTH managment frame with reason code */
9947 mgmt = kzalloc(len, GFP_KERNEL);
9948 if(mgmt == NULL)
9949 {
9950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9951 "%s: memory allocation failed (%d bytes)", __func__, len);
9952 return VOS_STATUS_E_NOMEM;
9953 }
9954 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009955
9956 /* Iterate over all adapters/devices */
9957 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9958 do
9959 {
9960 if( (status == VOS_STATUS_SUCCESS) &&
9961 pAdapterNode &&
9962 pAdapterNode->pAdapter)
9963 {
9964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9965 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9966 pAdapterNode->pAdapter->dev->name,
9967 pAdapterNode->pAdapter->device_mode,
9968 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009969 /*
9970 * CFG80211 event to restart the driver
9971 *
9972 * 'cfg80211_send_unprot_deauth' sends a
9973 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9974 * of SME(Linux Kernel) state machine.
9975 *
9976 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9977 * the driver.
9978 *
9979 */
9980
9981 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009982 }
9983 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9984 pAdapterNode = pNext;
9985 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9986
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009987
9988 /* Free the allocated management frame */
9989 kfree(mgmt);
9990
Jeff Johnsone7245742012-09-05 17:12:55 -07009991 /* Retry until we unload or reach max count */
9992 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9993 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9994
9995 return status;
9996
9997}
9998/**---------------------------------------------------------------------------
9999 *
10000 * \brief wlan_hdd_restart_timer_cb
10001 *
10002 * Restart timer callback. An internal function.
10003 *
10004 * \param - User data:
10005 *
10006 * \return - None
10007 *
10008 * --------------------------------------------------------------------------*/
10009
10010void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10011{
10012 hdd_context_t *pHddCtx = usrDataForCallback;
10013 wlan_hdd_framework_restart(pHddCtx);
10014 return;
10015
10016}
10017
10018
10019/**---------------------------------------------------------------------------
10020 *
10021 * \brief wlan_hdd_restart_driver
10022 *
10023 * This function sends an event to supplicant to restart the WLAN driver.
10024 *
10025 * This function is called from vos_wlanRestart.
10026 *
10027 * \param - pHddCtx
10028 *
10029 * \return - VOS_STATUS_SUCCESS: Success
10030 * VOS_STATUS_E_EMPTY: Adapter is Empty
10031 * VOS_STATUS_E_ALREADY: Request already in progress
10032
10033 * --------------------------------------------------------------------------*/
10034VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10035{
10036 VOS_STATUS status = VOS_STATUS_SUCCESS;
10037
10038 /* A tight check to make sure reentrancy */
10039 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10040 {
Mihir Shetefd528652014-06-23 19:07:50 +053010041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010042 "%s: WLAN restart is already in progress", __func__);
10043
10044 return VOS_STATUS_E_ALREADY;
10045 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010046 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010047#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010048 wcnss_reset_intr();
10049#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010050
Jeff Johnsone7245742012-09-05 17:12:55 -070010051 return status;
10052}
10053
Mihir Shetee1093ba2014-01-21 20:13:32 +053010054/**---------------------------------------------------------------------------
10055 *
10056 * \brief wlan_hdd_init_channels
10057 *
10058 * This function is used to initialize the channel list in CSR
10059 *
10060 * This function is called from hdd_wlan_startup
10061 *
10062 * \param - pHddCtx: HDD context
10063 *
10064 * \return - VOS_STATUS_SUCCESS: Success
10065 * VOS_STATUS_E_FAULT: Failure reported by SME
10066
10067 * --------------------------------------------------------------------------*/
10068static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10069{
10070 eHalStatus status;
10071
10072 status = sme_InitChannels(pHddCtx->hHal);
10073 if (HAL_STATUS_SUCCESS(status))
10074 {
10075 return VOS_STATUS_SUCCESS;
10076 }
10077 else
10078 {
10079 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10080 __func__, status);
10081 return VOS_STATUS_E_FAULT;
10082 }
10083}
10084
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010085static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
10086{
10087 eHalStatus status;
10088
10089 status = sme_InitChannelsForCC(pHddCtx->hHal);
10090 if (HAL_STATUS_SUCCESS(status))
10091 {
10092 return VOS_STATUS_SUCCESS;
10093 }
10094 else
10095 {
10096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10097 __func__, status);
10098 return VOS_STATUS_E_FAULT;
10099 }
10100}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010101/*
10102 * API to find if there is any STA or P2P-Client is connected
10103 */
10104VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10105{
10106 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10107}
Jeff Johnsone7245742012-09-05 17:12:55 -070010108
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010109int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10110{
10111 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10112 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010113 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010114
10115 pScanInfo = &pHddCtx->scan_info;
10116 if (pScanInfo->mScanPending)
10117 {
10118 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10119 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10120 eCSR_SCAN_ABORT_DEFAULT);
10121
10122 status = wait_for_completion_interruptible_timeout(
10123 &pScanInfo->abortscan_event_var,
10124 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010125 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010126 {
10127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010128 "%s: Timeout or Interrupt occurred while waiting for abort"
10129 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010130 return -ETIMEDOUT;
10131 }
10132 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010133 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010134}
10135
Jeff Johnson295189b2012-06-20 16:38:30 -070010136//Register the module init/exit functions
10137module_init(hdd_module_init);
10138module_exit(hdd_module_exit);
10139
10140MODULE_LICENSE("Dual BSD/GPL");
10141MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10142MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10143
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010144module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10145 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010146
Jeff Johnson76052702013-04-16 13:55:05 -070010147module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010148 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010149
10150module_param(enable_dfs_chan_scan, int,
10151 S_IRUSR | S_IRGRP | S_IROTH);
10152
10153module_param(enable_11d, int,
10154 S_IRUSR | S_IRGRP | S_IROTH);
10155
10156module_param(country_code, charp,
10157 S_IRUSR | S_IRGRP | S_IROTH);