blob: d5c1f60a422f9bbbfb51aee2743fc71e78eaa5ac [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{
2016 hdd_config_t *pCfg;
2017 tANI_U8 *value = command;
2018 int val = 0, ret = 0, temp = 0;
2019
2020 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini))
2021 {
2022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2023 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2024 ret = -EINVAL;
2025 return ret;
2026 }
2027
2028 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2029 {
2030 value = value + 24;
2031 temp = kstrtou32(value, 10, &val);
2032 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2033 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2034 {
2035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2036 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2037 ret = -EFAULT;
2038 return ret;
2039 }
2040 pCfg->nActiveMaxChnTime = val;
2041 }
2042 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2043 {
2044 value = value + 24;
2045 temp = kstrtou32(value, 10, &val);
2046 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2047 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2048 {
2049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2050 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2051 ret = -EFAULT;
2052 return ret;
2053 }
2054 pCfg->nActiveMinChnTime = val;
2055 }
2056 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2057 {
2058 value = value + 25;
2059 temp = kstrtou32(value, 10, &val);
2060 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2061 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2062 {
2063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2064 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2065 ret = -EFAULT;
2066 return ret;
2067 }
2068 pCfg->nPassiveMaxChnTime = val;
2069 }
2070 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2071 {
2072 value = value + 25;
2073 temp = kstrtou32(value, 10, &val);
2074 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2075 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2076 {
2077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2078 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2079 ret = -EFAULT;
2080 return ret;
2081 }
2082 pCfg->nPassiveMinChnTime = val;
2083 }
2084 else
2085 {
2086 ret = -EINVAL;
2087 }
2088
2089 return ret;
2090}
2091
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002092static int hdd_driver_command(hdd_adapter_t *pAdapter,
2093 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002094{
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 hdd_priv_data_t priv_data;
2096 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002097 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002098
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002099 /*
2100 * Note that valid pointers are provided by caller
2101 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002102
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002103 /* copy to local struct to avoid numerous changes to legacy code */
2104 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002105
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002106 if (priv_data.total_len <= 0 ||
2107 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002108 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002109 hddLog(VOS_TRACE_LEVEL_WARN,
2110 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2111 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002112 ret = -EINVAL;
2113 goto exit;
2114 }
2115
2116 /* Allocate +1 for '\0' */
2117 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 if (!command)
2119 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002120 hddLog(VOS_TRACE_LEVEL_ERROR,
2121 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 ret = -ENOMEM;
2123 goto exit;
2124 }
2125
2126 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2127 {
2128 ret = -EFAULT;
2129 goto exit;
2130 }
2131
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002132 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002133 command[priv_data.total_len] = '\0';
2134
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002135 /* at one time the following block of code was conditional. braces
2136 * have been retained to avoid re-indenting the legacy code
2137 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002138 {
2139 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2140
2141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002142 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002143
2144 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2145 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302146 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2147 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2148 pAdapter->sessionId, (unsigned)
2149 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2150 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2151 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2152 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2154 sizeof(tSirMacAddr)))
2155 {
2156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002157 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002158 ret = -EFAULT;
2159 }
2160 }
Amar Singhal0974e402013-02-12 14:27:46 -08002161 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002162 {
Amar Singhal0974e402013-02-12 14:27:46 -08002163 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002164
Jeff Johnson295189b2012-06-20 16:38:30 -07002165 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002166
2167 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002168 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002170 "%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 -07002171 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002172 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302173 if(ret != 0)
2174 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002175 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002176 }
Kiet Lamf040f472013-11-20 21:15:23 +05302177 else if(strncmp(command, "SETWMMPS", 8) == 0)
2178 {
2179 tANI_U8 *ptr = command;
2180 ret = hdd_wmmps_helper(pAdapter, ptr);
2181 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002182 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2183 {
2184 char *country_code;
2185
2186 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002187
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002188 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002189 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002190#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302191 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002192#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002193 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2194 (void *)(tSmeChangeCountryCallback)
2195 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302196 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002197 if (eHAL_STATUS_SUCCESS == ret)
2198 {
2199 ret = wait_for_completion_interruptible_timeout(
2200 &pAdapter->change_country_code,
2201 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2202 if (0 >= ret)
2203 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302205 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002206 }
2207 }
2208 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002209 {
2210 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002211 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002212 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002213 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002214
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002215 }
2216 /*
2217 command should be a string having format
2218 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2219 */
Amar Singhal0974e402013-02-12 14:27:46 -08002220 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002221 {
Amar Singhal0974e402013-02-12 14:27:46 -08002222 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002223
2224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002225 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002226
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002227 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002228 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002229 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2230 {
2231 int suspend = 0;
2232 tANI_U8 *ptr = (tANI_U8*)command + 15;
2233
2234 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2236 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2237 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002238 hdd_set_wlan_suspend_mode(suspend);
2239 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002240#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2241 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2242 {
2243 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002244 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002245 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2246 eHalStatus status = eHAL_STATUS_SUCCESS;
2247
2248 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2249 value = value + 15;
2250
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002251 /* Convert the value from ascii to integer */
2252 ret = kstrtos8(value, 10, &rssi);
2253 if (ret < 0)
2254 {
2255 /* If the input value is greater than max value of datatype, then also
2256 kstrtou8 fails */
2257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2258 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002259 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002260 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2261 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2262 ret = -EINVAL;
2263 goto exit;
2264 }
2265
Srinivas Girigowdade697412013-02-14 16:31:48 -08002266 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002267
Srinivas Girigowdade697412013-02-14 16:31:48 -08002268 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2269 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2270 {
2271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2272 "Neighbor lookup threshold value %d is out of range"
2273 " (Min: %d Max: %d)", lookUpThreshold,
2274 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2275 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2276 ret = -EINVAL;
2277 goto exit;
2278 }
2279
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302280 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2281 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2282 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2284 "%s: Received Command to Set Roam trigger"
2285 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2286
2287 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2288 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2289 if (eHAL_STATUS_SUCCESS != status)
2290 {
2291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2292 "%s: Failed to set roam trigger, try again", __func__);
2293 ret = -EPERM;
2294 goto exit;
2295 }
2296
2297 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302298 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002299 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2300 }
2301 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2302 {
2303 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2304 int rssi = (-1) * lookUpThreshold;
2305 char extra[32];
2306 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302307 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2308 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2309 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002310 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002311 if (copy_to_user(priv_data.buf, &extra, len + 1))
2312 {
2313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2314 "%s: failed to copy data to user buffer", __func__);
2315 ret = -EFAULT;
2316 goto exit;
2317 }
2318 }
2319 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2320 {
2321 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002322 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002323 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002324
Srinivas Girigowdade697412013-02-14 16:31:48 -08002325 /* input refresh period is in terms of seconds */
2326 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2327 value = value + 18;
2328 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002329 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002330 if (ret < 0)
2331 {
2332 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002333 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002335 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002336 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002337 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2338 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002339 ret = -EINVAL;
2340 goto exit;
2341 }
2342
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002343 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2344 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002345 {
2346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002347 "Roam scan period value %d is out of range"
2348 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002349 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2350 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002351 ret = -EINVAL;
2352 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302353 }
2354 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2355 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2356 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002357 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002358
2359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2360 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002361 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002362
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002363 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2364 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002365 }
2366 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2367 {
2368 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2369 char extra[32];
2370 tANI_U8 len = 0;
2371
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302372 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2373 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2374 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002375 len = scnprintf(extra, sizeof(extra), "%s %d",
2376 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002377 /* Returned value is in units of seconds */
2378 if (copy_to_user(priv_data.buf, &extra, len + 1))
2379 {
2380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2381 "%s: failed to copy data to user buffer", __func__);
2382 ret = -EFAULT;
2383 goto exit;
2384 }
2385 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002386 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2387 {
2388 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002389 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002390 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002391
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002392 /* input refresh period is in terms of seconds */
2393 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2394 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002395
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002396 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002397 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002398 if (ret < 0)
2399 {
2400 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002401 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002403 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002404 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002405 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2406 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2407 ret = -EINVAL;
2408 goto exit;
2409 }
2410
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002411 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2412 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2413 {
2414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2415 "Neighbor scan results refresh period value %d is out of range"
2416 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2417 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2418 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2419 ret = -EINVAL;
2420 goto exit;
2421 }
2422 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2423
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2425 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002426 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002427
2428 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2429 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2430 }
2431 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2432 {
2433 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2434 char extra[32];
2435 tANI_U8 len = 0;
2436
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002437 len = scnprintf(extra, sizeof(extra), "%s %d",
2438 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002439 /* Returned value is in units of seconds */
2440 if (copy_to_user(priv_data.buf, &extra, len + 1))
2441 {
2442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2443 "%s: failed to copy data to user buffer", __func__);
2444 ret = -EFAULT;
2445 goto exit;
2446 }
2447 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002448#ifdef FEATURE_WLAN_LFR
2449 /* SETROAMMODE */
2450 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2451 {
2452 tANI_U8 *value = command;
2453 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2454
2455 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2456 value = value + SIZE_OF_SETROAMMODE + 1;
2457
2458 /* Convert the value from ascii to integer */
2459 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2460 if (ret < 0)
2461 {
2462 /* If the input value is greater than max value of datatype, then also
2463 kstrtou8 fails */
2464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2465 "%s: kstrtou8 failed range [%d - %d]", __func__,
2466 CFG_LFR_FEATURE_ENABLED_MIN,
2467 CFG_LFR_FEATURE_ENABLED_MAX);
2468 ret = -EINVAL;
2469 goto exit;
2470 }
2471 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2472 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2473 {
2474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2475 "Roam Mode value %d is out of range"
2476 " (Min: %d Max: %d)", roamMode,
2477 CFG_LFR_FEATURE_ENABLED_MIN,
2478 CFG_LFR_FEATURE_ENABLED_MAX);
2479 ret = -EINVAL;
2480 goto exit;
2481 }
2482
2483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2484 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2485 /*
2486 * Note that
2487 * SETROAMMODE 0 is to enable LFR while
2488 * SETROAMMODE 1 is to disable LFR, but
2489 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2490 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2491 */
2492 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2493 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2494 else
2495 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2496
2497 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2498 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2499 }
2500 /* GETROAMMODE */
2501 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2502 {
2503 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2504 char extra[32];
2505 tANI_U8 len = 0;
2506
2507 /*
2508 * roamMode value shall be inverted because the sementics is different.
2509 */
2510 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2511 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2512 else
2513 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2514
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002515 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002516 if (copy_to_user(priv_data.buf, &extra, len + 1))
2517 {
2518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2519 "%s: failed to copy data to user buffer", __func__);
2520 ret = -EFAULT;
2521 goto exit;
2522 }
2523 }
2524#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002525#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002526#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002527 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2528 {
2529 tANI_U8 *value = command;
2530 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2531
2532 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2533 value = value + 13;
2534 /* Convert the value from ascii to integer */
2535 ret = kstrtou8(value, 10, &roamRssiDiff);
2536 if (ret < 0)
2537 {
2538 /* If the input value is greater than max value of datatype, then also
2539 kstrtou8 fails */
2540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2541 "%s: kstrtou8 failed range [%d - %d]", __func__,
2542 CFG_ROAM_RSSI_DIFF_MIN,
2543 CFG_ROAM_RSSI_DIFF_MAX);
2544 ret = -EINVAL;
2545 goto exit;
2546 }
2547
2548 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2549 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2550 {
2551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2552 "Roam rssi diff value %d is out of range"
2553 " (Min: %d Max: %d)", roamRssiDiff,
2554 CFG_ROAM_RSSI_DIFF_MIN,
2555 CFG_ROAM_RSSI_DIFF_MAX);
2556 ret = -EINVAL;
2557 goto exit;
2558 }
2559
2560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2561 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2562
2563 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2564 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2565 }
2566 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2567 {
2568 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2569 char extra[32];
2570 tANI_U8 len = 0;
2571
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302572 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2573 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2574 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002575 len = scnprintf(extra, sizeof(extra), "%s %d",
2576 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002577 if (copy_to_user(priv_data.buf, &extra, len + 1))
2578 {
2579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2580 "%s: failed to copy data to user buffer", __func__);
2581 ret = -EFAULT;
2582 goto exit;
2583 }
2584 }
2585#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002586#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002587 else if (strncmp(command, "GETBAND", 7) == 0)
2588 {
2589 int band = -1;
2590 char extra[32];
2591 tANI_U8 len = 0;
2592 hdd_getBand_helper(pHddCtx, &band);
2593
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302594 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2595 TRACE_CODE_HDD_GETBAND_IOCTL,
2596 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002597 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002598 if (copy_to_user(priv_data.buf, &extra, len + 1))
2599 {
2600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2601 "%s: failed to copy data to user buffer", __func__);
2602 ret = -EFAULT;
2603 goto exit;
2604 }
2605 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002606 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2607 {
2608 tANI_U8 *value = command;
2609 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2610 tANI_U8 numChannels = 0;
2611 eHalStatus status = eHAL_STATUS_SUCCESS;
2612
2613 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2614 if (eHAL_STATUS_SUCCESS != status)
2615 {
2616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2617 "%s: Failed to parse channel list information", __func__);
2618 ret = -EINVAL;
2619 goto exit;
2620 }
2621
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302622 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2623 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2624 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002625 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2626 {
2627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2628 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2629 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2630 ret = -EINVAL;
2631 goto exit;
2632 }
2633 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2634 numChannels);
2635 if (eHAL_STATUS_SUCCESS != status)
2636 {
2637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2638 "%s: Failed to update channel list information", __func__);
2639 ret = -EINVAL;
2640 goto exit;
2641 }
2642 }
2643 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2644 {
2645 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2646 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002647 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002648 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002649 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002650
2651 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2652 ChannelList, &numChannels ))
2653 {
2654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2655 "%s: failed to get roam scan channel list", __func__);
2656 ret = -EFAULT;
2657 goto exit;
2658 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302659 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2660 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2661 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002662 /* output channel list is of the format
2663 [Number of roam scan channels][Channel1][Channel2]... */
2664 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002665 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002666 for (j = 0; (j < numChannels); j++)
2667 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002668 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2669 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002670 }
2671
2672 if (copy_to_user(priv_data.buf, &extra, len + 1))
2673 {
2674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2675 "%s: failed to copy data to user buffer", __func__);
2676 ret = -EFAULT;
2677 goto exit;
2678 }
2679 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002680 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2681 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002682 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002683 char extra[32];
2684 tANI_U8 len = 0;
2685
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002686 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002687 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002688 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002689 hdd_is_okc_mode_enabled(pHddCtx) &&
2690 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2691 {
2692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002693 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002694 " hence this operation is not permitted!", __func__);
2695 ret = -EPERM;
2696 goto exit;
2697 }
2698
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002699 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002700 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002701 if (copy_to_user(priv_data.buf, &extra, len + 1))
2702 {
2703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2704 "%s: failed to copy data to user buffer", __func__);
2705 ret = -EFAULT;
2706 goto exit;
2707 }
2708 }
2709 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2710 {
2711 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2712 char extra[32];
2713 tANI_U8 len = 0;
2714
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002715 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002716 then this operation is not permitted (return FAILURE) */
2717 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002718 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002719 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2720 {
2721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002722 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002723 " hence this operation is not permitted!", __func__);
2724 ret = -EPERM;
2725 goto exit;
2726 }
2727
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002728 len = scnprintf(extra, sizeof(extra), "%s %d",
2729 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002730 if (copy_to_user(priv_data.buf, &extra, len + 1))
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: failed to copy data to user buffer", __func__);
2734 ret = -EFAULT;
2735 goto exit;
2736 }
2737 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002738 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002739 {
2740 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2741 char extra[32];
2742 tANI_U8 len = 0;
2743
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002744 len = scnprintf(extra, sizeof(extra), "%s %d",
2745 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002746 if (copy_to_user(priv_data.buf, &extra, len + 1))
2747 {
2748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2749 "%s: failed to copy data to user buffer", __func__);
2750 ret = -EFAULT;
2751 goto exit;
2752 }
2753 }
2754 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2755 {
2756 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2757 char extra[32];
2758 tANI_U8 len = 0;
2759
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002760 len = scnprintf(extra, sizeof(extra), "%s %d",
2761 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002762 if (copy_to_user(priv_data.buf, &extra, len + 1))
2763 {
2764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2765 "%s: failed to copy data to user buffer", __func__);
2766 ret = -EFAULT;
2767 goto exit;
2768 }
2769 }
2770 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2771 {
2772 tANI_U8 *value = command;
2773 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2774
2775 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2776 value = value + 26;
2777 /* Convert the value from ascii to integer */
2778 ret = kstrtou8(value, 10, &minTime);
2779 if (ret < 0)
2780 {
2781 /* If the input value is greater than max value of datatype, then also
2782 kstrtou8 fails */
2783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2784 "%s: kstrtou8 failed range [%d - %d]", __func__,
2785 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2786 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2787 ret = -EINVAL;
2788 goto exit;
2789 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002790 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2791 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2792 {
2793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2794 "scan min channel time value %d is out of range"
2795 " (Min: %d Max: %d)", minTime,
2796 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2797 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2798 ret = -EINVAL;
2799 goto exit;
2800 }
2801
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302802 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2803 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2804 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2806 "%s: Received Command to change channel min time = %d", __func__, minTime);
2807
2808 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2809 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2810 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002811 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2812 {
2813 tANI_U8 *value = command;
2814 tANI_U8 channel = 0;
2815 tANI_U8 dwellTime = 0;
2816 tANI_U8 bufLen = 0;
2817 tANI_U8 *buf = NULL;
2818 tSirMacAddr targetApBssid;
2819 eHalStatus status = eHAL_STATUS_SUCCESS;
2820 struct ieee80211_channel chan;
2821 tANI_U8 finalLen = 0;
2822 tANI_U8 *finalBuf = NULL;
2823 tANI_U8 temp = 0;
2824 u64 cookie;
2825 hdd_station_ctx_t *pHddStaCtx = NULL;
2826 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2827
2828 /* if not associated, no need to send action frame */
2829 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2830 {
2831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2832 ret = -EINVAL;
2833 goto exit;
2834 }
2835
2836 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2837 &dwellTime, &buf, &bufLen);
2838 if (eHAL_STATUS_SUCCESS != status)
2839 {
2840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2841 "%s: Failed to parse send action frame data", __func__);
2842 ret = -EINVAL;
2843 goto exit;
2844 }
2845
2846 /* if the target bssid is different from currently associated AP,
2847 then no need to send action frame */
2848 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2849 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2850 {
2851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2852 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002853 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002854 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002855 goto exit;
2856 }
2857
2858 /* if the channel number is different from operating channel then
2859 no need to send action frame */
2860 if (channel != pHddStaCtx->conn_info.operationChannel)
2861 {
2862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2863 "%s: channel(%d) is different from operating channel(%d)",
2864 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2865 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002866 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002867 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002868 goto exit;
2869 }
2870 chan.center_freq = sme_ChnToFreq(channel);
2871
2872 finalLen = bufLen + 24;
2873 finalBuf = vos_mem_malloc(finalLen);
2874 if (NULL == finalBuf)
2875 {
2876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2877 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002878 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002879 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002880 goto exit;
2881 }
2882 vos_mem_zero(finalBuf, finalLen);
2883
2884 /* Fill subtype */
2885 temp = SIR_MAC_MGMT_ACTION << 4;
2886 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2887
2888 /* Fill type */
2889 temp = SIR_MAC_MGMT_FRAME;
2890 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2891
2892 /* Fill destination address (bssid of the AP) */
2893 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2894
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002895 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002896 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2897
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002898 /* Fill BSSID (AP mac address) */
2899 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002900
2901 /* Fill received buffer from 24th address */
2902 vos_mem_copy(finalBuf + 24, buf, bufLen);
2903
Jeff Johnson11c33152013-04-16 17:52:40 -07002904 /* done with the parsed buffer */
2905 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002906 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002907
DARAM SUDHA39eede62014-02-12 11:16:40 +05302908 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2910 &(pAdapter->wdev),
2911#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002912 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002913#endif
2914 &chan, 0,
2915#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2916 NL80211_CHAN_HT20, 1,
2917#endif
2918 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002919 1, &cookie );
2920 vos_mem_free(finalBuf);
2921 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002922 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2923 {
2924 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2925 char extra[32];
2926 tANI_U8 len = 0;
2927
2928 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002929 len = scnprintf(extra, sizeof(extra), "%s %d",
2930 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302931 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2932 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2933 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002934 if (copy_to_user(priv_data.buf, &extra, len + 1))
2935 {
2936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2937 "%s: failed to copy data to user buffer", __func__);
2938 ret = -EFAULT;
2939 goto exit;
2940 }
2941 }
2942 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2943 {
2944 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002945 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002946
2947 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2948 value = value + 19;
2949 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002950 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002951 if (ret < 0)
2952 {
2953 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002954 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002956 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002957 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2958 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2959 ret = -EINVAL;
2960 goto exit;
2961 }
2962
2963 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2964 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2965 {
2966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2967 "lfr mode value %d is out of range"
2968 " (Min: %d Max: %d)", maxTime,
2969 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2970 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2971 ret = -EINVAL;
2972 goto exit;
2973 }
2974
2975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2976 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2977
2978 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2979 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2980 }
2981 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2982 {
2983 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2984 char extra[32];
2985 tANI_U8 len = 0;
2986
2987 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002988 len = scnprintf(extra, sizeof(extra), "%s %d",
2989 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002990 if (copy_to_user(priv_data.buf, &extra, len + 1))
2991 {
2992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2993 "%s: failed to copy data to user buffer", __func__);
2994 ret = -EFAULT;
2995 goto exit;
2996 }
2997 }
2998 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2999 {
3000 tANI_U8 *value = command;
3001 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3002
3003 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3004 value = value + 16;
3005 /* Convert the value from ascii to integer */
3006 ret = kstrtou16(value, 10, &val);
3007 if (ret < 0)
3008 {
3009 /* If the input value is greater than max value of datatype, then also
3010 kstrtou16 fails */
3011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3012 "%s: kstrtou16 failed range [%d - %d]", __func__,
3013 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3014 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3015 ret = -EINVAL;
3016 goto exit;
3017 }
3018
3019 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3020 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3021 {
3022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3023 "scan home time value %d is out of range"
3024 " (Min: %d Max: %d)", val,
3025 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3026 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3027 ret = -EINVAL;
3028 goto exit;
3029 }
3030
3031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3032 "%s: Received Command to change scan home time = %d", __func__, val);
3033
3034 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3035 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3036 }
3037 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3038 {
3039 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3040 char extra[32];
3041 tANI_U8 len = 0;
3042
3043 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003044 len = scnprintf(extra, sizeof(extra), "%s %d",
3045 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003046 if (copy_to_user(priv_data.buf, &extra, len + 1))
3047 {
3048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3049 "%s: failed to copy data to user buffer", __func__);
3050 ret = -EFAULT;
3051 goto exit;
3052 }
3053 }
3054 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3055 {
3056 tANI_U8 *value = command;
3057 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3058
3059 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3060 value = value + 17;
3061 /* Convert the value from ascii to integer */
3062 ret = kstrtou8(value, 10, &val);
3063 if (ret < 0)
3064 {
3065 /* If the input value is greater than max value of datatype, then also
3066 kstrtou8 fails */
3067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3068 "%s: kstrtou8 failed range [%d - %d]", __func__,
3069 CFG_ROAM_INTRA_BAND_MIN,
3070 CFG_ROAM_INTRA_BAND_MAX);
3071 ret = -EINVAL;
3072 goto exit;
3073 }
3074
3075 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3076 (val > CFG_ROAM_INTRA_BAND_MAX))
3077 {
3078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3079 "intra band mode value %d is out of range"
3080 " (Min: %d Max: %d)", val,
3081 CFG_ROAM_INTRA_BAND_MIN,
3082 CFG_ROAM_INTRA_BAND_MAX);
3083 ret = -EINVAL;
3084 goto exit;
3085 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3087 "%s: Received Command to change intra band = %d", __func__, val);
3088
3089 pHddCtx->cfg_ini->nRoamIntraBand = val;
3090 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3091 }
3092 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3093 {
3094 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3095 char extra[32];
3096 tANI_U8 len = 0;
3097
3098 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003099 len = scnprintf(extra, sizeof(extra), "%s %d",
3100 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003101 if (copy_to_user(priv_data.buf, &extra, len + 1))
3102 {
3103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3104 "%s: failed to copy data to user buffer", __func__);
3105 ret = -EFAULT;
3106 goto exit;
3107 }
3108 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003109 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3110 {
3111 tANI_U8 *value = command;
3112 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3113
3114 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3115 value = value + 15;
3116 /* Convert the value from ascii to integer */
3117 ret = kstrtou8(value, 10, &nProbes);
3118 if (ret < 0)
3119 {
3120 /* If the input value is greater than max value of datatype, then also
3121 kstrtou8 fails */
3122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3123 "%s: kstrtou8 failed range [%d - %d]", __func__,
3124 CFG_ROAM_SCAN_N_PROBES_MIN,
3125 CFG_ROAM_SCAN_N_PROBES_MAX);
3126 ret = -EINVAL;
3127 goto exit;
3128 }
3129
3130 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3131 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3132 {
3133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3134 "NProbes value %d is out of range"
3135 " (Min: %d Max: %d)", nProbes,
3136 CFG_ROAM_SCAN_N_PROBES_MIN,
3137 CFG_ROAM_SCAN_N_PROBES_MAX);
3138 ret = -EINVAL;
3139 goto exit;
3140 }
3141
3142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3143 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3144
3145 pHddCtx->cfg_ini->nProbes = nProbes;
3146 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3147 }
3148 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3149 {
3150 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3151 char extra[32];
3152 tANI_U8 len = 0;
3153
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003154 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003155 if (copy_to_user(priv_data.buf, &extra, len + 1))
3156 {
3157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3158 "%s: failed to copy data to user buffer", __func__);
3159 ret = -EFAULT;
3160 goto exit;
3161 }
3162 }
3163 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3164 {
3165 tANI_U8 *value = command;
3166 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3167
3168 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3169 /* input value is in units of msec */
3170 value = value + 20;
3171 /* Convert the value from ascii to integer */
3172 ret = kstrtou16(value, 10, &homeAwayTime);
3173 if (ret < 0)
3174 {
3175 /* If the input value is greater than max value of datatype, then also
3176 kstrtou8 fails */
3177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3178 "%s: kstrtou8 failed range [%d - %d]", __func__,
3179 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3180 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3181 ret = -EINVAL;
3182 goto exit;
3183 }
3184
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003185 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3186 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3187 {
3188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3189 "homeAwayTime value %d is out of range"
3190 " (Min: %d Max: %d)", homeAwayTime,
3191 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3192 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3193 ret = -EINVAL;
3194 goto exit;
3195 }
3196
3197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3198 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003199 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3200 {
3201 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3202 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3203 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003204 }
3205 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3206 {
3207 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3208 char extra[32];
3209 tANI_U8 len = 0;
3210
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003211 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003212 if (copy_to_user(priv_data.buf, &extra, len + 1))
3213 {
3214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3215 "%s: failed to copy data to user buffer", __func__);
3216 ret = -EFAULT;
3217 goto exit;
3218 }
3219 }
3220 else if (strncmp(command, "REASSOC", 7) == 0)
3221 {
3222 tANI_U8 *value = command;
3223 tANI_U8 channel = 0;
3224 tSirMacAddr targetApBssid;
3225 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003226#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3227 tCsrHandoffRequest handoffInfo;
3228#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003229 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003230 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3231
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003232 /* if not associated, no need to proceed with reassoc */
3233 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3234 {
3235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3236 ret = -EINVAL;
3237 goto exit;
3238 }
3239
3240 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3241 if (eHAL_STATUS_SUCCESS != status)
3242 {
3243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3244 "%s: Failed to parse reassoc command data", __func__);
3245 ret = -EINVAL;
3246 goto exit;
3247 }
3248
3249 /* if the target bssid is same as currently associated AP,
3250 then no need to proceed with reassoc */
3251 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3252 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3253 {
3254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3255 ret = -EINVAL;
3256 goto exit;
3257 }
3258
3259 /* Check channel number is a valid channel number */
3260 if(VOS_STATUS_SUCCESS !=
3261 wlan_hdd_validate_operation_channel(pAdapter, channel))
3262 {
3263 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003264 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003265 return -EINVAL;
3266 }
3267
3268 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003269#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3270 handoffInfo.channel = channel;
3271 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3272 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3273#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003274 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003275 else if (strncmp(command, "SETWESMODE", 10) == 0)
3276 {
3277 tANI_U8 *value = command;
3278 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3279
3280 /* Move pointer to ahead of SETWESMODE<delimiter> */
3281 value = value + 11;
3282 /* Convert the value from ascii to integer */
3283 ret = kstrtou8(value, 10, &wesMode);
3284 if (ret < 0)
3285 {
3286 /* If the input value is greater than max value of datatype, then also
3287 kstrtou8 fails */
3288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3289 "%s: kstrtou8 failed range [%d - %d]", __func__,
3290 CFG_ENABLE_WES_MODE_NAME_MIN,
3291 CFG_ENABLE_WES_MODE_NAME_MAX);
3292 ret = -EINVAL;
3293 goto exit;
3294 }
3295
3296 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3297 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3298 {
3299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3300 "WES Mode value %d is out of range"
3301 " (Min: %d Max: %d)", wesMode,
3302 CFG_ENABLE_WES_MODE_NAME_MIN,
3303 CFG_ENABLE_WES_MODE_NAME_MAX);
3304 ret = -EINVAL;
3305 goto exit;
3306 }
3307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3308 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3309
3310 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3311 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3312 }
3313 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3314 {
3315 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3316 char extra[32];
3317 tANI_U8 len = 0;
3318
Arif Hussain826d9412013-11-12 16:44:54 -08003319 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003320 if (copy_to_user(priv_data.buf, &extra, len + 1))
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3323 "%s: failed to copy data to user buffer", __func__);
3324 ret = -EFAULT;
3325 goto exit;
3326 }
3327 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003328#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003329#ifdef FEATURE_WLAN_LFR
3330 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3331 {
3332 tANI_U8 *value = command;
3333 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3334
3335 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3336 value = value + 12;
3337 /* Convert the value from ascii to integer */
3338 ret = kstrtou8(value, 10, &lfrMode);
3339 if (ret < 0)
3340 {
3341 /* If the input value is greater than max value of datatype, then also
3342 kstrtou8 fails */
3343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3344 "%s: kstrtou8 failed range [%d - %d]", __func__,
3345 CFG_LFR_FEATURE_ENABLED_MIN,
3346 CFG_LFR_FEATURE_ENABLED_MAX);
3347 ret = -EINVAL;
3348 goto exit;
3349 }
3350
3351 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3352 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3353 {
3354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3355 "lfr mode value %d is out of range"
3356 " (Min: %d Max: %d)", lfrMode,
3357 CFG_LFR_FEATURE_ENABLED_MIN,
3358 CFG_LFR_FEATURE_ENABLED_MAX);
3359 ret = -EINVAL;
3360 goto exit;
3361 }
3362
3363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3364 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3365
3366 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3367 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3368 }
3369#endif
3370#ifdef WLAN_FEATURE_VOWIFI_11R
3371 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3372 {
3373 tANI_U8 *value = command;
3374 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3375
3376 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3377 value = value + 18;
3378 /* Convert the value from ascii to integer */
3379 ret = kstrtou8(value, 10, &ft);
3380 if (ret < 0)
3381 {
3382 /* If the input value is greater than max value of datatype, then also
3383 kstrtou8 fails */
3384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3385 "%s: kstrtou8 failed range [%d - %d]", __func__,
3386 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3387 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3388 ret = -EINVAL;
3389 goto exit;
3390 }
3391
3392 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3393 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3394 {
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3396 "ft mode value %d is out of range"
3397 " (Min: %d Max: %d)", ft,
3398 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3399 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3400 ret = -EINVAL;
3401 goto exit;
3402 }
3403
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3405 "%s: Received Command to change ft mode = %d", __func__, ft);
3406
3407 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3408 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3409 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303410
3411 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3412 {
3413 tANI_U8 *value = command;
3414 tSirMacAddr targetApBssid;
3415 tANI_U8 trigger = 0;
3416 eHalStatus status = eHAL_STATUS_SUCCESS;
3417 hdd_station_ctx_t *pHddStaCtx = NULL;
3418 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3419
3420 /* if not associated, no need to proceed with reassoc */
3421 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3422 {
3423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3424 ret = -EINVAL;
3425 goto exit;
3426 }
3427
3428 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3429 if (eHAL_STATUS_SUCCESS != status)
3430 {
3431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3432 "%s: Failed to parse reassoc command data", __func__);
3433 ret = -EINVAL;
3434 goto exit;
3435 }
3436
3437 /* if the target bssid is same as currently associated AP,
3438 then no need to proceed with reassoc */
3439 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3440 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3441 {
3442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3443 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3444 __func__);
3445 ret = -EINVAL;
3446 goto exit;
3447 }
3448
3449 /* Proceed with scan/roam */
3450 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3451 &targetApBssid[0],
3452 (tSmeFastRoamTrigger)(trigger));
3453 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003454#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003455#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003456 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3457 {
3458 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003459 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003460
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003461 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003462 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003463 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003464 hdd_is_okc_mode_enabled(pHddCtx) &&
3465 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3466 {
3467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003468 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003469 " hence this operation is not permitted!", __func__);
3470 ret = -EPERM;
3471 goto exit;
3472 }
3473
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003474 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3475 value = value + 11;
3476 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003477 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003478 if (ret < 0)
3479 {
3480 /* If the input value is greater than max value of datatype, then also
3481 kstrtou8 fails */
3482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3483 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003484 CFG_ESE_FEATURE_ENABLED_MIN,
3485 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003486 ret = -EINVAL;
3487 goto exit;
3488 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003489 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3490 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003491 {
3492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003493 "Ese mode value %d is out of range"
3494 " (Min: %d Max: %d)", eseMode,
3495 CFG_ESE_FEATURE_ENABLED_MIN,
3496 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003497 ret = -EINVAL;
3498 goto exit;
3499 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003501 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003502
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003503 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3504 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003505 }
3506#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003507 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3508 {
3509 tANI_U8 *value = command;
3510 tANI_BOOLEAN roamScanControl = 0;
3511
3512 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3513 value = value + 19;
3514 /* Convert the value from ascii to integer */
3515 ret = kstrtou8(value, 10, &roamScanControl);
3516 if (ret < 0)
3517 {
3518 /* If the input value is greater than max value of datatype, then also
3519 kstrtou8 fails */
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3521 "%s: kstrtou8 failed ", __func__);
3522 ret = -EINVAL;
3523 goto exit;
3524 }
3525
3526 if (0 != roamScanControl)
3527 {
3528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3529 "roam scan control invalid value = %d",
3530 roamScanControl);
3531 ret = -EINVAL;
3532 goto exit;
3533 }
3534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3535 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3536
3537 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3538 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003539#ifdef FEATURE_WLAN_OKC
3540 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3541 {
3542 tANI_U8 *value = command;
3543 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3544
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003545 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003546 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003547 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003548 hdd_is_okc_mode_enabled(pHddCtx) &&
3549 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3550 {
3551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003552 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003553 " hence this operation is not permitted!", __func__);
3554 ret = -EPERM;
3555 goto exit;
3556 }
3557
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003558 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3559 value = value + 11;
3560 /* Convert the value from ascii to integer */
3561 ret = kstrtou8(value, 10, &okcMode);
3562 if (ret < 0)
3563 {
3564 /* If the input value is greater than max value of datatype, then also
3565 kstrtou8 fails */
3566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3567 "%s: kstrtou8 failed range [%d - %d]", __func__,
3568 CFG_OKC_FEATURE_ENABLED_MIN,
3569 CFG_OKC_FEATURE_ENABLED_MAX);
3570 ret = -EINVAL;
3571 goto exit;
3572 }
3573
3574 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3575 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3576 {
3577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3578 "Okc mode value %d is out of range"
3579 " (Min: %d Max: %d)", okcMode,
3580 CFG_OKC_FEATURE_ENABLED_MIN,
3581 CFG_OKC_FEATURE_ENABLED_MAX);
3582 ret = -EINVAL;
3583 goto exit;
3584 }
3585
3586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3587 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3588
3589 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3590 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003591#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003592 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3593 {
3594 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3595 char extra[32];
3596 tANI_U8 len = 0;
3597
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003598 len = scnprintf(extra, sizeof(extra), "%s %d",
3599 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003600 if (copy_to_user(priv_data.buf, &extra, len + 1))
3601 {
3602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3603 "%s: failed to copy data to user buffer", __func__);
3604 ret = -EFAULT;
3605 goto exit;
3606 }
3607 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303608#ifdef WLAN_FEATURE_PACKET_FILTERING
3609 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3610 {
3611 tANI_U8 filterType = 0;
3612 tANI_U8 *value = command;
3613
3614 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3615 value = value + 22;
3616
3617 /* Convert the value from ascii to integer */
3618 ret = kstrtou8(value, 10, &filterType);
3619 if (ret < 0)
3620 {
3621 /* If the input value is greater than max value of datatype,
3622 * then also kstrtou8 fails
3623 */
3624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3625 "%s: kstrtou8 failed range ", __func__);
3626 ret = -EINVAL;
3627 goto exit;
3628 }
3629
3630 if (filterType != 0 && filterType != 1)
3631 {
3632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3633 "%s: Accepted Values are 0 and 1 ", __func__);
3634 ret = -EINVAL;
3635 goto exit;
3636 }
3637 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3638 pAdapter->sessionId);
3639 }
3640#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303641 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3642 {
Kiet Lam94fd2922014-06-18 19:12:43 -07003643 char *bcMode;
3644 bcMode = command + 11;
3645 if ('1' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303646 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003648 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303649
3650 pHddCtx->btCoexModeSet = TRUE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303651 }
Kiet Lam94fd2922014-06-18 19:12:43 -07003652 else if ('2' == *bcMode)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303653 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lam94fd2922014-06-18 19:12:43 -07003655 FL("BTCOEXMODE %d"), *bcMode);
c_hpothu9b781ba2013-12-30 20:57:45 +05303656
3657 pHddCtx->btCoexModeSet = FALSE;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303658 }
3659 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003660 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3661 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3663 FL("making default scan to ACTIVE"));
3664 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003665 }
3666 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3667 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3669 FL("making default scan to PASSIVE"));
3670 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003671 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303672 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3673 {
3674 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3675 char extra[32];
3676 tANI_U8 len = 0;
3677
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303678 memset(extra, 0, sizeof(extra));
3679 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3680 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303681 {
3682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3683 "%s: failed to copy data to user buffer", __func__);
3684 ret = -EFAULT;
3685 goto exit;
3686 }
3687 ret = len;
3688 }
3689 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3690 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303691 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303692 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003693 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3694 {
3695 tANI_U8 filterType = 0;
3696 tANI_U8 *value;
3697 value = command + 9;
3698
3699 /* Convert the value from ascii to integer */
3700 ret = kstrtou8(value, 10, &filterType);
3701 if (ret < 0)
3702 {
3703 /* If the input value is greater than max value of datatype,
3704 * then also kstrtou8 fails
3705 */
3706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3707 "%s: kstrtou8 failed range ", __func__);
3708 ret = -EINVAL;
3709 goto exit;
3710 }
3711 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3712 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3713 {
3714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3715 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3716 " 2-Sink ", __func__);
3717 ret = -EINVAL;
3718 goto exit;
3719 }
3720 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3721 pHddCtx->drvr_miracast = filterType;
3722 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3723 }
Leo Chang614d2072013-08-22 14:59:44 -07003724 else if (strncmp(command, "SETMCRATE", 9) == 0)
3725 {
Leo Chang614d2072013-08-22 14:59:44 -07003726 tANI_U8 *value = command;
3727 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003728 tSirRateUpdateInd *rateUpdate;
3729 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003730
3731 /* Only valid for SAP mode */
3732 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3733 {
3734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3735 "%s: SAP mode is not running", __func__);
3736 ret = -EFAULT;
3737 goto exit;
3738 }
3739
3740 /* Move pointer to ahead of SETMCRATE<delimiter> */
3741 /* input value is in units of hundred kbps */
3742 value = value + 10;
3743 /* Convert the value from ascii to integer, decimal base */
3744 ret = kstrtouint(value, 10, &targetRate);
3745
Leo Chang1f98cbd2013-10-17 15:03:52 -07003746 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3747 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003748 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003749 hddLog(VOS_TRACE_LEVEL_ERROR,
3750 "%s: SETMCRATE indication alloc fail", __func__);
3751 ret = -EFAULT;
3752 goto exit;
3753 }
3754 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3755
3756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3757 "MC Target rate %d", targetRate);
3758 /* Ignore unicast */
3759 rateUpdate->ucastDataRate = -1;
3760 rateUpdate->mcastDataRate24GHz = targetRate;
3761 rateUpdate->mcastDataRate5GHz = targetRate;
3762 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3763 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3764 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3765 if (eHAL_STATUS_SUCCESS != status)
3766 {
3767 hddLog(VOS_TRACE_LEVEL_ERROR,
3768 "%s: SET_MC_RATE failed", __func__);
3769 vos_mem_free(rateUpdate);
3770 ret = -EFAULT;
3771 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003772 }
3773 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303774#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003775 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303776 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003777 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303778 }
3779#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003780#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003781 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3782 {
3783 tANI_U8 *value = command;
3784 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3785 tANI_U8 numChannels = 0;
3786 eHalStatus status = eHAL_STATUS_SUCCESS;
3787
3788 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3789 if (eHAL_STATUS_SUCCESS != status)
3790 {
3791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3792 "%s: Failed to parse channel list information", __func__);
3793 ret = -EINVAL;
3794 goto exit;
3795 }
3796
3797 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3798 {
3799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3800 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3801 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3802 ret = -EINVAL;
3803 goto exit;
3804 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003805 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003806 ChannelList,
3807 numChannels);
3808 if (eHAL_STATUS_SUCCESS != status)
3809 {
3810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3811 "%s: Failed to update channel list information", __func__);
3812 ret = -EINVAL;
3813 goto exit;
3814 }
3815 }
3816 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3817 {
3818 tANI_U8 *value = command;
3819 char extra[128] = {0};
3820 int len = 0;
3821 tANI_U8 tid = 0;
3822 hdd_station_ctx_t *pHddStaCtx = NULL;
3823 tAniTrafStrmMetrics tsmMetrics;
3824 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3825
3826 /* if not associated, return error */
3827 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3828 {
3829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3830 ret = -EINVAL;
3831 goto exit;
3832 }
3833
3834 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3835 value = value + 12;
3836 /* Convert the value from ascii to integer */
3837 ret = kstrtou8(value, 10, &tid);
3838 if (ret < 0)
3839 {
3840 /* If the input value is greater than max value of datatype, then also
3841 kstrtou8 fails */
3842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3843 "%s: kstrtou8 failed range [%d - %d]", __func__,
3844 TID_MIN_VALUE,
3845 TID_MAX_VALUE);
3846 ret = -EINVAL;
3847 goto exit;
3848 }
3849
3850 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3851 {
3852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3853 "tid value %d is out of range"
3854 " (Min: %d Max: %d)", tid,
3855 TID_MIN_VALUE,
3856 TID_MAX_VALUE);
3857 ret = -EINVAL;
3858 goto exit;
3859 }
3860
3861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3862 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3863
3864 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3865 {
3866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3867 "%s: failed to get tsm stats", __func__);
3868 ret = -EFAULT;
3869 goto exit;
3870 }
3871
3872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3873 "UplinkPktQueueDly(%d)\n"
3874 "UplinkPktQueueDlyHist[0](%d)\n"
3875 "UplinkPktQueueDlyHist[1](%d)\n"
3876 "UplinkPktQueueDlyHist[2](%d)\n"
3877 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303878 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003879 "UplinkPktLoss(%d)\n"
3880 "UplinkPktCount(%d)\n"
3881 "RoamingCount(%d)\n"
3882 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3883 tsmMetrics.UplinkPktQueueDlyHist[0],
3884 tsmMetrics.UplinkPktQueueDlyHist[1],
3885 tsmMetrics.UplinkPktQueueDlyHist[2],
3886 tsmMetrics.UplinkPktQueueDlyHist[3],
3887 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3888 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3889
3890 /* Output TSM stats is of the format
3891 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3892 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003893 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003894 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3895 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3896 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3897 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3898 tsmMetrics.RoamingDly);
3899
3900 if (copy_to_user(priv_data.buf, &extra, len + 1))
3901 {
3902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3903 "%s: failed to copy data to user buffer", __func__);
3904 ret = -EFAULT;
3905 goto exit;
3906 }
3907 }
3908 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3909 {
3910 tANI_U8 *value = command;
3911 tANI_U8 *cckmIe = NULL;
3912 tANI_U8 cckmIeLen = 0;
3913 eHalStatus status = eHAL_STATUS_SUCCESS;
3914
3915 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3916 if (eHAL_STATUS_SUCCESS != status)
3917 {
3918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3919 "%s: Failed to parse cckm ie data", __func__);
3920 ret = -EINVAL;
3921 goto exit;
3922 }
3923
3924 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3925 {
3926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3927 "%s: CCKM Ie input length is more than max[%d]", __func__,
3928 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003929 vos_mem_free(cckmIe);
3930 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003931 ret = -EINVAL;
3932 goto exit;
3933 }
3934 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003935 vos_mem_free(cckmIe);
3936 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003937 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003938 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3939 {
3940 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003941 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003942 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003943
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003944 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003945 if (eHAL_STATUS_SUCCESS != status)
3946 {
3947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003948 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003949 ret = -EINVAL;
3950 goto exit;
3951 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003952 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
3953 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
3954 hdd_indicateEseBcnReportNoResults (pAdapter,
3955 eseBcnReq.bcnReq[0].measurementToken,
3956 0x02, //BIT(1) set for measurement done
3957 0); // no BSS
3958 goto exit;
3959 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003960
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003961 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3962 if (eHAL_STATUS_SUCCESS != status)
3963 {
3964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3965 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3966 ret = -EINVAL;
3967 goto exit;
3968 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003969 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003970#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05303971 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
3972 {
3973 eHalStatus status;
3974 char buf[32], len;
3975 long waitRet;
3976 bcnMissRateContext_t getBcnMissRateCtx;
3977
3978 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3979
3980 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3981 {
3982 hddLog(VOS_TRACE_LEVEL_WARN,
3983 FL("GETBCNMISSRATE: STA is not in connected state"));
3984 ret = -1;
3985 goto exit;
3986 }
3987
3988 init_completion(&(getBcnMissRateCtx.completion));
3989 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
3990
3991 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
3992 pAdapter->sessionId,
3993 (void *)getBcnMissRateCB,
3994 (void *)(&getBcnMissRateCtx));
3995 if( eHAL_STATUS_SUCCESS != status)
3996 {
3997 hddLog(VOS_TRACE_LEVEL_INFO,
3998 FL("GETBCNMISSRATE: fail to post WDA cmd"));
3999 ret = -EINVAL;
4000 goto exit;
4001 }
4002
4003 waitRet = wait_for_completion_interruptible_timeout
4004 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4005 if(waitRet <= 0)
4006 {
4007 hddLog(VOS_TRACE_LEVEL_ERROR,
4008 FL("failed to wait on bcnMissRateComp %d"), ret);
4009
4010 //Make magic number to zero so that callback is not called.
4011 spin_lock(&hdd_context_lock);
4012 getBcnMissRateCtx.magic = 0x0;
4013 spin_unlock(&hdd_context_lock);
4014 ret = -EINVAL;
4015 goto exit;
4016 }
4017
4018 hddLog(VOS_TRACE_LEVEL_INFO,
4019 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4020
4021 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4022 if (copy_to_user(priv_data.buf, &buf, len + 1))
4023 {
4024 hddLog(VOS_TRACE_LEVEL_ERROR,
4025 "%s: failed to copy data to user buffer", __func__);
4026 ret = -EFAULT;
4027 goto exit;
4028 }
4029 ret = len;
4030 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004031 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304032 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4033 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4034 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004035 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4036 __func__, command);
4037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004038 }
4039exit:
4040 if (command)
4041 {
4042 kfree(command);
4043 }
4044 return ret;
4045}
4046
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004047#ifdef CONFIG_COMPAT
4048static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4049{
4050 struct {
4051 compat_uptr_t buf;
4052 int used_len;
4053 int total_len;
4054 } compat_priv_data;
4055 hdd_priv_data_t priv_data;
4056 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004057
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004058 /*
4059 * Note that pAdapter and ifr have already been verified by caller,
4060 * and HDD context has also been validated
4061 */
4062 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4063 sizeof(compat_priv_data))) {
4064 ret = -EFAULT;
4065 goto exit;
4066 }
4067 priv_data.buf = compat_ptr(compat_priv_data.buf);
4068 priv_data.used_len = compat_priv_data.used_len;
4069 priv_data.total_len = compat_priv_data.total_len;
4070 ret = hdd_driver_command(pAdapter, &priv_data);
4071 exit:
4072 return ret;
4073}
4074#else /* CONFIG_COMPAT */
4075static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4076{
4077 /* will never be invoked */
4078 return 0;
4079}
4080#endif /* CONFIG_COMPAT */
4081
4082static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4083{
4084 hdd_priv_data_t priv_data;
4085 int ret = 0;
4086
4087 /*
4088 * Note that pAdapter and ifr have already been verified by caller,
4089 * and HDD context has also been validated
4090 */
4091 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4092 ret = -EFAULT;
4093 } else {
4094 ret = hdd_driver_command(pAdapter, &priv_data);
4095 }
4096 return ret;
4097}
4098
4099int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4100{
4101 hdd_adapter_t *pAdapter;
4102 hdd_context_t *pHddCtx;
4103 int ret;
4104
4105 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4106 if (NULL == pAdapter) {
4107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4108 "%s: HDD adapter context is Null", __func__);
4109 ret = -ENODEV;
4110 goto exit;
4111 }
4112 if (dev != pAdapter->dev) {
4113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4114 "%s: HDD adapter/dev inconsistency", __func__);
4115 ret = -ENODEV;
4116 goto exit;
4117 }
4118
4119 if ((!ifr) || (!ifr->ifr_data)) {
4120 ret = -EINVAL;
4121 goto exit;
4122 }
4123
4124 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4125 ret = wlan_hdd_validate_context(pHddCtx);
4126 if (ret) {
4127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4128 "%s: invalid context", __func__);
4129 ret = -EBUSY;
4130 goto exit;
4131 }
4132
4133 switch (cmd) {
4134 case (SIOCDEVPRIVATE + 1):
4135 if (is_compat_task())
4136 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4137 else
4138 ret = hdd_driver_ioctl(pAdapter, ifr);
4139 break;
4140 default:
4141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4142 __func__, cmd);
4143 ret = -EINVAL;
4144 break;
4145 }
4146 exit:
4147 return ret;
4148}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004149
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004150#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004151/**---------------------------------------------------------------------------
4152
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004153 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004154
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004155 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004156 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4157 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4158 <space>Scan Mode N<space>Meas Duration N
4159 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4160 then take N.
4161 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4162 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4163 This function does not take care of removing duplicate channels from the list
4164
4165 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004166 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004167
4168 \return - 0 for success non-zero for failure
4169
4170 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004171static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4172 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004173{
4174 tANI_U8 *inPtr = pValue;
4175 int tempInt = 0;
4176 int j = 0, i = 0, v = 0;
4177 char buf[32];
4178
4179 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4180 /*no argument after the command*/
4181 if (NULL == inPtr)
4182 {
4183 return -EINVAL;
4184 }
4185 /*no space after the command*/
4186 else if (SPACE_ASCII_VALUE != *inPtr)
4187 {
4188 return -EINVAL;
4189 }
4190
4191 /*removing empty spaces*/
4192 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4193
4194 /*no argument followed by spaces*/
4195 if ('\0' == *inPtr) return -EINVAL;
4196
4197 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004198 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004199 if (1 != v) return -EINVAL;
4200
4201 v = kstrtos32(buf, 10, &tempInt);
4202 if ( v < 0) return -EINVAL;
4203
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004204 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004205
4206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004207 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004208
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004209 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004210 {
4211 for (i = 0; i < 4; i++)
4212 {
4213 /*inPtr pointing to the beginning of first space after number of ie fields*/
4214 inPtr = strpbrk( inPtr, " " );
4215 /*no ie data after the number of ie fields argument*/
4216 if (NULL == inPtr) return -EINVAL;
4217
4218 /*removing empty space*/
4219 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4220
4221 /*no ie data after the number of ie fields argument and spaces*/
4222 if ( '\0' == *inPtr ) return -EINVAL;
4223
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004224 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004225 if (1 != v) return -EINVAL;
4226
4227 v = kstrtos32(buf, 10, &tempInt);
4228 if (v < 0) return -EINVAL;
4229
4230 switch (i)
4231 {
4232 case 0: /* Measurement token */
4233 if (tempInt <= 0)
4234 {
4235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4236 "Invalid Measurement Token(%d)", tempInt);
4237 return -EINVAL;
4238 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004239 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004240 break;
4241
4242 case 1: /* Channel number */
4243 if ((tempInt <= 0) ||
4244 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4245 {
4246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4247 "Invalid Channel Number(%d)", tempInt);
4248 return -EINVAL;
4249 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004250 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004251 break;
4252
4253 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004254 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004255 {
4256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4257 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4258 return -EINVAL;
4259 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004260 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004261 break;
4262
4263 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004264 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4265 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004266 {
4267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4268 "Invalid Measurement Duration(%d)", tempInt);
4269 return -EINVAL;
4270 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004271 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004272 break;
4273 }
4274 }
4275 }
4276
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004277 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004278 {
4279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304280 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004281 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004282 pEseBcnReq->bcnReq[j].measurementToken,
4283 pEseBcnReq->bcnReq[j].channel,
4284 pEseBcnReq->bcnReq[j].scanMode,
4285 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004286 }
4287
4288 return VOS_STATUS_SUCCESS;
4289}
4290
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004291static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4292{
4293 struct statsContext *pStatsContext = NULL;
4294 hdd_adapter_t *pAdapter = NULL;
4295
4296 if (NULL == pContext)
4297 {
4298 hddLog(VOS_TRACE_LEVEL_ERROR,
4299 "%s: Bad param, pContext [%p]",
4300 __func__, pContext);
4301 return;
4302 }
4303
Jeff Johnson72a40512013-12-19 10:14:15 -08004304 /* there is a race condition that exists between this callback
4305 function and the caller since the caller could time out either
4306 before or while this code is executing. we use a spinlock to
4307 serialize these actions */
4308 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004309
4310 pStatsContext = pContext;
4311 pAdapter = pStatsContext->pAdapter;
4312 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4313 {
4314 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004315 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004316 hddLog(VOS_TRACE_LEVEL_WARN,
4317 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4318 __func__, pAdapter, pStatsContext->magic);
4319 return;
4320 }
4321
Jeff Johnson72a40512013-12-19 10:14:15 -08004322 /* context is valid so caller is still waiting */
4323
4324 /* paranoia: invalidate the magic */
4325 pStatsContext->magic = 0;
4326
4327 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004328 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4329 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4330 tsmMetrics.UplinkPktQueueDlyHist,
4331 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4332 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4333 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4334 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4335 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4336 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4337 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4338
Jeff Johnson72a40512013-12-19 10:14:15 -08004339 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004340 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004341
4342 /* serialization is complete */
4343 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004344}
4345
4346
4347
4348static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4349 tAniTrafStrmMetrics* pTsmMetrics)
4350{
4351 hdd_station_ctx_t *pHddStaCtx = NULL;
4352 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004353 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004354 long lrc;
4355 struct statsContext context;
4356 hdd_context_t *pHddCtx = NULL;
4357
4358 if (NULL == pAdapter)
4359 {
4360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4361 return VOS_STATUS_E_FAULT;
4362 }
4363
4364 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4365 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4366
4367 /* we are connected prepare our callback context */
4368 init_completion(&context.completion);
4369 context.pAdapter = pAdapter;
4370 context.magic = STATS_CONTEXT_MAGIC;
4371
4372 /* query tsm stats */
4373 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4374 pHddStaCtx->conn_info.staId[ 0 ],
4375 pHddStaCtx->conn_info.bssId,
4376 &context, pHddCtx->pvosContext, tid);
4377
4378 if (eHAL_STATUS_SUCCESS != hstatus)
4379 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4381 __func__);
4382 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004383 }
4384 else
4385 {
4386 /* request was sent -- wait for the response */
4387 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4388 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004389 if (lrc <= 0)
4390 {
4391 hddLog(VOS_TRACE_LEVEL_ERROR,
4392 "%s: SME %s while retrieving statistics",
4393 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004394 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004395 }
4396 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004397
Jeff Johnson72a40512013-12-19 10:14:15 -08004398 /* either we never sent a request, we sent a request and received a
4399 response or we sent a request and timed out. if we never sent a
4400 request or if we sent a request and got a response, we want to
4401 clear the magic out of paranoia. if we timed out there is a
4402 race condition such that the callback function could be
4403 executing at the same time we are. of primary concern is if the
4404 callback function had already verified the "magic" but had not
4405 yet set the completion variable when a timeout occurred. we
4406 serialize these activities by invalidating the magic while
4407 holding a shared spinlock which will cause us to block if the
4408 callback is currently executing */
4409 spin_lock(&hdd_context_lock);
4410 context.magic = 0;
4411 spin_unlock(&hdd_context_lock);
4412
4413 if (VOS_STATUS_SUCCESS == vstatus)
4414 {
4415 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4416 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4417 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4418 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4419 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4420 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4421 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4422 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4423 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4424 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4425 }
4426 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004427}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004428#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004429
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004430#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004431void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4432{
4433 eCsrBand band = -1;
4434 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4435 switch (band)
4436 {
4437 case eCSR_BAND_ALL:
4438 *pBand = WLAN_HDD_UI_BAND_AUTO;
4439 break;
4440
4441 case eCSR_BAND_24:
4442 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4443 break;
4444
4445 case eCSR_BAND_5G:
4446 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4447 break;
4448
4449 default:
4450 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4451 *pBand = -1;
4452 break;
4453 }
4454}
4455
4456/**---------------------------------------------------------------------------
4457
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004458 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4459
4460 This function parses the send action frame data passed in the format
4461 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4462
Srinivas Girigowda56076852013-08-20 14:00:50 -07004463 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004464 \param - pTargetApBssid Pointer to target Ap bssid
4465 \param - pChannel Pointer to the Target AP channel
4466 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4467 \param - pBuf Pointer to data
4468 \param - pBufLen Pointer to data length
4469
4470 \return - 0 for success non-zero for failure
4471
4472 --------------------------------------------------------------------------*/
4473VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4474 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4475{
4476 tANI_U8 *inPtr = pValue;
4477 tANI_U8 *dataEnd;
4478 int tempInt;
4479 int j = 0;
4480 int i = 0;
4481 int v = 0;
4482 tANI_U8 tempBuf[32];
4483 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004484 /* 12 hexa decimal digits, 5 ':' and '\0' */
4485 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004486
4487 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4488 /*no argument after the command*/
4489 if (NULL == inPtr)
4490 {
4491 return -EINVAL;
4492 }
4493
4494 /*no space after the command*/
4495 else if (SPACE_ASCII_VALUE != *inPtr)
4496 {
4497 return -EINVAL;
4498 }
4499
4500 /*removing empty spaces*/
4501 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4502
4503 /*no argument followed by spaces*/
4504 if ('\0' == *inPtr)
4505 {
4506 return -EINVAL;
4507 }
4508
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004509 v = sscanf(inPtr, "%17s", macAddress);
4510 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004511 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4513 "Invalid MAC address or All hex inputs are not read (%d)", v);
4514 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004515 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004516
4517 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4518 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4519 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4520 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4521 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4522 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004523
4524 /* point to the next argument */
4525 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4526 /*no argument after the command*/
4527 if (NULL == inPtr) return -EINVAL;
4528
4529 /*removing empty spaces*/
4530 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4531
4532 /*no argument followed by spaces*/
4533 if ('\0' == *inPtr)
4534 {
4535 return -EINVAL;
4536 }
4537
4538 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004539 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004540 if (1 != v) return -EINVAL;
4541
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004542 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304543 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304544 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004545
4546 *pChannel = tempInt;
4547
4548 /* point to the next argument */
4549 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4550 /*no argument after the command*/
4551 if (NULL == inPtr) return -EINVAL;
4552 /*removing empty spaces*/
4553 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4554
4555 /*no argument followed by spaces*/
4556 if ('\0' == *inPtr)
4557 {
4558 return -EINVAL;
4559 }
4560
4561 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004562 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004563 if (1 != v) return -EINVAL;
4564
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004565 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004566 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004567
4568 *pDwellTime = tempInt;
4569
4570 /* point to the next argument */
4571 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4572 /*no argument after the command*/
4573 if (NULL == inPtr) return -EINVAL;
4574 /*removing empty spaces*/
4575 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4576
4577 /*no argument followed by spaces*/
4578 if ('\0' == *inPtr)
4579 {
4580 return -EINVAL;
4581 }
4582
4583 /* find the length of data */
4584 dataEnd = inPtr;
4585 while(('\0' != *dataEnd) )
4586 {
4587 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004588 }
Kiet Lambe150c22013-11-21 16:30:32 +05304589 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004590 if ( *pBufLen <= 0) return -EINVAL;
4591
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004592 /* Allocate the number of bytes based on the number of input characters
4593 whether it is even or odd.
4594 if the number of input characters are even, then we need N/2 byte.
4595 if the number of input characters are odd, then we need do (N+1)/2 to
4596 compensate rounding off.
4597 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4598 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4599 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004600 if (NULL == *pBuf)
4601 {
4602 hddLog(VOS_TRACE_LEVEL_FATAL,
4603 "%s: vos_mem_alloc failed ", __func__);
4604 return -EINVAL;
4605 }
4606
4607 /* the buffer received from the upper layer is character buffer,
4608 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4609 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4610 and f0 in 3rd location */
4611 for (i = 0, j = 0; j < *pBufLen; j += 2)
4612 {
Kiet Lambe150c22013-11-21 16:30:32 +05304613 if( j+1 == *pBufLen)
4614 {
4615 tempByte = hdd_parse_hex(inPtr[j]);
4616 }
4617 else
4618 {
4619 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4620 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004621 (*pBuf)[i++] = tempByte;
4622 }
4623 *pBufLen = i;
4624 return VOS_STATUS_SUCCESS;
4625}
4626
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004627/**---------------------------------------------------------------------------
4628
Srinivas Girigowdade697412013-02-14 16:31:48 -08004629 \brief hdd_parse_channellist() - HDD Parse channel list
4630
4631 This function parses the channel list passed in the format
4632 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004633 if the Number of channels (N) does not match with the actual number of channels passed
4634 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4635 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4636 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4637 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004638
4639 \param - pValue Pointer to input channel list
4640 \param - ChannelList Pointer to local output array to record channel list
4641 \param - pNumChannels Pointer to number of roam scan channels
4642
4643 \return - 0 for success non-zero for failure
4644
4645 --------------------------------------------------------------------------*/
4646VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4647{
4648 tANI_U8 *inPtr = pValue;
4649 int tempInt;
4650 int j = 0;
4651 int v = 0;
4652 char buf[32];
4653
4654 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4655 /*no argument after the command*/
4656 if (NULL == inPtr)
4657 {
4658 return -EINVAL;
4659 }
4660
4661 /*no space after the command*/
4662 else if (SPACE_ASCII_VALUE != *inPtr)
4663 {
4664 return -EINVAL;
4665 }
4666
4667 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004668 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004669
4670 /*no argument followed by spaces*/
4671 if ('\0' == *inPtr)
4672 {
4673 return -EINVAL;
4674 }
4675
4676 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004677 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004678 if (1 != v) return -EINVAL;
4679
Srinivas Girigowdade697412013-02-14 16:31:48 -08004680 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004681 if ((v < 0) ||
4682 (tempInt <= 0) ||
4683 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4684 {
4685 return -EINVAL;
4686 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004687
4688 *pNumChannels = tempInt;
4689
4690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4691 "Number of channels are: %d", *pNumChannels);
4692
4693 for (j = 0; j < (*pNumChannels); j++)
4694 {
4695 /*inPtr pointing to the beginning of first space after number of channels*/
4696 inPtr = strpbrk( inPtr, " " );
4697 /*no channel list after the number of channels argument*/
4698 if (NULL == inPtr)
4699 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004700 if (0 != j)
4701 {
4702 *pNumChannels = j;
4703 return VOS_STATUS_SUCCESS;
4704 }
4705 else
4706 {
4707 return -EINVAL;
4708 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004709 }
4710
4711 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004712 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004713
4714 /*no channel list after the number of channels argument and spaces*/
4715 if ( '\0' == *inPtr )
4716 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004717 if (0 != j)
4718 {
4719 *pNumChannels = j;
4720 return VOS_STATUS_SUCCESS;
4721 }
4722 else
4723 {
4724 return -EINVAL;
4725 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004726 }
4727
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004728 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004729 if (1 != v) return -EINVAL;
4730
Srinivas Girigowdade697412013-02-14 16:31:48 -08004731 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004732 if ((v < 0) ||
4733 (tempInt <= 0) ||
4734 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4735 {
4736 return -EINVAL;
4737 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004738 pChannelList[j] = tempInt;
4739
4740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4741 "Channel %d added to preferred channel list",
4742 pChannelList[j] );
4743 }
4744
Srinivas Girigowdade697412013-02-14 16:31:48 -08004745 return VOS_STATUS_SUCCESS;
4746}
4747
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004748
4749/**---------------------------------------------------------------------------
4750
4751 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4752
4753 This function parses the reasoc command data passed in the format
4754 REASSOC<space><bssid><space><channel>
4755
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004756 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004757 \param - pTargetApBssid Pointer to target Ap bssid
4758 \param - pChannel Pointer to the Target AP channel
4759
4760 \return - 0 for success non-zero for failure
4761
4762 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004763VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4764 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004765{
4766 tANI_U8 *inPtr = pValue;
4767 int tempInt;
4768 int v = 0;
4769 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004770 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004771 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004772
4773 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4774 /*no argument after the command*/
4775 if (NULL == inPtr)
4776 {
4777 return -EINVAL;
4778 }
4779
4780 /*no space after the command*/
4781 else if (SPACE_ASCII_VALUE != *inPtr)
4782 {
4783 return -EINVAL;
4784 }
4785
4786 /*removing empty spaces*/
4787 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4788
4789 /*no argument followed by spaces*/
4790 if ('\0' == *inPtr)
4791 {
4792 return -EINVAL;
4793 }
4794
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004795 v = sscanf(inPtr, "%17s", macAddress);
4796 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004797 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4799 "Invalid MAC address or All hex inputs are not read (%d)", v);
4800 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004801 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004802
4803 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4804 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4805 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4806 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4807 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4808 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004809
4810 /* point to the next argument */
4811 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4812 /*no argument after the command*/
4813 if (NULL == inPtr) return -EINVAL;
4814
4815 /*removing empty spaces*/
4816 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4817
4818 /*no argument followed by spaces*/
4819 if ('\0' == *inPtr)
4820 {
4821 return -EINVAL;
4822 }
4823
4824 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004825 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004826 if (1 != v) return -EINVAL;
4827
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004828 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004829 if ((v < 0) ||
4830 (tempInt <= 0) ||
4831 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4832 {
4833 return -EINVAL;
4834 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004835
4836 *pChannel = tempInt;
4837 return VOS_STATUS_SUCCESS;
4838}
4839
4840#endif
4841
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004842#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004843/**---------------------------------------------------------------------------
4844
4845 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4846
4847 This function parses the SETCCKM IE command
4848 SETCCKMIE<space><ie data>
4849
4850 \param - pValue Pointer to input data
4851 \param - pCckmIe Pointer to output cckm Ie
4852 \param - pCckmIeLen Pointer to output cckm ie length
4853
4854 \return - 0 for success non-zero for failure
4855
4856 --------------------------------------------------------------------------*/
4857VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4858 tANI_U8 *pCckmIeLen)
4859{
4860 tANI_U8 *inPtr = pValue;
4861 tANI_U8 *dataEnd;
4862 int j = 0;
4863 int i = 0;
4864 tANI_U8 tempByte = 0;
4865
4866 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4867 /*no argument after the command*/
4868 if (NULL == inPtr)
4869 {
4870 return -EINVAL;
4871 }
4872
4873 /*no space after the command*/
4874 else if (SPACE_ASCII_VALUE != *inPtr)
4875 {
4876 return -EINVAL;
4877 }
4878
4879 /*removing empty spaces*/
4880 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4881
4882 /*no argument followed by spaces*/
4883 if ('\0' == *inPtr)
4884 {
4885 return -EINVAL;
4886 }
4887
4888 /* find the length of data */
4889 dataEnd = inPtr;
4890 while(('\0' != *dataEnd) )
4891 {
4892 dataEnd++;
4893 ++(*pCckmIeLen);
4894 }
4895 if ( *pCckmIeLen <= 0) return -EINVAL;
4896
4897 /* Allocate the number of bytes based on the number of input characters
4898 whether it is even or odd.
4899 if the number of input characters are even, then we need N/2 byte.
4900 if the number of input characters are odd, then we need do (N+1)/2 to
4901 compensate rounding off.
4902 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4903 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4904 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4905 if (NULL == *pCckmIe)
4906 {
4907 hddLog(VOS_TRACE_LEVEL_FATAL,
4908 "%s: vos_mem_alloc failed ", __func__);
4909 return -EINVAL;
4910 }
4911 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4912 /* the buffer received from the upper layer is character buffer,
4913 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4914 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4915 and f0 in 3rd location */
4916 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4917 {
4918 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4919 (*pCckmIe)[i++] = tempByte;
4920 }
4921 *pCckmIeLen = i;
4922
4923 return VOS_STATUS_SUCCESS;
4924}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004925#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004926
Jeff Johnson295189b2012-06-20 16:38:30 -07004927/**---------------------------------------------------------------------------
4928
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004929 \brief hdd_is_valid_mac_address() - Validate MAC address
4930
4931 This function validates whether the given MAC address is valid or not
4932 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4933 where X is the hexa decimal digit character and separated by ':'
4934 This algorithm works even if MAC address is not separated by ':'
4935
4936 This code checks given input string mac contains exactly 12 hexadecimal digits.
4937 and a separator colon : appears in the input string only after
4938 an even number of hex digits.
4939
4940 \param - pMacAddr pointer to the input MAC address
4941 \return - 1 for valid and 0 for invalid
4942
4943 --------------------------------------------------------------------------*/
4944
4945v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4946{
4947 int xdigit = 0;
4948 int separator = 0;
4949 while (*pMacAddr)
4950 {
4951 if (isxdigit(*pMacAddr))
4952 {
4953 xdigit++;
4954 }
4955 else if (':' == *pMacAddr)
4956 {
4957 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4958 break;
4959
4960 ++separator;
4961 }
4962 else
4963 {
4964 separator = -1;
4965 /* Invalid MAC found */
4966 return 0;
4967 }
4968 ++pMacAddr;
4969 }
4970 return (xdigit == 12 && (separator == 5 || separator == 0));
4971}
4972
4973/**---------------------------------------------------------------------------
4974
Jeff Johnson295189b2012-06-20 16:38:30 -07004975 \brief hdd_open() - HDD Open function
4976
4977 This is called in response to ifconfig up
4978
4979 \param - dev Pointer to net_device structure
4980
4981 \return - 0 for success non-zero for failure
4982
4983 --------------------------------------------------------------------------*/
4984int hdd_open (struct net_device *dev)
4985{
4986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4987 hdd_context_t *pHddCtx;
4988 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4989 VOS_STATUS status;
4990 v_BOOL_t in_standby = TRUE;
4991
4992 if (NULL == pAdapter)
4993 {
4994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304995 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 return -ENODEV;
4997 }
4998
4999 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305000 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5001 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005002 if (NULL == pHddCtx)
5003 {
5004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005005 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005006 return -ENODEV;
5007 }
5008
5009 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5010 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5011 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005012 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5013 {
5014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305015 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005016 in_standby = FALSE;
5017 break;
5018 }
5019 else
5020 {
5021 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5022 pAdapterNode = pNext;
5023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005024 }
5025
5026 if (TRUE == in_standby)
5027 {
5028 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5029 {
5030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5031 "wlan out of power save", __func__);
5032 return -EINVAL;
5033 }
5034 }
5035
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005036 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005037 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5038 {
5039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005040 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005041 /* Enable TX queues only when we are connected */
5042 netif_tx_start_all_queues(dev);
5043 }
5044
5045 return 0;
5046}
5047
5048int hdd_mon_open (struct net_device *dev)
5049{
5050 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5051
5052 if(pAdapter == NULL) {
5053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005054 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005055 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 }
5057
5058 netif_start_queue(dev);
5059
5060 return 0;
5061}
5062/**---------------------------------------------------------------------------
5063
5064 \brief hdd_stop() - HDD stop function
5065
5066 This is called in response to ifconfig down
5067
5068 \param - dev Pointer to net_device structure
5069
5070 \return - 0 for success non-zero for failure
5071
5072 --------------------------------------------------------------------------*/
5073
5074int hdd_stop (struct net_device *dev)
5075{
5076 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5077 hdd_context_t *pHddCtx;
5078 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5079 VOS_STATUS status;
5080 v_BOOL_t enter_standby = TRUE;
5081
5082 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005083 if (NULL == pAdapter)
5084 {
5085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305086 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005087 return -ENODEV;
5088 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305089 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5090 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5092 if (NULL == pHddCtx)
5093 {
5094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005095 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 return -ENODEV;
5097 }
5098
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305099 /* Nothing to be done if the interface is not opened */
5100 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5101 {
5102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5103 "%s: NETDEV Interface is not OPENED", __func__);
5104 return -ENODEV;
5105 }
5106
5107 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005108 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305110
5111 /* Disable TX on the interface, after this hard_start_xmit() will not
5112 * be called on that interface
5113 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305115
5116 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005117 netif_carrier_off(pAdapter->dev);
5118
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305119 /* The interface is marked as down for outside world (aka kernel)
5120 * But the driver is pretty much alive inside. The driver needs to
5121 * tear down the existing connection on the netdev (session)
5122 * cleanup the data pipes and wait until the control plane is stabilized
5123 * for this interface. The call also needs to wait until the above
5124 * mentioned actions are completed before returning to the caller.
5125 * Notice that the hdd_stop_adapter is requested not to close the session
5126 * That is intentional to be able to scan if it is a STA/P2P interface
5127 */
5128 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005129
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305130 /* DeInit the adapter. This ensures datapath cleanup as well */
5131 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 /* SoftAP ifaces should never go in power save mode
5133 making sure same here. */
5134 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5135 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005136 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005137 )
5138 {
5139 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5141 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 EXIT();
5143 return 0;
5144 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305145 /* Find if any iface is up. If any iface is up then can't put device to
5146 * sleep/power save mode
5147 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005148 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5149 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5150 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005151 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5152 {
5153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305154 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005155 enter_standby = FALSE;
5156 break;
5157 }
5158 else
5159 {
5160 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5161 pAdapterNode = pNext;
5162 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 }
5164
5165 if (TRUE == enter_standby)
5166 {
5167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5168 "entering standby", __func__);
5169 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5170 {
5171 /*log and return success*/
5172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5173 "wlan in power save", __func__);
5174 }
5175 }
5176
5177 EXIT();
5178 return 0;
5179}
5180
5181/**---------------------------------------------------------------------------
5182
5183 \brief hdd_uninit() - HDD uninit function
5184
5185 This is called during the netdev unregister to uninitialize all data
5186associated with the device
5187
5188 \param - dev Pointer to net_device structure
5189
5190 \return - void
5191
5192 --------------------------------------------------------------------------*/
5193static void hdd_uninit (struct net_device *dev)
5194{
5195 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5196
5197 ENTER();
5198
5199 do
5200 {
5201 if (NULL == pAdapter)
5202 {
5203 hddLog(VOS_TRACE_LEVEL_FATAL,
5204 "%s: NULL pAdapter", __func__);
5205 break;
5206 }
5207
5208 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5209 {
5210 hddLog(VOS_TRACE_LEVEL_FATAL,
5211 "%s: Invalid magic", __func__);
5212 break;
5213 }
5214
5215 if (NULL == pAdapter->pHddCtx)
5216 {
5217 hddLog(VOS_TRACE_LEVEL_FATAL,
5218 "%s: NULL pHddCtx", __func__);
5219 break;
5220 }
5221
5222 if (dev != pAdapter->dev)
5223 {
5224 hddLog(VOS_TRACE_LEVEL_FATAL,
5225 "%s: Invalid device reference", __func__);
5226 /* we haven't validated all cases so let this go for now */
5227 }
5228
5229 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5230
5231 /* after uninit our adapter structure will no longer be valid */
5232 pAdapter->dev = NULL;
5233 pAdapter->magic = 0;
5234 } while (0);
5235
5236 EXIT();
5237}
5238
5239/**---------------------------------------------------------------------------
5240
5241 \brief hdd_release_firmware() -
5242
5243 This function calls the release firmware API to free the firmware buffer.
5244
5245 \param - pFileName Pointer to the File Name.
5246 pCtx - Pointer to the adapter .
5247
5248
5249 \return - 0 for success, non zero for failure
5250
5251 --------------------------------------------------------------------------*/
5252
5253VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5254{
5255 VOS_STATUS status = VOS_STATUS_SUCCESS;
5256 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5257 ENTER();
5258
5259
5260 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5261
5262 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5263
5264 if(pHddCtx->fw) {
5265 release_firmware(pHddCtx->fw);
5266 pHddCtx->fw = NULL;
5267 }
5268 else
5269 status = VOS_STATUS_E_FAILURE;
5270 }
5271 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5272 if(pHddCtx->nv) {
5273 release_firmware(pHddCtx->nv);
5274 pHddCtx->nv = NULL;
5275 }
5276 else
5277 status = VOS_STATUS_E_FAILURE;
5278
5279 }
5280
5281 EXIT();
5282 return status;
5283}
5284
5285/**---------------------------------------------------------------------------
5286
5287 \brief hdd_request_firmware() -
5288
5289 This function reads the firmware file using the request firmware
5290 API and returns the the firmware data and the firmware file size.
5291
5292 \param - pfileName - Pointer to the file name.
5293 - pCtx - Pointer to the adapter .
5294 - ppfw_data - Pointer to the pointer of the firmware data.
5295 - pSize - Pointer to the file size.
5296
5297 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5298
5299 --------------------------------------------------------------------------*/
5300
5301
5302VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5303{
5304 int status;
5305 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5306 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5307 ENTER();
5308
5309 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5310
5311 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5312
5313 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5314 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5315 __func__, pfileName);
5316 retval = VOS_STATUS_E_FAILURE;
5317 }
5318
5319 else {
5320 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5321 *pSize = pHddCtx->fw->size;
5322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5323 __func__, *pSize);
5324 }
5325 }
5326 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5327
5328 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5329
5330 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5331 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5332 __func__, pfileName);
5333 retval = VOS_STATUS_E_FAILURE;
5334 }
5335
5336 else {
5337 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5338 *pSize = pHddCtx->nv->size;
5339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5340 __func__, *pSize);
5341 }
5342 }
5343
5344 EXIT();
5345 return retval;
5346}
5347/**---------------------------------------------------------------------------
5348 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5349
5350 This is the function invoked by SME to inform the result of a full power
5351 request issued by HDD
5352
5353 \param - callbackcontext - Pointer to cookie
5354 status - result of request
5355
5356 \return - None
5357
5358--------------------------------------------------------------------------*/
5359void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5360{
5361 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5362
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005363 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005364 if(&pHddCtx->full_pwr_comp_var)
5365 {
5366 complete(&pHddCtx->full_pwr_comp_var);
5367 }
5368}
5369
5370/**---------------------------------------------------------------------------
5371
5372 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5373
5374 This is the function invoked by SME to inform the result of BMPS
5375 request issued by HDD
5376
5377 \param - callbackcontext - Pointer to cookie
5378 status - result of request
5379
5380 \return - None
5381
5382--------------------------------------------------------------------------*/
5383void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5384{
5385
5386 struct completion *completion_var = (struct completion*) callbackContext;
5387
Arif Hussain6d2a3322013-11-17 19:50:10 -08005388 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 if(completion_var != NULL)
5390 {
5391 complete(completion_var);
5392 }
5393}
5394
5395/**---------------------------------------------------------------------------
5396
5397 \brief hdd_get_cfg_file_size() -
5398
5399 This function reads the configuration file using the request firmware
5400 API and returns the configuration file size.
5401
5402 \param - pCtx - Pointer to the adapter .
5403 - pFileName - Pointer to the file name.
5404 - pBufSize - Pointer to the buffer size.
5405
5406 \return - 0 for success, non zero for failure
5407
5408 --------------------------------------------------------------------------*/
5409
5410VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5411{
5412 int status;
5413 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5414
5415 ENTER();
5416
5417 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5418
5419 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5420 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5421 status = VOS_STATUS_E_FAILURE;
5422 }
5423 else {
5424 *pBufSize = pHddCtx->fw->size;
5425 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5426 release_firmware(pHddCtx->fw);
5427 pHddCtx->fw = NULL;
5428 }
5429
5430 EXIT();
5431 return VOS_STATUS_SUCCESS;
5432}
5433
5434/**---------------------------------------------------------------------------
5435
5436 \brief hdd_read_cfg_file() -
5437
5438 This function reads the configuration file using the request firmware
5439 API and returns the cfg data and the buffer size of the configuration file.
5440
5441 \param - pCtx - Pointer to the adapter .
5442 - pFileName - Pointer to the file name.
5443 - pBuffer - Pointer to the data buffer.
5444 - pBufSize - Pointer to the buffer size.
5445
5446 \return - 0 for success, non zero for failure
5447
5448 --------------------------------------------------------------------------*/
5449
5450VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5451 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5452{
5453 int status;
5454 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5455
5456 ENTER();
5457
5458 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5459
5460 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5461 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5462 return VOS_STATUS_E_FAILURE;
5463 }
5464 else {
5465 if(*pBufSize != pHddCtx->fw->size) {
5466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5467 "file size", __func__);
5468 release_firmware(pHddCtx->fw);
5469 pHddCtx->fw = NULL;
5470 return VOS_STATUS_E_FAILURE;
5471 }
5472 else {
5473 if(pBuffer) {
5474 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5475 }
5476 release_firmware(pHddCtx->fw);
5477 pHddCtx->fw = NULL;
5478 }
5479 }
5480
5481 EXIT();
5482
5483 return VOS_STATUS_SUCCESS;
5484}
5485
5486/**---------------------------------------------------------------------------
5487
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 \brief hdd_set_mac_address() -
5489
5490 This function sets the user specified mac address using
5491 the command ifconfig wlanX hw ether <mac adress>.
5492
5493 \param - dev - Pointer to the net device.
5494 - addr - Pointer to the sockaddr.
5495 \return - 0 for success, non zero for failure
5496
5497 --------------------------------------------------------------------------*/
5498
5499static int hdd_set_mac_address(struct net_device *dev, void *addr)
5500{
5501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5502 struct sockaddr *psta_mac_addr = addr;
5503 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5504
5505 ENTER();
5506
5507 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5509
5510 EXIT();
5511 return halStatus;
5512}
5513
5514tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5515{
5516 int i;
5517 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5518 {
Abhishek Singheb183782014-02-06 13:37:21 +05305519 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 break;
5521 }
5522
5523 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5524 return NULL;
5525
5526 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5527 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5528}
5529
5530void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5531{
5532 int i;
5533 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5534 {
5535 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5536 {
5537 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5538 break;
5539 }
5540 }
5541 return;
5542}
5543
5544#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5545 static struct net_device_ops wlan_drv_ops = {
5546 .ndo_open = hdd_open,
5547 .ndo_stop = hdd_stop,
5548 .ndo_uninit = hdd_uninit,
5549 .ndo_start_xmit = hdd_hard_start_xmit,
5550 .ndo_tx_timeout = hdd_tx_timeout,
5551 .ndo_get_stats = hdd_stats,
5552 .ndo_do_ioctl = hdd_ioctl,
5553 .ndo_set_mac_address = hdd_set_mac_address,
5554 .ndo_select_queue = hdd_select_queue,
5555#ifdef WLAN_FEATURE_PACKET_FILTERING
5556#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5557 .ndo_set_rx_mode = hdd_set_multicast_list,
5558#else
5559 .ndo_set_multicast_list = hdd_set_multicast_list,
5560#endif //LINUX_VERSION_CODE
5561#endif
5562 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 static struct net_device_ops wlan_mon_drv_ops = {
5564 .ndo_open = hdd_mon_open,
5565 .ndo_stop = hdd_stop,
5566 .ndo_uninit = hdd_uninit,
5567 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5568 .ndo_tx_timeout = hdd_tx_timeout,
5569 .ndo_get_stats = hdd_stats,
5570 .ndo_do_ioctl = hdd_ioctl,
5571 .ndo_set_mac_address = hdd_set_mac_address,
5572 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005573
5574#endif
5575
5576void hdd_set_station_ops( struct net_device *pWlanDev )
5577{
5578#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 pWlanDev->netdev_ops = &wlan_drv_ops;
5580#else
5581 pWlanDev->open = hdd_open;
5582 pWlanDev->stop = hdd_stop;
5583 pWlanDev->uninit = hdd_uninit;
5584 pWlanDev->hard_start_xmit = NULL;
5585 pWlanDev->tx_timeout = hdd_tx_timeout;
5586 pWlanDev->get_stats = hdd_stats;
5587 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 pWlanDev->set_mac_address = hdd_set_mac_address;
5589#endif
5590}
5591
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005592static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005593{
5594 struct net_device *pWlanDev = NULL;
5595 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005596 /*
5597 * cfg80211 initialization and registration....
5598 */
5599 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5600
Jeff Johnson295189b2012-06-20 16:38:30 -07005601 if(pWlanDev != NULL)
5602 {
5603
5604 //Save the pointer to the net_device in the HDD adapter
5605 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5606
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5608
5609 pAdapter->dev = pWlanDev;
5610 pAdapter->pHddCtx = pHddCtx;
5611 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5612
5613 init_completion(&pAdapter->session_open_comp_var);
5614 init_completion(&pAdapter->session_close_comp_var);
5615 init_completion(&pAdapter->disconnect_comp_var);
5616 init_completion(&pAdapter->linkup_event_var);
5617 init_completion(&pAdapter->cancel_rem_on_chan_var);
5618 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305619 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5621 init_completion(&pAdapter->offchannel_tx_event);
5622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005624#ifdef FEATURE_WLAN_TDLS
5625 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005626 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005627 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305628 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005629#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005630 init_completion(&pHddCtx->mc_sus_event_var);
5631 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305632 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005633 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005634 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005635
Rajeev79dbe4c2013-10-05 11:03:42 +05305636#ifdef FEATURE_WLAN_BATCH_SCAN
5637 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5638 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5639 pAdapter->pBatchScanRsp = NULL;
5640 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005641 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005642 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305643 mutex_init(&pAdapter->hdd_batch_scan_lock);
5644#endif
5645
Jeff Johnson295189b2012-06-20 16:38:30 -07005646 pAdapter->isLinkUpSvcNeeded = FALSE;
5647 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5648 //Init the net_device structure
5649 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5650
5651 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5652 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5653 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5654 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5655
5656 hdd_set_station_ops( pAdapter->dev );
5657
5658 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5660 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5661 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005662 /* set pWlanDev's parent to underlying device */
5663 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005664
5665 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005666 }
5667
5668 return pAdapter;
5669}
5670
5671VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5672{
5673 struct net_device *pWlanDev = pAdapter->dev;
5674 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5675 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5676 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5677
5678 if( rtnl_lock_held )
5679 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005680 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005681 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5682 {
5683 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5684 return VOS_STATUS_E_FAILURE;
5685 }
5686 }
5687 if (register_netdevice(pWlanDev))
5688 {
5689 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5690 return VOS_STATUS_E_FAILURE;
5691 }
5692 }
5693 else
5694 {
5695 if(register_netdev(pWlanDev))
5696 {
5697 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5698 return VOS_STATUS_E_FAILURE;
5699 }
5700 }
5701 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5702
5703 return VOS_STATUS_SUCCESS;
5704}
5705
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005706static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005707{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005708 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005709
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005710 if (NULL == pAdapter)
5711 {
5712 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5713 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005715
5716 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5717 {
5718 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5719 return eHAL_STATUS_NOT_INITIALIZED;
5720 }
5721
5722 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5723
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005724#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005725 /* need to make sure all of our scheduled work has completed.
5726 * This callback is called from MC thread context, so it is safe to
5727 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005728 *
5729 * Even though this is called from MC thread context, if there is a faulty
5730 * work item in the system, that can hang this call forever. So flushing
5731 * this global work queue is not safe; and now we make sure that
5732 * individual work queues are stopped correctly. But the cancel work queue
5733 * is a GPL only API, so the proprietary version of the driver would still
5734 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005735 */
5736 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005737#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005738
5739 /* We can be blocked while waiting for scheduled work to be
5740 * flushed, and the adapter structure can potentially be freed, in
5741 * which case the magic will have been reset. So make sure the
5742 * magic is still good, and hence the adapter structure is still
5743 * valid, before signaling completion */
5744 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5745 {
5746 complete(&pAdapter->session_close_comp_var);
5747 }
5748
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 return eHAL_STATUS_SUCCESS;
5750}
5751
5752VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5753{
5754 struct net_device *pWlanDev = pAdapter->dev;
5755 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5756 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5757 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5758 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305759 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005760
5761 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005762 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 //Open a SME session for future operation
5764 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005765 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5767 {
5768 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005769 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 halStatus, halStatus );
5771 status = VOS_STATUS_E_FAILURE;
5772 goto error_sme_open;
5773 }
5774
5775 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305776 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005777 &pAdapter->session_open_comp_var,
5778 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305779 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 {
5781 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305782 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 status = VOS_STATUS_E_FAILURE;
5784 goto error_sme_open;
5785 }
5786
5787 // Register wireless extensions
5788 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5789 {
5790 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005791 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 halStatus, halStatus );
5793 status = VOS_STATUS_E_FAILURE;
5794 goto error_register_wext;
5795 }
5796 //Safe to register the hard_start_xmit function again
5797#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5798 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5799#else
5800 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5801#endif
5802
5803 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305804 hddLog(VOS_TRACE_LEVEL_INFO,
5805 "%s: Set HDD connState to eConnectionState_NotConnected",
5806 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5808
5809 //Set the default operation channel
5810 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5811
5812 /* Make the default Auth Type as OPEN*/
5813 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5814
5815 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5816 {
5817 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005818 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 status, status );
5820 goto error_init_txrx;
5821 }
5822
5823 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5824
5825 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5826 {
5827 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005828 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 status, status );
5830 goto error_wmm_init;
5831 }
5832
5833 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5834
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005835#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305836 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005837 {
5838 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305839 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005840 goto error_tdls_init;
5841 }
5842 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5843#endif
5844
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 return VOS_STATUS_SUCCESS;
5846
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005847#ifdef FEATURE_WLAN_TDLS
5848error_tdls_init:
5849 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5850 hdd_wmm_adapter_close(pAdapter);
5851#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005852error_wmm_init:
5853 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5854 hdd_deinit_tx_rx(pAdapter);
5855error_init_txrx:
5856 hdd_UnregisterWext(pWlanDev);
5857error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005858 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 {
5860 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005861 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005863 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305865 unsigned long rc;
5866
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305868 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005869 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005870 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305871 if (rc <= 0)
5872 hddLog(VOS_TRACE_LEVEL_ERROR,
5873 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 }
5875}
5876error_sme_open:
5877 return status;
5878}
5879
Jeff Johnson295189b2012-06-20 16:38:30 -07005880void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5881{
5882 hdd_cfg80211_state_t *cfgState;
5883
5884 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5885
5886 if( NULL != cfgState->buf )
5887 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305888 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5890 rc = wait_for_completion_interruptible_timeout(
5891 &pAdapter->tx_action_cnf_event,
5892 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305893 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305896 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5897 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 }
5899 }
5900 return;
5901}
Jeff Johnson295189b2012-06-20 16:38:30 -07005902
5903void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5904{
5905 ENTER();
5906 switch ( pAdapter->device_mode )
5907 {
5908 case WLAN_HDD_INFRA_STATION:
5909 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005910 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 {
5912 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5913 {
5914 hdd_deinit_tx_rx( pAdapter );
5915 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5916 }
5917
5918 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5919 {
5920 hdd_wmm_adapter_close( pAdapter );
5921 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5922 }
5923
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005925#ifdef FEATURE_WLAN_TDLS
5926 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5927 {
5928 wlan_hdd_tdls_exit(pAdapter);
5929 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5930 }
5931#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005932
5933 break;
5934 }
5935
5936 case WLAN_HDD_SOFTAP:
5937 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305939
5940 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5941 {
5942 hdd_wmm_adapter_close( pAdapter );
5943 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5944 }
5945
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005947
5948 hdd_unregister_hostapd(pAdapter);
5949 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 break;
5952 }
5953
5954 case WLAN_HDD_MONITOR:
5955 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5958 {
5959 hdd_deinit_tx_rx( pAdapter );
5960 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 if(NULL != pAdapterforTx)
5963 {
5964 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 break;
5967 }
5968
5969
5970 default:
5971 break;
5972 }
5973
5974 EXIT();
5975}
5976
5977void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5978{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005979 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305980
5981 ENTER();
5982 if (NULL == pAdapter)
5983 {
5984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5985 "%s: HDD adapter is Null", __func__);
5986 return;
5987 }
5988
5989 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005990
Rajeev79dbe4c2013-10-05 11:03:42 +05305991#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305992 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5993 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005994 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305995 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5996 )
5997 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005998 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305999 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006000 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6001 {
6002 hdd_deinit_batch_scan(pAdapter);
6003 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306004 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006005 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306006#endif
6007
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6009 if( rtnl_held )
6010 {
6011 unregister_netdevice(pWlanDev);
6012 }
6013 else
6014 {
6015 unregister_netdev(pWlanDev);
6016 }
6017 // note that the pAdapter is no longer valid at this point
6018 // since the memory has been reclaimed
6019 }
6020
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306021 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006022}
6023
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006024void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6025{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306026 VOS_STATUS status;
6027 hdd_adapter_t *pAdapter = NULL;
6028 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006029
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306030 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006031
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306032 /*loop through all adapters.*/
6033 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006034 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306035 pAdapter = pAdapterNode->pAdapter;
6036 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6037 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006038
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306039 { // we skip this registration for modes other than STA and P2P client modes.
6040 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6041 pAdapterNode = pNext;
6042 continue;
6043 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006044
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306045 //Apply Dynamic DTIM For P2P
6046 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6047 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6048 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6049 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6050 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6051 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6052 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6053 (eConnectionState_Associated ==
6054 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6055 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6056 {
6057 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006058
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306059 powerRequest.uIgnoreDTIM = 1;
6060 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6061
6062 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6063 {
6064 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6065 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6066 }
6067 else
6068 {
6069 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6070 }
6071
6072 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6073 * specified during Enter/Exit BMPS when LCD off*/
6074 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6075 NULL, eANI_BOOLEAN_FALSE);
6076 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6077 NULL, eANI_BOOLEAN_FALSE);
6078
6079 /* switch to the DTIM specified in cfg.ini */
6080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6081 "Switch to DTIM %d", powerRequest.uListenInterval);
6082 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6083 break;
6084
6085 }
6086
6087 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6088 pAdapterNode = pNext;
6089 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006090}
6091
6092void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6093{
6094 /*Switch back to DTIM 1*/
6095 tSirSetPowerParamsReq powerRequest = { 0 };
6096
6097 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6098 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006099 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006100
6101 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6102 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6103 NULL, eANI_BOOLEAN_FALSE);
6104 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6105 NULL, eANI_BOOLEAN_FALSE);
6106
6107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6108 "Switch to DTIM%d",powerRequest.uListenInterval);
6109 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6110
6111}
6112
Jeff Johnson295189b2012-06-20 16:38:30 -07006113VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6114{
6115 VOS_STATUS status = VOS_STATUS_SUCCESS;
6116
6117 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6118 {
6119 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6120 }
6121
6122 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6123 {
6124 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6125 }
6126
6127 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6128 {
6129 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6130 }
6131
6132 return status;
6133}
6134
6135VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6136{
6137 hdd_adapter_t *pAdapter = NULL;
6138 eHalStatus halStatus;
6139 VOS_STATUS status = VOS_STATUS_E_INVAL;
6140 v_BOOL_t disableBmps = FALSE;
6141 v_BOOL_t disableImps = FALSE;
6142
6143 switch(session_type)
6144 {
6145 case WLAN_HDD_INFRA_STATION:
6146 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 case WLAN_HDD_P2P_CLIENT:
6148 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 //Exit BMPS -> Is Sta/P2P Client is already connected
6150 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6151 if((NULL != pAdapter)&&
6152 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6153 {
6154 disableBmps = TRUE;
6155 }
6156
6157 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6158 if((NULL != pAdapter)&&
6159 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6160 {
6161 disableBmps = TRUE;
6162 }
6163
6164 //Exit both Bmps and Imps incase of Go/SAP Mode
6165 if((WLAN_HDD_SOFTAP == session_type) ||
6166 (WLAN_HDD_P2P_GO == session_type))
6167 {
6168 disableBmps = TRUE;
6169 disableImps = TRUE;
6170 }
6171
6172 if(TRUE == disableImps)
6173 {
6174 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6175 {
6176 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6177 }
6178 }
6179
6180 if(TRUE == disableBmps)
6181 {
6182 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6183 {
6184 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6185
6186 if(eHAL_STATUS_SUCCESS != halStatus)
6187 {
6188 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006189 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 VOS_ASSERT(0);
6191 return status;
6192 }
6193 }
6194
6195 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6196 {
6197 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6198
6199 if(eHAL_STATUS_SUCCESS != halStatus)
6200 {
6201 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006202 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 VOS_ASSERT(0);
6204 return status;
6205 }
6206 }
6207 }
6208
6209 if((TRUE == disableBmps) ||
6210 (TRUE == disableImps))
6211 {
6212 /* Now, get the chip into Full Power now */
6213 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6214 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6215 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6216
6217 if(halStatus != eHAL_STATUS_SUCCESS)
6218 {
6219 if(halStatus == eHAL_STATUS_PMC_PENDING)
6220 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306221 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306223 ret = wait_for_completion_interruptible_timeout(
6224 &pHddCtx->full_pwr_comp_var,
6225 msecs_to_jiffies(1000));
6226 if (ret <= 0)
6227 {
6228 hddLog(VOS_TRACE_LEVEL_ERROR,
6229 "%s: wait on full_pwr_comp_var failed %ld",
6230 __func__, ret);
6231 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 }
6233 else
6234 {
6235 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006236 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 VOS_ASSERT(0);
6238 return status;
6239 }
6240 }
6241
6242 status = VOS_STATUS_SUCCESS;
6243 }
6244
6245 break;
6246 }
6247 return status;
6248}
6249
6250hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006251 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 tANI_U8 rtnl_held )
6253{
6254 hdd_adapter_t *pAdapter = NULL;
6255 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6256 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6257 VOS_STATUS exitbmpsStatus;
6258
Arif Hussain6d2a3322013-11-17 19:50:10 -08006259 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006260
Nirav Shah436658f2014-02-28 17:05:45 +05306261 if(macAddr == NULL)
6262 {
6263 /* Not received valid macAddr */
6264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6265 "%s:Unable to add virtual intf: Not able to get"
6266 "valid mac address",__func__);
6267 return NULL;
6268 }
6269
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 //Disable BMPS incase of Concurrency
6271 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6272
6273 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6274 {
6275 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306276 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 VOS_ASSERT(0);
6278 return NULL;
6279 }
6280
6281 switch(session_type)
6282 {
6283 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006285 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 {
6287 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6288
6289 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306290 {
6291 hddLog(VOS_TRACE_LEVEL_FATAL,
6292 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306294 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006295
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306296#ifdef FEATURE_WLAN_TDLS
6297 /* A Mutex Lock is introduced while changing/initializing the mode to
6298 * protect the concurrent access for the Adapters by TDLS module.
6299 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306300 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306301#endif
6302
Jeff Johnsone7245742012-09-05 17:12:55 -07006303 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6304 NL80211_IFTYPE_P2P_CLIENT:
6305 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006306
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306308#ifdef FEATURE_WLAN_TDLS
6309 mutex_unlock(&pHddCtx->tdls_lock);
6310#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306311
6312 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 if( VOS_STATUS_SUCCESS != status )
6314 goto err_free_netdev;
6315
6316 status = hdd_register_interface( pAdapter, rtnl_held );
6317 if( VOS_STATUS_SUCCESS != status )
6318 {
6319 hdd_deinit_adapter(pHddCtx, pAdapter);
6320 goto err_free_netdev;
6321 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306322
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306323 // Workqueue which gets scheduled in IPv4 notification callback.
6324 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6325
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306326#ifdef WLAN_NS_OFFLOAD
6327 // Workqueue which gets scheduled in IPv6 notification callback.
6328 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6329#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 //Stop the Interface TX queue.
6331 netif_tx_disable(pAdapter->dev);
6332 //netif_tx_disable(pWlanDev);
6333 netif_carrier_off(pAdapter->dev);
6334
6335 break;
6336 }
6337
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 case WLAN_HDD_SOFTAP:
6340 {
6341 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6342 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306343 {
6344 hddLog(VOS_TRACE_LEVEL_FATAL,
6345 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006348
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6350 NL80211_IFTYPE_AP:
6351 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 pAdapter->device_mode = session_type;
6353
6354 status = hdd_init_ap_mode(pAdapter);
6355 if( VOS_STATUS_SUCCESS != status )
6356 goto err_free_netdev;
6357
6358 status = hdd_register_hostapd( pAdapter, rtnl_held );
6359 if( VOS_STATUS_SUCCESS != status )
6360 {
6361 hdd_deinit_adapter(pHddCtx, pAdapter);
6362 goto err_free_netdev;
6363 }
6364
6365 netif_tx_disable(pAdapter->dev);
6366 netif_carrier_off(pAdapter->dev);
6367
6368 hdd_set_conparam( 1 );
6369 break;
6370 }
6371 case WLAN_HDD_MONITOR:
6372 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6374 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306375 {
6376 hddLog(VOS_TRACE_LEVEL_FATAL,
6377 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306379 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006380
6381 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6382 pAdapter->device_mode = session_type;
6383 status = hdd_register_interface( pAdapter, rtnl_held );
6384#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6385 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6386#else
6387 pAdapter->dev->open = hdd_mon_open;
6388 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6389#endif
6390 hdd_init_tx_rx( pAdapter );
6391 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6392 //Set adapter to be used for data tx. It will use either GO or softap.
6393 pAdapter->sessionCtx.monitor.pAdapterForTx =
6394 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6396 {
6397 pAdapter->sessionCtx.monitor.pAdapterForTx =
6398 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6399 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 /* This workqueue will be used to transmit management packet over
6401 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006402 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6403 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6404 return NULL;
6405 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006406
Jeff Johnson295189b2012-06-20 16:38:30 -07006407 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6408 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 }
6410 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 case WLAN_HDD_FTM:
6412 {
6413 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6414
6415 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306416 {
6417 hddLog(VOS_TRACE_LEVEL_FATAL,
6418 FL("failed to allocate adapter for session %d"), session_type);
6419 return NULL;
6420 }
6421
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6423 * message while loading driver in FTM mode. */
6424 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6425 pAdapter->device_mode = session_type;
6426 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306427
6428 hdd_init_tx_rx( pAdapter );
6429
6430 //Stop the Interface TX queue.
6431 netif_tx_disable(pAdapter->dev);
6432 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 }
6434 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 default:
6436 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306437 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6438 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 VOS_ASSERT(0);
6440 return NULL;
6441 }
6442 }
6443
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 if( VOS_STATUS_SUCCESS == status )
6445 {
6446 //Add it to the hdd's session list.
6447 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6448 if( NULL == pHddAdapterNode )
6449 {
6450 status = VOS_STATUS_E_NOMEM;
6451 }
6452 else
6453 {
6454 pHddAdapterNode->pAdapter = pAdapter;
6455 status = hdd_add_adapter_back ( pHddCtx,
6456 pHddAdapterNode );
6457 }
6458 }
6459
6460 if( VOS_STATUS_SUCCESS != status )
6461 {
6462 if( NULL != pAdapter )
6463 {
6464 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6465 pAdapter = NULL;
6466 }
6467 if( NULL != pHddAdapterNode )
6468 {
6469 vos_mem_free( pHddAdapterNode );
6470 }
6471
6472 goto resume_bmps;
6473 }
6474
6475 if(VOS_STATUS_SUCCESS == status)
6476 {
6477 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6478
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006479 //Initialize the WoWL service
6480 if(!hdd_init_wowl(pAdapter))
6481 {
6482 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6483 goto err_free_netdev;
6484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 return pAdapter;
6487
6488err_free_netdev:
6489 free_netdev(pAdapter->dev);
6490 wlan_hdd_release_intf_addr( pHddCtx,
6491 pAdapter->macAddressCurrent.bytes );
6492
6493resume_bmps:
6494 //If bmps disabled enable it
6495 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6496 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306497 if (pHddCtx->hdd_wlan_suspended)
6498 {
6499 hdd_set_pwrparams(pHddCtx);
6500 }
6501 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 }
6503 return NULL;
6504}
6505
6506VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6507 tANI_U8 rtnl_held )
6508{
6509 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6510 VOS_STATUS status;
6511
6512 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6513 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306514 {
6515 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6516 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306518 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006519
6520 while ( pCurrent->pAdapter != pAdapter )
6521 {
6522 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6523 if( VOS_STATUS_SUCCESS != status )
6524 break;
6525
6526 pCurrent = pNext;
6527 }
6528 pAdapterNode = pCurrent;
6529 if( VOS_STATUS_SUCCESS == status )
6530 {
6531 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6532 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306533
6534#ifdef FEATURE_WLAN_TDLS
6535
6536 /* A Mutex Lock is introduced while changing/initializing the mode to
6537 * protect the concurrent access for the Adapters by TDLS module.
6538 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306539 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306540#endif
6541
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 hdd_remove_adapter( pHddCtx, pAdapterNode );
6543 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006544 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006545
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306546#ifdef FEATURE_WLAN_TDLS
6547 mutex_unlock(&pHddCtx->tdls_lock);
6548#endif
6549
Jeff Johnson295189b2012-06-20 16:38:30 -07006550
6551 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306552 if ((!vos_concurrent_open_sessions_running()) &&
6553 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6554 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306556 if (pHddCtx->hdd_wlan_suspended)
6557 {
6558 hdd_set_pwrparams(pHddCtx);
6559 }
6560 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 }
6562
6563 return VOS_STATUS_SUCCESS;
6564 }
6565
6566 return VOS_STATUS_E_FAILURE;
6567}
6568
6569VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6570{
6571 hdd_adapter_list_node_t *pHddAdapterNode;
6572 VOS_STATUS status;
6573
6574 ENTER();
6575
6576 do
6577 {
6578 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6579 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6580 {
6581 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6582 vos_mem_free( pHddAdapterNode );
6583 }
6584 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6585
6586 EXIT();
6587
6588 return VOS_STATUS_SUCCESS;
6589}
6590
6591void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6592{
6593 v_U8_t addIE[1] = {0};
6594
6595 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6596 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6597 eANI_BOOLEAN_FALSE) )
6598 {
6599 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006600 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006601 }
6602
6603 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6604 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6605 eANI_BOOLEAN_FALSE) )
6606 {
6607 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006608 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006609 }
6610
6611 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6612 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6613 eANI_BOOLEAN_FALSE) )
6614 {
6615 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006616 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 }
6618}
6619
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306620VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6621 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006622{
6623 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6624 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6625 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306626 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306627 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006628
6629 ENTER();
6630
6631 switch(pAdapter->device_mode)
6632 {
6633 case WLAN_HDD_INFRA_STATION:
6634 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006635 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306636 {
6637 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6638 if( hdd_connIsConnected(pstation) ||
6639 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006640 {
6641 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6642 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6643 pAdapter->sessionId,
6644 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6645 else
6646 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6647 pAdapter->sessionId,
6648 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6649 //success implies disconnect command got queued up successfully
6650 if(halStatus == eHAL_STATUS_SUCCESS)
6651 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306652 ret = wait_for_completion_interruptible_timeout(
6653 &pAdapter->disconnect_comp_var,
6654 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6655 if (ret <= 0)
6656 {
6657 hddLog(VOS_TRACE_LEVEL_ERROR,
6658 "%s: wait on disconnect_comp_var failed %ld",
6659 __func__, ret);
6660 }
6661 }
6662 else
6663 {
6664 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6665 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 }
6667 memset(&wrqu, '\0', sizeof(wrqu));
6668 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6669 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6670 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6671 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306672 else if(pstation->conn_info.connState ==
6673 eConnectionState_Disconnecting)
6674 {
6675 ret = wait_for_completion_interruptible_timeout(
6676 &pAdapter->disconnect_comp_var,
6677 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6678 if (ret <= 0)
6679 {
6680 hddLog(VOS_TRACE_LEVEL_ERROR,
6681 FL("wait on disconnect_comp_var failed %ld"), ret);
6682 }
6683 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 else
6685 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306686 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6687 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306689 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6690 {
6691 while (pAdapter->is_roc_inprogress)
6692 {
6693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6694 "%s: ROC in progress for session %d!!!",
6695 __func__, pAdapter->sessionId);
6696 // waiting for ROC to expire
6697 msleep(500);
6698 /* In GO present case , if retry exceeds 3,
6699 it means something went wrong. */
6700 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6701 {
6702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6703 "%s: ROC completion is not received.!!!", __func__);
6704 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6705 pAdapter->sessionId);
6706 wait_for_completion_interruptible_timeout(
6707 &pAdapter->cancel_rem_on_chan_var,
6708 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6709 break;
6710 }
6711 }
6712 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306713#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306714#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306715 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6716#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306717 if (pAdapter->ipv6_notifier_registered)
6718 {
6719 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6720 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6721 pAdapter->ipv6_notifier_registered = false;
6722 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306723#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306724 if (pAdapter->ipv4_notifier_registered)
6725 {
6726 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6727 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6728 pAdapter->ipv4_notifier_registered = false;
6729 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306730#ifdef WLAN_OPEN_SOURCE
6731 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6732#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306733 /* It is possible that the caller of this function does not
6734 * wish to close the session
6735 */
6736 if (VOS_TRUE == bCloseSession &&
6737 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 {
6739 INIT_COMPLETION(pAdapter->session_close_comp_var);
6740 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306741 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6742 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306744 unsigned long ret;
6745
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306747 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306748 &pAdapter->session_close_comp_var,
6749 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306750 if ( 0 >= ret)
6751 {
6752 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306753 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306754 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 }
6756 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 break;
6759
6760 case WLAN_HDD_SOFTAP:
6761 case WLAN_HDD_P2P_GO:
6762 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306763 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6764 while (pAdapter->is_roc_inprogress) {
6765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6766 "%s: ROC in progress for session %d!!!",
6767 __func__, pAdapter->sessionId);
6768 msleep(500);
6769 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6771 "%s: ROC completion is not received.!!!", __func__);
6772 WLANSAP_CancelRemainOnChannel(
6773 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6774 wait_for_completion_interruptible_timeout(
6775 &pAdapter->cancel_rem_on_chan_var,
6776 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6777 break;
6778 }
6779 }
6780 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 mutex_lock(&pHddCtx->sap_lock);
6782 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6783 {
6784 VOS_STATUS status;
6785 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6786
6787 //Stop Bss.
6788 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6789 if (VOS_IS_STATUS_SUCCESS(status))
6790 {
6791 hdd_hostapd_state_t *pHostapdState =
6792 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6793
6794 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6795
6796 if (!VOS_IS_STATUS_SUCCESS(status))
6797 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306798 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6799 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006800 }
6801 }
6802 else
6803 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006804 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 }
6806 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306807 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006808
6809 if (eHAL_STATUS_FAILURE ==
6810 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6811 0, NULL, eANI_BOOLEAN_FALSE))
6812 {
6813 hddLog(LOGE,
6814 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006815 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 }
6817
6818 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6819 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6820 eANI_BOOLEAN_FALSE) )
6821 {
6822 hddLog(LOGE,
6823 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6824 }
6825
6826 // Reset WNI_CFG_PROBE_RSP Flags
6827 wlan_hdd_reset_prob_rspies(pAdapter);
6828 kfree(pAdapter->sessionCtx.ap.beacon);
6829 pAdapter->sessionCtx.ap.beacon = NULL;
6830 }
6831 mutex_unlock(&pHddCtx->sap_lock);
6832 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006833
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006835#ifdef WLAN_OPEN_SOURCE
6836 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6837#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006839
Jeff Johnson295189b2012-06-20 16:38:30 -07006840 default:
6841 break;
6842 }
6843
6844 EXIT();
6845 return VOS_STATUS_SUCCESS;
6846}
6847
6848VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6849{
6850 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6851 VOS_STATUS status;
6852 hdd_adapter_t *pAdapter;
6853
6854 ENTER();
6855
6856 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6857
6858 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6859 {
6860 pAdapter = pAdapterNode->pAdapter;
6861 netif_tx_disable(pAdapter->dev);
6862 netif_carrier_off(pAdapter->dev);
6863
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306864 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006865
6866 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6867 pAdapterNode = pNext;
6868 }
6869
6870 EXIT();
6871
6872 return VOS_STATUS_SUCCESS;
6873}
6874
Rajeev Kumarf999e582014-01-09 17:33:29 -08006875
6876#ifdef FEATURE_WLAN_BATCH_SCAN
6877/**---------------------------------------------------------------------------
6878
6879 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6880 structures
6881
6882 \param - pAdapter Pointer to HDD adapter
6883
6884 \return - None
6885
6886 --------------------------------------------------------------------------*/
6887void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6888{
6889 tHddBatchScanRsp *pNode;
6890 tHddBatchScanRsp *pPrev;
6891
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306892 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006893 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306894 hddLog(VOS_TRACE_LEVEL_ERROR,
6895 "%s: Adapter context is Null", __func__);
6896 return;
6897 }
6898
6899 pNode = pAdapter->pBatchScanRsp;
6900 while (pNode)
6901 {
6902 pPrev = pNode;
6903 pNode = pNode->pNext;
6904 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006905 }
6906
6907 pAdapter->pBatchScanRsp = NULL;
6908 pAdapter->numScanList = 0;
6909 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6910 pAdapter->prev_batch_id = 0;
6911
6912 return;
6913}
6914#endif
6915
6916
Jeff Johnson295189b2012-06-20 16:38:30 -07006917VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6918{
6919 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6920 VOS_STATUS status;
6921 hdd_adapter_t *pAdapter;
6922
6923 ENTER();
6924
6925 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6926
6927 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6928 {
6929 pAdapter = pAdapterNode->pAdapter;
6930 netif_tx_disable(pAdapter->dev);
6931 netif_carrier_off(pAdapter->dev);
6932
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006933 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6934
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306936 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6937 {
6938 hdd_wmm_adapter_close( pAdapter );
6939 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006941
Rajeev Kumarf999e582014-01-09 17:33:29 -08006942#ifdef FEATURE_WLAN_BATCH_SCAN
6943 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6944 {
6945 hdd_deinit_batch_scan(pAdapter);
6946 }
6947#endif
6948
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6950 pAdapterNode = pNext;
6951 }
6952
6953 EXIT();
6954
6955 return VOS_STATUS_SUCCESS;
6956}
6957
6958VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6959{
6960 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6961 VOS_STATUS status;
6962 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306963 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006964
6965 ENTER();
6966
6967 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6968
6969 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6970 {
6971 pAdapter = pAdapterNode->pAdapter;
6972
Kumar Anand82c009f2014-05-29 00:29:42 -07006973 hdd_wmm_init( pAdapter );
6974
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 switch(pAdapter->device_mode)
6976 {
6977 case WLAN_HDD_INFRA_STATION:
6978 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006979 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306980
6981 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6982
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 hdd_init_station_mode(pAdapter);
6984 /* Open the gates for HDD to receive Wext commands */
6985 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006986 pHddCtx->scan_info.mScanPending = FALSE;
6987 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006988
6989 //Trigger the initial scan
6990 hdd_wlan_initial_scan(pAdapter);
6991
6992 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306993 if (eConnectionState_Associated == connState ||
6994 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006995 {
6996 union iwreq_data wrqu;
6997 memset(&wrqu, '\0', sizeof(wrqu));
6998 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6999 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7000 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007001 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007002
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 /* indicate disconnected event to nl80211 */
7004 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7005 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307007 else if (eConnectionState_Connecting == connState)
7008 {
7009 /*
7010 * Indicate connect failure to supplicant if we were in the
7011 * process of connecting
7012 */
7013 cfg80211_connect_result(pAdapter->dev, NULL,
7014 NULL, 0, NULL, 0,
7015 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7016 GFP_KERNEL);
7017 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 break;
7019
7020 case WLAN_HDD_SOFTAP:
7021 /* softAP can handle SSR */
7022 break;
7023
7024 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007027 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 break;
7029
7030 case WLAN_HDD_MONITOR:
7031 /* monitor interface start */
7032 break;
7033 default:
7034 break;
7035 }
7036
7037 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7038 pAdapterNode = pNext;
7039 }
7040
7041 EXIT();
7042
7043 return VOS_STATUS_SUCCESS;
7044}
7045
7046VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7047{
7048 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7049 hdd_adapter_t *pAdapter;
7050 VOS_STATUS status;
7051 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307052 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007053
7054 ENTER();
7055
7056 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7057
7058 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7059 {
7060 pAdapter = pAdapterNode->pAdapter;
7061
7062 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7063 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7064 {
7065 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7066 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7067
Abhishek Singhf4669da2014-05-26 15:07:49 +05307068 hddLog(VOS_TRACE_LEVEL_INFO,
7069 "%s: Set HDD connState to eConnectionState_NotConnected",
7070 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7072 init_completion(&pAdapter->disconnect_comp_var);
7073 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7074 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7075
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307076 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 &pAdapter->disconnect_comp_var,
7078 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307079 if (0 >= ret)
7080 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7081 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007082
7083 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7084 pHddCtx->isAmpAllowed = VOS_FALSE;
7085 sme_RoamConnect(pHddCtx->hHal,
7086 pAdapter->sessionId, &(pWextState->roamProfile),
7087 &roamId);
7088 }
7089
7090 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7091 pAdapterNode = pNext;
7092 }
7093
7094 EXIT();
7095
7096 return VOS_STATUS_SUCCESS;
7097}
7098
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007099void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7100{
7101 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7102 VOS_STATUS status;
7103 hdd_adapter_t *pAdapter;
7104 hdd_station_ctx_t *pHddStaCtx;
7105 hdd_ap_ctx_t *pHddApCtx;
7106 hdd_hostapd_state_t * pHostapdState;
7107 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7108 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7109 const char *p2pMode = "DEV";
7110 const char *ccMode = "Standalone";
7111 int n;
7112
7113 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7114 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7115 {
7116 pAdapter = pAdapterNode->pAdapter;
7117 switch (pAdapter->device_mode) {
7118 case WLAN_HDD_INFRA_STATION:
7119 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7120 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7121 staChannel = pHddStaCtx->conn_info.operationChannel;
7122 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7123 }
7124 break;
7125 case WLAN_HDD_P2P_CLIENT:
7126 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7127 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7128 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7129 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7130 p2pMode = "CLI";
7131 }
7132 break;
7133 case WLAN_HDD_P2P_GO:
7134 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7135 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7136 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7137 p2pChannel = pHddApCtx->operatingChannel;
7138 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7139 }
7140 p2pMode = "GO";
7141 break;
7142 case WLAN_HDD_SOFTAP:
7143 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7144 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7145 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7146 apChannel = pHddApCtx->operatingChannel;
7147 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7148 }
7149 break;
7150 default:
7151 break;
7152 }
7153 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7154 pAdapterNode = pNext;
7155 }
7156 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7157 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7158 }
7159 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7160 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7161 if (p2pChannel > 0) {
7162 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7163 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7164 }
7165 if (apChannel > 0) {
7166 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7167 apChannel, MAC_ADDR_ARRAY(apBssid));
7168 }
7169
7170 if (p2pChannel > 0 && apChannel > 0) {
7171 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7172 }
7173}
7174
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007175bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007176{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007177 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007178}
7179
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007180/* Once SSR is disabled then it cannot be set. */
7181void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007182{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007183 if (HDD_SSR_DISABLED == isSsrRequired)
7184 return;
7185
Jeff Johnson295189b2012-06-20 16:38:30 -07007186 isSsrRequired = value;
7187}
7188
7189VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7190 hdd_adapter_list_node_t** ppAdapterNode)
7191{
7192 VOS_STATUS status;
7193 spin_lock(&pHddCtx->hddAdapters.lock);
7194 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7195 (hdd_list_node_t**) ppAdapterNode );
7196 spin_unlock(&pHddCtx->hddAdapters.lock);
7197 return status;
7198}
7199
7200VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7201 hdd_adapter_list_node_t* pAdapterNode,
7202 hdd_adapter_list_node_t** pNextAdapterNode)
7203{
7204 VOS_STATUS status;
7205 spin_lock(&pHddCtx->hddAdapters.lock);
7206 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7207 (hdd_list_node_t*) pAdapterNode,
7208 (hdd_list_node_t**)pNextAdapterNode );
7209
7210 spin_unlock(&pHddCtx->hddAdapters.lock);
7211 return status;
7212}
7213
7214VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7215 hdd_adapter_list_node_t* pAdapterNode)
7216{
7217 VOS_STATUS status;
7218 spin_lock(&pHddCtx->hddAdapters.lock);
7219 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7220 &pAdapterNode->node );
7221 spin_unlock(&pHddCtx->hddAdapters.lock);
7222 return status;
7223}
7224
7225VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7226 hdd_adapter_list_node_t** ppAdapterNode)
7227{
7228 VOS_STATUS status;
7229 spin_lock(&pHddCtx->hddAdapters.lock);
7230 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7231 (hdd_list_node_t**) ppAdapterNode );
7232 spin_unlock(&pHddCtx->hddAdapters.lock);
7233 return status;
7234}
7235
7236VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7237 hdd_adapter_list_node_t* pAdapterNode)
7238{
7239 VOS_STATUS status;
7240 spin_lock(&pHddCtx->hddAdapters.lock);
7241 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7242 (hdd_list_node_t*) pAdapterNode );
7243 spin_unlock(&pHddCtx->hddAdapters.lock);
7244 return status;
7245}
7246
7247VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7248 hdd_adapter_list_node_t* pAdapterNode)
7249{
7250 VOS_STATUS status;
7251 spin_lock(&pHddCtx->hddAdapters.lock);
7252 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7253 (hdd_list_node_t*) pAdapterNode );
7254 spin_unlock(&pHddCtx->hddAdapters.lock);
7255 return status;
7256}
7257
7258hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7259 tSirMacAddr macAddr )
7260{
7261 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7262 hdd_adapter_t *pAdapter;
7263 VOS_STATUS status;
7264
7265 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7266
7267 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7268 {
7269 pAdapter = pAdapterNode->pAdapter;
7270
7271 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7272 macAddr, sizeof(tSirMacAddr) ) )
7273 {
7274 return pAdapter;
7275 }
7276 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7277 pAdapterNode = pNext;
7278 }
7279
7280 return NULL;
7281
7282}
7283
7284hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7285{
7286 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7287 hdd_adapter_t *pAdapter;
7288 VOS_STATUS status;
7289
7290 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7291
7292 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7293 {
7294 pAdapter = pAdapterNode->pAdapter;
7295
7296 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7297 IFNAMSIZ ) )
7298 {
7299 return pAdapter;
7300 }
7301 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7302 pAdapterNode = pNext;
7303 }
7304
7305 return NULL;
7306
7307}
7308
7309hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7310{
7311 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7312 hdd_adapter_t *pAdapter;
7313 VOS_STATUS status;
7314
7315 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7316
7317 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7318 {
7319 pAdapter = pAdapterNode->pAdapter;
7320
7321 if( pAdapter && (mode == pAdapter->device_mode) )
7322 {
7323 return pAdapter;
7324 }
7325 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7326 pAdapterNode = pNext;
7327 }
7328
7329 return NULL;
7330
7331}
7332
7333//Remove this function later
7334hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7335{
7336 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7337 hdd_adapter_t *pAdapter;
7338 VOS_STATUS status;
7339
7340 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7341
7342 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7343 {
7344 pAdapter = pAdapterNode->pAdapter;
7345
7346 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7347 {
7348 return pAdapter;
7349 }
7350
7351 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7352 pAdapterNode = pNext;
7353 }
7354
7355 return NULL;
7356
7357}
7358
Jeff Johnson295189b2012-06-20 16:38:30 -07007359/**---------------------------------------------------------------------------
7360
7361 \brief hdd_set_monitor_tx_adapter() -
7362
7363 This API initializes the adapter to be used while transmitting on monitor
7364 adapter.
7365
7366 \param - pHddCtx - Pointer to the HDD context.
7367 pAdapter - Adapter that will used for TX. This can be NULL.
7368 \return - None.
7369 --------------------------------------------------------------------------*/
7370void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7371{
7372 hdd_adapter_t *pMonAdapter;
7373
7374 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7375
7376 if( NULL != pMonAdapter )
7377 {
7378 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7379 }
7380}
Jeff Johnson295189b2012-06-20 16:38:30 -07007381/**---------------------------------------------------------------------------
7382
7383 \brief hdd_select_queue() -
7384
7385 This API returns the operating channel of the requested device mode
7386
7387 \param - pHddCtx - Pointer to the HDD context.
7388 - mode - Device mode for which operating channel is required
7389 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7390 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7391 \return - channel number. "0" id the requested device is not found OR it is not connected.
7392 --------------------------------------------------------------------------*/
7393v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7394{
7395 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7396 VOS_STATUS status;
7397 hdd_adapter_t *pAdapter;
7398 v_U8_t operatingChannel = 0;
7399
7400 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7401
7402 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7403 {
7404 pAdapter = pAdapterNode->pAdapter;
7405
7406 if( mode == pAdapter->device_mode )
7407 {
7408 switch(pAdapter->device_mode)
7409 {
7410 case WLAN_HDD_INFRA_STATION:
7411 case WLAN_HDD_P2P_CLIENT:
7412 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7413 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7414 break;
7415 case WLAN_HDD_SOFTAP:
7416 case WLAN_HDD_P2P_GO:
7417 /*softap connection info */
7418 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7419 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7420 break;
7421 default:
7422 break;
7423 }
7424
7425 break; //Found the device of interest. break the loop
7426 }
7427
7428 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7429 pAdapterNode = pNext;
7430 }
7431 return operatingChannel;
7432}
7433
7434#ifdef WLAN_FEATURE_PACKET_FILTERING
7435/**---------------------------------------------------------------------------
7436
7437 \brief hdd_set_multicast_list() -
7438
7439 This used to set the multicast address list.
7440
7441 \param - dev - Pointer to the WLAN device.
7442 - skb - Pointer to OS packet (sk_buff).
7443 \return - success/fail
7444
7445 --------------------------------------------------------------------------*/
7446static void hdd_set_multicast_list(struct net_device *dev)
7447{
7448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 int mc_count;
7450 int i = 0;
7451 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307452
7453 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 {
7455 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307456 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007457 return;
7458 }
7459
7460 if (dev->flags & IFF_ALLMULTI)
7461 {
7462 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007463 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307464 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007465 }
7466 else
7467 {
7468 mc_count = netdev_mc_count(dev);
7469 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007470 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007471 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7472 {
7473 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007474 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307475 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 return;
7477 }
7478
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307479 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007480
7481 netdev_for_each_mc_addr(ha, dev) {
7482 if (i == mc_count)
7483 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307484 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7485 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307488 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007489 i++;
7490 }
7491 }
7492 return;
7493}
7494#endif
7495
7496/**---------------------------------------------------------------------------
7497
7498 \brief hdd_select_queue() -
7499
7500 This function is registered with the Linux OS for network
7501 core to decide which queue to use first.
7502
7503 \param - dev - Pointer to the WLAN device.
7504 - skb - Pointer to OS packet (sk_buff).
7505 \return - ac, Queue Index/access category corresponding to UP in IP header
7506
7507 --------------------------------------------------------------------------*/
7508v_U16_t hdd_select_queue(struct net_device *dev,
7509 struct sk_buff *skb)
7510{
7511 return hdd_wmm_select_queue(dev, skb);
7512}
7513
7514
7515/**---------------------------------------------------------------------------
7516
7517 \brief hdd_wlan_initial_scan() -
7518
7519 This function triggers the initial scan
7520
7521 \param - pAdapter - Pointer to the HDD adapter.
7522
7523 --------------------------------------------------------------------------*/
7524void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7525{
7526 tCsrScanRequest scanReq;
7527 tCsrChannelInfo channelInfo;
7528 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007529 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007530 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7531
7532 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7533 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7534 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7535
7536 if(sme_Is11dSupported(pHddCtx->hHal))
7537 {
7538 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7539 if ( HAL_STATUS_SUCCESS( halStatus ) )
7540 {
7541 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7542 if( !scanReq.ChannelInfo.ChannelList )
7543 {
7544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7545 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007546 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 return;
7548 }
7549 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7550 channelInfo.numOfChannels);
7551 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7552 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007553 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007554 }
7555
7556 scanReq.scanType = eSIR_PASSIVE_SCAN;
7557 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7558 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7559 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7560 }
7561 else
7562 {
7563 scanReq.scanType = eSIR_ACTIVE_SCAN;
7564 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7565 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7566 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7567 }
7568
7569 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7570 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7571 {
7572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7573 __func__, halStatus );
7574 }
7575
7576 if(sme_Is11dSupported(pHddCtx->hHal))
7577 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7578}
7579
Jeff Johnson295189b2012-06-20 16:38:30 -07007580/**---------------------------------------------------------------------------
7581
7582 \brief hdd_full_power_callback() - HDD full power callback function
7583
7584 This is the function invoked by SME to inform the result of a full power
7585 request issued by HDD
7586
7587 \param - callbackcontext - Pointer to cookie
7588 \param - status - result of request
7589
7590 \return - None
7591
7592 --------------------------------------------------------------------------*/
7593static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7594{
Jeff Johnson72a40512013-12-19 10:14:15 -08007595 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007596
7597 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307598 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007599
7600 if (NULL == callbackContext)
7601 {
7602 hddLog(VOS_TRACE_LEVEL_ERROR,
7603 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007604 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007605 return;
7606 }
7607
Jeff Johnson72a40512013-12-19 10:14:15 -08007608 /* there is a race condition that exists between this callback
7609 function and the caller since the caller could time out either
7610 before or while this code is executing. we use a spinlock to
7611 serialize these actions */
7612 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007613
7614 if (POWER_CONTEXT_MAGIC != pContext->magic)
7615 {
7616 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007617 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007618 hddLog(VOS_TRACE_LEVEL_WARN,
7619 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007620 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 return;
7622 }
7623
Jeff Johnson72a40512013-12-19 10:14:15 -08007624 /* context is valid so caller is still waiting */
7625
7626 /* paranoia: invalidate the magic */
7627 pContext->magic = 0;
7628
7629 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007631
7632 /* serialization is complete */
7633 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007634}
7635
7636/**---------------------------------------------------------------------------
7637
7638 \brief hdd_wlan_exit() - HDD WLAN exit function
7639
7640 This is the driver exit point (invoked during rmmod)
7641
7642 \param - pHddCtx - Pointer to the HDD Context
7643
7644 \return - None
7645
7646 --------------------------------------------------------------------------*/
7647void hdd_wlan_exit(hdd_context_t *pHddCtx)
7648{
7649 eHalStatus halStatus;
7650 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7651 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307652 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007653 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007654 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307656 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007657
7658 ENTER();
7659
Jeff Johnson88ba7742013-02-27 14:36:02 -08007660 if (VOS_FTM_MODE != hdd_get_conparam())
7661 {
7662 // Unloading, restart logic is no more required.
7663 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007664
c_hpothu5ab05e92014-06-13 17:34:05 +05307665 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7666 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307668 pAdapter = pAdapterNode->pAdapter;
7669 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307671 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7672 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7673 {
7674 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7675 hdd_UnregisterWext(pAdapter->dev);
7676 }
7677 // Cancel any outstanding scan requests. We are about to close all
7678 // of our adapters, but an adapter structure is what SME passes back
7679 // to our callback function. Hence if there are any outstanding scan
7680 // requests then there is a race condition between when the adapter
7681 // is closed and when the callback is invoked.We try to resolve that
7682 // race condition here by canceling any outstanding scans before we
7683 // close the adapters.
7684 // Note that the scans may be cancelled in an asynchronous manner,
7685 // so ideally there needs to be some kind of synchronization. Rather
7686 // than introduce a new synchronization here, we will utilize the
7687 // fact that we are about to Request Full Power, and since that is
7688 // synchronized, the expectation is that by the time Request Full
7689 // Power has completed all scans will be cancelled.
7690 if (pHddCtx->scan_info.mScanPending)
7691 {
7692 hddLog(VOS_TRACE_LEVEL_INFO,
7693 FL("abort scan mode: %d sessionId: %d"),
7694 pAdapter->device_mode,
7695 pAdapter->sessionId);
7696 hdd_abort_mac_scan(pHddCtx,
7697 pAdapter->sessionId,
7698 eCSR_SCAN_ABORT_DEFAULT);
7699 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307701 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7702 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007703 }
7704 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307705 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007706 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307707 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007708 wlan_hdd_ftm_close(pHddCtx);
7709 goto free_hdd_ctx;
7710 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307711
Jeff Johnson295189b2012-06-20 16:38:30 -07007712 /* DeRegister with platform driver as client for Suspend/Resume */
7713 vosStatus = hddDeregisterPmOps(pHddCtx);
7714 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7715 {
7716 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7717 VOS_ASSERT(0);
7718 }
7719
7720 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7721 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7722 {
7723 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7724 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007725
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007726 //Stop the traffic monitor timer
7727 if ( VOS_TIMER_STATE_RUNNING ==
7728 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7729 {
7730 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7731 }
7732
7733 // Destroy the traffic monitor timer
7734 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7735 &pHddCtx->tx_rx_trafficTmr)))
7736 {
7737 hddLog(VOS_TRACE_LEVEL_ERROR,
7738 "%s: Cannot deallocate Traffic monitor timer", __func__);
7739 }
7740
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 //Disable IMPS/BMPS as we do not want the device to enter any power
7742 //save mode during shutdown
7743 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7744 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7745 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7746
7747 //Ensure that device is in full power as we will touch H/W during vos_Stop
7748 init_completion(&powerContext.completion);
7749 powerContext.magic = POWER_CONTEXT_MAGIC;
7750
7751 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7752 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7753
7754 if (eHAL_STATUS_SUCCESS != halStatus)
7755 {
7756 if (eHAL_STATUS_PMC_PENDING == halStatus)
7757 {
7758 /* request was sent -- wait for the response */
7759 lrc = wait_for_completion_interruptible_timeout(
7760 &powerContext.completion,
7761 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 if (lrc <= 0)
7763 {
7764 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007765 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007766 }
7767 }
7768 else
7769 {
7770 hddLog(VOS_TRACE_LEVEL_ERROR,
7771 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007772 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 /* continue -- need to clean up as much as possible */
7774 }
7775 }
7776
Jeff Johnson72a40512013-12-19 10:14:15 -08007777 /* either we never sent a request, we sent a request and received a
7778 response or we sent a request and timed out. if we never sent a
7779 request or if we sent a request and got a response, we want to
7780 clear the magic out of paranoia. if we timed out there is a
7781 race condition such that the callback function could be
7782 executing at the same time we are. of primary concern is if the
7783 callback function had already verified the "magic" but had not
7784 yet set the completion variable when a timeout occurred. we
7785 serialize these activities by invalidating the magic while
7786 holding a shared spinlock which will cause us to block if the
7787 callback is currently executing */
7788 spin_lock(&hdd_context_lock);
7789 powerContext.magic = 0;
7790 spin_unlock(&hdd_context_lock);
7791
Yue Ma0d4891e2013-08-06 17:01:45 -07007792 hdd_debugfs_exit(pHddCtx);
7793
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 // Unregister the Net Device Notifier
7795 unregister_netdevice_notifier(&hdd_netdev_notifier);
7796
Jeff Johnson295189b2012-06-20 16:38:30 -07007797 hdd_stop_all_adapters( pHddCtx );
7798
Jeff Johnson295189b2012-06-20 16:38:30 -07007799#ifdef WLAN_BTAMP_FEATURE
7800 vosStatus = WLANBAP_Stop(pVosContext);
7801 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7802 {
7803 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7804 "%s: Failed to stop BAP",__func__);
7805 }
7806#endif //WLAN_BTAMP_FEATURE
7807
7808 //Stop all the modules
7809 vosStatus = vos_stop( pVosContext );
7810 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7811 {
7812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7813 "%s: Failed to stop VOSS",__func__);
7814 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7815 }
7816
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 //Assert Deep sleep signal now to put Libra HW in lowest power state
7818 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7819 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7820
7821 //Vote off any PMIC voltage supplies
7822 vos_chipPowerDown(NULL, NULL, NULL);
7823
7824 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7825
Leo Chang59cdc7e2013-07-10 10:08:21 -07007826
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007828 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007829
7830 //Close the scheduler before calling vos_close to make sure no thread is
7831 // scheduled after the each module close is called i.e after all the data
7832 // structures are freed.
7833 vosStatus = vos_sched_close( pVosContext );
7834 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7835 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7836 "%s: Failed to close VOSS Scheduler",__func__);
7837 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7838 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007839#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007840#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7841 /* Destroy the wake lock */
7842 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7843#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007844 /* Destroy the wake lock */
7845 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007846#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007847
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307848#ifdef CONFIG_ENABLE_LINUX_REG
7849 vosStatus = vos_nv_close();
7850 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7851 {
7852 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7853 "%s: Failed to close NV", __func__);
7854 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7855 }
7856#endif
7857
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 //Close VOSS
7859 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7860 vos_close(pVosContext);
7861
Jeff Johnson295189b2012-06-20 16:38:30 -07007862 //Close Watchdog
7863 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7864 vos_watchdog_close(pVosContext);
7865
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307866 //Clean up HDD Nlink Service
7867 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007868#ifdef WLAN_KD_READY_NOTIFIER
7869 nl_srv_exit(pHddCtx->ptt_pid);
7870#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307871 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007872#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307873
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307874#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307875 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307876 {
7877 wlan_logging_sock_deactivate_svc();
7878 }
7879#endif
7880
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 /* Cancel the vote for XO Core ON.
7882 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7883 * exited at this point
7884 */
7885 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007886 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7888 {
7889 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7890 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007891 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007892 }
7893
7894 hdd_close_all_adapters( pHddCtx );
7895
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 /* free the power on lock from platform driver */
7897 if (free_riva_power_on_lock("wlan"))
7898 {
7899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7900 __func__);
7901 }
7902
Jeff Johnson88ba7742013-02-27 14:36:02 -08007903free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307904
7905 //Free up dynamically allocated members inside HDD Adapter
7906 if (pHddCtx->cfg_ini)
7907 {
7908 kfree(pHddCtx->cfg_ini);
7909 pHddCtx->cfg_ini= NULL;
7910 }
7911
Leo Changf04ddad2013-09-18 13:46:38 -07007912 /* FTM mode, WIPHY did not registered
7913 If un-register here, system crash will happen */
7914 if (VOS_FTM_MODE != hdd_get_conparam())
7915 {
7916 wiphy_unregister(wiphy) ;
7917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007919 if (hdd_is_ssr_required())
7920 {
7921 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007922 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 msleep(5000);
7924 }
7925 hdd_set_ssr_required (VOS_FALSE);
7926}
7927
7928
7929/**---------------------------------------------------------------------------
7930
7931 \brief hdd_update_config_from_nv() - Function to update the contents of
7932 the running configuration with parameters taken from NV storage
7933
7934 \param - pHddCtx - Pointer to the HDD global context
7935
7936 \return - VOS_STATUS_SUCCESS if successful
7937
7938 --------------------------------------------------------------------------*/
7939static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7940{
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 v_BOOL_t itemIsValid = VOS_FALSE;
7942 VOS_STATUS status;
7943 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7944 v_U8_t macLoop;
7945
7946 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7947 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7948 if(status != VOS_STATUS_SUCCESS)
7949 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007950 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 return VOS_STATUS_E_FAILURE;
7952 }
7953
7954 if (itemIsValid == VOS_TRUE)
7955 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007956 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7958 VOS_MAX_CONCURRENCY_PERSONA);
7959 if(status != VOS_STATUS_SUCCESS)
7960 {
7961 /* Get MAC from NV fail, not update CFG info
7962 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007963 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 return VOS_STATUS_E_FAILURE;
7965 }
7966
7967 /* If first MAC is not valid, treat all others are not valid
7968 * Then all MACs will be got from ini file */
7969 if(vos_is_macaddr_zero(&macFromNV[0]))
7970 {
7971 /* MAC address in NV file is not configured yet */
7972 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7973 return VOS_STATUS_E_INVAL;
7974 }
7975
7976 /* Get MAC address from NV, update CFG info */
7977 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7978 {
7979 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7980 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307981 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 /* This MAC is not valid, skip it
7983 * This MAC will be got from ini file */
7984 }
7985 else
7986 {
7987 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7988 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7989 VOS_MAC_ADDR_SIZE);
7990 }
7991 }
7992 }
7993 else
7994 {
7995 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7996 return VOS_STATUS_E_FAILURE;
7997 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007998
Jeff Johnson295189b2012-06-20 16:38:30 -07007999
8000 return VOS_STATUS_SUCCESS;
8001}
8002
8003/**---------------------------------------------------------------------------
8004
8005 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8006
8007 \param - pAdapter - Pointer to the HDD
8008
8009 \return - None
8010
8011 --------------------------------------------------------------------------*/
8012VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8013{
8014 eHalStatus halStatus;
8015 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308016 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008017
Jeff Johnson295189b2012-06-20 16:38:30 -07008018
8019 // Send ready indication to the HDD. This will kick off the MAC
8020 // into a 'running' state and should kick off an initial scan.
8021 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8022 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8023 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308024 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 "code %08d [x%08x]",__func__, halStatus, halStatus );
8026 return VOS_STATUS_E_FAILURE;
8027 }
8028
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308029 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008030 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8031 // And RIVA will crash
8032 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8033 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308034 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8035 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8036
8037
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 return VOS_STATUS_SUCCESS;
8039}
8040
Jeff Johnson295189b2012-06-20 16:38:30 -07008041/* wake lock APIs for HDD */
8042void hdd_prevent_suspend(void)
8043{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008044#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008046#else
8047 wcnss_prevent_suspend();
8048#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008049}
8050
8051void hdd_allow_suspend(void)
8052{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008053#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008055#else
8056 wcnss_allow_suspend();
8057#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008058}
8059
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308060void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008061{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008062#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008063 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008064#else
8065 /* Do nothing as there is no API in wcnss for timeout*/
8066#endif
8067}
8068
Jeff Johnson295189b2012-06-20 16:38:30 -07008069/**---------------------------------------------------------------------------
8070
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008071 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8072 information between Host and Riva
8073
8074 This function gets reported version of FW
8075 It also finds the version of Riva headers used to compile the host
8076 It compares the above two and prints a warning if they are different
8077 It gets the SW and HW version string
8078 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8079 indicating the features they support through a bitmap
8080
8081 \param - pHddCtx - Pointer to HDD context
8082
8083 \return - void
8084
8085 --------------------------------------------------------------------------*/
8086
8087void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8088{
8089
8090 tSirVersionType versionCompiled;
8091 tSirVersionType versionReported;
8092 tSirVersionString versionString;
8093 tANI_U8 fwFeatCapsMsgSupported = 0;
8094 VOS_STATUS vstatus;
8095
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008096 memset(&versionCompiled, 0, sizeof(versionCompiled));
8097 memset(&versionReported, 0, sizeof(versionReported));
8098
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008099 /* retrieve and display WCNSS version information */
8100 do {
8101
8102 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8103 &versionCompiled);
8104 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8105 {
8106 hddLog(VOS_TRACE_LEVEL_FATAL,
8107 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008108 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008109 break;
8110 }
8111
8112 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8113 &versionReported);
8114 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8115 {
8116 hddLog(VOS_TRACE_LEVEL_FATAL,
8117 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008118 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008119 break;
8120 }
8121
8122 if ((versionCompiled.major != versionReported.major) ||
8123 (versionCompiled.minor != versionReported.minor) ||
8124 (versionCompiled.version != versionReported.version) ||
8125 (versionCompiled.revision != versionReported.revision))
8126 {
8127 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8128 "Host expected %u.%u.%u.%u\n",
8129 WLAN_MODULE_NAME,
8130 (int)versionReported.major,
8131 (int)versionReported.minor,
8132 (int)versionReported.version,
8133 (int)versionReported.revision,
8134 (int)versionCompiled.major,
8135 (int)versionCompiled.minor,
8136 (int)versionCompiled.version,
8137 (int)versionCompiled.revision);
8138 }
8139 else
8140 {
8141 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8142 WLAN_MODULE_NAME,
8143 (int)versionReported.major,
8144 (int)versionReported.minor,
8145 (int)versionReported.version,
8146 (int)versionReported.revision);
8147 }
8148
8149 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8150 versionString,
8151 sizeof(versionString));
8152 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8153 {
8154 hddLog(VOS_TRACE_LEVEL_FATAL,
8155 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008156 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008157 break;
8158 }
8159
8160 pr_info("%s: WCNSS software version %s\n",
8161 WLAN_MODULE_NAME, versionString);
8162
8163 vstatus = sme_GetWcnssHardwareVersion(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 hardware 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 hardware version %s\n",
8175 WLAN_MODULE_NAME, versionString);
8176
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008177 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8178 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008179 send the message only if it the riva is 1.1
8180 minor numbers for different riva branches:
8181 0 -> (1.0)Mainline Build
8182 1 -> (1.1)Mainline Build
8183 2->(1.04) Stability Build
8184 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008185 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008186 ((versionReported.minor>=1) && (versionReported.version>=1)))
8187 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8188 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008189
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008190 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008191 {
8192#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8193 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8194 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8195#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008196 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8197 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8198 {
8199 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8200 }
8201
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008202 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008203 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008204
8205 } while (0);
8206
8207}
8208
8209/**---------------------------------------------------------------------------
8210
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308211 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8212
8213 \param - pHddCtx - Pointer to the hdd context
8214
8215 \return - true if hardware supports 5GHz
8216
8217 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308218boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308219{
8220 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8221 * then hardware support 5Ghz.
8222 */
8223 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8224 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308226 return true;
8227 }
8228 else
8229 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308231 __func__);
8232 return false;
8233 }
8234}
8235
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308236/**---------------------------------------------------------------------------
8237
8238 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8239 generate function
8240
8241 This is generate the random mac address for WLAN interface
8242
8243 \param - pHddCtx - Pointer to HDD context
8244 idx - Start interface index to get auto
8245 generated mac addr.
8246 mac_addr - Mac address
8247
8248 \return - 0 for success, < 0 for failure
8249
8250 --------------------------------------------------------------------------*/
8251
8252static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8253 int idx, v_MACADDR_t mac_addr)
8254{
8255 int i;
8256 unsigned int serialno;
8257 serialno = wcnss_get_serial_number();
8258
8259 if (0 != serialno)
8260 {
8261 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8262 bytes of the serial number that can be used to generate
8263 the other 3 bytes of the MAC address. Mask off all but
8264 the lower 3 bytes (this will also make sure we don't
8265 overflow in the next step) */
8266 serialno &= 0x00FFFFFF;
8267
8268 /* we need a unique address for each session */
8269 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8270
8271 /* autogen other Mac addresses */
8272 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8273 {
8274 /* start with the entire default address */
8275 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8276 /* then replace the lower 3 bytes */
8277 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8278 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8279 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8280
8281 serialno++;
8282 hddLog(VOS_TRACE_LEVEL_ERROR,
8283 "%s: Derived Mac Addr: "
8284 MAC_ADDRESS_STR, __func__,
8285 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8286 }
8287
8288 }
8289 else
8290 {
8291 hddLog(LOGE, FL("Failed to Get Serial NO"));
8292 return -1;
8293 }
8294 return 0;
8295}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308296
8297/**---------------------------------------------------------------------------
8298
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308299 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8300 completed to flush out the scan results
8301
8302 11d scan is done during driver load and is a passive scan on all
8303 channels supported by the device, 11d scans may find some APs on
8304 frequencies which are forbidden to be used in the regulatory domain
8305 the device is operating in. If these APs are notified to the supplicant
8306 it may try to connect to these APs, thus flush out all the scan results
8307 which are present in SME after 11d scan is done.
8308
8309 \return - eHalStatus
8310
8311 --------------------------------------------------------------------------*/
8312static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8313 tANI_U32 scanId, eCsrScanStatus status)
8314{
8315 ENTER();
8316
8317 sme_ScanFlushResult(halHandle, 0);
8318
8319 EXIT();
8320
8321 return eHAL_STATUS_SUCCESS;
8322}
8323
8324/**---------------------------------------------------------------------------
8325
Jeff Johnson295189b2012-06-20 16:38:30 -07008326 \brief hdd_wlan_startup() - HDD init function
8327
8328 This is the driver startup code executed once a WLAN device has been detected
8329
8330 \param - dev - Pointer to the underlying device
8331
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008332 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008333
8334 --------------------------------------------------------------------------*/
8335
8336int hdd_wlan_startup(struct device *dev )
8337{
8338 VOS_STATUS status;
8339 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008340 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 hdd_context_t *pHddCtx = NULL;
8342 v_CONTEXT_t pVosContext= NULL;
8343#ifdef WLAN_BTAMP_FEATURE
8344 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8345 WLANBAP_ConfigType btAmpConfig;
8346 hdd_config_t *pConfig;
8347#endif
8348 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308350 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008351
8352 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 /*
8354 * cfg80211: wiphy allocation
8355 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308356 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008357
8358 if(wiphy == NULL)
8359 {
8360 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008361 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 }
8363
8364 pHddCtx = wiphy_priv(wiphy);
8365
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 //Initialize the adapter context to zeros.
8367 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8368
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008370 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308371 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008372
8373 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8374
8375 /*Get vos context here bcoz vos_open requires it*/
8376 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8377
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008378 if(pVosContext == NULL)
8379 {
8380 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8381 goto err_free_hdd_context;
8382 }
8383
Jeff Johnson295189b2012-06-20 16:38:30 -07008384 //Save the Global VOSS context in adapter context for future.
8385 pHddCtx->pvosContext = pVosContext;
8386
8387 //Save the adapter context in global context for future.
8388 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8389
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 pHddCtx->parent_dev = dev;
8391
8392 init_completion(&pHddCtx->full_pwr_comp_var);
8393 init_completion(&pHddCtx->standby_comp_var);
8394 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008395 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008396 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308397 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308398 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008399
8400#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008401 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008402#else
8403 init_completion(&pHddCtx->driver_crda_req);
8404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008405
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308406 spin_lock_init(&pHddCtx->schedScan_lock);
8407
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8409
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308410#ifdef FEATURE_WLAN_TDLS
8411 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8412 * invoked by other instances also) to protect the concurrent
8413 * access for the Adapters by TDLS module.
8414 */
8415 mutex_init(&pHddCtx->tdls_lock);
8416#endif
8417
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308418 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 // Load all config first as TL config is needed during vos_open
8420 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8421 if(pHddCtx->cfg_ini == NULL)
8422 {
8423 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8424 goto err_free_hdd_context;
8425 }
8426
8427 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8428
8429 // Read and parse the qcom_cfg.ini file
8430 status = hdd_parse_config_ini( pHddCtx );
8431 if ( VOS_STATUS_SUCCESS != status )
8432 {
8433 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8434 __func__, WLAN_INI_FILE);
8435 goto err_config;
8436 }
Arif Hussaind5218912013-12-05 01:10:55 -08008437#ifdef MEMORY_DEBUG
8438 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8439 vos_mem_init();
8440
8441 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8442 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008444
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308445 /* INI has been read, initialise the configuredMcastBcastFilter with
8446 * INI value as this will serve as the default value
8447 */
8448 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8449 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8450 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308451
8452 if (false == hdd_is_5g_supported(pHddCtx))
8453 {
8454 //5Ghz is not supported.
8455 if (1 != pHddCtx->cfg_ini->nBandCapability)
8456 {
8457 hddLog(VOS_TRACE_LEVEL_INFO,
8458 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8459 pHddCtx->cfg_ini->nBandCapability = 1;
8460 }
8461 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308462
8463 /* If SNR Monitoring is enabled, FW has to parse all beacons
8464 * for calcaluting and storing the average SNR, so set Nth beacon
8465 * filter to 1 to enable FW to parse all the beaocons
8466 */
8467 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8468 {
8469 /* The log level is deliberately set to WARN as overriding
8470 * nthBeaconFilter to 1 will increase power cosumption and this
8471 * might just prove helpful to detect the power issue.
8472 */
8473 hddLog(VOS_TRACE_LEVEL_WARN,
8474 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8475 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308478 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008480 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008482 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8483 {
8484 hddLog(VOS_TRACE_LEVEL_FATAL,
8485 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8486 goto err_config;
8487 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008489
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008490 // Update VOS trace levels based upon the cfg.ini
8491 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8492 pHddCtx->cfg_ini->vosTraceEnableBAP);
8493 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8494 pHddCtx->cfg_ini->vosTraceEnableTL);
8495 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8496 pHddCtx->cfg_ini->vosTraceEnableWDI);
8497 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8498 pHddCtx->cfg_ini->vosTraceEnableHDD);
8499 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8500 pHddCtx->cfg_ini->vosTraceEnableSME);
8501 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8502 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308503 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8504 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008505 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8506 pHddCtx->cfg_ini->vosTraceEnableWDA);
8507 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8508 pHddCtx->cfg_ini->vosTraceEnableSYS);
8509 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8510 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008511 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8512 pHddCtx->cfg_ini->vosTraceEnableSAP);
8513 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8514 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008515
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 // Update WDI trace levels based upon the cfg.ini
8517 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8518 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8519 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8520 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8521 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8522 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8523 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8524 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008525
Jeff Johnson88ba7742013-02-27 14:36:02 -08008526 if (VOS_FTM_MODE == hdd_get_conparam())
8527 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8529 {
8530 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8531 goto err_free_hdd_context;
8532 }
8533 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308534
8535 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008536 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008538
Jeff Johnson88ba7742013-02-27 14:36:02 -08008539 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8541 {
8542 status = vos_watchdog_open(pVosContext,
8543 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8544
8545 if(!VOS_IS_STATUS_SUCCESS( status ))
8546 {
8547 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308548 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008549 }
8550 }
8551
8552 pHddCtx->isLogpInProgress = FALSE;
8553 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8554
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8556 if(!VOS_IS_STATUS_SUCCESS(status))
8557 {
8558 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008559 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 }
8561
Amar Singhala49cbc52013-10-08 18:37:44 -07008562#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008563 /* initialize the NV module. This is required so that
8564 we can initialize the channel information in wiphy
8565 from the NV.bin data. The channel information in
8566 wiphy needs to be initialized before wiphy registration */
8567
8568 status = vos_nv_open();
8569 if (!VOS_IS_STATUS_SUCCESS(status))
8570 {
8571 /* NV module cannot be initialized */
8572 hddLog( VOS_TRACE_LEVEL_FATAL,
8573 "%s: vos_nv_open failed", __func__);
8574 goto err_clkvote;
8575 }
8576
8577 status = vos_init_wiphy_from_nv_bin();
8578 if (!VOS_IS_STATUS_SUCCESS(status))
8579 {
8580 /* NV module cannot be initialized */
8581 hddLog( VOS_TRACE_LEVEL_FATAL,
8582 "%s: vos_init_wiphy failed", __func__);
8583 goto err_vos_nv_close;
8584 }
8585
Amar Singhala49cbc52013-10-08 18:37:44 -07008586#endif
8587
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308588 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 if ( !VOS_IS_STATUS_SUCCESS( status ))
8590 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008591 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308592 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 }
8594
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8596
8597 if ( NULL == pHddCtx->hHal )
8598 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008599 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 goto err_vosclose;
8601 }
8602
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008603 status = vos_preStart( pHddCtx->pvosContext );
8604 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8605 {
8606 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308607 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008608 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008609
Arif Hussaineaf68602013-12-30 23:10:44 -08008610 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8611 {
8612 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8614 __func__, enable_dfs_chan_scan);
8615 }
8616 if (0 == enable_11d || 1 == enable_11d)
8617 {
8618 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8620 __func__, enable_11d);
8621 }
8622
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008623 /* Note that the vos_preStart() sequence triggers the cfg download.
8624 The cfg download must occur before we update the SME config
8625 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 status = hdd_set_sme_config( pHddCtx );
8627
8628 if ( VOS_STATUS_SUCCESS != status )
8629 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008630 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308631 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008632 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008633
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 /* In the integrated architecture we update the configuration from
8635 the INI file and from NV before vOSS has been started so that
8636 the final contents are available to send down to the cCPU */
8637
8638 // Apply the cfg.ini to cfg.dat
8639 if (FALSE == hdd_update_config_dat(pHddCtx))
8640 {
8641 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308642 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008643 }
8644
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308645 // Get mac addr from platform driver
8646 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8647
8648 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308650 /* Store the mac addr for first interface */
8651 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8652
8653 hddLog(VOS_TRACE_LEVEL_ERROR,
8654 "%s: WLAN Mac Addr: "
8655 MAC_ADDRESS_STR, __func__,
8656 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8657
8658 /* Here, passing Arg2 as 1 because we do not want to change the
8659 last 3 bytes (means non OUI bytes) of first interface mac
8660 addr.
8661 */
8662 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8663 {
8664 hddLog(VOS_TRACE_LEVEL_ERROR,
8665 "%s: Failed to generate wlan interface mac addr "
8666 "using MAC from ini file ", __func__);
8667 }
8668 }
8669 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8670 {
8671 // Apply the NV to cfg.dat
8672 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008673#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8674 /* There was not a valid set of MAC Addresses in NV. See if the
8675 default addresses were modified by the cfg.ini settings. If so,
8676 we'll use them, but if not, we'll autogenerate a set of MAC
8677 addresses based upon the device serial number */
8678
8679 static const v_MACADDR_t default_address =
8680 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008681
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308682 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8683 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 {
8685 /* cfg.ini has the default address, invoke autogen logic */
8686
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308687 /* Here, passing Arg2 as 0 because we want to change the
8688 last 3 bytes (means non OUI bytes) of all the interfaces
8689 mac addr.
8690 */
8691 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8692 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008693 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308694 hddLog(VOS_TRACE_LEVEL_ERROR,
8695 "%s: Failed to generate wlan interface mac addr "
8696 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8697 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 }
8700 else
8701#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8702 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008703 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 "%s: Invalid MAC address in NV, using MAC from ini file "
8705 MAC_ADDRESS_STR, __func__,
8706 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8707 }
8708 }
8709 {
8710 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308711
8712 /* Set the MAC Address Currently this is used by HAL to
8713 * add self sta. Remove this once self sta is added as
8714 * part of session open.
8715 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8717 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8718 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308719
Jeff Johnson295189b2012-06-20 16:38:30 -07008720 if (!HAL_STATUS_SUCCESS( halStatus ))
8721 {
8722 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8723 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308724 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 }
8726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008727
8728 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8729 Note: Firmware image will be read and downloaded inside vos_start API */
8730 status = vos_start( pHddCtx->pvosContext );
8731 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8732 {
8733 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308734 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 }
8736
Leo Chang6cec3e22014-01-21 15:33:49 -08008737#ifdef FEATURE_WLAN_CH_AVOID
8738 /* Plug in avoid channel notification callback
8739 * This should happen before ADD_SELF_STA
8740 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308741
8742 /* check the Channel Avoidance is enabled */
8743 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8744 {
8745 sme_AddChAvoidCallback(pHddCtx->hHal,
8746 hdd_hostapd_ch_avoid_cb);
8747 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008748#endif /* FEATURE_WLAN_CH_AVOID */
8749
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008750 /* Exchange capability info between Host and FW and also get versioning info from FW */
8751 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008752
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308753#ifdef CONFIG_ENABLE_LINUX_REG
8754 status = wlan_hdd_init_channels(pHddCtx);
8755 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8756 {
8757 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8758 __func__);
8759 goto err_vosstop;
8760 }
8761#endif
8762
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 status = hdd_post_voss_start_config( pHddCtx );
8764 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8765 {
8766 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8767 __func__);
8768 goto err_vosstop;
8769 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008770
8771#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308772 wlan_hdd_cfg80211_update_reg_info( wiphy );
8773
8774 /* registration of wiphy dev with cfg80211 */
8775 if (0 > wlan_hdd_cfg80211_register(wiphy))
8776 {
8777 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8778 goto err_vosstop;
8779 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008780#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008781
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308782#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308783 /* registration of wiphy dev with cfg80211 */
8784 if (0 > wlan_hdd_cfg80211_register(wiphy))
8785 {
8786 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8787 goto err_vosstop;
8788 }
8789
8790 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8791 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8792 {
8793 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8794 __func__);
8795 goto err_unregister_wiphy;
8796 }
8797#endif
8798
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8800 {
8801 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8802 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8803 }
8804 else
8805 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008806 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8807 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8808 if (pAdapter != NULL)
8809 {
kaidde69982014-06-18 13:23:21 +08008810 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308812 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8813 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8814 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008815
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308816 /* Generate the P2P Device Address. This consists of the device's
8817 * primary MAC address with the locally administered bit set.
8818 */
8819 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008820 }
8821 else
8822 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308823 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8824 if (p2p_dev_addr != NULL)
8825 {
8826 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8827 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8828 }
8829 else
8830 {
8831 hddLog(VOS_TRACE_LEVEL_FATAL,
8832 "%s: Failed to allocate mac_address for p2p_device",
8833 __func__);
8834 goto err_close_adapter;
8835 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008837
8838 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8839 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8840 if ( NULL == pP2pAdapter )
8841 {
8842 hddLog(VOS_TRACE_LEVEL_FATAL,
8843 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008844 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008845 goto err_close_adapter;
8846 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008847 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008849
8850 if( pAdapter == NULL )
8851 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8853 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008855
Arif Hussain66559122013-11-21 10:11:40 -08008856 if (country_code)
8857 {
8858 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008859 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008860 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8861#ifndef CONFIG_ENABLE_LINUX_REG
8862 hdd_checkandupdate_phymode(pAdapter, country_code);
8863#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008864 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8865 (void *)(tSmeChangeCountryCallback)
8866 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008867 country_code,
8868 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308869 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008870 if (eHAL_STATUS_SUCCESS == ret)
8871 {
Arif Hussaincb607082013-12-20 11:57:42 -08008872 ret = wait_for_completion_interruptible_timeout(
8873 &pAdapter->change_country_code,
8874 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8875
8876 if (0 >= ret)
8877 {
8878 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8879 "%s: SME while setting country code timed out", __func__);
8880 }
Arif Hussain66559122013-11-21 10:11:40 -08008881 }
8882 else
8883 {
Arif Hussaincb607082013-12-20 11:57:42 -08008884 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8885 "%s: SME Change Country code from module param fail ret=%d",
8886 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008887 }
8888 }
8889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890#ifdef WLAN_BTAMP_FEATURE
8891 vStatus = WLANBAP_Open(pVosContext);
8892 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8893 {
8894 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8895 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008896 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008897 }
8898
8899 vStatus = BSL_Init(pVosContext);
8900 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8901 {
8902 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8903 "%s: Failed to Init BSL",__func__);
8904 goto err_bap_close;
8905 }
8906 vStatus = WLANBAP_Start(pVosContext);
8907 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8908 {
8909 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8910 "%s: Failed to start TL",__func__);
8911 goto err_bap_close;
8912 }
8913
8914 pConfig = pHddCtx->cfg_ini;
8915 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8916 status = WLANBAP_SetConfig(&btAmpConfig);
8917
8918#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008919
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008920#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8921 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8922 {
8923 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8924 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8925 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8926 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8927 }
8928#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008929
Agarwal Ashish4b87f922014-06-18 03:03:21 +05308930 wlan_hdd_tdls_init(pHddCtx);
8931
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308932 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8933
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 /* Register with platform driver as client for Suspend/Resume */
8935 status = hddRegisterPmOps(pHddCtx);
8936 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8937 {
8938 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8939#ifdef WLAN_BTAMP_FEATURE
8940 goto err_bap_stop;
8941#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008942 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008943#endif //WLAN_BTAMP_FEATURE
8944 }
8945
Yue Ma0d4891e2013-08-06 17:01:45 -07008946 /* Open debugfs interface */
8947 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8948 {
8949 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8950 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008951 }
8952
Jeff Johnson295189b2012-06-20 16:38:30 -07008953 /* Register TM level change handler function to the platform */
8954 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8955 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8956 {
8957 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8958 goto err_unregister_pmops;
8959 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008960
8961 /* register for riva power on lock to platform driver */
8962 if (req_riva_power_on_lock("wlan"))
8963 {
8964 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8965 __func__);
8966 goto err_unregister_pmops;
8967 }
8968
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 // register net device notifier for device change notification
8970 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8971
8972 if(ret < 0)
8973 {
8974 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8975 goto err_free_power_on_lock;
8976 }
8977
8978 //Initialize the nlink service
8979 if(nl_srv_init() != 0)
8980 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308981 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 goto err_reg_netdev;
8983 }
8984
Leo Chang4ce1cc52013-10-21 18:27:15 -07008985#ifdef WLAN_KD_READY_NOTIFIER
8986 pHddCtx->kd_nl_init = 1;
8987#endif /* WLAN_KD_READY_NOTIFIER */
8988
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 //Initialize the BTC service
8990 if(btc_activate_service(pHddCtx) != 0)
8991 {
8992 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8993 goto err_nl_srv;
8994 }
8995
8996#ifdef PTT_SOCK_SVC_ENABLE
8997 //Initialize the PTT service
8998 if(ptt_sock_activate_svc(pHddCtx) != 0)
8999 {
9000 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9001 goto err_nl_srv;
9002 }
9003#endif
9004
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309005#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9006 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9007 {
9008 if(wlan_logging_sock_activate_svc(
9009 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9010 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9011 {
9012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9013 " failed", __func__);
9014 goto err_nl_srv;
9015 }
9016 }
9017#endif
9018
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009021 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009022 /* Action frame registered in one adapter which will
9023 * applicable to all interfaces
9024 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309025 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009027
9028 mutex_init(&pHddCtx->sap_lock);
9029
Jeff Johnson295189b2012-06-20 16:38:30 -07009030
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009031#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009032#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9033 /* Initialize the wake lcok */
9034 wake_lock_init(&pHddCtx->rx_wake_lock,
9035 WAKE_LOCK_SUSPEND,
9036 "qcom_rx_wakelock");
9037#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009038 /* Initialize the wake lcok */
9039 wake_lock_init(&pHddCtx->sap_wake_lock,
9040 WAKE_LOCK_SUSPEND,
9041 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009042#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009043
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009044 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9045 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009046
Katya Nigam5c306ea2014-06-19 15:39:54 +05309047 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9049 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309050
9051#ifdef FEATURE_WLAN_SCAN_PNO
9052 /*SME must send channel update configuration to RIVA*/
9053 sme_UpdateChannelConfig(pHddCtx->hHal);
9054#endif
9055
Abhishek Singha306a442013-11-07 18:39:01 +05309056#ifndef CONFIG_ENABLE_LINUX_REG
9057 /*updating wiphy so that regulatory user hints can be processed*/
9058 if (wiphy)
9059 {
9060 regulatory_hint(wiphy, "00");
9061 }
9062#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009063 // Initialize the restart logic
9064 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309065
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009066 //Register the traffic monitor timer now
9067 if ( pHddCtx->cfg_ini->dynSplitscan)
9068 {
9069 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9070 VOS_TIMER_TYPE_SW,
9071 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9072 (void *)pHddCtx);
9073 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309074#ifdef WLAN_FEATURE_EXTSCAN
9075 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9076 wlan_hdd_cfg80211_extscan_callback,
9077 pHddCtx);
9078#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009079 goto success;
9080
9081err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009082#ifdef WLAN_KD_READY_NOTIFIER
9083 nl_srv_exit(pHddCtx->ptt_pid);
9084#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009086#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009087err_reg_netdev:
9088 unregister_netdevice_notifier(&hdd_netdev_notifier);
9089
9090err_free_power_on_lock:
9091 free_riva_power_on_lock("wlan");
9092
9093err_unregister_pmops:
9094 hddDevTmUnregisterNotifyCallback(pHddCtx);
9095 hddDeregisterPmOps(pHddCtx);
9096
Yue Ma0d4891e2013-08-06 17:01:45 -07009097 hdd_debugfs_exit(pHddCtx);
9098
Jeff Johnson295189b2012-06-20 16:38:30 -07009099#ifdef WLAN_BTAMP_FEATURE
9100err_bap_stop:
9101 WLANBAP_Stop(pVosContext);
9102#endif
9103
9104#ifdef WLAN_BTAMP_FEATURE
9105err_bap_close:
9106 WLANBAP_Close(pVosContext);
9107#endif
9108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109err_close_adapter:
9110 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309111err_unregister_wiphy:
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309112 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009113err_vosstop:
9114 vos_stop(pVosContext);
9115
Amar Singhala49cbc52013-10-08 18:37:44 -07009116err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 status = vos_sched_close( pVosContext );
9118 if (!VOS_IS_STATUS_SUCCESS(status)) {
9119 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9120 "%s: Failed to close VOSS Scheduler", __func__);
9121 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9122 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009123 vos_close(pVosContext );
9124
Amar Singhal0a402232013-10-11 20:57:16 -07009125err_vos_nv_close:
9126
c_hpothue6a36282014-03-19 12:27:38 +05309127#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009128 vos_nv_close();
9129
Jeff Johnson295189b2012-06-20 16:38:30 -07009130err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309131#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009132 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009133
9134err_wdclose:
9135 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9136 vos_watchdog_close(pVosContext);
9137
Jeff Johnson295189b2012-06-20 16:38:30 -07009138err_config:
9139 kfree(pHddCtx->cfg_ini);
9140 pHddCtx->cfg_ini= NULL;
9141
9142err_free_hdd_context:
9143 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 wiphy_free(wiphy) ;
9145 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 VOS_BUG(1);
9147
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009148 if (hdd_is_ssr_required())
9149 {
9150 /* WDI timeout had happened during load, so SSR is needed here */
9151 subsystem_restart("wcnss");
9152 msleep(5000);
9153 }
9154 hdd_set_ssr_required (VOS_FALSE);
9155
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009156 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009157
9158success:
9159 EXIT();
9160 return 0;
9161}
9162
9163/**---------------------------------------------------------------------------
9164
Jeff Johnson32d95a32012-09-10 13:15:23 -07009165 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009166
Jeff Johnson32d95a32012-09-10 13:15:23 -07009167 This is the driver entry point - called in different timeline depending
9168 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009169
9170 \param - None
9171
9172 \return - 0 for success, non zero for failure
9173
9174 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009175static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009176{
9177 VOS_STATUS status;
9178 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 struct device *dev = NULL;
9180 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009181#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9182 int max_retries = 0;
9183#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009184
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309185#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9186 wlan_logging_sock_init_svc();
9187#endif
9188
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 ENTER();
9190
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009191#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009194
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309195 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9197 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9198
9199 //Power Up Libra WLAN card first if not already powered up
9200 status = vos_chipPowerUp(NULL,NULL,NULL);
9201 if (!VOS_IS_STATUS_SUCCESS(status))
9202 {
9203 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9204 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309205#ifdef WLAN_OPEN_SOURCE
9206 wake_lock_destroy(&wlan_wake_lock);
9207#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309208
9209#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9210 wlan_logging_sock_deinit_svc();
9211#endif
9212
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009213 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 }
9215
Jeff Johnson295189b2012-06-20 16:38:30 -07009216#ifdef ANI_BUS_TYPE_PCI
9217
9218 dev = wcnss_wlan_get_device();
9219
9220#endif // ANI_BUS_TYPE_PCI
9221
9222#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009223
9224#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9225 /* wait until WCNSS driver downloads NV */
9226 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9227 msleep(1000);
9228 }
9229 if (max_retries >= 5) {
9230 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309231#ifdef WLAN_OPEN_SOURCE
9232 wake_lock_destroy(&wlan_wake_lock);
9233#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309234
9235#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9236 wlan_logging_sock_deinit_svc();
9237#endif
9238
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009239 return -ENODEV;
9240 }
9241#endif
9242
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 dev = wcnss_wlan_get_device();
9244#endif // ANI_BUS_TYPE_PLATFORM
9245
9246
9247 do {
9248 if (NULL == dev) {
9249 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9250 ret_status = -1;
9251 break;
9252 }
9253
Jeff Johnson295189b2012-06-20 16:38:30 -07009254#ifdef TIMER_MANAGER
9255 vos_timer_manager_init();
9256#endif
9257
9258 /* Preopen VOSS so that it is ready to start at least SAL */
9259 status = vos_preOpen(&pVosContext);
9260
9261 if (!VOS_IS_STATUS_SUCCESS(status))
9262 {
9263 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9264 ret_status = -1;
9265 break;
9266 }
9267
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009268#ifndef MODULE
9269 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9270 */
9271 hdd_set_conparam((v_UINT_t)con_mode);
9272#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009273
9274 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009275 if (hdd_wlan_startup(dev))
9276 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009278 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 vos_preClose( &pVosContext );
9280 ret_status = -1;
9281 break;
9282 }
9283
9284 /* Cancel the vote for XO Core ON
9285 * This is done here for safety purposes in case we re-initialize without turning
9286 * it OFF in any error scenario.
9287 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009288 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009290 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9292 {
9293 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009294 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 }
9296 } while (0);
9297
9298 if (0 != ret_status)
9299 {
9300 //Assert Deep sleep signal now to put Libra HW in lowest power state
9301 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9302 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9303
9304 //Vote off any PMIC voltage supplies
9305 vos_chipPowerDown(NULL, NULL, NULL);
9306#ifdef TIMER_MANAGER
9307 vos_timer_exit();
9308#endif
9309#ifdef MEMORY_DEBUG
9310 vos_mem_exit();
9311#endif
9312
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009313#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009315#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309316
9317#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9318 wlan_logging_sock_deinit_svc();
9319#endif
9320
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9322 }
9323 else
9324 {
9325 //Send WLAN UP indication to Nlink Service
9326 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9327
9328 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 }
9330
9331 EXIT();
9332
9333 return ret_status;
9334}
9335
Jeff Johnson32d95a32012-09-10 13:15:23 -07009336/**---------------------------------------------------------------------------
9337
9338 \brief hdd_module_init() - Init Function
9339
9340 This is the driver entry point (invoked when module is loaded using insmod)
9341
9342 \param - None
9343
9344 \return - 0 for success, non zero for failure
9345
9346 --------------------------------------------------------------------------*/
9347#ifdef MODULE
9348static int __init hdd_module_init ( void)
9349{
9350 return hdd_driver_init();
9351}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009352#else /* #ifdef MODULE */
9353static int __init hdd_module_init ( void)
9354{
9355 /* Driver initialization is delayed to fwpath_changed_handler */
9356 return 0;
9357}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009358#endif /* #ifdef MODULE */
9359
Jeff Johnson295189b2012-06-20 16:38:30 -07009360
9361/**---------------------------------------------------------------------------
9362
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009363 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009364
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009365 This is the driver exit point (invoked when module is unloaded using rmmod
9366 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009367
9368 \param - None
9369
9370 \return - None
9371
9372 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009373static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009374{
9375 hdd_context_t *pHddCtx = NULL;
9376 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309377 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309378 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009379
9380 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9381
9382 //Get the global vos context
9383 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9384
9385 if(!pVosContext)
9386 {
9387 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9388 goto done;
9389 }
9390
9391 //Get the HDD context.
9392 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9393
9394 if(!pHddCtx)
9395 {
9396 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9397 }
9398 else
9399 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309400 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9401
9402 if (pHddCtx->isLogpInProgress)
9403 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309405 "%s:SSR in Progress; block rmmod !!!", __func__);
9406 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9407 msecs_to_jiffies(30000));
9408 if(!rc)
9409 {
9410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9411 "%s:SSR timedout, fatal error", __func__);
9412 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009413 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309414 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009415
Mihir Shete18156292014-03-11 15:38:30 +05309416 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9418
Agarwal Ashish5e414792014-06-08 15:25:23 +05309419 if (eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
9420 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority )
9421 {
9422 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9423 }
9424
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 //Do all the cleanup before deregistering the driver
9426 hdd_wlan_exit(pHddCtx);
9427 }
9428
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 vos_preClose( &pVosContext );
9430
9431#ifdef TIMER_MANAGER
9432 vos_timer_exit();
9433#endif
9434#ifdef MEMORY_DEBUG
9435 vos_mem_exit();
9436#endif
9437
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309438#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9439 wlan_logging_sock_deinit_svc();
9440#endif
9441
Jeff Johnson295189b2012-06-20 16:38:30 -07009442done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009443#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009445#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309446
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9448}
9449
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009450/**---------------------------------------------------------------------------
9451
9452 \brief hdd_module_exit() - Exit function
9453
9454 This is the driver exit point (invoked when module is unloaded using rmmod)
9455
9456 \param - None
9457
9458 \return - None
9459
9460 --------------------------------------------------------------------------*/
9461static void __exit hdd_module_exit(void)
9462{
9463 hdd_driver_exit();
9464}
9465
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009466#ifdef MODULE
9467static int fwpath_changed_handler(const char *kmessage,
9468 struct kernel_param *kp)
9469{
Jeff Johnson76052702013-04-16 13:55:05 -07009470 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009471}
9472
9473static int con_mode_handler(const char *kmessage,
9474 struct kernel_param *kp)
9475{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009476 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009477}
9478#else /* #ifdef MODULE */
9479/**---------------------------------------------------------------------------
9480
Jeff Johnson76052702013-04-16 13:55:05 -07009481 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009482
Jeff Johnson76052702013-04-16 13:55:05 -07009483 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009484 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009485 - invoked when module parameter fwpath is modified from userspace to signal
9486 initializing the WLAN driver or when con_mode is modified from userspace
9487 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009488
9489 \return - 0 for success, non zero for failure
9490
9491 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009492static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009493{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009494 int ret_status;
9495
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009496 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009497 ret_status = hdd_driver_init();
9498 wlan_hdd_inited = ret_status ? 0 : 1;
9499 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009500 }
9501
9502 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009503
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009504 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009505
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009506 ret_status = hdd_driver_init();
9507 wlan_hdd_inited = ret_status ? 0 : 1;
9508 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009509}
9510
Jeff Johnson295189b2012-06-20 16:38:30 -07009511/**---------------------------------------------------------------------------
9512
Jeff Johnson76052702013-04-16 13:55:05 -07009513 \brief fwpath_changed_handler() - Handler Function
9514
9515 Handle changes to the fwpath parameter
9516
9517 \return - 0 for success, non zero for failure
9518
9519 --------------------------------------------------------------------------*/
9520static int fwpath_changed_handler(const char *kmessage,
9521 struct kernel_param *kp)
9522{
9523 int ret;
9524
9525 ret = param_set_copystring(kmessage, kp);
9526 if (0 == ret)
9527 ret = kickstart_driver();
9528 return ret;
9529}
9530
9531/**---------------------------------------------------------------------------
9532
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009533 \brief con_mode_handler() -
9534
9535 Handler function for module param con_mode when it is changed by userspace
9536 Dynamically linked - do nothing
9537 Statically linked - exit and init driver, as in rmmod and insmod
9538
Jeff Johnson76052702013-04-16 13:55:05 -07009539 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009540
Jeff Johnson76052702013-04-16 13:55:05 -07009541 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009542
9543 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009544static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009545{
Jeff Johnson76052702013-04-16 13:55:05 -07009546 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009547
Jeff Johnson76052702013-04-16 13:55:05 -07009548 ret = param_set_int(kmessage, kp);
9549 if (0 == ret)
9550 ret = kickstart_driver();
9551 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009552}
9553#endif /* #ifdef MODULE */
9554
9555/**---------------------------------------------------------------------------
9556
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 \brief hdd_get_conparam() -
9558
9559 This is the driver exit point (invoked when module is unloaded using rmmod)
9560
9561 \param - None
9562
9563 \return - tVOS_CON_MODE
9564
9565 --------------------------------------------------------------------------*/
9566tVOS_CON_MODE hdd_get_conparam ( void )
9567{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009568#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009570#else
9571 return (tVOS_CON_MODE)curr_con_mode;
9572#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009573}
9574void hdd_set_conparam ( v_UINT_t newParam )
9575{
9576 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009577#ifndef MODULE
9578 curr_con_mode = con_mode;
9579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009580}
9581/**---------------------------------------------------------------------------
9582
9583 \brief hdd_softap_sta_deauth() - function
9584
9585 This to take counter measure to handle deauth req from HDD
9586
9587 \param - pAdapter - Pointer to the HDD
9588
9589 \param - enable - boolean value
9590
9591 \return - None
9592
9593 --------------------------------------------------------------------------*/
9594
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009595VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009596{
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009598 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009599
9600 ENTER();
9601
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009602 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9603 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009604
9605 //Ignore request to deauth bcmc station
9606 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009607 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009608
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009609 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009610
9611 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009612 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009613}
9614
9615/**---------------------------------------------------------------------------
9616
9617 \brief hdd_softap_sta_disassoc() - function
9618
9619 This to take counter measure to handle deauth req from HDD
9620
9621 \param - pAdapter - Pointer to the HDD
9622
9623 \param - enable - boolean value
9624
9625 \return - None
9626
9627 --------------------------------------------------------------------------*/
9628
9629void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9630{
9631 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9632
9633 ENTER();
9634
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309635 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009636
9637 //Ignore request to disassoc bcmc station
9638 if( pDestMacAddress[0] & 0x1 )
9639 return;
9640
9641 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9642}
9643
9644void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9645{
9646 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9647
9648 ENTER();
9649
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309650 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009651
9652 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9653}
9654
Jeff Johnson295189b2012-06-20 16:38:30 -07009655/**---------------------------------------------------------------------------
9656 *
9657 * \brief hdd_get__concurrency_mode() -
9658 *
9659 *
9660 * \param - None
9661 *
9662 * \return - CONCURRENCY MODE
9663 *
9664 * --------------------------------------------------------------------------*/
9665tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9666{
9667 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9668 hdd_context_t *pHddCtx;
9669
9670 if (NULL != pVosContext)
9671 {
9672 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9673 if (NULL != pHddCtx)
9674 {
9675 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9676 }
9677 }
9678
9679 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009680 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 return VOS_STA;
9682}
9683
9684/* Decide whether to allow/not the apps power collapse.
9685 * Allow apps power collapse if we are in connected state.
9686 * if not, allow only if we are in IMPS */
9687v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9688{
9689 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009690 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009691 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9693 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9694 hdd_adapter_t *pAdapter = NULL;
9695 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009696 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009697
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9699 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009700
Yathish9f22e662012-12-10 14:21:35 -08009701 concurrent_state = hdd_get_concurrency_mode();
9702
9703#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9704 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9705 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9706 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9707 return TRUE;
9708#endif
9709
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 /*loop through all adapters. TBD fix for Concurrency */
9711 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9712 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9713 {
9714 pAdapter = pAdapterNode->pAdapter;
9715 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9716 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9717 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009718 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309719 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009720 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009721 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9722 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009724 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009725 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9726 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 return FALSE;
9728 }
9729 }
9730 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9731 pAdapterNode = pNext;
9732 }
9733 return TRUE;
9734}
9735
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009736/* Decides whether to send suspend notification to Riva
9737 * if any adapter is in BMPS; then it is required */
9738v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9739{
9740 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9741 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9742
9743 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9744 {
9745 return TRUE;
9746 }
9747 return FALSE;
9748}
9749
Jeff Johnson295189b2012-06-20 16:38:30 -07009750void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9751{
9752 switch(mode)
9753 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009754 case VOS_STA_MODE:
9755 case VOS_P2P_CLIENT_MODE:
9756 case VOS_P2P_GO_MODE:
9757 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009758 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309759 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 break;
9761 default:
9762 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309764 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9765 "Number of open sessions for mode %d = %d"),
9766 pHddCtx->concurrency_mode, mode,
9767 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009768}
9769
9770
9771void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9772{
9773 switch(mode)
9774 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009775 case VOS_STA_MODE:
9776 case VOS_P2P_CLIENT_MODE:
9777 case VOS_P2P_GO_MODE:
9778 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +05309779 pHddCtx->no_of_open_sessions[mode]--;
9780 if (!(pHddCtx->no_of_open_sessions[mode]))
9781 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 break;
9783 default:
9784 break;
9785 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309786 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9787 "Number of open sessions for mode %d = %d"),
9788 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
9789
9790}
9791/**---------------------------------------------------------------------------
9792 *
9793 * \brief wlan_hdd_incr_active_session()
9794 *
9795 * This function increments the number of active sessions
9796 * maintained per device mode
9797 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
9798 * Incase of SAP/P2P GO upon bss start it is incremented
9799 *
9800 * \param pHddCtx - HDD Context
9801 * \param mode - device mode
9802 *
9803 * \return - None
9804 *
9805 * --------------------------------------------------------------------------*/
9806void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9807{
9808 switch (mode) {
9809 case VOS_STA_MODE:
9810 case VOS_P2P_CLIENT_MODE:
9811 case VOS_P2P_GO_MODE:
9812 case VOS_STA_SAP_MODE:
9813 pHddCtx->no_of_active_sessions[mode]++;
9814 break;
9815 default:
9816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9817 break;
9818 }
9819 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9820 mode,
9821 pHddCtx->no_of_active_sessions[mode]);
9822}
9823
9824/**---------------------------------------------------------------------------
9825 *
9826 * \brief wlan_hdd_decr_active_session()
9827 *
9828 * This function decrements the number of active sessions
9829 * maintained per device mode
9830 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
9831 * Incase of SAP/P2P GO upon bss stop it is decremented
9832 *
9833 * \param pHddCtx - HDD Context
9834 * \param mode - device mode
9835 *
9836 * \return - None
9837 *
9838 * --------------------------------------------------------------------------*/
9839void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9840{
9841 switch (mode) {
9842 case VOS_STA_MODE:
9843 case VOS_P2P_CLIENT_MODE:
9844 case VOS_P2P_GO_MODE:
9845 case VOS_STA_SAP_MODE:
9846 pHddCtx->no_of_active_sessions[mode]--;
9847 break;
9848 default:
9849 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9850 break;
9851 }
9852 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9853 mode,
9854 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009855}
9856
Jeff Johnsone7245742012-09-05 17:12:55 -07009857/**---------------------------------------------------------------------------
9858 *
9859 * \brief wlan_hdd_restart_init
9860 *
9861 * This function initalizes restart timer/flag. An internal function.
9862 *
9863 * \param - pHddCtx
9864 *
9865 * \return - None
9866 *
9867 * --------------------------------------------------------------------------*/
9868
9869static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9870{
9871 /* Initialize */
9872 pHddCtx->hdd_restart_retries = 0;
9873 atomic_set(&pHddCtx->isRestartInProgress, 0);
9874 vos_timer_init(&pHddCtx->hdd_restart_timer,
9875 VOS_TIMER_TYPE_SW,
9876 wlan_hdd_restart_timer_cb,
9877 pHddCtx);
9878}
9879/**---------------------------------------------------------------------------
9880 *
9881 * \brief wlan_hdd_restart_deinit
9882 *
9883 * This function cleans up the resources used. An internal function.
9884 *
9885 * \param - pHddCtx
9886 *
9887 * \return - None
9888 *
9889 * --------------------------------------------------------------------------*/
9890
9891static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9892{
9893
9894 VOS_STATUS vos_status;
9895 /* Block any further calls */
9896 atomic_set(&pHddCtx->isRestartInProgress, 1);
9897 /* Cleanup */
9898 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9899 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309900 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009901 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9902 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309903 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009904
9905}
9906
9907/**---------------------------------------------------------------------------
9908 *
9909 * \brief wlan_hdd_framework_restart
9910 *
9911 * This function uses a cfg80211 API to start a framework initiated WLAN
9912 * driver module unload/load.
9913 *
9914 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9915 *
9916 *
9917 * \param - pHddCtx
9918 *
9919 * \return - VOS_STATUS_SUCCESS: Success
9920 * VOS_STATUS_E_EMPTY: Adapter is Empty
9921 * VOS_STATUS_E_NOMEM: No memory
9922
9923 * --------------------------------------------------------------------------*/
9924
9925static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9926{
9927 VOS_STATUS status = VOS_STATUS_SUCCESS;
9928 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009929 int len = (sizeof (struct ieee80211_mgmt));
9930 struct ieee80211_mgmt *mgmt = NULL;
9931
9932 /* Prepare the DEAUTH managment frame with reason code */
9933 mgmt = kzalloc(len, GFP_KERNEL);
9934 if(mgmt == NULL)
9935 {
9936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9937 "%s: memory allocation failed (%d bytes)", __func__, len);
9938 return VOS_STATUS_E_NOMEM;
9939 }
9940 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009941
9942 /* Iterate over all adapters/devices */
9943 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9944 do
9945 {
9946 if( (status == VOS_STATUS_SUCCESS) &&
9947 pAdapterNode &&
9948 pAdapterNode->pAdapter)
9949 {
9950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9951 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9952 pAdapterNode->pAdapter->dev->name,
9953 pAdapterNode->pAdapter->device_mode,
9954 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009955 /*
9956 * CFG80211 event to restart the driver
9957 *
9958 * 'cfg80211_send_unprot_deauth' sends a
9959 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9960 * of SME(Linux Kernel) state machine.
9961 *
9962 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9963 * the driver.
9964 *
9965 */
9966
9967 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009968 }
9969 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9970 pAdapterNode = pNext;
9971 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9972
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009973
9974 /* Free the allocated management frame */
9975 kfree(mgmt);
9976
Jeff Johnsone7245742012-09-05 17:12:55 -07009977 /* Retry until we unload or reach max count */
9978 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9979 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9980
9981 return status;
9982
9983}
9984/**---------------------------------------------------------------------------
9985 *
9986 * \brief wlan_hdd_restart_timer_cb
9987 *
9988 * Restart timer callback. An internal function.
9989 *
9990 * \param - User data:
9991 *
9992 * \return - None
9993 *
9994 * --------------------------------------------------------------------------*/
9995
9996void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9997{
9998 hdd_context_t *pHddCtx = usrDataForCallback;
9999 wlan_hdd_framework_restart(pHddCtx);
10000 return;
10001
10002}
10003
10004
10005/**---------------------------------------------------------------------------
10006 *
10007 * \brief wlan_hdd_restart_driver
10008 *
10009 * This function sends an event to supplicant to restart the WLAN driver.
10010 *
10011 * This function is called from vos_wlanRestart.
10012 *
10013 * \param - pHddCtx
10014 *
10015 * \return - VOS_STATUS_SUCCESS: Success
10016 * VOS_STATUS_E_EMPTY: Adapter is Empty
10017 * VOS_STATUS_E_ALREADY: Request already in progress
10018
10019 * --------------------------------------------------------------------------*/
10020VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10021{
10022 VOS_STATUS status = VOS_STATUS_SUCCESS;
10023
10024 /* A tight check to make sure reentrancy */
10025 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10026 {
Mihir Shetefd528652014-06-23 19:07:50 +053010027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010028 "%s: WLAN restart is already in progress", __func__);
10029
10030 return VOS_STATUS_E_ALREADY;
10031 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010032 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010033#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010034 wcnss_reset_intr();
10035#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010036
Jeff Johnsone7245742012-09-05 17:12:55 -070010037 return status;
10038}
10039
Mihir Shetee1093ba2014-01-21 20:13:32 +053010040/**---------------------------------------------------------------------------
10041 *
10042 * \brief wlan_hdd_init_channels
10043 *
10044 * This function is used to initialize the channel list in CSR
10045 *
10046 * This function is called from hdd_wlan_startup
10047 *
10048 * \param - pHddCtx: HDD context
10049 *
10050 * \return - VOS_STATUS_SUCCESS: Success
10051 * VOS_STATUS_E_FAULT: Failure reported by SME
10052
10053 * --------------------------------------------------------------------------*/
10054static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10055{
10056 eHalStatus status;
10057
10058 status = sme_InitChannels(pHddCtx->hHal);
10059 if (HAL_STATUS_SUCCESS(status))
10060 {
10061 return VOS_STATUS_SUCCESS;
10062 }
10063 else
10064 {
10065 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10066 __func__, status);
10067 return VOS_STATUS_E_FAULT;
10068 }
10069}
10070
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010071static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
10072{
10073 eHalStatus status;
10074
10075 status = sme_InitChannelsForCC(pHddCtx->hHal);
10076 if (HAL_STATUS_SUCCESS(status))
10077 {
10078 return VOS_STATUS_SUCCESS;
10079 }
10080 else
10081 {
10082 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10083 __func__, status);
10084 return VOS_STATUS_E_FAULT;
10085 }
10086}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010087/*
10088 * API to find if there is any STA or P2P-Client is connected
10089 */
10090VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10091{
10092 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10093}
Jeff Johnsone7245742012-09-05 17:12:55 -070010094
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010095int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10096{
10097 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10098 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010099 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010100
10101 pScanInfo = &pHddCtx->scan_info;
10102 if (pScanInfo->mScanPending)
10103 {
10104 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10105 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10106 eCSR_SCAN_ABORT_DEFAULT);
10107
10108 status = wait_for_completion_interruptible_timeout(
10109 &pScanInfo->abortscan_event_var,
10110 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010111 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010112 {
10113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010114 "%s: Timeout or Interrupt occurred while waiting for abort"
10115 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010116 return -ETIMEDOUT;
10117 }
10118 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010119 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010120}
10121
Jeff Johnson295189b2012-06-20 16:38:30 -070010122//Register the module init/exit functions
10123module_init(hdd_module_init);
10124module_exit(hdd_module_exit);
10125
10126MODULE_LICENSE("Dual BSD/GPL");
10127MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10128MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10129
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010130module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10131 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010132
Jeff Johnson76052702013-04-16 13:55:05 -070010133module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010134 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010135
10136module_param(enable_dfs_chan_scan, int,
10137 S_IRUSR | S_IRGRP | S_IROTH);
10138
10139module_param(enable_11d, int,
10140 S_IRUSR | S_IRGRP | S_IROTH);
10141
10142module_param(country_code, charp,
10143 S_IRUSR | S_IRGRP | S_IROTH);