blob: 9ed77bede64725fcf9dcad8fd9b92d58c4a2aca0 [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
Atul Mittal1d722422014-03-19 11:15:07 +0530190/*
191 * Maximum buffer size used for returning the data back to user space
192 */
193#define WLAN_MAX_BUF_SIZE 1024
194#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700195/*
196 * Driver miracast parameters 0-Disabled
197 * 1-Source, 2-Sink
198 */
199#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
200#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
201
c_hpothu92367912014-05-01 15:18:17 +0530202//wait time for beacon miss rate.
203#define BCN_MISS_RATE_TIME 500
204
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800205#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700206static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700207#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700208/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700209static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700210
211//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700212static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
213static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
214static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
215void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800216void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700217
Jeff Johnson295189b2012-06-20 16:38:30 -0700218v_U16_t hdd_select_queue(struct net_device *dev,
219 struct sk_buff *skb);
220
221#ifdef WLAN_FEATURE_PACKET_FILTERING
222static void hdd_set_multicast_list(struct net_device *dev);
223#endif
224
225void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
226
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800227#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
229static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700230static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
231 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
232 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700233static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
234 tANI_U8 *pTargetApBssid,
235 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800236#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800237#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700238VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800239#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700240
Mihir Shetee1093ba2014-01-21 20:13:32 +0530241static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530242const char * hdd_device_modetoString(v_U8_t device_mode)
243{
244 switch(device_mode)
245 {
246 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
247 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
248 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
250 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
251 CASE_RETURN_STRING( WLAN_HDD_FTM );
252 CASE_RETURN_STRING( WLAN_HDD_IBSS );
253 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
254 default:
255 return "device_mode Unknown";
256 }
257}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530258
Jeff Johnson295189b2012-06-20 16:38:30 -0700259static int hdd_netdev_notifier_call(struct notifier_block * nb,
260 unsigned long state,
261 void *ndev)
262{
263 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700264 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700265 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266#ifdef WLAN_BTAMP_FEATURE
267 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700268#endif
269
270 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700271 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700272 (strncmp(dev->name, "p2p", 3)))
273 return NOTIFY_DONE;
274
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700276 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800280 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 VOS_ASSERT(0);
282 return NOTIFY_DONE;
283 }
284
Jeff Johnson27cee452013-03-27 11:10:24 -0700285 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
286 if (NULL == pHddCtx)
287 {
288 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
289 VOS_ASSERT(0);
290 return NOTIFY_DONE;
291 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800292 if (pHddCtx->isLogpInProgress)
293 return NOTIFY_DONE;
294
Jeff Johnson27cee452013-03-27 11:10:24 -0700295
296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
297 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700298
299 switch (state) {
300 case NETDEV_REGISTER:
301 break;
302
303 case NETDEV_UNREGISTER:
304 break;
305
306 case NETDEV_UP:
307 break;
308
309 case NETDEV_DOWN:
310 break;
311
312 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700313 if(TRUE == pAdapter->isLinkUpSvcNeeded)
314 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700315 break;
316
317 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700318 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530320 long result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800321 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +0530322 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId,
323 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700324 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800325 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530327 if (result <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 {
329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530330 "%s: Timeout occurred while waiting for abortscan %ld",
331 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700332 }
333 }
334 else
335 {
336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700337 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 }
339#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 status = WLANBAP_StopAmp();
342 if(VOS_STATUS_SUCCESS != status )
343 {
344 pHddCtx->isAmpAllowed = VOS_TRUE;
345 hddLog(VOS_TRACE_LEVEL_FATAL,
346 "%s: Failed to stop AMP", __func__);
347 }
348 else
349 {
350 //a state m/c implementation in PAL is TBD to avoid this delay
351 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700352 if ( pHddCtx->isAmpAllowed )
353 {
354 WLANBAP_DeregisterFromHCI();
355 pHddCtx->isAmpAllowed = VOS_FALSE;
356 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700357 }
358#endif //WLAN_BTAMP_FEATURE
359 break;
360
361 default:
362 break;
363 }
364
365 return NOTIFY_DONE;
366}
367
368struct notifier_block hdd_netdev_notifier = {
369 .notifier_call = hdd_netdev_notifier_call,
370};
371
372/*---------------------------------------------------------------------------
373 * Function definitions
374 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700375void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
376void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700378static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700379#ifndef MODULE
380/* current con_mode - used only for statically linked driver
381 * con_mode is changed by userspace to indicate a mode change which will
382 * result in calling the module exit and init functions. The module
383 * exit function will clean up based on the value of con_mode prior to it
384 * being changed by userspace. So curr_con_mode records the current con_mode
385 * for exit when con_mode becomes the next mode for init
386 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700387static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700388#endif
389
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800390/**---------------------------------------------------------------------------
391
392 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
393
394 Called immediately after the cfg.ini is read in order to configure
395 the desired trace levels.
396
397 \param - moduleId - module whose trace level is being configured
398 \param - bitmask - bitmask of log levels to be enabled
399
400 \return - void
401
402 --------------------------------------------------------------------------*/
403static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
404{
405 wpt_tracelevel level;
406
407 /* if the bitmask is the default value, then a bitmask was not
408 specified in cfg.ini, so leave the logging level alone (it
409 will remain at the "compiled in" default value) */
410 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
411 {
412 return;
413 }
414
415 /* a mask was specified. start by disabling all logging */
416 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
417
418 /* now cycle through the bitmask until all "set" bits are serviced */
419 level = VOS_TRACE_LEVEL_FATAL;
420 while (0 != bitmask)
421 {
422 if (bitmask & 1)
423 {
424 vos_trace_setValue(moduleId, level, 1);
425 }
426 level++;
427 bitmask >>= 1;
428 }
429}
430
431
Jeff Johnson295189b2012-06-20 16:38:30 -0700432/**---------------------------------------------------------------------------
433
434 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
435
436 Called immediately after the cfg.ini is read in order to configure
437 the desired trace levels in the WDI.
438
439 \param - moduleId - module whose trace level is being configured
440 \param - bitmask - bitmask of log levels to be enabled
441
442 \return - void
443
444 --------------------------------------------------------------------------*/
445static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
446{
447 wpt_tracelevel level;
448
449 /* if the bitmask is the default value, then a bitmask was not
450 specified in cfg.ini, so leave the logging level alone (it
451 will remain at the "compiled in" default value) */
452 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
453 {
454 return;
455 }
456
457 /* a mask was specified. start by disabling all logging */
458 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
459
460 /* now cycle through the bitmask until all "set" bits are serviced */
461 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
462 while (0 != bitmask)
463 {
464 if (bitmask & 1)
465 {
466 wpalTraceSetLevel(moduleId, level, 1);
467 }
468 level++;
469 bitmask >>= 1;
470 }
471}
Jeff Johnson295189b2012-06-20 16:38:30 -0700472
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530473/*
474 * FUNCTION: wlan_hdd_validate_context
475 * This function is used to check the HDD context
476 */
477int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
478{
479 ENTER();
480
481 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
482 {
483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "%s: HDD context is Null", __func__);
485 return -ENODEV;
486 }
487
488 if (pHddCtx->isLogpInProgress)
489 {
490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
491 "%s: LOGP in Progress. Ignore!!!", __func__);
492 return -EAGAIN;
493 }
494
Mihir Shete18156292014-03-11 15:38:30 +0530495 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496 {
497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
498 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
499 return -EAGAIN;
500 }
501 return 0;
502}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700503#ifdef CONFIG_ENABLE_LINUX_REG
504void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
505{
506 hdd_adapter_t *pAdapter = NULL;
507 hdd_station_ctx_t *pHddStaCtx = NULL;
508 eCsrPhyMode phyMode;
509 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530510
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700511 if (NULL == pHddCtx)
512 {
513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
514 "HDD Context is null !!");
515 return ;
516 }
517
518 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
519 if (NULL == pAdapter)
520 {
521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
522 "pAdapter is null !!");
523 return ;
524 }
525
526 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
527 if (NULL == pHddStaCtx)
528 {
529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
530 "pHddStaCtx is null !!");
531 return ;
532 }
533
534 cfg_param = pHddCtx->cfg_ini;
535 if (NULL == cfg_param)
536 {
537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
538 "cfg_params not available !!");
539 return ;
540 }
541
542 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
543
544 if (!pHddCtx->isVHT80Allowed)
545 {
546 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
547 (eCSR_DOT11_MODE_11ac == phyMode) ||
548 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
549 {
550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
551 "Setting phymode to 11n!!");
552 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
553 }
554 }
555 else
556 {
557 /*New country Supports 11ac as well resetting value back from .ini*/
558 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
559 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
560 return ;
561 }
562
563 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
564 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
565 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
566 {
567 VOS_STATUS vosStatus;
568
569 // need to issue a disconnect to CSR.
570 INIT_COMPLETION(pAdapter->disconnect_comp_var);
571 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
572 pAdapter->sessionId,
573 eCSR_DISCONNECT_REASON_UNSPECIFIED );
574
575 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530576 {
577 long ret;
578
579 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700580 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 if (0 >= ret)
582 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
583 ret);
584 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700585
586 }
587}
588#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
590{
591 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
592 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
593 hdd_config_t *cfg_param;
594 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530595 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530596
597 if (NULL == pHddCtx)
598 {
599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
600 "HDD Context is null !!");
601 return ;
602 }
603
604 cfg_param = pHddCtx->cfg_ini;
605
606 if (NULL == cfg_param)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
609 "cfg_params not available !!");
610 return ;
611 }
612
613 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
614
615 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
616 {
617 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
618 (eCSR_DOT11_MODE_11ac == phyMode) ||
619 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
620 {
621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
622 "Setting phymode to 11n!!");
623 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
624 }
625 }
626 else
627 {
628 /*New country Supports 11ac as well resetting value back from .ini*/
629 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
630 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
631 return ;
632 }
633
634 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
635 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
636 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
637 {
638 VOS_STATUS vosStatus;
639
640 // need to issue a disconnect to CSR.
641 INIT_COMPLETION(pAdapter->disconnect_comp_var);
642 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
643 pAdapter->sessionId,
644 eCSR_DISCONNECT_REASON_UNSPECIFIED );
645
646 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530647 {
648 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530650 if (ret <= 0)
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
653 "wait on disconnect_comp_var is failed %ld", ret);
654 }
655 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
657 }
658}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700659#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530660
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700661void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
662{
663 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
664 hdd_config_t *cfg_param;
665
666 if (NULL == pHddCtx)
667 {
668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
669 "HDD Context is null !!");
670 return ;
671 }
672
673 cfg_param = pHddCtx->cfg_ini;
674
675 if (NULL == cfg_param)
676 {
677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
678 "cfg_params not available !!");
679 return ;
680 }
681
682 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
683 {
684 /*New country doesn't support DFS */
685 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
686 }
687 else
688 {
689 /*New country Supports DFS as well resetting value back from .ini*/
690 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
691 }
692
693}
694
Rajeev79dbe4c2013-10-05 11:03:42 +0530695#ifdef FEATURE_WLAN_BATCH_SCAN
696
697/**---------------------------------------------------------------------------
698
699 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
700 input string
701
702 This function extracts assigned integer from string in below format:
703 "STRING=10" : extracts integer 10 from this string
704
705 \param - pInPtr Pointer to input string
706 \param - base Base for string to int conversion(10 for decimal 16 for hex)
707 \param - pOutPtr Pointer to variable in which extracted integer needs to be
708 assigned
709 \param - pLastArg to tell whether it is last arguement in input string or
710 not
711
712 \return - NULL for failure cases
713 pointer to next arguement in input string for success cases
714 --------------------------------------------------------------------------*/
715static tANI_U8 *
716hdd_extract_assigned_int_from_str
717(
718 tANI_U8 *pInPtr,
719 tANI_U8 base,
720 tANI_U32 *pOutPtr,
721 tANI_U8 *pLastArg
722)
723{
724 int tempInt;
725 int v = 0;
726 char buf[32];
727 int val = 0;
728 *pLastArg = FALSE;
729
730 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
731 if (NULL == pInPtr)
732 {
733 return NULL;
734 }
735
736 pInPtr++;
737
738 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
739
740 val = sscanf(pInPtr, "%32s ", buf);
741 if (val < 0 && val > strlen(pInPtr))
742 {
743 return NULL;
744 }
745 pInPtr += val;
746 v = kstrtos32(buf, base, &tempInt);
747 if (v < 0)
748 {
749 return NULL;
750 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800751 if (tempInt < 0)
752 {
753 tempInt = 0;
754 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530755 *pOutPtr = tempInt;
756
757 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
758 if (NULL == pInPtr)
759 {
760 *pLastArg = TRUE;
761 return NULL;
762 }
763 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
764
765 return pInPtr;
766}
767
768/**---------------------------------------------------------------------------
769
770 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
771 input string
772
773 This function extracts assigned character from string in below format:
774 "STRING=A" : extracts char 'A' from this string
775
776 \param - pInPtr Pointer to input string
777 \param - pOutPtr Pointer to variable in which extracted char needs to be
778 assigned
779 \param - pLastArg to tell whether it is last arguement in input string or
780 not
781
782 \return - NULL for failure cases
783 pointer to next arguement in input string for success cases
784 --------------------------------------------------------------------------*/
785static tANI_U8 *
786hdd_extract_assigned_char_from_str
787(
788 tANI_U8 *pInPtr,
789 tANI_U8 *pOutPtr,
790 tANI_U8 *pLastArg
791)
792{
793 *pLastArg = FALSE;
794
795 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
796 if (NULL == pInPtr)
797 {
798 return NULL;
799 }
800
801 pInPtr++;
802
803 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
804
805 *pOutPtr = *pInPtr;
806
807 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
808 if (NULL == pInPtr)
809 {
810 *pLastArg = TRUE;
811 return NULL;
812 }
813 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
814
815 return pInPtr;
816}
817
818
819/**---------------------------------------------------------------------------
820
821 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
822
823 This function parses set batch scan command in below format:
824 WLS_BATCHING_SET <space> followed by below arguements
825 "SCANFREQ=XX" : Optional defaults to 30 sec
826 "MSCAN=XX" : Required number of scans to attempt to batch
827 "BESTN=XX" : Best Network (RSSI) defaults to 16
828 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
829 A. implies only 5 GHz , B. implies only 2.4GHz
830 "RTT=X" : optional defaults to 0
831 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
832 error
833
834 For example input commands:
835 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
836 translated into set batch scan with following parameters:
837 a) Frequence 60 seconds
838 b) Batch 10 scans together
839 c) Best RSSI to be 20
840 d) 5GHz band only
841 e) RTT is equal to 0
842
843 \param - pValue Pointer to input channel list
844 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
845
846 \return - 0 for success non-zero for failure
847
848 --------------------------------------------------------------------------*/
849static int
850hdd_parse_set_batchscan_command
851(
852 tANI_U8 *pValue,
853 tSirSetBatchScanReq *pHddSetBatchScanReq
854)
855{
856 tANI_U8 *inPtr = pValue;
857 tANI_U8 val = 0;
858 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800859 tANI_U32 nScanFreq;
860 tANI_U32 nMscan;
861 tANI_U32 nBestN;
862 tANI_U8 ucRfBand;
863 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800864 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530865
866 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800867 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
868 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
869 nRtt = 0;
870 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530871
872 /*go to space after WLS_BATCHING_SET command*/
873 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
874 /*no argument after the command*/
875 if (NULL == inPtr)
876 {
877 return -EINVAL;
878 }
879
880 /*no space after the command*/
881 else if (SPACE_ASCII_VALUE != *inPtr)
882 {
883 return -EINVAL;
884 }
885
886 /*removing empty spaces*/
887 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
888
889 /*no argument followed by spaces*/
890 if ('\0' == *inPtr)
891 {
892 return -EINVAL;
893 }
894
895 /*check and parse SCANFREQ*/
896 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
897 {
898 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800899 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800900
Rajeev Kumarc933d982013-11-18 20:04:20 -0800901 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800902 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800903 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800904 }
905
Rajeev79dbe4c2013-10-05 11:03:42 +0530906 if ( (NULL == inPtr) || (TRUE == lastArg))
907 {
908 return -EINVAL;
909 }
910 }
911
912 /*check and parse MSCAN*/
913 if ((strncmp(inPtr, "MSCAN", 5) == 0))
914 {
915 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800916 &nMscan, &lastArg);
917
918 if (0 == nMscan)
919 {
920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
921 "invalid MSCAN=%d", nMscan);
922 return -EINVAL;
923 }
924
Rajeev79dbe4c2013-10-05 11:03:42 +0530925 if (TRUE == lastArg)
926 {
927 goto done;
928 }
929 else if (NULL == inPtr)
930 {
931 return -EINVAL;
932 }
933 }
934 else
935 {
936 return -EINVAL;
937 }
938
939 /*check and parse BESTN*/
940 if ((strncmp(inPtr, "BESTN", 5) == 0))
941 {
942 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800943 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800944
Rajeev Kumarc933d982013-11-18 20:04:20 -0800945 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800946 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800947 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800948 }
949
Rajeev79dbe4c2013-10-05 11:03:42 +0530950 if (TRUE == lastArg)
951 {
952 goto done;
953 }
954 else if (NULL == inPtr)
955 {
956 return -EINVAL;
957 }
958 }
959
960 /*check and parse CHANNEL*/
961 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
962 {
963 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800964
Rajeev79dbe4c2013-10-05 11:03:42 +0530965 if (('A' == val) || ('a' == val))
966 {
c_hpothuebf89732014-02-25 13:00:24 +0530967 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530968 }
969 else if (('B' == val) || ('b' == val))
970 {
c_hpothuebf89732014-02-25 13:00:24 +0530971 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530972 }
973 else
974 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800975 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
976 }
977
978 if (TRUE == lastArg)
979 {
980 goto done;
981 }
982 else if (NULL == inPtr)
983 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530984 return -EINVAL;
985 }
986 }
987
988 /*check and parse RTT*/
989 if ((strncmp(inPtr, "RTT", 3) == 0))
990 {
991 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800992 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530993 if (TRUE == lastArg)
994 {
995 goto done;
996 }
997 if (NULL == inPtr)
998 {
999 return -EINVAL;
1000 }
1001 }
1002
1003
1004done:
1005
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001006 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1007 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1008 pHddSetBatchScanReq->bestNetwork = nBestN;
1009 pHddSetBatchScanReq->rfBand = ucRfBand;
1010 pHddSetBatchScanReq->rtt = nRtt;
1011
Rajeev79dbe4c2013-10-05 11:03:42 +05301012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1013 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1014 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1015 pHddSetBatchScanReq->scanFrequency,
1016 pHddSetBatchScanReq->numberOfScansToBatch,
1017 pHddSetBatchScanReq->bestNetwork,
1018 pHddSetBatchScanReq->rfBand,
1019 pHddSetBatchScanReq->rtt);
1020
1021 return 0;
1022}/*End of hdd_parse_set_batchscan_command*/
1023
1024/**---------------------------------------------------------------------------
1025
1026 \brief hdd_set_batch_scan_req_callback () - This function is called after
1027 receiving set batch scan response from FW and it saves set batch scan
1028 response data FW to HDD context and sets the completion event on
1029 which hdd_ioctl is waiting
1030
1031 \param - callbackContext Pointer to HDD adapter
1032 \param - pRsp Pointer to set batch scan response data received from FW
1033
1034 \return - nothing
1035
1036 --------------------------------------------------------------------------*/
1037static void hdd_set_batch_scan_req_callback
1038(
1039 void *callbackContext,
1040 tSirSetBatchScanRsp *pRsp
1041)
1042{
1043 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1044 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1045
1046 /*sanity check*/
1047 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1048 {
1049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1050 "%s: Invalid pAdapter magic", __func__);
1051 VOS_ASSERT(0);
1052 return;
1053 }
1054 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1055
1056 /*save set batch scan response*/
1057 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1058
1059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1060 "Received set batch scan rsp from FW with nScansToBatch=%d",
1061 pHddSetBatchScanRsp->nScansToBatch);
1062
1063 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1064 complete(&pAdapter->hdd_set_batch_scan_req_var);
1065
1066 return;
1067}/*End of hdd_set_batch_scan_req_callback*/
1068
1069
1070/**---------------------------------------------------------------------------
1071
1072 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1073 info in hdd batch scan response queue
1074
1075 \param - pAdapter Pointer to hdd adapter
1076 \param - pAPMetaInfo Pointer to access point meta info
1077 \param - scanId scan ID of batch scan response
1078 \param - isLastAp tells whether AP is last AP in batch scan response or not
1079
1080 \return - nothing
1081
1082 --------------------------------------------------------------------------*/
1083static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1084 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1085{
1086 tHddBatchScanRsp *pHead;
1087 tHddBatchScanRsp *pNode;
1088 tHddBatchScanRsp *pPrev;
1089 tHddBatchScanRsp *pTemp;
1090 tANI_U8 ssidLen;
1091
1092 /*head of hdd batch scan response queue*/
1093 pHead = pAdapter->pBatchScanRsp;
1094
1095 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1096 if (NULL == pNode)
1097 {
1098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1099 "%s: Could not allocate memory", __func__);
1100 VOS_ASSERT(0);
1101 return;
1102 }
1103
1104 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1105 sizeof(pNode->ApInfo.bssid));
1106 ssidLen = strlen(pApMetaInfo->ssid);
1107 if (SIR_MAX_SSID_SIZE < ssidLen)
1108 {
1109 /*invalid scan result*/
1110 vos_mem_free(pNode);
1111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1112 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1113 return;
1114 }
1115 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1116 /*null terminate ssid*/
1117 pNode->ApInfo.ssid[ssidLen] = '\0';
1118 pNode->ApInfo.ch = pApMetaInfo->ch;
1119 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1120 pNode->ApInfo.age = pApMetaInfo->timestamp;
1121 pNode->ApInfo.batchId = scanId;
1122 pNode->ApInfo.isLastAp = isLastAp;
1123
1124 pNode->pNext = NULL;
1125 if (NULL == pHead)
1126 {
1127 pAdapter->pBatchScanRsp = pNode;
1128 }
1129 else
1130 {
1131 pTemp = pHead;
1132 while (NULL != pTemp)
1133 {
1134 pPrev = pTemp;
1135 pTemp = pTemp->pNext;
1136 }
1137 pPrev->pNext = pNode;
1138 }
1139
1140 return;
1141}/*End of hdd_populate_batch_scan_rsp_queue*/
1142
1143/**---------------------------------------------------------------------------
1144
1145 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1146 receiving batch scan response indication from FW. It saves get batch scan
1147 response data in HDD batch scan response queue. This callback sets the
1148 completion event on which hdd_ioctl is waiting only after getting complete
1149 batch scan response data from FW
1150
1151 \param - callbackContext Pointer to HDD adapter
1152 \param - pRsp Pointer to get batch scan response data received from FW
1153
1154 \return - nothing
1155
1156 --------------------------------------------------------------------------*/
1157static void hdd_batch_scan_result_ind_callback
1158(
1159 void *callbackContext,
1160 void *pRsp
1161)
1162{
1163 v_BOOL_t isLastAp;
1164 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001165 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301166 tANI_U32 numberScanList;
1167 tANI_U32 nextScanListOffset;
1168 tANI_U32 nextApMetaInfoOffset;
1169 hdd_adapter_t* pAdapter;
1170 tpSirBatchScanList pScanList;
1171 tpSirBatchScanNetworkInfo pApMetaInfo;
1172 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1173 tSirSetBatchScanReq *pReq;
1174
1175 pAdapter = (hdd_adapter_t *)callbackContext;
1176 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001177 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301178 {
1179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1180 "%s: Invalid pAdapter magic", __func__);
1181 VOS_ASSERT(0);
1182 return;
1183 }
1184
1185 /*initialize locals*/
1186 pReq = &pAdapter->hddSetBatchScanReq;
1187 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1188 isLastAp = FALSE;
1189 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001190 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301191 numberScanList = 0;
1192 nextScanListOffset = 0;
1193 nextApMetaInfoOffset = 0;
1194 pScanList = NULL;
1195 pApMetaInfo = NULL;
1196
1197 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1198 {
1199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1200 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1201 isLastAp = TRUE;
1202 goto done;
1203 }
1204
1205 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1207 "Batch scan rsp: numberScalList %d", numberScanList);
1208
1209 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1210 {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1212 "%s: numberScanList %d", __func__, numberScanList);
1213 isLastAp = TRUE;
1214 goto done;
1215 }
1216
1217 while (numberScanList)
1218 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001219 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301220 nextScanListOffset);
1221 if (NULL == pScanList)
1222 {
1223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1224 "%s: pScanList is %p", __func__, pScanList);
1225 isLastAp = TRUE;
1226 goto done;
1227 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001228 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001230 "Batch scan rsp: numApMetaInfo %d scanId %d",
1231 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301232
1233 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1234 {
1235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1236 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1237 isLastAp = TRUE;
1238 goto done;
1239 }
1240
Rajeev Kumarce651e42013-10-21 18:57:15 -07001241 /*Initialize next AP meta info offset for next scan list*/
1242 nextApMetaInfoOffset = 0;
1243
Rajeev79dbe4c2013-10-05 11:03:42 +05301244 while (numApMetaInfo)
1245 {
1246 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1247 nextApMetaInfoOffset);
1248 if (NULL == pApMetaInfo)
1249 {
1250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1251 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1252 isLastAp = TRUE;
1253 goto done;
1254 }
1255 /*calculate AP age*/
1256 pApMetaInfo->timestamp =
1257 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1258
1259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001260 "%s: bssId "MAC_ADDRESS_STR
1261 " ch %d rssi %d timestamp %d", __func__,
1262 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1263 pApMetaInfo->ch, pApMetaInfo->rssi,
1264 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301265
1266 /*mark last AP in batch scan response*/
1267 if ((TRUE == pBatchScanRsp->isLastResult) &&
1268 (1 == numberScanList) && (1 == numApMetaInfo))
1269 {
1270 isLastAp = TRUE;
1271 }
1272
1273 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1274 /*store batch scan repsonse in hdd queue*/
1275 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1276 pScanList->scanId, isLastAp);
1277 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1278
1279 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1280 numApMetaInfo--;
1281 }
1282
Rajeev Kumarce651e42013-10-21 18:57:15 -07001283 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1284 + (sizeof(tSirBatchScanNetworkInfo)
1285 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301286 numberScanList--;
1287 }
1288
1289done:
1290
1291 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1292 requested from hdd_ioctl*/
1293 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1294 (TRUE == isLastAp))
1295 {
1296 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1297 complete(&pAdapter->hdd_get_batch_scan_req_var);
1298 }
1299
1300 return;
1301}/*End of hdd_batch_scan_result_ind_callback*/
1302
1303/**---------------------------------------------------------------------------
1304
1305 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1306 response as per batch scan FR request format by putting proper markers
1307
1308 \param - pDest pointer to destination buffer
1309 \param - cur_len current length
1310 \param - tot_len total remaining size which can be written to user space
1311 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1312 \param - pAdapter Pointer to HDD adapter
1313
1314 \return - ret no of characters written
1315
1316 --------------------------------------------------------------------------*/
1317static tANI_U32
1318hdd_format_batch_scan_rsp
1319(
1320 tANI_U8 *pDest,
1321 tANI_U32 cur_len,
1322 tANI_U32 tot_len,
1323 tHddBatchScanRsp *pApMetaInfo,
1324 hdd_adapter_t* pAdapter
1325)
1326{
1327 tANI_U32 ret = 0;
1328 tANI_U32 rem_len = 0;
1329 tANI_U8 temp_len = 0;
1330 tANI_U8 temp_total_len = 0;
1331 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1332 tANI_U8 *pTemp = temp;
1333
1334 /*Batch scan reponse needs to be returned to user space in
1335 following format:
1336 "scancount=X\n" where X is the number of scans in current batch
1337 batch
1338 "trunc\n" optional present if current scan truncated
1339 "bssid=XX:XX:XX:XX:XX:XX\n"
1340 "ssid=XXXX\n"
1341 "freq=X\n" frequency in Mhz
1342 "level=XX\n"
1343 "age=X\n" ms
1344 "dist=X\n" cm (-1 if not available)
1345 "errror=X\n" (-1if not available)
1346 "====\n" (end of ap marker)
1347 "####\n" (end of scan marker)
1348 "----\n" (end of results)*/
1349 /*send scan result in above format to user space based on
1350 available length*/
1351 /*The GET response may have more data than the driver can return in its
1352 buffer. In that case the buffer should be filled to the nearest complete
1353 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1354 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1355 The final buffer should end with "----\n"*/
1356
1357 /*sanity*/
1358 if (cur_len > tot_len)
1359 {
1360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1361 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1362 return 0;
1363 }
1364 else
1365 {
1366 rem_len = (tot_len - cur_len);
1367 }
1368
1369 /*end scan marker*/
1370 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1371 {
1372 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1373 pTemp += temp_len;
1374 temp_total_len += temp_len;
1375 }
1376
1377 /*bssid*/
1378 temp_len = snprintf(pTemp, sizeof(temp),
1379 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1380 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1381 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1382 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1383 pTemp += temp_len;
1384 temp_total_len += temp_len;
1385
1386 /*ssid*/
1387 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1388 pApMetaInfo->ApInfo.ssid);
1389 pTemp += temp_len;
1390 temp_total_len += temp_len;
1391
1392 /*freq*/
1393 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001394 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301395 pTemp += temp_len;
1396 temp_total_len += temp_len;
1397
1398 /*level*/
1399 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1400 pApMetaInfo->ApInfo.rssi);
1401 pTemp += temp_len;
1402 temp_total_len += temp_len;
1403
1404 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001405 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301406 pApMetaInfo->ApInfo.age);
1407 pTemp += temp_len;
1408 temp_total_len += temp_len;
1409
1410 /*dist*/
1411 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1412 pTemp += temp_len;
1413 temp_total_len += temp_len;
1414
1415 /*error*/
1416 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1417 pTemp += temp_len;
1418 temp_total_len += temp_len;
1419
1420 /*end AP marker*/
1421 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1422 pTemp += temp_len;
1423 temp_total_len += temp_len;
1424
1425 /*last AP in batch scan response*/
1426 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1427 {
1428 /*end scan marker*/
1429 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1430 pTemp += temp_len;
1431 temp_total_len += temp_len;
1432
1433 /*end batch scan result marker*/
1434 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1435 pTemp += temp_len;
1436 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001437
Rajeev79dbe4c2013-10-05 11:03:42 +05301438 }
1439
1440 if (temp_total_len < rem_len)
1441 {
1442 ret = temp_total_len + 1;
1443 strlcpy(pDest, temp, ret);
1444 pAdapter->isTruncated = FALSE;
1445 }
1446 else
1447 {
1448 pAdapter->isTruncated = TRUE;
1449 if (rem_len >= strlen("%%%%"))
1450 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001451 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301452 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001453 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301454 {
1455 ret = 0;
1456 }
1457 }
1458
1459 return ret;
1460
1461}/*End of hdd_format_batch_scan_rsp*/
1462
1463/**---------------------------------------------------------------------------
1464
1465 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1466 buffer starting with head of hdd batch scan response queue
1467
1468 \param - pAdapter Pointer to HDD adapter
1469 \param - pDest Pointer to user data buffer
1470 \param - cur_len current offset in user buffer
1471 \param - rem_len remaining no of bytes in user buffer
1472
1473 \return - number of bytes written in user buffer
1474
1475 --------------------------------------------------------------------------*/
1476
1477tANI_U32 hdd_populate_user_batch_scan_rsp
1478(
1479 hdd_adapter_t* pAdapter,
1480 tANI_U8 *pDest,
1481 tANI_U32 cur_len,
1482 tANI_U32 rem_len
1483)
1484{
1485 tHddBatchScanRsp *pHead;
1486 tHddBatchScanRsp *pPrev;
1487 tANI_U32 len;
1488
Rajeev79dbe4c2013-10-05 11:03:42 +05301489 pAdapter->isTruncated = FALSE;
1490
1491 /*head of hdd batch scan response queue*/
1492 pHead = pAdapter->pBatchScanRsp;
1493 while (pHead)
1494 {
1495 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1496 pAdapter);
1497 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001498 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301499 cur_len += len;
1500 if(TRUE == pAdapter->isTruncated)
1501 {
1502 /*result is truncated return rest of scan rsp in next req*/
1503 cur_len = rem_len;
1504 break;
1505 }
1506 pPrev = pHead;
1507 pHead = pHead->pNext;
1508 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001509 if (TRUE == pPrev->ApInfo.isLastAp)
1510 {
1511 pAdapter->prev_batch_id = 0;
1512 }
1513 else
1514 {
1515 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1516 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301517 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001518 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301519 }
1520
1521 return cur_len;
1522}/*End of hdd_populate_user_batch_scan_rsp*/
1523
1524/**---------------------------------------------------------------------------
1525
1526 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1527 scan response data from HDD queue to user space
1528 It does following in detail:
1529 a) if HDD has enough data in its queue then it 1st copies data to user
1530 space and then send get batch scan indication message to FW. In this
1531 case it does not wait on any event and batch scan response data will
1532 be populated in HDD response queue in MC thread context after receiving
1533 indication from FW
1534 b) else send get batch scan indication message to FW and wait on an event
1535 which will be set once HDD receives complete batch scan response from
1536 FW and then this function returns batch scan response to user space
1537
1538 \param - pAdapter Pointer to HDD adapter
1539 \param - pPrivData Pointer to priv_data
1540
1541 \return - 0 for success -EFAULT for failure
1542
1543 --------------------------------------------------------------------------*/
1544
1545int hdd_return_batch_scan_rsp_to_user
1546(
1547 hdd_adapter_t* pAdapter,
1548 hdd_priv_data_t *pPrivData,
1549 tANI_U8 *command
1550)
1551{
1552 tANI_U8 *pDest;
1553 tANI_U32 count = 0;
1554 tANI_U32 len = 0;
1555 tANI_U32 cur_len = 0;
1556 tANI_U32 rem_len = 0;
1557 eHalStatus halStatus;
1558 unsigned long rc;
1559 tSirTriggerBatchScanResultInd *pReq;
1560
1561 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1562 pReq->param = 0;/*batch scan client*/
1563 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1564 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1565
1566 cur_len = pPrivData->used_len;
1567 if (pPrivData->total_len > pPrivData->used_len)
1568 {
1569 rem_len = pPrivData->total_len - pPrivData->used_len;
1570 }
1571 else
1572 {
1573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1574 "%s: Invalid user data buffer total_len %d used_len %d",
1575 __func__, pPrivData->total_len, pPrivData->used_len);
1576 return -EFAULT;
1577 }
1578
1579 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1580 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1581 cur_len, rem_len);
1582 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1583
1584 /*enough scan result available in cache to return to user space or
1585 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001586 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301587 {
1588 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1589 halStatus = sme_TriggerBatchScanResultInd(
1590 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1591 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1592 pAdapter);
1593 if ( eHAL_STATUS_SUCCESS == halStatus )
1594 {
1595 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1596 {
1597 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1598 rc = wait_for_completion_timeout(
1599 &pAdapter->hdd_get_batch_scan_req_var,
1600 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1601 if (0 == rc)
1602 {
1603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1604 "%s: Timeout waiting to fetch batch scan rsp from fw",
1605 __func__);
1606 return -EFAULT;
1607 }
1608 }
1609
1610 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001611 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301612 pDest += len;
1613 cur_len += len;
1614
1615 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1616 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1617 cur_len, rem_len);
1618 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1619
1620 count = 0;
1621 len = (len - pPrivData->used_len);
1622 pDest = (command + pPrivData->used_len);
1623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001624 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301625 while(count < len)
1626 {
1627 printk("%c", *(pDest + count));
1628 count++;
1629 }
1630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1631 "%s: copy %d data to user buffer", __func__, len);
1632 if (copy_to_user(pPrivData->buf, pDest, len))
1633 {
1634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1635 "%s: failed to copy data to user buffer", __func__);
1636 return -EFAULT;
1637 }
1638 }
1639 else
1640 {
1641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1642 "sme_GetBatchScanScan returned failure halStatus %d",
1643 halStatus);
1644 return -EINVAL;
1645 }
1646 }
1647 else
1648 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301649 count = 0;
1650 len = (len - pPrivData->used_len);
1651 pDest = (command + pPrivData->used_len);
1652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001653 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301654 while(count < len)
1655 {
1656 printk("%c", *(pDest + count));
1657 count++;
1658 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1660 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301661 if (copy_to_user(pPrivData->buf, pDest, len))
1662 {
1663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1664 "%s: failed to copy data to user buffer", __func__);
1665 return -EFAULT;
1666 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301667 }
1668
1669 return 0;
1670} /*End of hdd_return_batch_scan_rsp_to_user*/
1671
Rajeev Kumar8b373292014-01-08 20:36:55 -08001672
1673/**---------------------------------------------------------------------------
1674
1675 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1676 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1677 WLS_BATCHING VERSION
1678 WLS_BATCHING SET
1679 WLS_BATCHING GET
1680 WLS_BATCHING STOP
1681
1682 \param - pAdapter Pointer to HDD adapter
1683 \param - pPrivdata Pointer to priv_data
1684 \param - command Pointer to command
1685
1686 \return - 0 for success -EFAULT for failure
1687
1688 --------------------------------------------------------------------------*/
1689
1690int hdd_handle_batch_scan_ioctl
1691(
1692 hdd_adapter_t *pAdapter,
1693 hdd_priv_data_t *pPrivdata,
1694 tANI_U8 *command
1695)
1696{
1697 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001698 hdd_context_t *pHddCtx;
1699
1700 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1701 ret = wlan_hdd_validate_context(pHddCtx);
1702 if (ret)
1703 {
1704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1705 "%s: HDD context is not valid!", __func__);
1706 goto exit;
1707 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001708
1709 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1710 {
1711 char extra[32];
1712 tANI_U8 len = 0;
1713 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1714
1715 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1716 {
1717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1718 "%s: Batch scan feature is not supported by FW", __func__);
1719 ret = -EINVAL;
1720 goto exit;
1721 }
1722
1723 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1724 version);
1725 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1726 {
1727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1728 "%s: failed to copy data to user buffer", __func__);
1729 ret = -EFAULT;
1730 goto exit;
1731 }
1732 ret = HDD_BATCH_SCAN_VERSION;
1733 }
1734 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1735 {
1736 int status;
1737 tANI_U8 *value = (command + 16);
1738 eHalStatus halStatus;
1739 unsigned long rc;
1740 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1741 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1742
1743 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1744 {
1745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1746 "%s: Batch scan feature is not supported by FW", __func__);
1747 ret = -EINVAL;
1748 goto exit;
1749 }
1750
1751 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1752 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1753 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1754 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1755 {
1756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301757 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001758 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301759 hdd_device_modetoString(pAdapter->device_mode),
1760 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001761 ret = -EINVAL;
1762 goto exit;
1763 }
1764
1765 status = hdd_parse_set_batchscan_command(value, pReq);
1766 if (status)
1767 {
1768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1769 "Invalid WLS_BATCHING SET command");
1770 ret = -EINVAL;
1771 goto exit;
1772 }
1773
1774
1775 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1776 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1777 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1778 pAdapter);
1779
1780 if ( eHAL_STATUS_SUCCESS == halStatus )
1781 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301782 char extra[32];
1783 tANI_U8 len = 0;
1784 tANI_U8 mScan = 0;
1785
Rajeev Kumar8b373292014-01-08 20:36:55 -08001786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1787 "sme_SetBatchScanReq returned success halStatus %d",
1788 halStatus);
1789 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1790 {
1791 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1792 rc = wait_for_completion_timeout(
1793 &pAdapter->hdd_set_batch_scan_req_var,
1794 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1795 if (0 == rc)
1796 {
1797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1798 "%s: Timeout waiting for set batch scan to complete",
1799 __func__);
1800 ret = -EINVAL;
1801 goto exit;
1802 }
1803 }
1804 if ( !pRsp->nScansToBatch )
1805 {
1806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1807 "%s: Received set batch scan failure response from FW",
1808 __func__);
1809 ret = -EINVAL;
1810 goto exit;
1811 }
1812 /*As per the Batch Scan Framework API we should return the MIN of
1813 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301814 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001815
1816 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1817
1818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1819 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301820 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1821 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1822 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1823 {
1824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1825 "%s: failed to copy MSCAN value to user buffer", __func__);
1826 ret = -EFAULT;
1827 goto exit;
1828 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001829 }
1830 else
1831 {
1832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1833 "sme_SetBatchScanReq returned failure halStatus %d",
1834 halStatus);
1835 ret = -EINVAL;
1836 goto exit;
1837 }
1838 }
1839 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1840 {
1841 eHalStatus halStatus;
1842 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1843 pInd->param = 0;
1844
1845 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1846 {
1847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1848 "%s: Batch scan feature is not supported by FW", __func__);
1849 ret = -EINVAL;
1850 goto exit;
1851 }
1852
1853 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1854 {
1855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1856 "Batch scan is not yet enabled batch scan state %d",
1857 pAdapter->batchScanState);
1858 ret = -EINVAL;
1859 goto exit;
1860 }
1861
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001862 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1863 hdd_deinit_batch_scan(pAdapter);
1864 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1865
Rajeev Kumar8b373292014-01-08 20:36:55 -08001866 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1867
1868 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1869 pAdapter->sessionId);
1870 if ( eHAL_STATUS_SUCCESS == halStatus )
1871 {
1872 ret = 0;
1873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1874 "sme_StopBatchScanInd returned success halStatus %d",
1875 halStatus);
1876 }
1877 else
1878 {
1879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1880 "sme_StopBatchScanInd returned failure halStatus %d",
1881 halStatus);
1882 ret = -EINVAL;
1883 goto exit;
1884 }
1885 }
1886 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1887 {
1888 tANI_U32 remain_len;
1889
1890 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1891 {
1892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1893 "%s: Batch scan feature is not supported by FW", __func__);
1894 ret = -EINVAL;
1895 goto exit;
1896 }
1897
1898 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1899 {
1900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1901 "Batch scan is not yet enabled could not return results"
1902 "Batch Scan state %d",
1903 pAdapter->batchScanState);
1904 ret = -EINVAL;
1905 goto exit;
1906 }
1907
1908 pPrivdata->used_len = 16;
1909 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1910 if (remain_len < pPrivdata->total_len)
1911 {
1912 /*Clear previous batch scan response data if any*/
1913 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1914 }
1915 else
1916 {
1917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1918 "Invalid total length from user space can't fetch batch"
1919 " scan response total_len %d used_len %d remain len %d",
1920 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1921 ret = -EINVAL;
1922 goto exit;
1923 }
1924 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1925 }
1926
1927exit:
1928
1929 return ret;
1930}
1931
1932
Rajeev79dbe4c2013-10-05 11:03:42 +05301933#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1934
c_hpothu92367912014-05-01 15:18:17 +05301935static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1936{
1937 bcnMissRateContext_t *pCBCtx = (bcnMissRateContext_t *)data;
1938
1939 /* there is a race condition that exists between this callback
1940 function and the caller since the caller could time out either
1941 before or while this code is executing. we use a spinlock to
1942 serialize these actions */
1943 spin_lock(&hdd_context_lock);
1944
1945 gbcnMissRate = -1;
1946
1947 if(pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC || NULL == data)
1948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR,
1950 FL("invalid context magic: %08x data: %p"), pCBCtx->magic, data );
1951 spin_unlock(&hdd_context_lock);
1952 return ;
1953 }
1954
1955 if (VOS_STATUS_SUCCESS == status)
1956 {
1957 gbcnMissRate = bcnMissRate;
1958 }
1959 complete(&(pCBCtx->completion));
1960 spin_unlock(&hdd_context_lock);
1961
1962 return;
1963}
1964
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001965static int hdd_driver_command(hdd_adapter_t *pAdapter,
1966 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07001967{
Jeff Johnson295189b2012-06-20 16:38:30 -07001968 hdd_priv_data_t priv_data;
1969 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001970 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001971
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001972 /*
1973 * Note that valid pointers are provided by caller
1974 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001975
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001976 /* copy to local struct to avoid numerous changes to legacy code */
1977 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07001978
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001979 if (priv_data.total_len <= 0 ||
1980 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001981 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001982 hddLog(VOS_TRACE_LEVEL_WARN,
1983 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1984 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001985 ret = -EINVAL;
1986 goto exit;
1987 }
1988
1989 /* Allocate +1 for '\0' */
1990 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 if (!command)
1992 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001993 hddLog(VOS_TRACE_LEVEL_ERROR,
1994 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 ret = -ENOMEM;
1996 goto exit;
1997 }
1998
1999 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2000 {
2001 ret = -EFAULT;
2002 goto exit;
2003 }
2004
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002005 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002006 command[priv_data.total_len] = '\0';
2007
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002008 /* at one time the following block of code was conditional. braces
2009 * have been retained to avoid re-indenting the legacy code
2010 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 {
2012 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2013
2014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002015 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002016
2017 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2018 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2020 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2021 pAdapter->sessionId, (unsigned)
2022 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2023 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2024 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2025 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2027 sizeof(tSirMacAddr)))
2028 {
2029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002030 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 ret = -EFAULT;
2032 }
2033 }
Amar Singhal0974e402013-02-12 14:27:46 -08002034 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 {
Amar Singhal0974e402013-02-12 14:27:46 -08002036 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002037
Jeff Johnson295189b2012-06-20 16:38:30 -07002038 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002039
2040 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002043 "%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 -07002044 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002045 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302046 if(ret != 0)
2047 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002048 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002049 }
Kiet Lamf040f472013-11-20 21:15:23 +05302050 else if(strncmp(command, "SETWMMPS", 8) == 0)
2051 {
2052 tANI_U8 *ptr = command;
2053 ret = hdd_wmmps_helper(pAdapter, ptr);
2054 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002055 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2056 {
2057 char *country_code;
2058
2059 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002060
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002061 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002062 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002063#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302064 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002065#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002066 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2067 (void *)(tSmeChangeCountryCallback)
2068 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302069 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002070 if (eHAL_STATUS_SUCCESS == ret)
2071 {
2072 ret = wait_for_completion_interruptible_timeout(
2073 &pAdapter->change_country_code,
2074 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2075 if (0 >= ret)
2076 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302078 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002079 }
2080 }
2081 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002082 {
2083 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002084 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002085 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002086 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002087
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002088 }
2089 /*
2090 command should be a string having format
2091 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2092 */
Amar Singhal0974e402013-02-12 14:27:46 -08002093 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002094 {
Amar Singhal0974e402013-02-12 14:27:46 -08002095 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002096
2097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002098 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002099
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002100 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002101 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002102 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2103 {
2104 int suspend = 0;
2105 tANI_U8 *ptr = (tANI_U8*)command + 15;
2106
2107 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2109 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2110 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002111 hdd_set_wlan_suspend_mode(suspend);
2112 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002113#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2114 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2115 {
2116 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002117 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002118 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2119 eHalStatus status = eHAL_STATUS_SUCCESS;
2120
2121 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2122 value = value + 15;
2123
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002124 /* Convert the value from ascii to integer */
2125 ret = kstrtos8(value, 10, &rssi);
2126 if (ret < 0)
2127 {
2128 /* If the input value is greater than max value of datatype, then also
2129 kstrtou8 fails */
2130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2131 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002132 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002133 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2134 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2135 ret = -EINVAL;
2136 goto exit;
2137 }
2138
Srinivas Girigowdade697412013-02-14 16:31:48 -08002139 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002140
Srinivas Girigowdade697412013-02-14 16:31:48 -08002141 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2142 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2143 {
2144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2145 "Neighbor lookup threshold value %d is out of range"
2146 " (Min: %d Max: %d)", lookUpThreshold,
2147 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2148 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2149 ret = -EINVAL;
2150 goto exit;
2151 }
2152
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302153 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2154 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2155 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2157 "%s: Received Command to Set Roam trigger"
2158 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2159
2160 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2161 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2162 if (eHAL_STATUS_SUCCESS != status)
2163 {
2164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2165 "%s: Failed to set roam trigger, try again", __func__);
2166 ret = -EPERM;
2167 goto exit;
2168 }
2169
2170 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2171 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2172 }
2173 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2174 {
2175 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2176 int rssi = (-1) * lookUpThreshold;
2177 char extra[32];
2178 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2180 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2181 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002182 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002183 if (copy_to_user(priv_data.buf, &extra, len + 1))
2184 {
2185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2186 "%s: failed to copy data to user buffer", __func__);
2187 ret = -EFAULT;
2188 goto exit;
2189 }
2190 }
2191 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2192 {
2193 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002194 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002195 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002196
Srinivas Girigowdade697412013-02-14 16:31:48 -08002197 /* input refresh period is in terms of seconds */
2198 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2199 value = value + 18;
2200 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002201 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002202 if (ret < 0)
2203 {
2204 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002205 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002207 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002208 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002209 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2210 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002211 ret = -EINVAL;
2212 goto exit;
2213 }
2214
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002215 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2216 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002217 {
2218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002219 "Roam scan period value %d is out of range"
2220 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002221 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2222 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002223 ret = -EINVAL;
2224 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302225 }
2226 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2227 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2228 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002229 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002230
2231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2232 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002233 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002234
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002235 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2236 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002237 }
2238 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2239 {
2240 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2241 char extra[32];
2242 tANI_U8 len = 0;
2243
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2245 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2246 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002247 len = scnprintf(extra, sizeof(extra), "%s %d",
2248 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002249 /* Returned value is in units of seconds */
2250 if (copy_to_user(priv_data.buf, &extra, len + 1))
2251 {
2252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2253 "%s: failed to copy data to user buffer", __func__);
2254 ret = -EFAULT;
2255 goto exit;
2256 }
2257 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002258 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2259 {
2260 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002261 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002262 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002263
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002264 /* input refresh period is in terms of seconds */
2265 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2266 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002267
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002268 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002269 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002270 if (ret < 0)
2271 {
2272 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002273 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002275 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002276 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002277 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2278 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2279 ret = -EINVAL;
2280 goto exit;
2281 }
2282
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002283 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2284 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2285 {
2286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2287 "Neighbor scan results refresh period value %d is out of range"
2288 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2289 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2290 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2291 ret = -EINVAL;
2292 goto exit;
2293 }
2294 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2295
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2297 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002298 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002299
2300 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2301 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2302 }
2303 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2304 {
2305 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2306 char extra[32];
2307 tANI_U8 len = 0;
2308
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002309 len = scnprintf(extra, sizeof(extra), "%s %d",
2310 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002311 /* Returned value is in units of seconds */
2312 if (copy_to_user(priv_data.buf, &extra, len + 1))
2313 {
2314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2315 "%s: failed to copy data to user buffer", __func__);
2316 ret = -EFAULT;
2317 goto exit;
2318 }
2319 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002320#ifdef FEATURE_WLAN_LFR
2321 /* SETROAMMODE */
2322 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2323 {
2324 tANI_U8 *value = command;
2325 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2326
2327 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2328 value = value + SIZE_OF_SETROAMMODE + 1;
2329
2330 /* Convert the value from ascii to integer */
2331 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2332 if (ret < 0)
2333 {
2334 /* If the input value is greater than max value of datatype, then also
2335 kstrtou8 fails */
2336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2337 "%s: kstrtou8 failed range [%d - %d]", __func__,
2338 CFG_LFR_FEATURE_ENABLED_MIN,
2339 CFG_LFR_FEATURE_ENABLED_MAX);
2340 ret = -EINVAL;
2341 goto exit;
2342 }
2343 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2344 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2345 {
2346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2347 "Roam Mode value %d is out of range"
2348 " (Min: %d Max: %d)", roamMode,
2349 CFG_LFR_FEATURE_ENABLED_MIN,
2350 CFG_LFR_FEATURE_ENABLED_MAX);
2351 ret = -EINVAL;
2352 goto exit;
2353 }
2354
2355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2356 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2357 /*
2358 * Note that
2359 * SETROAMMODE 0 is to enable LFR while
2360 * SETROAMMODE 1 is to disable LFR, but
2361 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2362 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2363 */
2364 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2365 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2366 else
2367 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2368
2369 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2370 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2371 }
2372 /* GETROAMMODE */
2373 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2374 {
2375 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2376 char extra[32];
2377 tANI_U8 len = 0;
2378
2379 /*
2380 * roamMode value shall be inverted because the sementics is different.
2381 */
2382 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2383 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2384 else
2385 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2386
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002387 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002388 if (copy_to_user(priv_data.buf, &extra, len + 1))
2389 {
2390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2391 "%s: failed to copy data to user buffer", __func__);
2392 ret = -EFAULT;
2393 goto exit;
2394 }
2395 }
2396#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002397#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002398#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002399 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2400 {
2401 tANI_U8 *value = command;
2402 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2403
2404 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2405 value = value + 13;
2406 /* Convert the value from ascii to integer */
2407 ret = kstrtou8(value, 10, &roamRssiDiff);
2408 if (ret < 0)
2409 {
2410 /* If the input value is greater than max value of datatype, then also
2411 kstrtou8 fails */
2412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2413 "%s: kstrtou8 failed range [%d - %d]", __func__,
2414 CFG_ROAM_RSSI_DIFF_MIN,
2415 CFG_ROAM_RSSI_DIFF_MAX);
2416 ret = -EINVAL;
2417 goto exit;
2418 }
2419
2420 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2421 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2422 {
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2424 "Roam rssi diff value %d is out of range"
2425 " (Min: %d Max: %d)", roamRssiDiff,
2426 CFG_ROAM_RSSI_DIFF_MIN,
2427 CFG_ROAM_RSSI_DIFF_MAX);
2428 ret = -EINVAL;
2429 goto exit;
2430 }
2431
2432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2433 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2434
2435 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2436 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2437 }
2438 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2439 {
2440 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2441 char extra[32];
2442 tANI_U8 len = 0;
2443
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302444 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2445 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2446 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002447 len = scnprintf(extra, sizeof(extra), "%s %d",
2448 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002449 if (copy_to_user(priv_data.buf, &extra, len + 1))
2450 {
2451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2452 "%s: failed to copy data to user buffer", __func__);
2453 ret = -EFAULT;
2454 goto exit;
2455 }
2456 }
2457#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002458#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002459 else if (strncmp(command, "GETBAND", 7) == 0)
2460 {
2461 int band = -1;
2462 char extra[32];
2463 tANI_U8 len = 0;
2464 hdd_getBand_helper(pHddCtx, &band);
2465
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302466 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2467 TRACE_CODE_HDD_GETBAND_IOCTL,
2468 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002469 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002470 if (copy_to_user(priv_data.buf, &extra, len + 1))
2471 {
2472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2473 "%s: failed to copy data to user buffer", __func__);
2474 ret = -EFAULT;
2475 goto exit;
2476 }
2477 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2479 {
2480 tANI_U8 *value = command;
2481 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2482 tANI_U8 numChannels = 0;
2483 eHalStatus status = eHAL_STATUS_SUCCESS;
2484
2485 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2486 if (eHAL_STATUS_SUCCESS != status)
2487 {
2488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2489 "%s: Failed to parse channel list information", __func__);
2490 ret = -EINVAL;
2491 goto exit;
2492 }
2493
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302494 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2495 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2496 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002497 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2500 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2501 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2502 ret = -EINVAL;
2503 goto exit;
2504 }
2505 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2506 numChannels);
2507 if (eHAL_STATUS_SUCCESS != status)
2508 {
2509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2510 "%s: Failed to update channel list information", __func__);
2511 ret = -EINVAL;
2512 goto exit;
2513 }
2514 }
2515 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2516 {
2517 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2518 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002519 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002520 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002521 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002522
2523 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2524 ChannelList, &numChannels ))
2525 {
2526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2527 "%s: failed to get roam scan channel list", __func__);
2528 ret = -EFAULT;
2529 goto exit;
2530 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302531 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2532 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2533 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002534 /* output channel list is of the format
2535 [Number of roam scan channels][Channel1][Channel2]... */
2536 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002537 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002538 for (j = 0; (j < numChannels); j++)
2539 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002540 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2541 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002542 }
2543
2544 if (copy_to_user(priv_data.buf, &extra, len + 1))
2545 {
2546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2547 "%s: failed to copy data to user buffer", __func__);
2548 ret = -EFAULT;
2549 goto exit;
2550 }
2551 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002552 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2553 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002554 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 char extra[32];
2556 tANI_U8 len = 0;
2557
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002558 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002559 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002560 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002561 hdd_is_okc_mode_enabled(pHddCtx) &&
2562 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2563 {
2564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002565 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002566 " hence this operation is not permitted!", __func__);
2567 ret = -EPERM;
2568 goto exit;
2569 }
2570
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002571 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002572 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002573 if (copy_to_user(priv_data.buf, &extra, len + 1))
2574 {
2575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2576 "%s: failed to copy data to user buffer", __func__);
2577 ret = -EFAULT;
2578 goto exit;
2579 }
2580 }
2581 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2582 {
2583 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2584 char extra[32];
2585 tANI_U8 len = 0;
2586
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002587 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002588 then this operation is not permitted (return FAILURE) */
2589 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002590 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002591 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2592 {
2593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002594 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002595 " hence this operation is not permitted!", __func__);
2596 ret = -EPERM;
2597 goto exit;
2598 }
2599
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002600 len = scnprintf(extra, sizeof(extra), "%s %d",
2601 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002602 if (copy_to_user(priv_data.buf, &extra, len + 1))
2603 {
2604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2605 "%s: failed to copy data to user buffer", __func__);
2606 ret = -EFAULT;
2607 goto exit;
2608 }
2609 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002610 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002611 {
2612 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2613 char extra[32];
2614 tANI_U8 len = 0;
2615
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002616 len = scnprintf(extra, sizeof(extra), "%s %d",
2617 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002618 if (copy_to_user(priv_data.buf, &extra, len + 1))
2619 {
2620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2621 "%s: failed to copy data to user buffer", __func__);
2622 ret = -EFAULT;
2623 goto exit;
2624 }
2625 }
2626 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2627 {
2628 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2629 char extra[32];
2630 tANI_U8 len = 0;
2631
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002632 len = scnprintf(extra, sizeof(extra), "%s %d",
2633 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002634 if (copy_to_user(priv_data.buf, &extra, len + 1))
2635 {
2636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2637 "%s: failed to copy data to user buffer", __func__);
2638 ret = -EFAULT;
2639 goto exit;
2640 }
2641 }
2642 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2643 {
2644 tANI_U8 *value = command;
2645 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2646
2647 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2648 value = value + 26;
2649 /* Convert the value from ascii to integer */
2650 ret = kstrtou8(value, 10, &minTime);
2651 if (ret < 0)
2652 {
2653 /* If the input value is greater than max value of datatype, then also
2654 kstrtou8 fails */
2655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2656 "%s: kstrtou8 failed range [%d - %d]", __func__,
2657 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2658 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2659 ret = -EINVAL;
2660 goto exit;
2661 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002662 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2663 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2664 {
2665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2666 "scan min channel time value %d is out of range"
2667 " (Min: %d Max: %d)", minTime,
2668 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2669 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2670 ret = -EINVAL;
2671 goto exit;
2672 }
2673
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302674 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2675 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2676 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2678 "%s: Received Command to change channel min time = %d", __func__, minTime);
2679
2680 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2681 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2682 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002683 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2684 {
2685 tANI_U8 *value = command;
2686 tANI_U8 channel = 0;
2687 tANI_U8 dwellTime = 0;
2688 tANI_U8 bufLen = 0;
2689 tANI_U8 *buf = NULL;
2690 tSirMacAddr targetApBssid;
2691 eHalStatus status = eHAL_STATUS_SUCCESS;
2692 struct ieee80211_channel chan;
2693 tANI_U8 finalLen = 0;
2694 tANI_U8 *finalBuf = NULL;
2695 tANI_U8 temp = 0;
2696 u64 cookie;
2697 hdd_station_ctx_t *pHddStaCtx = NULL;
2698 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2699
2700 /* if not associated, no need to send action frame */
2701 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2702 {
2703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2704 ret = -EINVAL;
2705 goto exit;
2706 }
2707
2708 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2709 &dwellTime, &buf, &bufLen);
2710 if (eHAL_STATUS_SUCCESS != status)
2711 {
2712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2713 "%s: Failed to parse send action frame data", __func__);
2714 ret = -EINVAL;
2715 goto exit;
2716 }
2717
2718 /* if the target bssid is different from currently associated AP,
2719 then no need to send action frame */
2720 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2721 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2722 {
2723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2724 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002725 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002726 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002727 goto exit;
2728 }
2729
2730 /* if the channel number is different from operating channel then
2731 no need to send action frame */
2732 if (channel != pHddStaCtx->conn_info.operationChannel)
2733 {
2734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2735 "%s: channel(%d) is different from operating channel(%d)",
2736 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2737 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002738 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002739 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002740 goto exit;
2741 }
2742 chan.center_freq = sme_ChnToFreq(channel);
2743
2744 finalLen = bufLen + 24;
2745 finalBuf = vos_mem_malloc(finalLen);
2746 if (NULL == finalBuf)
2747 {
2748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2749 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002750 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002751 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002752 goto exit;
2753 }
2754 vos_mem_zero(finalBuf, finalLen);
2755
2756 /* Fill subtype */
2757 temp = SIR_MAC_MGMT_ACTION << 4;
2758 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2759
2760 /* Fill type */
2761 temp = SIR_MAC_MGMT_FRAME;
2762 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2763
2764 /* Fill destination address (bssid of the AP) */
2765 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2766
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002767 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002768 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2769
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002770 /* Fill BSSID (AP mac address) */
2771 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002772
2773 /* Fill received buffer from 24th address */
2774 vos_mem_copy(finalBuf + 24, buf, bufLen);
2775
Jeff Johnson11c33152013-04-16 17:52:40 -07002776 /* done with the parsed buffer */
2777 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002778 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002779
DARAM SUDHA39eede62014-02-12 11:16:40 +05302780 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2782 &(pAdapter->wdev),
2783#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002784 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002785#endif
2786 &chan, 0,
2787#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2788 NL80211_CHAN_HT20, 1,
2789#endif
2790 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002791 1, &cookie );
2792 vos_mem_free(finalBuf);
2793 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002794 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2795 {
2796 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2797 char extra[32];
2798 tANI_U8 len = 0;
2799
2800 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002801 len = scnprintf(extra, sizeof(extra), "%s %d",
2802 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302803 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2804 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2805 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002806 if (copy_to_user(priv_data.buf, &extra, len + 1))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2809 "%s: failed to copy data to user buffer", __func__);
2810 ret = -EFAULT;
2811 goto exit;
2812 }
2813 }
2814 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2815 {
2816 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002817 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002818
2819 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2820 value = value + 19;
2821 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002822 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002823 if (ret < 0)
2824 {
2825 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002826 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002828 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002829 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2830 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2831 ret = -EINVAL;
2832 goto exit;
2833 }
2834
2835 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2836 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2837 {
2838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2839 "lfr mode value %d is out of range"
2840 " (Min: %d Max: %d)", maxTime,
2841 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2842 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2843 ret = -EINVAL;
2844 goto exit;
2845 }
2846
2847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2848 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2849
2850 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2851 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2852 }
2853 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2854 {
2855 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2856 char extra[32];
2857 tANI_U8 len = 0;
2858
2859 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002860 len = scnprintf(extra, sizeof(extra), "%s %d",
2861 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002862 if (copy_to_user(priv_data.buf, &extra, len + 1))
2863 {
2864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2865 "%s: failed to copy data to user buffer", __func__);
2866 ret = -EFAULT;
2867 goto exit;
2868 }
2869 }
2870 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2871 {
2872 tANI_U8 *value = command;
2873 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2874
2875 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2876 value = value + 16;
2877 /* Convert the value from ascii to integer */
2878 ret = kstrtou16(value, 10, &val);
2879 if (ret < 0)
2880 {
2881 /* If the input value is greater than max value of datatype, then also
2882 kstrtou16 fails */
2883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2884 "%s: kstrtou16 failed range [%d - %d]", __func__,
2885 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2886 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2887 ret = -EINVAL;
2888 goto exit;
2889 }
2890
2891 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2892 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2893 {
2894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2895 "scan home time value %d is out of range"
2896 " (Min: %d Max: %d)", val,
2897 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2898 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2899 ret = -EINVAL;
2900 goto exit;
2901 }
2902
2903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2904 "%s: Received Command to change scan home time = %d", __func__, val);
2905
2906 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2907 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2908 }
2909 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2910 {
2911 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2912 char extra[32];
2913 tANI_U8 len = 0;
2914
2915 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002916 len = scnprintf(extra, sizeof(extra), "%s %d",
2917 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002918 if (copy_to_user(priv_data.buf, &extra, len + 1))
2919 {
2920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2921 "%s: failed to copy data to user buffer", __func__);
2922 ret = -EFAULT;
2923 goto exit;
2924 }
2925 }
2926 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2927 {
2928 tANI_U8 *value = command;
2929 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2930
2931 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2932 value = value + 17;
2933 /* Convert the value from ascii to integer */
2934 ret = kstrtou8(value, 10, &val);
2935 if (ret < 0)
2936 {
2937 /* If the input value is greater than max value of datatype, then also
2938 kstrtou8 fails */
2939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2940 "%s: kstrtou8 failed range [%d - %d]", __func__,
2941 CFG_ROAM_INTRA_BAND_MIN,
2942 CFG_ROAM_INTRA_BAND_MAX);
2943 ret = -EINVAL;
2944 goto exit;
2945 }
2946
2947 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2948 (val > CFG_ROAM_INTRA_BAND_MAX))
2949 {
2950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2951 "intra band mode value %d is out of range"
2952 " (Min: %d Max: %d)", val,
2953 CFG_ROAM_INTRA_BAND_MIN,
2954 CFG_ROAM_INTRA_BAND_MAX);
2955 ret = -EINVAL;
2956 goto exit;
2957 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2959 "%s: Received Command to change intra band = %d", __func__, val);
2960
2961 pHddCtx->cfg_ini->nRoamIntraBand = val;
2962 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2963 }
2964 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2965 {
2966 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2967 char extra[32];
2968 tANI_U8 len = 0;
2969
2970 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002971 len = scnprintf(extra, sizeof(extra), "%s %d",
2972 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002973 if (copy_to_user(priv_data.buf, &extra, len + 1))
2974 {
2975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2976 "%s: failed to copy data to user buffer", __func__);
2977 ret = -EFAULT;
2978 goto exit;
2979 }
2980 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002981 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2982 {
2983 tANI_U8 *value = command;
2984 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2985
2986 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2987 value = value + 15;
2988 /* Convert the value from ascii to integer */
2989 ret = kstrtou8(value, 10, &nProbes);
2990 if (ret < 0)
2991 {
2992 /* If the input value is greater than max value of datatype, then also
2993 kstrtou8 fails */
2994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2995 "%s: kstrtou8 failed range [%d - %d]", __func__,
2996 CFG_ROAM_SCAN_N_PROBES_MIN,
2997 CFG_ROAM_SCAN_N_PROBES_MAX);
2998 ret = -EINVAL;
2999 goto exit;
3000 }
3001
3002 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3003 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3004 {
3005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3006 "NProbes value %d is out of range"
3007 " (Min: %d Max: %d)", nProbes,
3008 CFG_ROAM_SCAN_N_PROBES_MIN,
3009 CFG_ROAM_SCAN_N_PROBES_MAX);
3010 ret = -EINVAL;
3011 goto exit;
3012 }
3013
3014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3015 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3016
3017 pHddCtx->cfg_ini->nProbes = nProbes;
3018 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3019 }
3020 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3021 {
3022 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3023 char extra[32];
3024 tANI_U8 len = 0;
3025
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003026 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003027 if (copy_to_user(priv_data.buf, &extra, len + 1))
3028 {
3029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3030 "%s: failed to copy data to user buffer", __func__);
3031 ret = -EFAULT;
3032 goto exit;
3033 }
3034 }
3035 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3036 {
3037 tANI_U8 *value = command;
3038 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3039
3040 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3041 /* input value is in units of msec */
3042 value = value + 20;
3043 /* Convert the value from ascii to integer */
3044 ret = kstrtou16(value, 10, &homeAwayTime);
3045 if (ret < 0)
3046 {
3047 /* If the input value is greater than max value of datatype, then also
3048 kstrtou8 fails */
3049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3050 "%s: kstrtou8 failed range [%d - %d]", __func__,
3051 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3052 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3053 ret = -EINVAL;
3054 goto exit;
3055 }
3056
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003057 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3058 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3059 {
3060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3061 "homeAwayTime value %d is out of range"
3062 " (Min: %d Max: %d)", homeAwayTime,
3063 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3064 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3065 ret = -EINVAL;
3066 goto exit;
3067 }
3068
3069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3070 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003071 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3072 {
3073 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3074 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3075 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003076 }
3077 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3078 {
3079 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3080 char extra[32];
3081 tANI_U8 len = 0;
3082
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003083 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003084 if (copy_to_user(priv_data.buf, &extra, len + 1))
3085 {
3086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3087 "%s: failed to copy data to user buffer", __func__);
3088 ret = -EFAULT;
3089 goto exit;
3090 }
3091 }
3092 else if (strncmp(command, "REASSOC", 7) == 0)
3093 {
3094 tANI_U8 *value = command;
3095 tANI_U8 channel = 0;
3096 tSirMacAddr targetApBssid;
3097 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003098#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3099 tCsrHandoffRequest handoffInfo;
3100#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003101 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003102 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3103
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003104 /* if not associated, no need to proceed with reassoc */
3105 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3106 {
3107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3108 ret = -EINVAL;
3109 goto exit;
3110 }
3111
3112 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3113 if (eHAL_STATUS_SUCCESS != status)
3114 {
3115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3116 "%s: Failed to parse reassoc command data", __func__);
3117 ret = -EINVAL;
3118 goto exit;
3119 }
3120
3121 /* if the target bssid is same as currently associated AP,
3122 then no need to proceed with reassoc */
3123 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3124 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3125 {
3126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3127 ret = -EINVAL;
3128 goto exit;
3129 }
3130
3131 /* Check channel number is a valid channel number */
3132 if(VOS_STATUS_SUCCESS !=
3133 wlan_hdd_validate_operation_channel(pAdapter, channel))
3134 {
3135 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003136 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003137 return -EINVAL;
3138 }
3139
3140 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003141#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3142 handoffInfo.channel = channel;
3143 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3144 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3145#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003146 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003147 else if (strncmp(command, "SETWESMODE", 10) == 0)
3148 {
3149 tANI_U8 *value = command;
3150 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3151
3152 /* Move pointer to ahead of SETWESMODE<delimiter> */
3153 value = value + 11;
3154 /* Convert the value from ascii to integer */
3155 ret = kstrtou8(value, 10, &wesMode);
3156 if (ret < 0)
3157 {
3158 /* If the input value is greater than max value of datatype, then also
3159 kstrtou8 fails */
3160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3161 "%s: kstrtou8 failed range [%d - %d]", __func__,
3162 CFG_ENABLE_WES_MODE_NAME_MIN,
3163 CFG_ENABLE_WES_MODE_NAME_MAX);
3164 ret = -EINVAL;
3165 goto exit;
3166 }
3167
3168 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3169 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3170 {
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "WES Mode value %d is out of range"
3173 " (Min: %d Max: %d)", wesMode,
3174 CFG_ENABLE_WES_MODE_NAME_MIN,
3175 CFG_ENABLE_WES_MODE_NAME_MAX);
3176 ret = -EINVAL;
3177 goto exit;
3178 }
3179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3180 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3181
3182 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3183 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3184 }
3185 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3186 {
3187 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3188 char extra[32];
3189 tANI_U8 len = 0;
3190
Arif Hussain826d9412013-11-12 16:44:54 -08003191 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003192 if (copy_to_user(priv_data.buf, &extra, len + 1))
3193 {
3194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3195 "%s: failed to copy data to user buffer", __func__);
3196 ret = -EFAULT;
3197 goto exit;
3198 }
3199 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003200#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003201#ifdef FEATURE_WLAN_LFR
3202 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3203 {
3204 tANI_U8 *value = command;
3205 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3206
3207 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3208 value = value + 12;
3209 /* Convert the value from ascii to integer */
3210 ret = kstrtou8(value, 10, &lfrMode);
3211 if (ret < 0)
3212 {
3213 /* If the input value is greater than max value of datatype, then also
3214 kstrtou8 fails */
3215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3216 "%s: kstrtou8 failed range [%d - %d]", __func__,
3217 CFG_LFR_FEATURE_ENABLED_MIN,
3218 CFG_LFR_FEATURE_ENABLED_MAX);
3219 ret = -EINVAL;
3220 goto exit;
3221 }
3222
3223 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3224 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3225 {
3226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3227 "lfr mode value %d is out of range"
3228 " (Min: %d Max: %d)", lfrMode,
3229 CFG_LFR_FEATURE_ENABLED_MIN,
3230 CFG_LFR_FEATURE_ENABLED_MAX);
3231 ret = -EINVAL;
3232 goto exit;
3233 }
3234
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3236 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3237
3238 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3239 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3240 }
3241#endif
3242#ifdef WLAN_FEATURE_VOWIFI_11R
3243 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3244 {
3245 tANI_U8 *value = command;
3246 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3247
3248 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3249 value = value + 18;
3250 /* Convert the value from ascii to integer */
3251 ret = kstrtou8(value, 10, &ft);
3252 if (ret < 0)
3253 {
3254 /* If the input value is greater than max value of datatype, then also
3255 kstrtou8 fails */
3256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3257 "%s: kstrtou8 failed range [%d - %d]", __func__,
3258 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3259 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3260 ret = -EINVAL;
3261 goto exit;
3262 }
3263
3264 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3265 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3266 {
3267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3268 "ft mode value %d is out of range"
3269 " (Min: %d Max: %d)", ft,
3270 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3271 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3272 ret = -EINVAL;
3273 goto exit;
3274 }
3275
3276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3277 "%s: Received Command to change ft mode = %d", __func__, ft);
3278
3279 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3280 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3281 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303282
3283 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3284 {
3285 tANI_U8 *value = command;
3286 tSirMacAddr targetApBssid;
3287 tANI_U8 trigger = 0;
3288 eHalStatus status = eHAL_STATUS_SUCCESS;
3289 hdd_station_ctx_t *pHddStaCtx = NULL;
3290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3291
3292 /* if not associated, no need to proceed with reassoc */
3293 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3294 {
3295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3296 ret = -EINVAL;
3297 goto exit;
3298 }
3299
3300 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3301 if (eHAL_STATUS_SUCCESS != status)
3302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3304 "%s: Failed to parse reassoc command data", __func__);
3305 ret = -EINVAL;
3306 goto exit;
3307 }
3308
3309 /* if the target bssid is same as currently associated AP,
3310 then no need to proceed with reassoc */
3311 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3312 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3313 {
3314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3315 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3316 __func__);
3317 ret = -EINVAL;
3318 goto exit;
3319 }
3320
3321 /* Proceed with scan/roam */
3322 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3323 &targetApBssid[0],
3324 (tSmeFastRoamTrigger)(trigger));
3325 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003326#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003327#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003328 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3329 {
3330 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003331 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003332
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003333 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003334 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003335 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003336 hdd_is_okc_mode_enabled(pHddCtx) &&
3337 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3338 {
3339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003340 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003341 " hence this operation is not permitted!", __func__);
3342 ret = -EPERM;
3343 goto exit;
3344 }
3345
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003346 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3347 value = value + 11;
3348 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003349 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003350 if (ret < 0)
3351 {
3352 /* If the input value is greater than max value of datatype, then also
3353 kstrtou8 fails */
3354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3355 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003356 CFG_ESE_FEATURE_ENABLED_MIN,
3357 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003358 ret = -EINVAL;
3359 goto exit;
3360 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003361 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3362 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003363 {
3364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003365 "Ese mode value %d is out of range"
3366 " (Min: %d Max: %d)", eseMode,
3367 CFG_ESE_FEATURE_ENABLED_MIN,
3368 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003369 ret = -EINVAL;
3370 goto exit;
3371 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003373 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003374
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003375 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3376 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003377 }
3378#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003379 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3380 {
3381 tANI_U8 *value = command;
3382 tANI_BOOLEAN roamScanControl = 0;
3383
3384 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3385 value = value + 19;
3386 /* Convert the value from ascii to integer */
3387 ret = kstrtou8(value, 10, &roamScanControl);
3388 if (ret < 0)
3389 {
3390 /* If the input value is greater than max value of datatype, then also
3391 kstrtou8 fails */
3392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3393 "%s: kstrtou8 failed ", __func__);
3394 ret = -EINVAL;
3395 goto exit;
3396 }
3397
3398 if (0 != roamScanControl)
3399 {
3400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3401 "roam scan control invalid value = %d",
3402 roamScanControl);
3403 ret = -EINVAL;
3404 goto exit;
3405 }
3406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3407 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3408
3409 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3410 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003411#ifdef FEATURE_WLAN_OKC
3412 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3413 {
3414 tANI_U8 *value = command;
3415 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3416
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003417 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003418 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003419 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003420 hdd_is_okc_mode_enabled(pHddCtx) &&
3421 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3422 {
3423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003424 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003425 " hence this operation is not permitted!", __func__);
3426 ret = -EPERM;
3427 goto exit;
3428 }
3429
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003430 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3431 value = value + 11;
3432 /* Convert the value from ascii to integer */
3433 ret = kstrtou8(value, 10, &okcMode);
3434 if (ret < 0)
3435 {
3436 /* If the input value is greater than max value of datatype, then also
3437 kstrtou8 fails */
3438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3439 "%s: kstrtou8 failed range [%d - %d]", __func__,
3440 CFG_OKC_FEATURE_ENABLED_MIN,
3441 CFG_OKC_FEATURE_ENABLED_MAX);
3442 ret = -EINVAL;
3443 goto exit;
3444 }
3445
3446 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3447 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3448 {
3449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3450 "Okc mode value %d is out of range"
3451 " (Min: %d Max: %d)", okcMode,
3452 CFG_OKC_FEATURE_ENABLED_MIN,
3453 CFG_OKC_FEATURE_ENABLED_MAX);
3454 ret = -EINVAL;
3455 goto exit;
3456 }
3457
3458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3459 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3460
3461 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3462 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003463#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003464 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3465 {
3466 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3467 char extra[32];
3468 tANI_U8 len = 0;
3469
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003470 len = scnprintf(extra, sizeof(extra), "%s %d",
3471 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003472 if (copy_to_user(priv_data.buf, &extra, len + 1))
3473 {
3474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3475 "%s: failed to copy data to user buffer", __func__);
3476 ret = -EFAULT;
3477 goto exit;
3478 }
3479 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303480#ifdef WLAN_FEATURE_PACKET_FILTERING
3481 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3482 {
3483 tANI_U8 filterType = 0;
3484 tANI_U8 *value = command;
3485
3486 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3487 value = value + 22;
3488
3489 /* Convert the value from ascii to integer */
3490 ret = kstrtou8(value, 10, &filterType);
3491 if (ret < 0)
3492 {
3493 /* If the input value is greater than max value of datatype,
3494 * then also kstrtou8 fails
3495 */
3496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3497 "%s: kstrtou8 failed range ", __func__);
3498 ret = -EINVAL;
3499 goto exit;
3500 }
3501
3502 if (filterType != 0 && filterType != 1)
3503 {
3504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3505 "%s: Accepted Values are 0 and 1 ", __func__);
3506 ret = -EINVAL;
3507 goto exit;
3508 }
3509 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3510 pAdapter->sessionId);
3511 }
3512#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303513 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3514 {
3515 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303516 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303517 if ('1' == *dhcpPhase)
3518 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303520 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303521
3522 pHddCtx->btCoexModeSet = TRUE;
3523
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303524 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303525 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303526 }
3527 else if ('2' == *dhcpPhase)
3528 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303530 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303531
3532 pHddCtx->btCoexModeSet = FALSE;
3533
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303534 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303535 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303536 }
3537 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003538 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3539 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3541 FL("making default scan to ACTIVE"));
3542 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003543 }
3544 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3545 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3547 FL("making default scan to PASSIVE"));
3548 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003549 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303550 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3551 {
3552 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3553 char extra[32];
3554 tANI_U8 len = 0;
3555
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003556 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303557 (int)pCfg->nActiveMaxChnTime);
3558 if (copy_to_user(priv_data.buf, &extra, len + 1))
3559 {
3560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3561 "%s: failed to copy data to user buffer", __func__);
3562 ret = -EFAULT;
3563 goto exit;
3564 }
3565 ret = len;
3566 }
3567 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3568 {
3569 tANI_U8 *value = command;
3570 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3571 int val = 0, temp;
3572
3573 value = value + 13;
3574 temp = kstrtou32(value, 10, &val);
3575 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3576 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3577 {
3578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3580 ret = -EFAULT;
3581 goto exit;
3582 }
3583 pCfg->nActiveMaxChnTime = val;
3584 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003585 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3586 {
3587 tANI_U8 filterType = 0;
3588 tANI_U8 *value;
3589 value = command + 9;
3590
3591 /* Convert the value from ascii to integer */
3592 ret = kstrtou8(value, 10, &filterType);
3593 if (ret < 0)
3594 {
3595 /* If the input value is greater than max value of datatype,
3596 * then also kstrtou8 fails
3597 */
3598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3599 "%s: kstrtou8 failed range ", __func__);
3600 ret = -EINVAL;
3601 goto exit;
3602 }
3603 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3604 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3605 {
3606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3607 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3608 " 2-Sink ", __func__);
3609 ret = -EINVAL;
3610 goto exit;
3611 }
3612 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3613 pHddCtx->drvr_miracast = filterType;
3614 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3615 }
Leo Chang614d2072013-08-22 14:59:44 -07003616 else if (strncmp(command, "SETMCRATE", 9) == 0)
3617 {
Leo Chang614d2072013-08-22 14:59:44 -07003618 tANI_U8 *value = command;
3619 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003620 tSirRateUpdateInd *rateUpdate;
3621 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003622
3623 /* Only valid for SAP mode */
3624 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3625 {
3626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3627 "%s: SAP mode is not running", __func__);
3628 ret = -EFAULT;
3629 goto exit;
3630 }
3631
3632 /* Move pointer to ahead of SETMCRATE<delimiter> */
3633 /* input value is in units of hundred kbps */
3634 value = value + 10;
3635 /* Convert the value from ascii to integer, decimal base */
3636 ret = kstrtouint(value, 10, &targetRate);
3637
Leo Chang1f98cbd2013-10-17 15:03:52 -07003638 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3639 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003640 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003641 hddLog(VOS_TRACE_LEVEL_ERROR,
3642 "%s: SETMCRATE indication alloc fail", __func__);
3643 ret = -EFAULT;
3644 goto exit;
3645 }
3646 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3647
3648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3649 "MC Target rate %d", targetRate);
3650 /* Ignore unicast */
3651 rateUpdate->ucastDataRate = -1;
3652 rateUpdate->mcastDataRate24GHz = targetRate;
3653 rateUpdate->mcastDataRate5GHz = targetRate;
3654 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3655 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3656 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3657 if (eHAL_STATUS_SUCCESS != status)
3658 {
3659 hddLog(VOS_TRACE_LEVEL_ERROR,
3660 "%s: SET_MC_RATE failed", __func__);
3661 vos_mem_free(rateUpdate);
3662 ret = -EFAULT;
3663 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003664 }
3665 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303666#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003667 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303668 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003669 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303670 }
3671#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003672#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003673 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3674 {
3675 tANI_U8 *value = command;
3676 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3677 tANI_U8 numChannels = 0;
3678 eHalStatus status = eHAL_STATUS_SUCCESS;
3679
3680 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3681 if (eHAL_STATUS_SUCCESS != status)
3682 {
3683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3684 "%s: Failed to parse channel list information", __func__);
3685 ret = -EINVAL;
3686 goto exit;
3687 }
3688
3689 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3690 {
3691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3692 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3693 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3694 ret = -EINVAL;
3695 goto exit;
3696 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003697 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003698 ChannelList,
3699 numChannels);
3700 if (eHAL_STATUS_SUCCESS != status)
3701 {
3702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3703 "%s: Failed to update channel list information", __func__);
3704 ret = -EINVAL;
3705 goto exit;
3706 }
3707 }
3708 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3709 {
3710 tANI_U8 *value = command;
3711 char extra[128] = {0};
3712 int len = 0;
3713 tANI_U8 tid = 0;
3714 hdd_station_ctx_t *pHddStaCtx = NULL;
3715 tAniTrafStrmMetrics tsmMetrics;
3716 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3717
3718 /* if not associated, return error */
3719 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3720 {
3721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3722 ret = -EINVAL;
3723 goto exit;
3724 }
3725
3726 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3727 value = value + 12;
3728 /* Convert the value from ascii to integer */
3729 ret = kstrtou8(value, 10, &tid);
3730 if (ret < 0)
3731 {
3732 /* If the input value is greater than max value of datatype, then also
3733 kstrtou8 fails */
3734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3735 "%s: kstrtou8 failed range [%d - %d]", __func__,
3736 TID_MIN_VALUE,
3737 TID_MAX_VALUE);
3738 ret = -EINVAL;
3739 goto exit;
3740 }
3741
3742 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3743 {
3744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3745 "tid value %d is out of range"
3746 " (Min: %d Max: %d)", tid,
3747 TID_MIN_VALUE,
3748 TID_MAX_VALUE);
3749 ret = -EINVAL;
3750 goto exit;
3751 }
3752
3753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3754 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3755
3756 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3757 {
3758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3759 "%s: failed to get tsm stats", __func__);
3760 ret = -EFAULT;
3761 goto exit;
3762 }
3763
3764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3765 "UplinkPktQueueDly(%d)\n"
3766 "UplinkPktQueueDlyHist[0](%d)\n"
3767 "UplinkPktQueueDlyHist[1](%d)\n"
3768 "UplinkPktQueueDlyHist[2](%d)\n"
3769 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303770 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003771 "UplinkPktLoss(%d)\n"
3772 "UplinkPktCount(%d)\n"
3773 "RoamingCount(%d)\n"
3774 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3775 tsmMetrics.UplinkPktQueueDlyHist[0],
3776 tsmMetrics.UplinkPktQueueDlyHist[1],
3777 tsmMetrics.UplinkPktQueueDlyHist[2],
3778 tsmMetrics.UplinkPktQueueDlyHist[3],
3779 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3780 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3781
3782 /* Output TSM stats is of the format
3783 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3784 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003785 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003786 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3787 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3788 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3789 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3790 tsmMetrics.RoamingDly);
3791
3792 if (copy_to_user(priv_data.buf, &extra, len + 1))
3793 {
3794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3795 "%s: failed to copy data to user buffer", __func__);
3796 ret = -EFAULT;
3797 goto exit;
3798 }
3799 }
3800 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3801 {
3802 tANI_U8 *value = command;
3803 tANI_U8 *cckmIe = NULL;
3804 tANI_U8 cckmIeLen = 0;
3805 eHalStatus status = eHAL_STATUS_SUCCESS;
3806
3807 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3808 if (eHAL_STATUS_SUCCESS != status)
3809 {
3810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3811 "%s: Failed to parse cckm ie data", __func__);
3812 ret = -EINVAL;
3813 goto exit;
3814 }
3815
3816 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3817 {
3818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3819 "%s: CCKM Ie input length is more than max[%d]", __func__,
3820 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003821 vos_mem_free(cckmIe);
3822 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003823 ret = -EINVAL;
3824 goto exit;
3825 }
3826 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003827 vos_mem_free(cckmIe);
3828 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003829 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003830 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3831 {
3832 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003833 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003834 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003835 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003836 if (eHAL_STATUS_SUCCESS != status)
3837 {
3838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003839 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003840 ret = -EINVAL;
3841 goto exit;
3842 }
3843
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003844 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3845 if (eHAL_STATUS_SUCCESS != status)
3846 {
3847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3848 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3849 ret = -EINVAL;
3850 goto exit;
3851 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003852 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003853#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05303854 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
3855 {
3856 eHalStatus status;
3857 char buf[32], len;
3858 long waitRet;
3859 bcnMissRateContext_t getBcnMissRateCtx;
3860
3861 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3862
3863 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3864 {
3865 hddLog(VOS_TRACE_LEVEL_WARN,
3866 FL("GETBCNMISSRATE: STA is not in connected state"));
3867 ret = -1;
3868 goto exit;
3869 }
3870
3871 init_completion(&(getBcnMissRateCtx.completion));
3872 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
3873
3874 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
3875 pAdapter->sessionId,
3876 (void *)getBcnMissRateCB,
3877 (void *)(&getBcnMissRateCtx));
3878 if( eHAL_STATUS_SUCCESS != status)
3879 {
3880 hddLog(VOS_TRACE_LEVEL_INFO,
3881 FL("GETBCNMISSRATE: fail to post WDA cmd"));
3882 ret = -EINVAL;
3883 goto exit;
3884 }
3885
3886 waitRet = wait_for_completion_interruptible_timeout
3887 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
3888 if(waitRet <= 0)
3889 {
3890 hddLog(VOS_TRACE_LEVEL_ERROR,
3891 FL("failed to wait on bcnMissRateComp %d"), ret);
3892
3893 //Make magic number to zero so that callback is not called.
3894 spin_lock(&hdd_context_lock);
3895 getBcnMissRateCtx.magic = 0x0;
3896 spin_unlock(&hdd_context_lock);
3897 ret = -EINVAL;
3898 goto exit;
3899 }
3900
3901 hddLog(VOS_TRACE_LEVEL_INFO,
3902 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
3903
3904 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
3905 if (copy_to_user(priv_data.buf, &buf, len + 1))
3906 {
3907 hddLog(VOS_TRACE_LEVEL_ERROR,
3908 "%s: failed to copy data to user buffer", __func__);
3909 ret = -EFAULT;
3910 goto exit;
3911 }
3912 ret = len;
3913 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003914 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3916 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
3917 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003918 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3919 __func__, command);
3920 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 }
3922exit:
3923 if (command)
3924 {
3925 kfree(command);
3926 }
3927 return ret;
3928}
3929
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003930#ifdef CONFIG_COMPAT
3931static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3932{
3933 struct {
3934 compat_uptr_t buf;
3935 int used_len;
3936 int total_len;
3937 } compat_priv_data;
3938 hdd_priv_data_t priv_data;
3939 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003940
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003941 /*
3942 * Note that pAdapter and ifr have already been verified by caller,
3943 * and HDD context has also been validated
3944 */
3945 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
3946 sizeof(compat_priv_data))) {
3947 ret = -EFAULT;
3948 goto exit;
3949 }
3950 priv_data.buf = compat_ptr(compat_priv_data.buf);
3951 priv_data.used_len = compat_priv_data.used_len;
3952 priv_data.total_len = compat_priv_data.total_len;
3953 ret = hdd_driver_command(pAdapter, &priv_data);
3954 exit:
3955 return ret;
3956}
3957#else /* CONFIG_COMPAT */
3958static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3959{
3960 /* will never be invoked */
3961 return 0;
3962}
3963#endif /* CONFIG_COMPAT */
3964
3965static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3966{
3967 hdd_priv_data_t priv_data;
3968 int ret = 0;
3969
3970 /*
3971 * Note that pAdapter and ifr have already been verified by caller,
3972 * and HDD context has also been validated
3973 */
3974 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
3975 ret = -EFAULT;
3976 } else {
3977 ret = hdd_driver_command(pAdapter, &priv_data);
3978 }
3979 return ret;
3980}
3981
3982int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
3983{
3984 hdd_adapter_t *pAdapter;
3985 hdd_context_t *pHddCtx;
3986 int ret;
3987
3988 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3989 if (NULL == pAdapter) {
3990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3991 "%s: HDD adapter context is Null", __func__);
3992 ret = -ENODEV;
3993 goto exit;
3994 }
3995 if (dev != pAdapter->dev) {
3996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3997 "%s: HDD adapter/dev inconsistency", __func__);
3998 ret = -ENODEV;
3999 goto exit;
4000 }
4001
4002 if ((!ifr) || (!ifr->ifr_data)) {
4003 ret = -EINVAL;
4004 goto exit;
4005 }
4006
4007 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4008 ret = wlan_hdd_validate_context(pHddCtx);
4009 if (ret) {
4010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4011 "%s: invalid context", __func__);
4012 ret = -EBUSY;
4013 goto exit;
4014 }
4015
4016 switch (cmd) {
4017 case (SIOCDEVPRIVATE + 1):
4018 if (is_compat_task())
4019 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4020 else
4021 ret = hdd_driver_ioctl(pAdapter, ifr);
4022 break;
4023 default:
4024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4025 __func__, cmd);
4026 ret = -EINVAL;
4027 break;
4028 }
4029 exit:
4030 return ret;
4031}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004032
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004033#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004034/**---------------------------------------------------------------------------
4035
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004036 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004037
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004038 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004039 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4040 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4041 <space>Scan Mode N<space>Meas Duration N
4042 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4043 then take N.
4044 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4045 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4046 This function does not take care of removing duplicate channels from the list
4047
4048 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004049 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004050
4051 \return - 0 for success non-zero for failure
4052
4053 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004054static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4055 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004056{
4057 tANI_U8 *inPtr = pValue;
4058 int tempInt = 0;
4059 int j = 0, i = 0, v = 0;
4060 char buf[32];
4061
4062 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4063 /*no argument after the command*/
4064 if (NULL == inPtr)
4065 {
4066 return -EINVAL;
4067 }
4068 /*no space after the command*/
4069 else if (SPACE_ASCII_VALUE != *inPtr)
4070 {
4071 return -EINVAL;
4072 }
4073
4074 /*removing empty spaces*/
4075 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4076
4077 /*no argument followed by spaces*/
4078 if ('\0' == *inPtr) return -EINVAL;
4079
4080 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004081 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004082 if (1 != v) return -EINVAL;
4083
4084 v = kstrtos32(buf, 10, &tempInt);
4085 if ( v < 0) return -EINVAL;
4086
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004087 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004088
4089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004090 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004091
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004092 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004093 {
4094 for (i = 0; i < 4; i++)
4095 {
4096 /*inPtr pointing to the beginning of first space after number of ie fields*/
4097 inPtr = strpbrk( inPtr, " " );
4098 /*no ie data after the number of ie fields argument*/
4099 if (NULL == inPtr) return -EINVAL;
4100
4101 /*removing empty space*/
4102 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4103
4104 /*no ie data after the number of ie fields argument and spaces*/
4105 if ( '\0' == *inPtr ) return -EINVAL;
4106
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004107 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004108 if (1 != v) return -EINVAL;
4109
4110 v = kstrtos32(buf, 10, &tempInt);
4111 if (v < 0) return -EINVAL;
4112
4113 switch (i)
4114 {
4115 case 0: /* Measurement token */
4116 if (tempInt <= 0)
4117 {
4118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4119 "Invalid Measurement Token(%d)", tempInt);
4120 return -EINVAL;
4121 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004122 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004123 break;
4124
4125 case 1: /* Channel number */
4126 if ((tempInt <= 0) ||
4127 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4128 {
4129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4130 "Invalid Channel Number(%d)", tempInt);
4131 return -EINVAL;
4132 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004133 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004134 break;
4135
4136 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004137 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004138 {
4139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4140 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4141 return -EINVAL;
4142 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004143 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004144 break;
4145
4146 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004147 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4148 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004149 {
4150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4151 "Invalid Measurement Duration(%d)", tempInt);
4152 return -EINVAL;
4153 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004154 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004155 break;
4156 }
4157 }
4158 }
4159
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004160 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004161 {
4162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304163 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004164 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004165 pEseBcnReq->bcnReq[j].measurementToken,
4166 pEseBcnReq->bcnReq[j].channel,
4167 pEseBcnReq->bcnReq[j].scanMode,
4168 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004169 }
4170
4171 return VOS_STATUS_SUCCESS;
4172}
4173
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004174static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4175{
4176 struct statsContext *pStatsContext = NULL;
4177 hdd_adapter_t *pAdapter = NULL;
4178
4179 if (NULL == pContext)
4180 {
4181 hddLog(VOS_TRACE_LEVEL_ERROR,
4182 "%s: Bad param, pContext [%p]",
4183 __func__, pContext);
4184 return;
4185 }
4186
Jeff Johnson72a40512013-12-19 10:14:15 -08004187 /* there is a race condition that exists between this callback
4188 function and the caller since the caller could time out either
4189 before or while this code is executing. we use a spinlock to
4190 serialize these actions */
4191 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004192
4193 pStatsContext = pContext;
4194 pAdapter = pStatsContext->pAdapter;
4195 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4196 {
4197 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004198 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004199 hddLog(VOS_TRACE_LEVEL_WARN,
4200 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4201 __func__, pAdapter, pStatsContext->magic);
4202 return;
4203 }
4204
Jeff Johnson72a40512013-12-19 10:14:15 -08004205 /* context is valid so caller is still waiting */
4206
4207 /* paranoia: invalidate the magic */
4208 pStatsContext->magic = 0;
4209
4210 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004211 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4212 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4213 tsmMetrics.UplinkPktQueueDlyHist,
4214 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4215 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4216 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4217 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4218 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4219 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4220 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4221
Jeff Johnson72a40512013-12-19 10:14:15 -08004222 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004223 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004224
4225 /* serialization is complete */
4226 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004227}
4228
4229
4230
4231static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4232 tAniTrafStrmMetrics* pTsmMetrics)
4233{
4234 hdd_station_ctx_t *pHddStaCtx = NULL;
4235 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004236 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004237 long lrc;
4238 struct statsContext context;
4239 hdd_context_t *pHddCtx = NULL;
4240
4241 if (NULL == pAdapter)
4242 {
4243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4244 return VOS_STATUS_E_FAULT;
4245 }
4246
4247 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4248 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4249
4250 /* we are connected prepare our callback context */
4251 init_completion(&context.completion);
4252 context.pAdapter = pAdapter;
4253 context.magic = STATS_CONTEXT_MAGIC;
4254
4255 /* query tsm stats */
4256 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4257 pHddStaCtx->conn_info.staId[ 0 ],
4258 pHddStaCtx->conn_info.bssId,
4259 &context, pHddCtx->pvosContext, tid);
4260
4261 if (eHAL_STATUS_SUCCESS != hstatus)
4262 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4264 __func__);
4265 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004266 }
4267 else
4268 {
4269 /* request was sent -- wait for the response */
4270 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4271 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004272 if (lrc <= 0)
4273 {
4274 hddLog(VOS_TRACE_LEVEL_ERROR,
4275 "%s: SME %s while retrieving statistics",
4276 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004277 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004278 }
4279 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004280
Jeff Johnson72a40512013-12-19 10:14:15 -08004281 /* either we never sent a request, we sent a request and received a
4282 response or we sent a request and timed out. if we never sent a
4283 request or if we sent a request and got a response, we want to
4284 clear the magic out of paranoia. if we timed out there is a
4285 race condition such that the callback function could be
4286 executing at the same time we are. of primary concern is if the
4287 callback function had already verified the "magic" but had not
4288 yet set the completion variable when a timeout occurred. we
4289 serialize these activities by invalidating the magic while
4290 holding a shared spinlock which will cause us to block if the
4291 callback is currently executing */
4292 spin_lock(&hdd_context_lock);
4293 context.magic = 0;
4294 spin_unlock(&hdd_context_lock);
4295
4296 if (VOS_STATUS_SUCCESS == vstatus)
4297 {
4298 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4299 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4300 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4301 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4302 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4303 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4304 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4305 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4306 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4307 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4308 }
4309 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004310}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004311#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004312
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004313#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004314void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4315{
4316 eCsrBand band = -1;
4317 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4318 switch (band)
4319 {
4320 case eCSR_BAND_ALL:
4321 *pBand = WLAN_HDD_UI_BAND_AUTO;
4322 break;
4323
4324 case eCSR_BAND_24:
4325 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4326 break;
4327
4328 case eCSR_BAND_5G:
4329 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4330 break;
4331
4332 default:
4333 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4334 *pBand = -1;
4335 break;
4336 }
4337}
4338
4339/**---------------------------------------------------------------------------
4340
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004341 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4342
4343 This function parses the send action frame data passed in the format
4344 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4345
Srinivas Girigowda56076852013-08-20 14:00:50 -07004346 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004347 \param - pTargetApBssid Pointer to target Ap bssid
4348 \param - pChannel Pointer to the Target AP channel
4349 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4350 \param - pBuf Pointer to data
4351 \param - pBufLen Pointer to data length
4352
4353 \return - 0 for success non-zero for failure
4354
4355 --------------------------------------------------------------------------*/
4356VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4357 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4358{
4359 tANI_U8 *inPtr = pValue;
4360 tANI_U8 *dataEnd;
4361 int tempInt;
4362 int j = 0;
4363 int i = 0;
4364 int v = 0;
4365 tANI_U8 tempBuf[32];
4366 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004367 /* 12 hexa decimal digits, 5 ':' and '\0' */
4368 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004369
4370 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4371 /*no argument after the command*/
4372 if (NULL == inPtr)
4373 {
4374 return -EINVAL;
4375 }
4376
4377 /*no space after the command*/
4378 else if (SPACE_ASCII_VALUE != *inPtr)
4379 {
4380 return -EINVAL;
4381 }
4382
4383 /*removing empty spaces*/
4384 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4385
4386 /*no argument followed by spaces*/
4387 if ('\0' == *inPtr)
4388 {
4389 return -EINVAL;
4390 }
4391
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004392 v = sscanf(inPtr, "%17s", macAddress);
4393 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004394 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4396 "Invalid MAC address or All hex inputs are not read (%d)", v);
4397 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004398 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004399
4400 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4401 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4402 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4403 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4404 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4405 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004406
4407 /* point to the next argument */
4408 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4409 /*no argument after the command*/
4410 if (NULL == inPtr) return -EINVAL;
4411
4412 /*removing empty spaces*/
4413 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4414
4415 /*no argument followed by spaces*/
4416 if ('\0' == *inPtr)
4417 {
4418 return -EINVAL;
4419 }
4420
4421 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004422 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004423 if (1 != v) return -EINVAL;
4424
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004425 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304426 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304427 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004428
4429 *pChannel = tempInt;
4430
4431 /* point to the next argument */
4432 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4433 /*no argument after the command*/
4434 if (NULL == inPtr) return -EINVAL;
4435 /*removing empty spaces*/
4436 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4437
4438 /*no argument followed by spaces*/
4439 if ('\0' == *inPtr)
4440 {
4441 return -EINVAL;
4442 }
4443
4444 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004445 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004446 if (1 != v) return -EINVAL;
4447
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004448 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004449 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004450
4451 *pDwellTime = tempInt;
4452
4453 /* point to the next argument */
4454 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4455 /*no argument after the command*/
4456 if (NULL == inPtr) return -EINVAL;
4457 /*removing empty spaces*/
4458 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4459
4460 /*no argument followed by spaces*/
4461 if ('\0' == *inPtr)
4462 {
4463 return -EINVAL;
4464 }
4465
4466 /* find the length of data */
4467 dataEnd = inPtr;
4468 while(('\0' != *dataEnd) )
4469 {
4470 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004471 }
Kiet Lambe150c22013-11-21 16:30:32 +05304472 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004473 if ( *pBufLen <= 0) return -EINVAL;
4474
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004475 /* Allocate the number of bytes based on the number of input characters
4476 whether it is even or odd.
4477 if the number of input characters are even, then we need N/2 byte.
4478 if the number of input characters are odd, then we need do (N+1)/2 to
4479 compensate rounding off.
4480 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4481 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4482 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004483 if (NULL == *pBuf)
4484 {
4485 hddLog(VOS_TRACE_LEVEL_FATAL,
4486 "%s: vos_mem_alloc failed ", __func__);
4487 return -EINVAL;
4488 }
4489
4490 /* the buffer received from the upper layer is character buffer,
4491 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4492 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4493 and f0 in 3rd location */
4494 for (i = 0, j = 0; j < *pBufLen; j += 2)
4495 {
Kiet Lambe150c22013-11-21 16:30:32 +05304496 if( j+1 == *pBufLen)
4497 {
4498 tempByte = hdd_parse_hex(inPtr[j]);
4499 }
4500 else
4501 {
4502 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4503 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004504 (*pBuf)[i++] = tempByte;
4505 }
4506 *pBufLen = i;
4507 return VOS_STATUS_SUCCESS;
4508}
4509
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004510/**---------------------------------------------------------------------------
4511
Srinivas Girigowdade697412013-02-14 16:31:48 -08004512 \brief hdd_parse_channellist() - HDD Parse channel list
4513
4514 This function parses the channel list passed in the format
4515 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004516 if the Number of channels (N) does not match with the actual number of channels passed
4517 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4518 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4519 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4520 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004521
4522 \param - pValue Pointer to input channel list
4523 \param - ChannelList Pointer to local output array to record channel list
4524 \param - pNumChannels Pointer to number of roam scan channels
4525
4526 \return - 0 for success non-zero for failure
4527
4528 --------------------------------------------------------------------------*/
4529VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4530{
4531 tANI_U8 *inPtr = pValue;
4532 int tempInt;
4533 int j = 0;
4534 int v = 0;
4535 char buf[32];
4536
4537 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4538 /*no argument after the command*/
4539 if (NULL == inPtr)
4540 {
4541 return -EINVAL;
4542 }
4543
4544 /*no space after the command*/
4545 else if (SPACE_ASCII_VALUE != *inPtr)
4546 {
4547 return -EINVAL;
4548 }
4549
4550 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004551 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004552
4553 /*no argument followed by spaces*/
4554 if ('\0' == *inPtr)
4555 {
4556 return -EINVAL;
4557 }
4558
4559 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004560 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004561 if (1 != v) return -EINVAL;
4562
Srinivas Girigowdade697412013-02-14 16:31:48 -08004563 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004564 if ((v < 0) ||
4565 (tempInt <= 0) ||
4566 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4567 {
4568 return -EINVAL;
4569 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004570
4571 *pNumChannels = tempInt;
4572
4573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4574 "Number of channels are: %d", *pNumChannels);
4575
4576 for (j = 0; j < (*pNumChannels); j++)
4577 {
4578 /*inPtr pointing to the beginning of first space after number of channels*/
4579 inPtr = strpbrk( inPtr, " " );
4580 /*no channel list after the number of channels argument*/
4581 if (NULL == inPtr)
4582 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004583 if (0 != j)
4584 {
4585 *pNumChannels = j;
4586 return VOS_STATUS_SUCCESS;
4587 }
4588 else
4589 {
4590 return -EINVAL;
4591 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004592 }
4593
4594 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004595 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004596
4597 /*no channel list after the number of channels argument and spaces*/
4598 if ( '\0' == *inPtr )
4599 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004600 if (0 != j)
4601 {
4602 *pNumChannels = j;
4603 return VOS_STATUS_SUCCESS;
4604 }
4605 else
4606 {
4607 return -EINVAL;
4608 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004609 }
4610
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004611 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004612 if (1 != v) return -EINVAL;
4613
Srinivas Girigowdade697412013-02-14 16:31:48 -08004614 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004615 if ((v < 0) ||
4616 (tempInt <= 0) ||
4617 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4618 {
4619 return -EINVAL;
4620 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004621 pChannelList[j] = tempInt;
4622
4623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4624 "Channel %d added to preferred channel list",
4625 pChannelList[j] );
4626 }
4627
Srinivas Girigowdade697412013-02-14 16:31:48 -08004628 return VOS_STATUS_SUCCESS;
4629}
4630
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004631
4632/**---------------------------------------------------------------------------
4633
4634 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4635
4636 This function parses the reasoc command data passed in the format
4637 REASSOC<space><bssid><space><channel>
4638
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004639 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004640 \param - pTargetApBssid Pointer to target Ap bssid
4641 \param - pChannel Pointer to the Target AP channel
4642
4643 \return - 0 for success non-zero for failure
4644
4645 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004646VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4647 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004648{
4649 tANI_U8 *inPtr = pValue;
4650 int tempInt;
4651 int v = 0;
4652 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004653 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004654 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004655
4656 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4657 /*no argument after the command*/
4658 if (NULL == inPtr)
4659 {
4660 return -EINVAL;
4661 }
4662
4663 /*no space after the command*/
4664 else if (SPACE_ASCII_VALUE != *inPtr)
4665 {
4666 return -EINVAL;
4667 }
4668
4669 /*removing empty spaces*/
4670 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4671
4672 /*no argument followed by spaces*/
4673 if ('\0' == *inPtr)
4674 {
4675 return -EINVAL;
4676 }
4677
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004678 v = sscanf(inPtr, "%17s", macAddress);
4679 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004680 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4682 "Invalid MAC address or All hex inputs are not read (%d)", v);
4683 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004684 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004685
4686 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4687 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4688 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4689 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4690 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4691 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004692
4693 /* point to the next argument */
4694 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4695 /*no argument after the command*/
4696 if (NULL == inPtr) return -EINVAL;
4697
4698 /*removing empty spaces*/
4699 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4700
4701 /*no argument followed by spaces*/
4702 if ('\0' == *inPtr)
4703 {
4704 return -EINVAL;
4705 }
4706
4707 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004708 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004709 if (1 != v) return -EINVAL;
4710
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004711 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004712 if ((v < 0) ||
4713 (tempInt <= 0) ||
4714 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4715 {
4716 return -EINVAL;
4717 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004718
4719 *pChannel = tempInt;
4720 return VOS_STATUS_SUCCESS;
4721}
4722
4723#endif
4724
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004725#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004726/**---------------------------------------------------------------------------
4727
4728 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4729
4730 This function parses the SETCCKM IE command
4731 SETCCKMIE<space><ie data>
4732
4733 \param - pValue Pointer to input data
4734 \param - pCckmIe Pointer to output cckm Ie
4735 \param - pCckmIeLen Pointer to output cckm ie length
4736
4737 \return - 0 for success non-zero for failure
4738
4739 --------------------------------------------------------------------------*/
4740VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4741 tANI_U8 *pCckmIeLen)
4742{
4743 tANI_U8 *inPtr = pValue;
4744 tANI_U8 *dataEnd;
4745 int j = 0;
4746 int i = 0;
4747 tANI_U8 tempByte = 0;
4748
4749 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4750 /*no argument after the command*/
4751 if (NULL == inPtr)
4752 {
4753 return -EINVAL;
4754 }
4755
4756 /*no space after the command*/
4757 else if (SPACE_ASCII_VALUE != *inPtr)
4758 {
4759 return -EINVAL;
4760 }
4761
4762 /*removing empty spaces*/
4763 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4764
4765 /*no argument followed by spaces*/
4766 if ('\0' == *inPtr)
4767 {
4768 return -EINVAL;
4769 }
4770
4771 /* find the length of data */
4772 dataEnd = inPtr;
4773 while(('\0' != *dataEnd) )
4774 {
4775 dataEnd++;
4776 ++(*pCckmIeLen);
4777 }
4778 if ( *pCckmIeLen <= 0) return -EINVAL;
4779
4780 /* Allocate the number of bytes based on the number of input characters
4781 whether it is even or odd.
4782 if the number of input characters are even, then we need N/2 byte.
4783 if the number of input characters are odd, then we need do (N+1)/2 to
4784 compensate rounding off.
4785 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4786 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4787 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4788 if (NULL == *pCckmIe)
4789 {
4790 hddLog(VOS_TRACE_LEVEL_FATAL,
4791 "%s: vos_mem_alloc failed ", __func__);
4792 return -EINVAL;
4793 }
4794 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4795 /* the buffer received from the upper layer is character buffer,
4796 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4797 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4798 and f0 in 3rd location */
4799 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4800 {
4801 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4802 (*pCckmIe)[i++] = tempByte;
4803 }
4804 *pCckmIeLen = i;
4805
4806 return VOS_STATUS_SUCCESS;
4807}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004808#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004809
Jeff Johnson295189b2012-06-20 16:38:30 -07004810/**---------------------------------------------------------------------------
4811
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004812 \brief hdd_is_valid_mac_address() - Validate MAC address
4813
4814 This function validates whether the given MAC address is valid or not
4815 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4816 where X is the hexa decimal digit character and separated by ':'
4817 This algorithm works even if MAC address is not separated by ':'
4818
4819 This code checks given input string mac contains exactly 12 hexadecimal digits.
4820 and a separator colon : appears in the input string only after
4821 an even number of hex digits.
4822
4823 \param - pMacAddr pointer to the input MAC address
4824 \return - 1 for valid and 0 for invalid
4825
4826 --------------------------------------------------------------------------*/
4827
4828v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4829{
4830 int xdigit = 0;
4831 int separator = 0;
4832 while (*pMacAddr)
4833 {
4834 if (isxdigit(*pMacAddr))
4835 {
4836 xdigit++;
4837 }
4838 else if (':' == *pMacAddr)
4839 {
4840 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4841 break;
4842
4843 ++separator;
4844 }
4845 else
4846 {
4847 separator = -1;
4848 /* Invalid MAC found */
4849 return 0;
4850 }
4851 ++pMacAddr;
4852 }
4853 return (xdigit == 12 && (separator == 5 || separator == 0));
4854}
4855
4856/**---------------------------------------------------------------------------
4857
Jeff Johnson295189b2012-06-20 16:38:30 -07004858 \brief hdd_open() - HDD Open function
4859
4860 This is called in response to ifconfig up
4861
4862 \param - dev Pointer to net_device structure
4863
4864 \return - 0 for success non-zero for failure
4865
4866 --------------------------------------------------------------------------*/
4867int hdd_open (struct net_device *dev)
4868{
4869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4870 hdd_context_t *pHddCtx;
4871 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4872 VOS_STATUS status;
4873 v_BOOL_t in_standby = TRUE;
4874
4875 if (NULL == pAdapter)
4876 {
4877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304878 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004879 return -ENODEV;
4880 }
4881
4882 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304883 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4884 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 if (NULL == pHddCtx)
4886 {
4887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004888 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004889 return -ENODEV;
4890 }
4891
4892 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4893 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4894 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004895 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4896 {
4897 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304898 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004899 in_standby = FALSE;
4900 break;
4901 }
4902 else
4903 {
4904 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4905 pAdapterNode = pNext;
4906 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004907 }
4908
4909 if (TRUE == in_standby)
4910 {
4911 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4912 {
4913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4914 "wlan out of power save", __func__);
4915 return -EINVAL;
4916 }
4917 }
4918
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004919 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4921 {
4922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004923 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004924 /* Enable TX queues only when we are connected */
4925 netif_tx_start_all_queues(dev);
4926 }
4927
4928 return 0;
4929}
4930
4931int hdd_mon_open (struct net_device *dev)
4932{
4933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4934
4935 if(pAdapter == NULL) {
4936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004937 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004938 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004939 }
4940
4941 netif_start_queue(dev);
4942
4943 return 0;
4944}
4945/**---------------------------------------------------------------------------
4946
4947 \brief hdd_stop() - HDD stop function
4948
4949 This is called in response to ifconfig down
4950
4951 \param - dev Pointer to net_device structure
4952
4953 \return - 0 for success non-zero for failure
4954
4955 --------------------------------------------------------------------------*/
4956
4957int hdd_stop (struct net_device *dev)
4958{
4959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4960 hdd_context_t *pHddCtx;
4961 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4962 VOS_STATUS status;
4963 v_BOOL_t enter_standby = TRUE;
4964
4965 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004966 if (NULL == pAdapter)
4967 {
4968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304969 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 return -ENODEV;
4971 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304972 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4973 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004974 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4975 if (NULL == pHddCtx)
4976 {
4977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004978 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004979 return -ENODEV;
4980 }
4981
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004982 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4984 netif_tx_disable(pAdapter->dev);
4985 netif_carrier_off(pAdapter->dev);
4986
4987
4988 /* SoftAP ifaces should never go in power save mode
4989 making sure same here. */
4990 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4991 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004993 )
4994 {
4995 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4997 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 EXIT();
4999 return 0;
5000 }
5001
5002 /* Find if any iface is up then
5003 if any iface is up then can't put device to sleep/ power save mode. */
5004 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5005 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5006 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005007 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5008 {
5009 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305010 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005011 enter_standby = FALSE;
5012 break;
5013 }
5014 else
5015 {
5016 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5017 pAdapterNode = pNext;
5018 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005019 }
5020
5021 if (TRUE == enter_standby)
5022 {
5023 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5024 "entering standby", __func__);
5025 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5026 {
5027 /*log and return success*/
5028 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5029 "wlan in power save", __func__);
5030 }
5031 }
5032
5033 EXIT();
5034 return 0;
5035}
5036
5037/**---------------------------------------------------------------------------
5038
5039 \brief hdd_uninit() - HDD uninit function
5040
5041 This is called during the netdev unregister to uninitialize all data
5042associated with the device
5043
5044 \param - dev Pointer to net_device structure
5045
5046 \return - void
5047
5048 --------------------------------------------------------------------------*/
5049static void hdd_uninit (struct net_device *dev)
5050{
5051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5052
5053 ENTER();
5054
5055 do
5056 {
5057 if (NULL == pAdapter)
5058 {
5059 hddLog(VOS_TRACE_LEVEL_FATAL,
5060 "%s: NULL pAdapter", __func__);
5061 break;
5062 }
5063
5064 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5065 {
5066 hddLog(VOS_TRACE_LEVEL_FATAL,
5067 "%s: Invalid magic", __func__);
5068 break;
5069 }
5070
5071 if (NULL == pAdapter->pHddCtx)
5072 {
5073 hddLog(VOS_TRACE_LEVEL_FATAL,
5074 "%s: NULL pHddCtx", __func__);
5075 break;
5076 }
5077
5078 if (dev != pAdapter->dev)
5079 {
5080 hddLog(VOS_TRACE_LEVEL_FATAL,
5081 "%s: Invalid device reference", __func__);
5082 /* we haven't validated all cases so let this go for now */
5083 }
5084
5085 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5086
5087 /* after uninit our adapter structure will no longer be valid */
5088 pAdapter->dev = NULL;
5089 pAdapter->magic = 0;
5090 } while (0);
5091
5092 EXIT();
5093}
5094
5095/**---------------------------------------------------------------------------
5096
5097 \brief hdd_release_firmware() -
5098
5099 This function calls the release firmware API to free the firmware buffer.
5100
5101 \param - pFileName Pointer to the File Name.
5102 pCtx - Pointer to the adapter .
5103
5104
5105 \return - 0 for success, non zero for failure
5106
5107 --------------------------------------------------------------------------*/
5108
5109VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5110{
5111 VOS_STATUS status = VOS_STATUS_SUCCESS;
5112 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5113 ENTER();
5114
5115
5116 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5117
5118 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5119
5120 if(pHddCtx->fw) {
5121 release_firmware(pHddCtx->fw);
5122 pHddCtx->fw = NULL;
5123 }
5124 else
5125 status = VOS_STATUS_E_FAILURE;
5126 }
5127 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5128 if(pHddCtx->nv) {
5129 release_firmware(pHddCtx->nv);
5130 pHddCtx->nv = NULL;
5131 }
5132 else
5133 status = VOS_STATUS_E_FAILURE;
5134
5135 }
5136
5137 EXIT();
5138 return status;
5139}
5140
5141/**---------------------------------------------------------------------------
5142
5143 \brief hdd_request_firmware() -
5144
5145 This function reads the firmware file using the request firmware
5146 API and returns the the firmware data and the firmware file size.
5147
5148 \param - pfileName - Pointer to the file name.
5149 - pCtx - Pointer to the adapter .
5150 - ppfw_data - Pointer to the pointer of the firmware data.
5151 - pSize - Pointer to the file size.
5152
5153 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5154
5155 --------------------------------------------------------------------------*/
5156
5157
5158VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5159{
5160 int status;
5161 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5162 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5163 ENTER();
5164
5165 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5166
5167 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5168
5169 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5170 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5171 __func__, pfileName);
5172 retval = VOS_STATUS_E_FAILURE;
5173 }
5174
5175 else {
5176 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5177 *pSize = pHddCtx->fw->size;
5178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5179 __func__, *pSize);
5180 }
5181 }
5182 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5183
5184 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5185
5186 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5187 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5188 __func__, pfileName);
5189 retval = VOS_STATUS_E_FAILURE;
5190 }
5191
5192 else {
5193 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5194 *pSize = pHddCtx->nv->size;
5195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5196 __func__, *pSize);
5197 }
5198 }
5199
5200 EXIT();
5201 return retval;
5202}
5203/**---------------------------------------------------------------------------
5204 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5205
5206 This is the function invoked by SME to inform the result of a full power
5207 request issued by HDD
5208
5209 \param - callbackcontext - Pointer to cookie
5210 status - result of request
5211
5212 \return - None
5213
5214--------------------------------------------------------------------------*/
5215void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5216{
5217 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5218
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005219 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005220 if(&pHddCtx->full_pwr_comp_var)
5221 {
5222 complete(&pHddCtx->full_pwr_comp_var);
5223 }
5224}
5225
5226/**---------------------------------------------------------------------------
5227
5228 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5229
5230 This is the function invoked by SME to inform the result of BMPS
5231 request issued by HDD
5232
5233 \param - callbackcontext - Pointer to cookie
5234 status - result of request
5235
5236 \return - None
5237
5238--------------------------------------------------------------------------*/
5239void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5240{
5241
5242 struct completion *completion_var = (struct completion*) callbackContext;
5243
Arif Hussain6d2a3322013-11-17 19:50:10 -08005244 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005245 if(completion_var != NULL)
5246 {
5247 complete(completion_var);
5248 }
5249}
5250
5251/**---------------------------------------------------------------------------
5252
5253 \brief hdd_get_cfg_file_size() -
5254
5255 This function reads the configuration file using the request firmware
5256 API and returns the configuration file size.
5257
5258 \param - pCtx - Pointer to the adapter .
5259 - pFileName - Pointer to the file name.
5260 - pBufSize - Pointer to the buffer size.
5261
5262 \return - 0 for success, non zero for failure
5263
5264 --------------------------------------------------------------------------*/
5265
5266VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5267{
5268 int status;
5269 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5270
5271 ENTER();
5272
5273 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5274
5275 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5276 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5277 status = VOS_STATUS_E_FAILURE;
5278 }
5279 else {
5280 *pBufSize = pHddCtx->fw->size;
5281 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5282 release_firmware(pHddCtx->fw);
5283 pHddCtx->fw = NULL;
5284 }
5285
5286 EXIT();
5287 return VOS_STATUS_SUCCESS;
5288}
5289
5290/**---------------------------------------------------------------------------
5291
5292 \brief hdd_read_cfg_file() -
5293
5294 This function reads the configuration file using the request firmware
5295 API and returns the cfg data and the buffer size of the configuration file.
5296
5297 \param - pCtx - Pointer to the adapter .
5298 - pFileName - Pointer to the file name.
5299 - pBuffer - Pointer to the data buffer.
5300 - pBufSize - Pointer to the buffer size.
5301
5302 \return - 0 for success, non zero for failure
5303
5304 --------------------------------------------------------------------------*/
5305
5306VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5307 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5308{
5309 int status;
5310 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5311
5312 ENTER();
5313
5314 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5315
5316 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5317 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5318 return VOS_STATUS_E_FAILURE;
5319 }
5320 else {
5321 if(*pBufSize != pHddCtx->fw->size) {
5322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5323 "file size", __func__);
5324 release_firmware(pHddCtx->fw);
5325 pHddCtx->fw = NULL;
5326 return VOS_STATUS_E_FAILURE;
5327 }
5328 else {
5329 if(pBuffer) {
5330 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5331 }
5332 release_firmware(pHddCtx->fw);
5333 pHddCtx->fw = NULL;
5334 }
5335 }
5336
5337 EXIT();
5338
5339 return VOS_STATUS_SUCCESS;
5340}
5341
5342/**---------------------------------------------------------------------------
5343
Jeff Johnson295189b2012-06-20 16:38:30 -07005344 \brief hdd_set_mac_address() -
5345
5346 This function sets the user specified mac address using
5347 the command ifconfig wlanX hw ether <mac adress>.
5348
5349 \param - dev - Pointer to the net device.
5350 - addr - Pointer to the sockaddr.
5351 \return - 0 for success, non zero for failure
5352
5353 --------------------------------------------------------------------------*/
5354
5355static int hdd_set_mac_address(struct net_device *dev, void *addr)
5356{
5357 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5358 struct sockaddr *psta_mac_addr = addr;
5359 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5360
5361 ENTER();
5362
5363 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5364
5365#ifdef HDD_SESSIONIZE
5366 // set the MAC address though the STA ID CFG.
5367 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5368 (v_U8_t *)&pAdapter->macAddressCurrent,
5369 sizeof( pAdapter->macAddressCurrent ),
5370 hdd_set_mac_addr_cb, VOS_FALSE );
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305371
5372 if(eHAL_STATUS_SUCCESS != halStatus)
5373 {
5374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5375 "%s: failed to set MAC address in CFG", __func__);
5376 }
5377
Jeff Johnson295189b2012-06-20 16:38:30 -07005378#endif
5379
5380 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5381
5382 EXIT();
5383 return halStatus;
5384}
5385
5386tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5387{
5388 int i;
5389 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5390 {
Abhishek Singheb183782014-02-06 13:37:21 +05305391 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 break;
5393 }
5394
5395 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5396 return NULL;
5397
5398 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5399 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5400}
5401
5402void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5403{
5404 int i;
5405 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5406 {
5407 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5408 {
5409 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5410 break;
5411 }
5412 }
5413 return;
5414}
5415
5416#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5417 static struct net_device_ops wlan_drv_ops = {
5418 .ndo_open = hdd_open,
5419 .ndo_stop = hdd_stop,
5420 .ndo_uninit = hdd_uninit,
5421 .ndo_start_xmit = hdd_hard_start_xmit,
5422 .ndo_tx_timeout = hdd_tx_timeout,
5423 .ndo_get_stats = hdd_stats,
5424 .ndo_do_ioctl = hdd_ioctl,
5425 .ndo_set_mac_address = hdd_set_mac_address,
5426 .ndo_select_queue = hdd_select_queue,
5427#ifdef WLAN_FEATURE_PACKET_FILTERING
5428#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5429 .ndo_set_rx_mode = hdd_set_multicast_list,
5430#else
5431 .ndo_set_multicast_list = hdd_set_multicast_list,
5432#endif //LINUX_VERSION_CODE
5433#endif
5434 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 static struct net_device_ops wlan_mon_drv_ops = {
5436 .ndo_open = hdd_mon_open,
5437 .ndo_stop = hdd_stop,
5438 .ndo_uninit = hdd_uninit,
5439 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5440 .ndo_tx_timeout = hdd_tx_timeout,
5441 .ndo_get_stats = hdd_stats,
5442 .ndo_do_ioctl = hdd_ioctl,
5443 .ndo_set_mac_address = hdd_set_mac_address,
5444 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005445
5446#endif
5447
5448void hdd_set_station_ops( struct net_device *pWlanDev )
5449{
5450#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 pWlanDev->netdev_ops = &wlan_drv_ops;
5452#else
5453 pWlanDev->open = hdd_open;
5454 pWlanDev->stop = hdd_stop;
5455 pWlanDev->uninit = hdd_uninit;
5456 pWlanDev->hard_start_xmit = NULL;
5457 pWlanDev->tx_timeout = hdd_tx_timeout;
5458 pWlanDev->get_stats = hdd_stats;
5459 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 pWlanDev->set_mac_address = hdd_set_mac_address;
5461#endif
5462}
5463
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005464static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005465{
5466 struct net_device *pWlanDev = NULL;
5467 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 /*
5469 * cfg80211 initialization and registration....
5470 */
5471 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5472
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 if(pWlanDev != NULL)
5474 {
5475
5476 //Save the pointer to the net_device in the HDD adapter
5477 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5478
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5480
5481 pAdapter->dev = pWlanDev;
5482 pAdapter->pHddCtx = pHddCtx;
5483 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5484
5485 init_completion(&pAdapter->session_open_comp_var);
5486 init_completion(&pAdapter->session_close_comp_var);
5487 init_completion(&pAdapter->disconnect_comp_var);
5488 init_completion(&pAdapter->linkup_event_var);
5489 init_completion(&pAdapter->cancel_rem_on_chan_var);
5490 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305491 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005492#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5493 init_completion(&pAdapter->offchannel_tx_event);
5494#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005496#ifdef FEATURE_WLAN_TDLS
5497 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005498 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005499 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305500 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005501#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 init_completion(&pHddCtx->mc_sus_event_var);
5503 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305504 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005505 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005506 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005507
Rajeev79dbe4c2013-10-05 11:03:42 +05305508#ifdef FEATURE_WLAN_BATCH_SCAN
5509 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5510 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5511 pAdapter->pBatchScanRsp = NULL;
5512 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005513 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005514 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305515 mutex_init(&pAdapter->hdd_batch_scan_lock);
5516#endif
5517
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 pAdapter->isLinkUpSvcNeeded = FALSE;
5519 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5520 //Init the net_device structure
5521 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5522
5523 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5524 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5525 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5526 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5527
5528 hdd_set_station_ops( pAdapter->dev );
5529
5530 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5532 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5533 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 /* set pWlanDev's parent to underlying device */
5535 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5536 }
5537
5538 return pAdapter;
5539}
5540
5541VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5542{
5543 struct net_device *pWlanDev = pAdapter->dev;
5544 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5545 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5546 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5547
5548 if( rtnl_lock_held )
5549 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005550 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5552 {
5553 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5554 return VOS_STATUS_E_FAILURE;
5555 }
5556 }
5557 if (register_netdevice(pWlanDev))
5558 {
5559 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5560 return VOS_STATUS_E_FAILURE;
5561 }
5562 }
5563 else
5564 {
5565 if(register_netdev(pWlanDev))
5566 {
5567 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5568 return VOS_STATUS_E_FAILURE;
5569 }
5570 }
5571 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5572
5573 return VOS_STATUS_SUCCESS;
5574}
5575
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005576static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005577{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005578 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005579
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005580 if (NULL == pAdapter)
5581 {
5582 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5583 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005585
5586 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5587 {
5588 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5589 return eHAL_STATUS_NOT_INITIALIZED;
5590 }
5591
5592 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5593
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005594#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005595 /* need to make sure all of our scheduled work has completed.
5596 * This callback is called from MC thread context, so it is safe to
5597 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005598 *
5599 * Even though this is called from MC thread context, if there is a faulty
5600 * work item in the system, that can hang this call forever. So flushing
5601 * this global work queue is not safe; and now we make sure that
5602 * individual work queues are stopped correctly. But the cancel work queue
5603 * is a GPL only API, so the proprietary version of the driver would still
5604 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005605 */
5606 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005607#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005608
5609 /* We can be blocked while waiting for scheduled work to be
5610 * flushed, and the adapter structure can potentially be freed, in
5611 * which case the magic will have been reset. So make sure the
5612 * magic is still good, and hence the adapter structure is still
5613 * valid, before signaling completion */
5614 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5615 {
5616 complete(&pAdapter->session_close_comp_var);
5617 }
5618
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 return eHAL_STATUS_SUCCESS;
5620}
5621
5622VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5623{
5624 struct net_device *pWlanDev = pAdapter->dev;
5625 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5626 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5627 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5628 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305629 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005630
5631 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005632 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 //Open a SME session for future operation
5634 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005635 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5637 {
5638 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005639 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 halStatus, halStatus );
5641 status = VOS_STATUS_E_FAILURE;
5642 goto error_sme_open;
5643 }
5644
5645 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305646 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 &pAdapter->session_open_comp_var,
5648 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305649 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 {
5651 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305652 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005653 status = VOS_STATUS_E_FAILURE;
5654 goto error_sme_open;
5655 }
5656
5657 // Register wireless extensions
5658 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5659 {
5660 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005661 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005662 halStatus, halStatus );
5663 status = VOS_STATUS_E_FAILURE;
5664 goto error_register_wext;
5665 }
5666 //Safe to register the hard_start_xmit function again
5667#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5668 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5669#else
5670 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5671#endif
5672
5673 //Set the Connection State to Not Connected
5674 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5675
5676 //Set the default operation channel
5677 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5678
5679 /* Make the default Auth Type as OPEN*/
5680 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5681
5682 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5683 {
5684 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005685 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 status, status );
5687 goto error_init_txrx;
5688 }
5689
5690 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5691
5692 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5693 {
5694 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005695 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 status, status );
5697 goto error_wmm_init;
5698 }
5699
5700 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5701
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005702#ifdef FEATURE_WLAN_TDLS
5703 if(0 != wlan_hdd_tdls_init(pAdapter))
5704 {
5705 status = VOS_STATUS_E_FAILURE;
5706 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5707 goto error_tdls_init;
5708 }
5709 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5710#endif
5711
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 return VOS_STATUS_SUCCESS;
5713
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005714#ifdef FEATURE_WLAN_TDLS
5715error_tdls_init:
5716 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5717 hdd_wmm_adapter_close(pAdapter);
5718#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005719error_wmm_init:
5720 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5721 hdd_deinit_tx_rx(pAdapter);
5722error_init_txrx:
5723 hdd_UnregisterWext(pWlanDev);
5724error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005725 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005726 {
5727 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005728 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005730 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305732 unsigned long rc;
5733
Jeff Johnson295189b2012-06-20 16:38:30 -07005734 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305735 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005737 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305738 if (rc <= 0)
5739 hddLog(VOS_TRACE_LEVEL_ERROR,
5740 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005741 }
5742}
5743error_sme_open:
5744 return status;
5745}
5746
Jeff Johnson295189b2012-06-20 16:38:30 -07005747void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5748{
5749 hdd_cfg80211_state_t *cfgState;
5750
5751 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5752
5753 if( NULL != cfgState->buf )
5754 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305755 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5757 rc = wait_for_completion_interruptible_timeout(
5758 &pAdapter->tx_action_cnf_event,
5759 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305760 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305763 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5764 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 }
5766 }
5767 return;
5768}
Jeff Johnson295189b2012-06-20 16:38:30 -07005769
5770void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5771{
5772 ENTER();
5773 switch ( pAdapter->device_mode )
5774 {
5775 case WLAN_HDD_INFRA_STATION:
5776 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005777 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 {
5779 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5780 {
5781 hdd_deinit_tx_rx( pAdapter );
5782 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5783 }
5784
5785 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5786 {
5787 hdd_wmm_adapter_close( pAdapter );
5788 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5789 }
5790
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005792#ifdef FEATURE_WLAN_TDLS
5793 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5794 {
5795 wlan_hdd_tdls_exit(pAdapter);
5796 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5797 }
5798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005799
5800 break;
5801 }
5802
5803 case WLAN_HDD_SOFTAP:
5804 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305806
5807 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5808 {
5809 hdd_wmm_adapter_close( pAdapter );
5810 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5811 }
5812
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005814
5815 hdd_unregister_hostapd(pAdapter);
5816 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 break;
5819 }
5820
5821 case WLAN_HDD_MONITOR:
5822 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5825 {
5826 hdd_deinit_tx_rx( pAdapter );
5827 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 if(NULL != pAdapterforTx)
5830 {
5831 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 break;
5834 }
5835
5836
5837 default:
5838 break;
5839 }
5840
5841 EXIT();
5842}
5843
5844void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5845{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005846 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305847
5848 ENTER();
5849 if (NULL == pAdapter)
5850 {
5851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5852 "%s: HDD adapter is Null", __func__);
5853 return;
5854 }
5855
5856 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005857
Rajeev79dbe4c2013-10-05 11:03:42 +05305858#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305859 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5860 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005861 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305862 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5863 )
5864 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005865 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305866 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005867 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5868 {
5869 hdd_deinit_batch_scan(pAdapter);
5870 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305871 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005872 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305873#endif
5874
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5876 if( rtnl_held )
5877 {
5878 unregister_netdevice(pWlanDev);
5879 }
5880 else
5881 {
5882 unregister_netdev(pWlanDev);
5883 }
5884 // note that the pAdapter is no longer valid at this point
5885 // since the memory has been reclaimed
5886 }
5887
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305888 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005889}
5890
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005891void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5892{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305893 VOS_STATUS status;
5894 hdd_adapter_t *pAdapter = NULL;
5895 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005896
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305897 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005898
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305899 /*loop through all adapters.*/
5900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005901 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305902 pAdapter = pAdapterNode->pAdapter;
5903 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5904 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005905
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305906 { // we skip this registration for modes other than STA and P2P client modes.
5907 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5908 pAdapterNode = pNext;
5909 continue;
5910 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005911
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305912 //Apply Dynamic DTIM For P2P
5913 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5914 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5915 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5916 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5917 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5918 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5919 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5920 (eConnectionState_Associated ==
5921 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5922 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5923 {
5924 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005925
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305926 powerRequest.uIgnoreDTIM = 1;
5927 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5928
5929 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5930 {
5931 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5932 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5933 }
5934 else
5935 {
5936 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5937 }
5938
5939 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5940 * specified during Enter/Exit BMPS when LCD off*/
5941 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5942 NULL, eANI_BOOLEAN_FALSE);
5943 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5944 NULL, eANI_BOOLEAN_FALSE);
5945
5946 /* switch to the DTIM specified in cfg.ini */
5947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5948 "Switch to DTIM %d", powerRequest.uListenInterval);
5949 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5950 break;
5951
5952 }
5953
5954 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5955 pAdapterNode = pNext;
5956 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005957}
5958
5959void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5960{
5961 /*Switch back to DTIM 1*/
5962 tSirSetPowerParamsReq powerRequest = { 0 };
5963
5964 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5965 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005966 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005967
5968 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5969 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5970 NULL, eANI_BOOLEAN_FALSE);
5971 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5972 NULL, eANI_BOOLEAN_FALSE);
5973
5974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5975 "Switch to DTIM%d",powerRequest.uListenInterval);
5976 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5977
5978}
5979
Jeff Johnson295189b2012-06-20 16:38:30 -07005980VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5981{
5982 VOS_STATUS status = VOS_STATUS_SUCCESS;
5983
5984 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5985 {
5986 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5987 }
5988
5989 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5990 {
5991 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5992 }
5993
5994 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5995 {
5996 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5997 }
5998
5999 return status;
6000}
6001
6002VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6003{
6004 hdd_adapter_t *pAdapter = NULL;
6005 eHalStatus halStatus;
6006 VOS_STATUS status = VOS_STATUS_E_INVAL;
6007 v_BOOL_t disableBmps = FALSE;
6008 v_BOOL_t disableImps = FALSE;
6009
6010 switch(session_type)
6011 {
6012 case WLAN_HDD_INFRA_STATION:
6013 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 case WLAN_HDD_P2P_CLIENT:
6015 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 //Exit BMPS -> Is Sta/P2P Client is already connected
6017 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6018 if((NULL != pAdapter)&&
6019 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6020 {
6021 disableBmps = TRUE;
6022 }
6023
6024 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6025 if((NULL != pAdapter)&&
6026 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6027 {
6028 disableBmps = TRUE;
6029 }
6030
6031 //Exit both Bmps and Imps incase of Go/SAP Mode
6032 if((WLAN_HDD_SOFTAP == session_type) ||
6033 (WLAN_HDD_P2P_GO == session_type))
6034 {
6035 disableBmps = TRUE;
6036 disableImps = TRUE;
6037 }
6038
6039 if(TRUE == disableImps)
6040 {
6041 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6042 {
6043 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6044 }
6045 }
6046
6047 if(TRUE == disableBmps)
6048 {
6049 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6050 {
6051 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6052
6053 if(eHAL_STATUS_SUCCESS != halStatus)
6054 {
6055 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006056 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006057 VOS_ASSERT(0);
6058 return status;
6059 }
6060 }
6061
6062 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6063 {
6064 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6065
6066 if(eHAL_STATUS_SUCCESS != halStatus)
6067 {
6068 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006069 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006070 VOS_ASSERT(0);
6071 return status;
6072 }
6073 }
6074 }
6075
6076 if((TRUE == disableBmps) ||
6077 (TRUE == disableImps))
6078 {
6079 /* Now, get the chip into Full Power now */
6080 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6081 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6082 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6083
6084 if(halStatus != eHAL_STATUS_SUCCESS)
6085 {
6086 if(halStatus == eHAL_STATUS_PMC_PENDING)
6087 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306088 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306090 ret = wait_for_completion_interruptible_timeout(
6091 &pHddCtx->full_pwr_comp_var,
6092 msecs_to_jiffies(1000));
6093 if (ret <= 0)
6094 {
6095 hddLog(VOS_TRACE_LEVEL_ERROR,
6096 "%s: wait on full_pwr_comp_var failed %ld",
6097 __func__, ret);
6098 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 }
6100 else
6101 {
6102 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006103 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 VOS_ASSERT(0);
6105 return status;
6106 }
6107 }
6108
6109 status = VOS_STATUS_SUCCESS;
6110 }
6111
6112 break;
6113 }
6114 return status;
6115}
6116
6117hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006118 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 tANI_U8 rtnl_held )
6120{
6121 hdd_adapter_t *pAdapter = NULL;
6122 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6123 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6124 VOS_STATUS exitbmpsStatus;
6125
Arif Hussain6d2a3322013-11-17 19:50:10 -08006126 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006127
Nirav Shah436658f2014-02-28 17:05:45 +05306128 if(macAddr == NULL)
6129 {
6130 /* Not received valid macAddr */
6131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6132 "%s:Unable to add virtual intf: Not able to get"
6133 "valid mac address",__func__);
6134 return NULL;
6135 }
6136
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 //Disable BMPS incase of Concurrency
6138 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6139
6140 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6141 {
6142 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306143 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 VOS_ASSERT(0);
6145 return NULL;
6146 }
6147
6148 switch(session_type)
6149 {
6150 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006151 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006152 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 {
6154 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6155
6156 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306157 {
6158 hddLog(VOS_TRACE_LEVEL_FATAL,
6159 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306161 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006162
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306163#ifdef FEATURE_WLAN_TDLS
6164 /* A Mutex Lock is introduced while changing/initializing the mode to
6165 * protect the concurrent access for the Adapters by TDLS module.
6166 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306167 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306168#endif
6169
Jeff Johnsone7245742012-09-05 17:12:55 -07006170 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6171 NL80211_IFTYPE_P2P_CLIENT:
6172 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006173
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306175#ifdef FEATURE_WLAN_TDLS
6176 mutex_unlock(&pHddCtx->tdls_lock);
6177#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306178
6179 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 if( VOS_STATUS_SUCCESS != status )
6181 goto err_free_netdev;
6182
6183 status = hdd_register_interface( pAdapter, rtnl_held );
6184 if( VOS_STATUS_SUCCESS != status )
6185 {
6186 hdd_deinit_adapter(pHddCtx, pAdapter);
6187 goto err_free_netdev;
6188 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306189
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306190 // Workqueue which gets scheduled in IPv4 notification callback.
6191 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6192
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306193#ifdef WLAN_NS_OFFLOAD
6194 // Workqueue which gets scheduled in IPv6 notification callback.
6195 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6196#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 //Stop the Interface TX queue.
6198 netif_tx_disable(pAdapter->dev);
6199 //netif_tx_disable(pWlanDev);
6200 netif_carrier_off(pAdapter->dev);
6201
6202 break;
6203 }
6204
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 case WLAN_HDD_SOFTAP:
6207 {
6208 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6209 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306210 {
6211 hddLog(VOS_TRACE_LEVEL_FATAL,
6212 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306214 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006215
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6217 NL80211_IFTYPE_AP:
6218 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006219 pAdapter->device_mode = session_type;
6220
6221 status = hdd_init_ap_mode(pAdapter);
6222 if( VOS_STATUS_SUCCESS != status )
6223 goto err_free_netdev;
6224
6225 status = hdd_register_hostapd( pAdapter, rtnl_held );
6226 if( VOS_STATUS_SUCCESS != status )
6227 {
6228 hdd_deinit_adapter(pHddCtx, pAdapter);
6229 goto err_free_netdev;
6230 }
6231
6232 netif_tx_disable(pAdapter->dev);
6233 netif_carrier_off(pAdapter->dev);
6234
6235 hdd_set_conparam( 1 );
6236 break;
6237 }
6238 case WLAN_HDD_MONITOR:
6239 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6241 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306242 {
6243 hddLog(VOS_TRACE_LEVEL_FATAL,
6244 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306246 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006247
6248 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6249 pAdapter->device_mode = session_type;
6250 status = hdd_register_interface( pAdapter, rtnl_held );
6251#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6252 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6253#else
6254 pAdapter->dev->open = hdd_mon_open;
6255 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6256#endif
6257 hdd_init_tx_rx( pAdapter );
6258 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6259 //Set adapter to be used for data tx. It will use either GO or softap.
6260 pAdapter->sessionCtx.monitor.pAdapterForTx =
6261 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6263 {
6264 pAdapter->sessionCtx.monitor.pAdapterForTx =
6265 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6266 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 /* This workqueue will be used to transmit management packet over
6268 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006269 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6270 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6271 return NULL;
6272 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006273
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6275 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 }
6277 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 case WLAN_HDD_FTM:
6279 {
6280 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6281
6282 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306283 {
6284 hddLog(VOS_TRACE_LEVEL_FATAL,
6285 FL("failed to allocate adapter for session %d"), session_type);
6286 return NULL;
6287 }
6288
Jeff Johnson295189b2012-06-20 16:38:30 -07006289 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6290 * message while loading driver in FTM mode. */
6291 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6292 pAdapter->device_mode = session_type;
6293 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306294
6295 hdd_init_tx_rx( pAdapter );
6296
6297 //Stop the Interface TX queue.
6298 netif_tx_disable(pAdapter->dev);
6299 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 }
6301 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 default:
6303 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306304 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6305 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 VOS_ASSERT(0);
6307 return NULL;
6308 }
6309 }
6310
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 if( VOS_STATUS_SUCCESS == status )
6312 {
6313 //Add it to the hdd's session list.
6314 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6315 if( NULL == pHddAdapterNode )
6316 {
6317 status = VOS_STATUS_E_NOMEM;
6318 }
6319 else
6320 {
6321 pHddAdapterNode->pAdapter = pAdapter;
6322 status = hdd_add_adapter_back ( pHddCtx,
6323 pHddAdapterNode );
6324 }
6325 }
6326
6327 if( VOS_STATUS_SUCCESS != status )
6328 {
6329 if( NULL != pAdapter )
6330 {
6331 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6332 pAdapter = NULL;
6333 }
6334 if( NULL != pHddAdapterNode )
6335 {
6336 vos_mem_free( pHddAdapterNode );
6337 }
6338
6339 goto resume_bmps;
6340 }
6341
6342 if(VOS_STATUS_SUCCESS == status)
6343 {
6344 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6345
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006346 //Initialize the WoWL service
6347 if(!hdd_init_wowl(pAdapter))
6348 {
6349 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6350 goto err_free_netdev;
6351 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 return pAdapter;
6354
6355err_free_netdev:
6356 free_netdev(pAdapter->dev);
6357 wlan_hdd_release_intf_addr( pHddCtx,
6358 pAdapter->macAddressCurrent.bytes );
6359
6360resume_bmps:
6361 //If bmps disabled enable it
6362 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6363 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306364 if (pHddCtx->hdd_wlan_suspended)
6365 {
6366 hdd_set_pwrparams(pHddCtx);
6367 }
6368 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 }
6370 return NULL;
6371}
6372
6373VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6374 tANI_U8 rtnl_held )
6375{
6376 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6377 VOS_STATUS status;
6378
6379 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6380 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306381 {
6382 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6383 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306385 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006386
6387 while ( pCurrent->pAdapter != pAdapter )
6388 {
6389 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6390 if( VOS_STATUS_SUCCESS != status )
6391 break;
6392
6393 pCurrent = pNext;
6394 }
6395 pAdapterNode = pCurrent;
6396 if( VOS_STATUS_SUCCESS == status )
6397 {
6398 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6399 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306400
6401#ifdef FEATURE_WLAN_TDLS
6402
6403 /* A Mutex Lock is introduced while changing/initializing the mode to
6404 * protect the concurrent access for the Adapters by TDLS module.
6405 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306406 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306407#endif
6408
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 hdd_remove_adapter( pHddCtx, pAdapterNode );
6410 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006411 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006412
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306413#ifdef FEATURE_WLAN_TDLS
6414 mutex_unlock(&pHddCtx->tdls_lock);
6415#endif
6416
Jeff Johnson295189b2012-06-20 16:38:30 -07006417
6418 /* If there is a single session of STA/P2P client, re-enable BMPS */
6419 if ((!vos_concurrent_sessions_running()) &&
6420 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6421 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6422 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306423 if (pHddCtx->hdd_wlan_suspended)
6424 {
6425 hdd_set_pwrparams(pHddCtx);
6426 }
6427 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 }
6429
6430 return VOS_STATUS_SUCCESS;
6431 }
6432
6433 return VOS_STATUS_E_FAILURE;
6434}
6435
6436VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6437{
6438 hdd_adapter_list_node_t *pHddAdapterNode;
6439 VOS_STATUS status;
6440
6441 ENTER();
6442
6443 do
6444 {
6445 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6446 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6447 {
6448 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6449 vos_mem_free( pHddAdapterNode );
6450 }
6451 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6452
6453 EXIT();
6454
6455 return VOS_STATUS_SUCCESS;
6456}
6457
6458void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6459{
6460 v_U8_t addIE[1] = {0};
6461
6462 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6463 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6464 eANI_BOOLEAN_FALSE) )
6465 {
6466 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006467 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 }
6469
6470 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6471 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6472 eANI_BOOLEAN_FALSE) )
6473 {
6474 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006475 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 }
6477
6478 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6479 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6480 eANI_BOOLEAN_FALSE) )
6481 {
6482 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006483 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 }
6485}
6486
6487VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6488{
6489 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6490 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6491 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306492 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306493 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006494
6495 ENTER();
6496
6497 switch(pAdapter->device_mode)
6498 {
6499 case WLAN_HDD_INFRA_STATION:
6500 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006501 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306502 {
6503 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6504 if( hdd_connIsConnected(pstation) ||
6505 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 {
6507 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6508 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6509 pAdapter->sessionId,
6510 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6511 else
6512 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6513 pAdapter->sessionId,
6514 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6515 //success implies disconnect command got queued up successfully
6516 if(halStatus == eHAL_STATUS_SUCCESS)
6517 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306518 ret = wait_for_completion_interruptible_timeout(
6519 &pAdapter->disconnect_comp_var,
6520 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6521 if (ret <= 0)
6522 {
6523 hddLog(VOS_TRACE_LEVEL_ERROR,
6524 "%s: wait on disconnect_comp_var failed %ld",
6525 __func__, ret);
6526 }
6527 }
6528 else
6529 {
6530 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6531 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006532 }
6533 memset(&wrqu, '\0', sizeof(wrqu));
6534 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6535 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6536 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6537 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306538 else if(pstation->conn_info.connState ==
6539 eConnectionState_Disconnecting)
6540 {
6541 ret = wait_for_completion_interruptible_timeout(
6542 &pAdapter->disconnect_comp_var,
6543 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6544 if (ret <= 0)
6545 {
6546 hddLog(VOS_TRACE_LEVEL_ERROR,
6547 FL("wait on disconnect_comp_var failed %ld"), ret);
6548 }
6549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 else
6551 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306552 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6553 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306555 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6556 {
6557 while (pAdapter->is_roc_inprogress)
6558 {
6559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6560 "%s: ROC in progress for session %d!!!",
6561 __func__, pAdapter->sessionId);
6562 // waiting for ROC to expire
6563 msleep(500);
6564 /* In GO present case , if retry exceeds 3,
6565 it means something went wrong. */
6566 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6567 {
6568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6569 "%s: ROC completion is not received.!!!", __func__);
6570 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6571 pAdapter->sessionId);
6572 wait_for_completion_interruptible_timeout(
6573 &pAdapter->cancel_rem_on_chan_var,
6574 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6575 break;
6576 }
6577 }
6578 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306579#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306580#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306581 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6582#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306583 if (pAdapter->ipv6_notifier_registered)
6584 {
6585 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6586 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6587 pAdapter->ipv6_notifier_registered = false;
6588 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306589#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306590 if (pAdapter->ipv4_notifier_registered)
6591 {
6592 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6593 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6594 pAdapter->ipv4_notifier_registered = false;
6595 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306596#ifdef WLAN_OPEN_SOURCE
6597 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6598#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006599 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6600 {
6601 INIT_COMPLETION(pAdapter->session_close_comp_var);
6602 if (eHAL_STATUS_SUCCESS ==
6603 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6604 hdd_smeCloseSessionCallback, pAdapter))
6605 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306606 unsigned long ret;
6607
Jeff Johnson295189b2012-06-20 16:38:30 -07006608 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306609 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 &pAdapter->session_close_comp_var,
6611 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306612 if ( 0 >= ret)
6613 {
6614 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6615 __func__, ret);
6616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 }
6618 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306619 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006620 break;
6621
6622 case WLAN_HDD_SOFTAP:
6623 case WLAN_HDD_P2P_GO:
6624 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306625 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6626 while (pAdapter->is_roc_inprogress) {
6627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6628 "%s: ROC in progress for session %d!!!",
6629 __func__, pAdapter->sessionId);
6630 msleep(500);
6631 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6633 "%s: ROC completion is not received.!!!", __func__);
6634 WLANSAP_CancelRemainOnChannel(
6635 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6636 wait_for_completion_interruptible_timeout(
6637 &pAdapter->cancel_rem_on_chan_var,
6638 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6639 break;
6640 }
6641 }
6642 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 mutex_lock(&pHddCtx->sap_lock);
6644 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6645 {
6646 VOS_STATUS status;
6647 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6648
6649 //Stop Bss.
6650 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6651 if (VOS_IS_STATUS_SUCCESS(status))
6652 {
6653 hdd_hostapd_state_t *pHostapdState =
6654 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6655
6656 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6657
6658 if (!VOS_IS_STATUS_SUCCESS(status))
6659 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306660 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6661 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006662 }
6663 }
6664 else
6665 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006666 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 }
6668 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6669
6670 if (eHAL_STATUS_FAILURE ==
6671 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6672 0, NULL, eANI_BOOLEAN_FALSE))
6673 {
6674 hddLog(LOGE,
6675 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006676 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 }
6678
6679 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6680 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6681 eANI_BOOLEAN_FALSE) )
6682 {
6683 hddLog(LOGE,
6684 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6685 }
6686
6687 // Reset WNI_CFG_PROBE_RSP Flags
6688 wlan_hdd_reset_prob_rspies(pAdapter);
6689 kfree(pAdapter->sessionCtx.ap.beacon);
6690 pAdapter->sessionCtx.ap.beacon = NULL;
6691 }
6692 mutex_unlock(&pHddCtx->sap_lock);
6693 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006694
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006696#ifdef WLAN_OPEN_SOURCE
6697 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6698#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006700
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 default:
6702 break;
6703 }
6704
6705 EXIT();
6706 return VOS_STATUS_SUCCESS;
6707}
6708
6709VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6710{
6711 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6712 VOS_STATUS status;
6713 hdd_adapter_t *pAdapter;
6714
6715 ENTER();
6716
6717 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6718
6719 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6720 {
6721 pAdapter = pAdapterNode->pAdapter;
6722 netif_tx_disable(pAdapter->dev);
6723 netif_carrier_off(pAdapter->dev);
6724
6725 hdd_stop_adapter( pHddCtx, pAdapter );
6726
6727 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6728 pAdapterNode = pNext;
6729 }
6730
6731 EXIT();
6732
6733 return VOS_STATUS_SUCCESS;
6734}
6735
Rajeev Kumarf999e582014-01-09 17:33:29 -08006736
6737#ifdef FEATURE_WLAN_BATCH_SCAN
6738/**---------------------------------------------------------------------------
6739
6740 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6741 structures
6742
6743 \param - pAdapter Pointer to HDD adapter
6744
6745 \return - None
6746
6747 --------------------------------------------------------------------------*/
6748void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6749{
6750 tHddBatchScanRsp *pNode;
6751 tHddBatchScanRsp *pPrev;
6752
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306753 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006754 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306755 hddLog(VOS_TRACE_LEVEL_ERROR,
6756 "%s: Adapter context is Null", __func__);
6757 return;
6758 }
6759
6760 pNode = pAdapter->pBatchScanRsp;
6761 while (pNode)
6762 {
6763 pPrev = pNode;
6764 pNode = pNode->pNext;
6765 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006766 }
6767
6768 pAdapter->pBatchScanRsp = NULL;
6769 pAdapter->numScanList = 0;
6770 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6771 pAdapter->prev_batch_id = 0;
6772
6773 return;
6774}
6775#endif
6776
6777
Jeff Johnson295189b2012-06-20 16:38:30 -07006778VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6779{
6780 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6781 VOS_STATUS status;
6782 hdd_adapter_t *pAdapter;
6783
6784 ENTER();
6785
6786 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6787
6788 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6789 {
6790 pAdapter = pAdapterNode->pAdapter;
6791 netif_tx_disable(pAdapter->dev);
6792 netif_carrier_off(pAdapter->dev);
6793
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006794 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6795
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306797 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6798 {
6799 hdd_wmm_adapter_close( pAdapter );
6800 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006802
Rajeev Kumarf999e582014-01-09 17:33:29 -08006803#ifdef FEATURE_WLAN_BATCH_SCAN
6804 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6805 {
6806 hdd_deinit_batch_scan(pAdapter);
6807 }
6808#endif
6809
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6811 pAdapterNode = pNext;
6812 }
6813
6814 EXIT();
6815
6816 return VOS_STATUS_SUCCESS;
6817}
6818
6819VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6820{
6821 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6822 VOS_STATUS status;
6823 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306824 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006825
6826 ENTER();
6827
6828 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6829
6830 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6831 {
6832 pAdapter = pAdapterNode->pAdapter;
6833
6834 switch(pAdapter->device_mode)
6835 {
6836 case WLAN_HDD_INFRA_STATION:
6837 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006838 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306839
6840 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6841
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 hdd_init_station_mode(pAdapter);
6843 /* Open the gates for HDD to receive Wext commands */
6844 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006845 pHddCtx->scan_info.mScanPending = FALSE;
6846 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006847
6848 //Trigger the initial scan
6849 hdd_wlan_initial_scan(pAdapter);
6850
6851 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306852 if (eConnectionState_Associated == connState ||
6853 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 {
6855 union iwreq_data wrqu;
6856 memset(&wrqu, '\0', sizeof(wrqu));
6857 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6858 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6859 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006860 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006861
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 /* indicate disconnected event to nl80211 */
6863 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6864 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306866 else if (eConnectionState_Connecting == connState)
6867 {
6868 /*
6869 * Indicate connect failure to supplicant if we were in the
6870 * process of connecting
6871 */
6872 cfg80211_connect_result(pAdapter->dev, NULL,
6873 NULL, 0, NULL, 0,
6874 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6875 GFP_KERNEL);
6876 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 break;
6878
6879 case WLAN_HDD_SOFTAP:
6880 /* softAP can handle SSR */
6881 break;
6882
6883 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006884 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006886 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006887 break;
6888
6889 case WLAN_HDD_MONITOR:
6890 /* monitor interface start */
6891 break;
6892 default:
6893 break;
6894 }
6895
6896 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6897 pAdapterNode = pNext;
6898 }
6899
6900 EXIT();
6901
6902 return VOS_STATUS_SUCCESS;
6903}
6904
6905VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6906{
6907 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6908 hdd_adapter_t *pAdapter;
6909 VOS_STATUS status;
6910 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306911 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006912
6913 ENTER();
6914
6915 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6916
6917 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6918 {
6919 pAdapter = pAdapterNode->pAdapter;
6920
6921 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6922 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6923 {
6924 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6925 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6926
6927 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6928 init_completion(&pAdapter->disconnect_comp_var);
6929 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6930 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6931
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306932 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 &pAdapter->disconnect_comp_var,
6934 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306935 if (0 >= ret)
6936 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6937 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006938
6939 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6940 pHddCtx->isAmpAllowed = VOS_FALSE;
6941 sme_RoamConnect(pHddCtx->hHal,
6942 pAdapter->sessionId, &(pWextState->roamProfile),
6943 &roamId);
6944 }
6945
6946 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6947 pAdapterNode = pNext;
6948 }
6949
6950 EXIT();
6951
6952 return VOS_STATUS_SUCCESS;
6953}
6954
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006955void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6956{
6957 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6958 VOS_STATUS status;
6959 hdd_adapter_t *pAdapter;
6960 hdd_station_ctx_t *pHddStaCtx;
6961 hdd_ap_ctx_t *pHddApCtx;
6962 hdd_hostapd_state_t * pHostapdState;
6963 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6964 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6965 const char *p2pMode = "DEV";
6966 const char *ccMode = "Standalone";
6967 int n;
6968
6969 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6970 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6971 {
6972 pAdapter = pAdapterNode->pAdapter;
6973 switch (pAdapter->device_mode) {
6974 case WLAN_HDD_INFRA_STATION:
6975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6976 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6977 staChannel = pHddStaCtx->conn_info.operationChannel;
6978 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6979 }
6980 break;
6981 case WLAN_HDD_P2P_CLIENT:
6982 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6983 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6984 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6985 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6986 p2pMode = "CLI";
6987 }
6988 break;
6989 case WLAN_HDD_P2P_GO:
6990 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6991 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6992 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6993 p2pChannel = pHddApCtx->operatingChannel;
6994 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6995 }
6996 p2pMode = "GO";
6997 break;
6998 case WLAN_HDD_SOFTAP:
6999 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7000 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7001 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7002 apChannel = pHddApCtx->operatingChannel;
7003 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7004 }
7005 break;
7006 default:
7007 break;
7008 }
7009 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7010 pAdapterNode = pNext;
7011 }
7012 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7013 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7014 }
7015 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7016 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7017 if (p2pChannel > 0) {
7018 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7019 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7020 }
7021 if (apChannel > 0) {
7022 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7023 apChannel, MAC_ADDR_ARRAY(apBssid));
7024 }
7025
7026 if (p2pChannel > 0 && apChannel > 0) {
7027 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7028 }
7029}
7030
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007031bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007032{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007033 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007034}
7035
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007036/* Once SSR is disabled then it cannot be set. */
7037void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007038{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007039 if (HDD_SSR_DISABLED == isSsrRequired)
7040 return;
7041
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 isSsrRequired = value;
7043}
7044
7045VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7046 hdd_adapter_list_node_t** ppAdapterNode)
7047{
7048 VOS_STATUS status;
7049 spin_lock(&pHddCtx->hddAdapters.lock);
7050 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7051 (hdd_list_node_t**) ppAdapterNode );
7052 spin_unlock(&pHddCtx->hddAdapters.lock);
7053 return status;
7054}
7055
7056VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7057 hdd_adapter_list_node_t* pAdapterNode,
7058 hdd_adapter_list_node_t** pNextAdapterNode)
7059{
7060 VOS_STATUS status;
7061 spin_lock(&pHddCtx->hddAdapters.lock);
7062 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7063 (hdd_list_node_t*) pAdapterNode,
7064 (hdd_list_node_t**)pNextAdapterNode );
7065
7066 spin_unlock(&pHddCtx->hddAdapters.lock);
7067 return status;
7068}
7069
7070VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7071 hdd_adapter_list_node_t* pAdapterNode)
7072{
7073 VOS_STATUS status;
7074 spin_lock(&pHddCtx->hddAdapters.lock);
7075 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7076 &pAdapterNode->node );
7077 spin_unlock(&pHddCtx->hddAdapters.lock);
7078 return status;
7079}
7080
7081VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7082 hdd_adapter_list_node_t** ppAdapterNode)
7083{
7084 VOS_STATUS status;
7085 spin_lock(&pHddCtx->hddAdapters.lock);
7086 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7087 (hdd_list_node_t**) ppAdapterNode );
7088 spin_unlock(&pHddCtx->hddAdapters.lock);
7089 return status;
7090}
7091
7092VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7093 hdd_adapter_list_node_t* pAdapterNode)
7094{
7095 VOS_STATUS status;
7096 spin_lock(&pHddCtx->hddAdapters.lock);
7097 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7098 (hdd_list_node_t*) pAdapterNode );
7099 spin_unlock(&pHddCtx->hddAdapters.lock);
7100 return status;
7101}
7102
7103VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7104 hdd_adapter_list_node_t* pAdapterNode)
7105{
7106 VOS_STATUS status;
7107 spin_lock(&pHddCtx->hddAdapters.lock);
7108 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7109 (hdd_list_node_t*) pAdapterNode );
7110 spin_unlock(&pHddCtx->hddAdapters.lock);
7111 return status;
7112}
7113
7114hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7115 tSirMacAddr macAddr )
7116{
7117 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7118 hdd_adapter_t *pAdapter;
7119 VOS_STATUS status;
7120
7121 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7122
7123 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7124 {
7125 pAdapter = pAdapterNode->pAdapter;
7126
7127 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7128 macAddr, sizeof(tSirMacAddr) ) )
7129 {
7130 return pAdapter;
7131 }
7132 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7133 pAdapterNode = pNext;
7134 }
7135
7136 return NULL;
7137
7138}
7139
7140hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7141{
7142 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7143 hdd_adapter_t *pAdapter;
7144 VOS_STATUS status;
7145
7146 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7147
7148 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7149 {
7150 pAdapter = pAdapterNode->pAdapter;
7151
7152 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7153 IFNAMSIZ ) )
7154 {
7155 return pAdapter;
7156 }
7157 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7158 pAdapterNode = pNext;
7159 }
7160
7161 return NULL;
7162
7163}
7164
7165hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7166{
7167 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7168 hdd_adapter_t *pAdapter;
7169 VOS_STATUS status;
7170
7171 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7172
7173 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7174 {
7175 pAdapter = pAdapterNode->pAdapter;
7176
7177 if( pAdapter && (mode == pAdapter->device_mode) )
7178 {
7179 return pAdapter;
7180 }
7181 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7182 pAdapterNode = pNext;
7183 }
7184
7185 return NULL;
7186
7187}
7188
7189//Remove this function later
7190hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7191{
7192 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7193 hdd_adapter_t *pAdapter;
7194 VOS_STATUS status;
7195
7196 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7197
7198 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7199 {
7200 pAdapter = pAdapterNode->pAdapter;
7201
7202 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7203 {
7204 return pAdapter;
7205 }
7206
7207 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7208 pAdapterNode = pNext;
7209 }
7210
7211 return NULL;
7212
7213}
7214
Jeff Johnson295189b2012-06-20 16:38:30 -07007215/**---------------------------------------------------------------------------
7216
7217 \brief hdd_set_monitor_tx_adapter() -
7218
7219 This API initializes the adapter to be used while transmitting on monitor
7220 adapter.
7221
7222 \param - pHddCtx - Pointer to the HDD context.
7223 pAdapter - Adapter that will used for TX. This can be NULL.
7224 \return - None.
7225 --------------------------------------------------------------------------*/
7226void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7227{
7228 hdd_adapter_t *pMonAdapter;
7229
7230 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7231
7232 if( NULL != pMonAdapter )
7233 {
7234 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7235 }
7236}
Jeff Johnson295189b2012-06-20 16:38:30 -07007237/**---------------------------------------------------------------------------
7238
7239 \brief hdd_select_queue() -
7240
7241 This API returns the operating channel of the requested device mode
7242
7243 \param - pHddCtx - Pointer to the HDD context.
7244 - mode - Device mode for which operating channel is required
7245 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7246 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7247 \return - channel number. "0" id the requested device is not found OR it is not connected.
7248 --------------------------------------------------------------------------*/
7249v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7250{
7251 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7252 VOS_STATUS status;
7253 hdd_adapter_t *pAdapter;
7254 v_U8_t operatingChannel = 0;
7255
7256 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7257
7258 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7259 {
7260 pAdapter = pAdapterNode->pAdapter;
7261
7262 if( mode == pAdapter->device_mode )
7263 {
7264 switch(pAdapter->device_mode)
7265 {
7266 case WLAN_HDD_INFRA_STATION:
7267 case WLAN_HDD_P2P_CLIENT:
7268 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7269 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7270 break;
7271 case WLAN_HDD_SOFTAP:
7272 case WLAN_HDD_P2P_GO:
7273 /*softap connection info */
7274 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7275 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7276 break;
7277 default:
7278 break;
7279 }
7280
7281 break; //Found the device of interest. break the loop
7282 }
7283
7284 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7285 pAdapterNode = pNext;
7286 }
7287 return operatingChannel;
7288}
7289
7290#ifdef WLAN_FEATURE_PACKET_FILTERING
7291/**---------------------------------------------------------------------------
7292
7293 \brief hdd_set_multicast_list() -
7294
7295 This used to set the multicast address list.
7296
7297 \param - dev - Pointer to the WLAN device.
7298 - skb - Pointer to OS packet (sk_buff).
7299 \return - success/fail
7300
7301 --------------------------------------------------------------------------*/
7302static void hdd_set_multicast_list(struct net_device *dev)
7303{
7304 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 int mc_count;
7306 int i = 0;
7307 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307308
7309 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007310 {
7311 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307312 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 return;
7314 }
7315
7316 if (dev->flags & IFF_ALLMULTI)
7317 {
7318 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007319 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307320 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 }
7322 else
7323 {
7324 mc_count = netdev_mc_count(dev);
7325 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007326 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7328 {
7329 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007330 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307331 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 return;
7333 }
7334
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307335 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007336
7337 netdev_for_each_mc_addr(ha, dev) {
7338 if (i == mc_count)
7339 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307340 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7341 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007342 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007343 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307344 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 i++;
7346 }
7347 }
7348 return;
7349}
7350#endif
7351
7352/**---------------------------------------------------------------------------
7353
7354 \brief hdd_select_queue() -
7355
7356 This function is registered with the Linux OS for network
7357 core to decide which queue to use first.
7358
7359 \param - dev - Pointer to the WLAN device.
7360 - skb - Pointer to OS packet (sk_buff).
7361 \return - ac, Queue Index/access category corresponding to UP in IP header
7362
7363 --------------------------------------------------------------------------*/
7364v_U16_t hdd_select_queue(struct net_device *dev,
7365 struct sk_buff *skb)
7366{
7367 return hdd_wmm_select_queue(dev, skb);
7368}
7369
7370
7371/**---------------------------------------------------------------------------
7372
7373 \brief hdd_wlan_initial_scan() -
7374
7375 This function triggers the initial scan
7376
7377 \param - pAdapter - Pointer to the HDD adapter.
7378
7379 --------------------------------------------------------------------------*/
7380void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7381{
7382 tCsrScanRequest scanReq;
7383 tCsrChannelInfo channelInfo;
7384 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007385 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007386 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7387
7388 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7389 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7390 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7391
7392 if(sme_Is11dSupported(pHddCtx->hHal))
7393 {
7394 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7395 if ( HAL_STATUS_SUCCESS( halStatus ) )
7396 {
7397 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7398 if( !scanReq.ChannelInfo.ChannelList )
7399 {
7400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7401 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007402 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007403 return;
7404 }
7405 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7406 channelInfo.numOfChannels);
7407 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7408 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007409 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 }
7411
7412 scanReq.scanType = eSIR_PASSIVE_SCAN;
7413 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7414 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7415 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7416 }
7417 else
7418 {
7419 scanReq.scanType = eSIR_ACTIVE_SCAN;
7420 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7421 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7422 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7423 }
7424
7425 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7426 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7427 {
7428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7429 __func__, halStatus );
7430 }
7431
7432 if(sme_Is11dSupported(pHddCtx->hHal))
7433 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7434}
7435
Jeff Johnson295189b2012-06-20 16:38:30 -07007436/**---------------------------------------------------------------------------
7437
7438 \brief hdd_full_power_callback() - HDD full power callback function
7439
7440 This is the function invoked by SME to inform the result of a full power
7441 request issued by HDD
7442
7443 \param - callbackcontext - Pointer to cookie
7444 \param - status - result of request
7445
7446 \return - None
7447
7448 --------------------------------------------------------------------------*/
7449static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7450{
Jeff Johnson72a40512013-12-19 10:14:15 -08007451 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007452
7453 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307454 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007455
7456 if (NULL == callbackContext)
7457 {
7458 hddLog(VOS_TRACE_LEVEL_ERROR,
7459 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007460 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 return;
7462 }
7463
Jeff Johnson72a40512013-12-19 10:14:15 -08007464 /* there is a race condition that exists between this callback
7465 function and the caller since the caller could time out either
7466 before or while this code is executing. we use a spinlock to
7467 serialize these actions */
7468 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007469
7470 if (POWER_CONTEXT_MAGIC != pContext->magic)
7471 {
7472 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007473 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007474 hddLog(VOS_TRACE_LEVEL_WARN,
7475 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007476 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 return;
7478 }
7479
Jeff Johnson72a40512013-12-19 10:14:15 -08007480 /* context is valid so caller is still waiting */
7481
7482 /* paranoia: invalidate the magic */
7483 pContext->magic = 0;
7484
7485 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007487
7488 /* serialization is complete */
7489 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007490}
7491
7492/**---------------------------------------------------------------------------
7493
7494 \brief hdd_wlan_exit() - HDD WLAN exit function
7495
7496 This is the driver exit point (invoked during rmmod)
7497
7498 \param - pHddCtx - Pointer to the HDD Context
7499
7500 \return - None
7501
7502 --------------------------------------------------------------------------*/
7503void hdd_wlan_exit(hdd_context_t *pHddCtx)
7504{
7505 eHalStatus halStatus;
7506 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7507 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307508 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007509 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007510 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007511 long lrc;
7512
7513 ENTER();
7514
Jeff Johnson88ba7742013-02-27 14:36:02 -08007515 if (VOS_FTM_MODE != hdd_get_conparam())
7516 {
7517 // Unloading, restart logic is no more required.
7518 wlan_hdd_restart_deinit(pHddCtx);
7519 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007520
Jeff Johnson295189b2012-06-20 16:38:30 -07007521 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007523 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007524 {
7525 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7526 WLAN_HDD_INFRA_STATION);
7527 if (pAdapter == NULL)
7528 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7529
7530 if (pAdapter != NULL)
7531 {
7532 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7533 hdd_UnregisterWext(pAdapter->dev);
7534 }
7535 }
7536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007537
Jeff Johnson295189b2012-06-20 16:38:30 -07007538 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007539 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307540 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007541 wlan_hdd_ftm_close(pHddCtx);
7542 goto free_hdd_ctx;
7543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 //Stop the Interface TX queue.
7545 //netif_tx_disable(pWlanDev);
7546 //netif_carrier_off(pWlanDev);
7547
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7549 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307550 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007551 pAdapter = hdd_get_adapter(pHddCtx,
7552 WLAN_HDD_SOFTAP);
7553 }
7554 else
7555 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007556 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307558 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 pAdapter = hdd_get_adapter(pHddCtx,
7560 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007561 if (pAdapter == NULL)
7562 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307565
7566 if(NULL == pAdapter)
7567 {
7568 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7569 goto free_hdd_ctx;
7570 }
7571
Jeff Johnson295189b2012-06-20 16:38:30 -07007572 /* DeRegister with platform driver as client for Suspend/Resume */
7573 vosStatus = hddDeregisterPmOps(pHddCtx);
7574 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7575 {
7576 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7577 VOS_ASSERT(0);
7578 }
7579
7580 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7581 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7582 {
7583 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007585
7586 // Cancel any outstanding scan requests. We are about to close all
7587 // of our adapters, but an adapter structure is what SME passes back
7588 // to our callback function. Hence if there are any outstanding scan
7589 // requests then there is a race condition between when the adapter
7590 // is closed and when the callback is invoked. We try to resolve that
7591 // race condition here by canceling any outstanding scans before we
7592 // close the adapters.
7593 // Note that the scans may be cancelled in an asynchronous manner, so
7594 // ideally there needs to be some kind of synchronization. Rather than
7595 // introduce a new synchronization here, we will utilize the fact that
7596 // we are about to Request Full Power, and since that is synchronized,
7597 // the expectation is that by the time Request Full Power has completed,
7598 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007599 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307600 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007601 else
7602 hddLog(VOS_TRACE_LEVEL_ERROR,
7603 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007604
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007605 //Stop the traffic monitor timer
7606 if ( VOS_TIMER_STATE_RUNNING ==
7607 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7608 {
7609 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7610 }
7611
7612 // Destroy the traffic monitor timer
7613 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7614 &pHddCtx->tx_rx_trafficTmr)))
7615 {
7616 hddLog(VOS_TRACE_LEVEL_ERROR,
7617 "%s: Cannot deallocate Traffic monitor timer", __func__);
7618 }
7619
Jeff Johnson295189b2012-06-20 16:38:30 -07007620 //Disable IMPS/BMPS as we do not want the device to enter any power
7621 //save mode during shutdown
7622 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7623 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7624 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7625
7626 //Ensure that device is in full power as we will touch H/W during vos_Stop
7627 init_completion(&powerContext.completion);
7628 powerContext.magic = POWER_CONTEXT_MAGIC;
7629
7630 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7631 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7632
7633 if (eHAL_STATUS_SUCCESS != halStatus)
7634 {
7635 if (eHAL_STATUS_PMC_PENDING == halStatus)
7636 {
7637 /* request was sent -- wait for the response */
7638 lrc = wait_for_completion_interruptible_timeout(
7639 &powerContext.completion,
7640 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 if (lrc <= 0)
7642 {
7643 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007644 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 }
7646 }
7647 else
7648 {
7649 hddLog(VOS_TRACE_LEVEL_ERROR,
7650 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007651 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 /* continue -- need to clean up as much as possible */
7653 }
7654 }
7655
Jeff Johnson72a40512013-12-19 10:14:15 -08007656 /* either we never sent a request, we sent a request and received a
7657 response or we sent a request and timed out. if we never sent a
7658 request or if we sent a request and got a response, we want to
7659 clear the magic out of paranoia. if we timed out there is a
7660 race condition such that the callback function could be
7661 executing at the same time we are. of primary concern is if the
7662 callback function had already verified the "magic" but had not
7663 yet set the completion variable when a timeout occurred. we
7664 serialize these activities by invalidating the magic while
7665 holding a shared spinlock which will cause us to block if the
7666 callback is currently executing */
7667 spin_lock(&hdd_context_lock);
7668 powerContext.magic = 0;
7669 spin_unlock(&hdd_context_lock);
7670
Yue Ma0d4891e2013-08-06 17:01:45 -07007671 hdd_debugfs_exit(pHddCtx);
7672
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 // Unregister the Net Device Notifier
7674 unregister_netdevice_notifier(&hdd_netdev_notifier);
7675
Jeff Johnson295189b2012-06-20 16:38:30 -07007676 hdd_stop_all_adapters( pHddCtx );
7677
Jeff Johnson295189b2012-06-20 16:38:30 -07007678#ifdef WLAN_BTAMP_FEATURE
7679 vosStatus = WLANBAP_Stop(pVosContext);
7680 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7681 {
7682 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7683 "%s: Failed to stop BAP",__func__);
7684 }
7685#endif //WLAN_BTAMP_FEATURE
7686
7687 //Stop all the modules
7688 vosStatus = vos_stop( pVosContext );
7689 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7690 {
7691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7692 "%s: Failed to stop VOSS",__func__);
7693 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7694 }
7695
Jeff Johnson295189b2012-06-20 16:38:30 -07007696 //Assert Deep sleep signal now to put Libra HW in lowest power state
7697 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7698 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7699
7700 //Vote off any PMIC voltage supplies
7701 vos_chipPowerDown(NULL, NULL, NULL);
7702
7703 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7704
Leo Chang59cdc7e2013-07-10 10:08:21 -07007705
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007707 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007708
7709 //Close the scheduler before calling vos_close to make sure no thread is
7710 // scheduled after the each module close is called i.e after all the data
7711 // structures are freed.
7712 vosStatus = vos_sched_close( pVosContext );
7713 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7714 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7715 "%s: Failed to close VOSS Scheduler",__func__);
7716 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7717 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007718#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007719#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7720 /* Destroy the wake lock */
7721 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7722#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007723 /* Destroy the wake lock */
7724 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007725#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007726
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307727#ifdef CONFIG_ENABLE_LINUX_REG
7728 vosStatus = vos_nv_close();
7729 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7730 {
7731 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7732 "%s: Failed to close NV", __func__);
7733 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7734 }
7735#endif
7736
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 //Close VOSS
7738 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7739 vos_close(pVosContext);
7740
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 //Close Watchdog
7742 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7743 vos_watchdog_close(pVosContext);
7744
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307745 //Clean up HDD Nlink Service
7746 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007747#ifdef WLAN_KD_READY_NOTIFIER
7748 nl_srv_exit(pHddCtx->ptt_pid);
7749#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307750 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007751#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307752
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307753#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307754 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307755 {
7756 wlan_logging_sock_deactivate_svc();
7757 }
7758#endif
7759
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 /* Cancel the vote for XO Core ON.
7761 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7762 * exited at this point
7763 */
7764 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007765 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007766 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7767 {
7768 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7769 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007770 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007771 }
7772
7773 hdd_close_all_adapters( pHddCtx );
7774
7775
7776 //Free up dynamically allocated members inside HDD Adapter
7777 kfree(pHddCtx->cfg_ini);
7778 pHddCtx->cfg_ini= NULL;
7779
7780 /* free the power on lock from platform driver */
7781 if (free_riva_power_on_lock("wlan"))
7782 {
7783 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7784 __func__);
7785 }
7786
Jeff Johnson88ba7742013-02-27 14:36:02 -08007787free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007788 /* FTM mode, WIPHY did not registered
7789 If un-register here, system crash will happen */
7790 if (VOS_FTM_MODE != hdd_get_conparam())
7791 {
7792 wiphy_unregister(wiphy) ;
7793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 if (hdd_is_ssr_required())
7796 {
7797 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007798 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 msleep(5000);
7800 }
7801 hdd_set_ssr_required (VOS_FALSE);
7802}
7803
7804
7805/**---------------------------------------------------------------------------
7806
7807 \brief hdd_update_config_from_nv() - Function to update the contents of
7808 the running configuration with parameters taken from NV storage
7809
7810 \param - pHddCtx - Pointer to the HDD global context
7811
7812 \return - VOS_STATUS_SUCCESS if successful
7813
7814 --------------------------------------------------------------------------*/
7815static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7816{
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 v_BOOL_t itemIsValid = VOS_FALSE;
7818 VOS_STATUS status;
7819 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7820 v_U8_t macLoop;
7821
7822 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7823 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7824 if(status != VOS_STATUS_SUCCESS)
7825 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007826 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 return VOS_STATUS_E_FAILURE;
7828 }
7829
7830 if (itemIsValid == VOS_TRUE)
7831 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007832 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7834 VOS_MAX_CONCURRENCY_PERSONA);
7835 if(status != VOS_STATUS_SUCCESS)
7836 {
7837 /* Get MAC from NV fail, not update CFG info
7838 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007839 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 return VOS_STATUS_E_FAILURE;
7841 }
7842
7843 /* If first MAC is not valid, treat all others are not valid
7844 * Then all MACs will be got from ini file */
7845 if(vos_is_macaddr_zero(&macFromNV[0]))
7846 {
7847 /* MAC address in NV file is not configured yet */
7848 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7849 return VOS_STATUS_E_INVAL;
7850 }
7851
7852 /* Get MAC address from NV, update CFG info */
7853 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7854 {
7855 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7856 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307857 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 /* This MAC is not valid, skip it
7859 * This MAC will be got from ini file */
7860 }
7861 else
7862 {
7863 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7864 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7865 VOS_MAC_ADDR_SIZE);
7866 }
7867 }
7868 }
7869 else
7870 {
7871 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7872 return VOS_STATUS_E_FAILURE;
7873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007874
Jeff Johnson295189b2012-06-20 16:38:30 -07007875
7876 return VOS_STATUS_SUCCESS;
7877}
7878
7879/**---------------------------------------------------------------------------
7880
7881 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7882
7883 \param - pAdapter - Pointer to the HDD
7884
7885 \return - None
7886
7887 --------------------------------------------------------------------------*/
7888VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7889{
7890 eHalStatus halStatus;
7891 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307892 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007893
Jeff Johnson295189b2012-06-20 16:38:30 -07007894
7895 // Send ready indication to the HDD. This will kick off the MAC
7896 // into a 'running' state and should kick off an initial scan.
7897 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7898 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7899 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307900 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 "code %08d [x%08x]",__func__, halStatus, halStatus );
7902 return VOS_STATUS_E_FAILURE;
7903 }
7904
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307905 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7907 // And RIVA will crash
7908 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7909 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307910 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7911 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7912
7913
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 return VOS_STATUS_SUCCESS;
7915}
7916
Jeff Johnson295189b2012-06-20 16:38:30 -07007917/* wake lock APIs for HDD */
7918void hdd_prevent_suspend(void)
7919{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007920#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007922#else
7923 wcnss_prevent_suspend();
7924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007925}
7926
7927void hdd_allow_suspend(void)
7928{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007929#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007930 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007931#else
7932 wcnss_allow_suspend();
7933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007934}
7935
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307936void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007937{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007938#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007939 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007940#else
7941 /* Do nothing as there is no API in wcnss for timeout*/
7942#endif
7943}
7944
Jeff Johnson295189b2012-06-20 16:38:30 -07007945/**---------------------------------------------------------------------------
7946
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007947 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7948 information between Host and Riva
7949
7950 This function gets reported version of FW
7951 It also finds the version of Riva headers used to compile the host
7952 It compares the above two and prints a warning if they are different
7953 It gets the SW and HW version string
7954 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7955 indicating the features they support through a bitmap
7956
7957 \param - pHddCtx - Pointer to HDD context
7958
7959 \return - void
7960
7961 --------------------------------------------------------------------------*/
7962
7963void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7964{
7965
7966 tSirVersionType versionCompiled;
7967 tSirVersionType versionReported;
7968 tSirVersionString versionString;
7969 tANI_U8 fwFeatCapsMsgSupported = 0;
7970 VOS_STATUS vstatus;
7971
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007972 memset(&versionCompiled, 0, sizeof(versionCompiled));
7973 memset(&versionReported, 0, sizeof(versionReported));
7974
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007975 /* retrieve and display WCNSS version information */
7976 do {
7977
7978 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7979 &versionCompiled);
7980 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7981 {
7982 hddLog(VOS_TRACE_LEVEL_FATAL,
7983 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007984 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007985 break;
7986 }
7987
7988 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7989 &versionReported);
7990 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7991 {
7992 hddLog(VOS_TRACE_LEVEL_FATAL,
7993 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007994 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007995 break;
7996 }
7997
7998 if ((versionCompiled.major != versionReported.major) ||
7999 (versionCompiled.minor != versionReported.minor) ||
8000 (versionCompiled.version != versionReported.version) ||
8001 (versionCompiled.revision != versionReported.revision))
8002 {
8003 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8004 "Host expected %u.%u.%u.%u\n",
8005 WLAN_MODULE_NAME,
8006 (int)versionReported.major,
8007 (int)versionReported.minor,
8008 (int)versionReported.version,
8009 (int)versionReported.revision,
8010 (int)versionCompiled.major,
8011 (int)versionCompiled.minor,
8012 (int)versionCompiled.version,
8013 (int)versionCompiled.revision);
8014 }
8015 else
8016 {
8017 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8018 WLAN_MODULE_NAME,
8019 (int)versionReported.major,
8020 (int)versionReported.minor,
8021 (int)versionReported.version,
8022 (int)versionReported.revision);
8023 }
8024
8025 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8026 versionString,
8027 sizeof(versionString));
8028 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8029 {
8030 hddLog(VOS_TRACE_LEVEL_FATAL,
8031 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008032 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008033 break;
8034 }
8035
8036 pr_info("%s: WCNSS software version %s\n",
8037 WLAN_MODULE_NAME, versionString);
8038
8039 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8040 versionString,
8041 sizeof(versionString));
8042 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8043 {
8044 hddLog(VOS_TRACE_LEVEL_FATAL,
8045 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008046 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008047 break;
8048 }
8049
8050 pr_info("%s: WCNSS hardware version %s\n",
8051 WLAN_MODULE_NAME, versionString);
8052
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008053 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8054 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008055 send the message only if it the riva is 1.1
8056 minor numbers for different riva branches:
8057 0 -> (1.0)Mainline Build
8058 1 -> (1.1)Mainline Build
8059 2->(1.04) Stability Build
8060 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008061 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008062 ((versionReported.minor>=1) && (versionReported.version>=1)))
8063 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8064 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008065
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008066 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008067 {
8068#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8069 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8070 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8071#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008072 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8073 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8074 {
8075 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8076 }
8077
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008078 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008079 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008080
8081 } while (0);
8082
8083}
8084
8085/**---------------------------------------------------------------------------
8086
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308087 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8088
8089 \param - pHddCtx - Pointer to the hdd context
8090
8091 \return - true if hardware supports 5GHz
8092
8093 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308094boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308095{
8096 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8097 * then hardware support 5Ghz.
8098 */
8099 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8100 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308102 return true;
8103 }
8104 else
8105 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308107 __func__);
8108 return false;
8109 }
8110}
8111
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308112/**---------------------------------------------------------------------------
8113
8114 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8115 generate function
8116
8117 This is generate the random mac address for WLAN interface
8118
8119 \param - pHddCtx - Pointer to HDD context
8120 idx - Start interface index to get auto
8121 generated mac addr.
8122 mac_addr - Mac address
8123
8124 \return - 0 for success, < 0 for failure
8125
8126 --------------------------------------------------------------------------*/
8127
8128static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8129 int idx, v_MACADDR_t mac_addr)
8130{
8131 int i;
8132 unsigned int serialno;
8133 serialno = wcnss_get_serial_number();
8134
8135 if (0 != serialno)
8136 {
8137 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8138 bytes of the serial number that can be used to generate
8139 the other 3 bytes of the MAC address. Mask off all but
8140 the lower 3 bytes (this will also make sure we don't
8141 overflow in the next step) */
8142 serialno &= 0x00FFFFFF;
8143
8144 /* we need a unique address for each session */
8145 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8146
8147 /* autogen other Mac addresses */
8148 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8149 {
8150 /* start with the entire default address */
8151 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8152 /* then replace the lower 3 bytes */
8153 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8154 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8155 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8156
8157 serialno++;
8158 hddLog(VOS_TRACE_LEVEL_ERROR,
8159 "%s: Derived Mac Addr: "
8160 MAC_ADDRESS_STR, __func__,
8161 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8162 }
8163
8164 }
8165 else
8166 {
8167 hddLog(LOGE, FL("Failed to Get Serial NO"));
8168 return -1;
8169 }
8170 return 0;
8171}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308172
8173/**---------------------------------------------------------------------------
8174
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308175 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8176 completed to flush out the scan results
8177
8178 11d scan is done during driver load and is a passive scan on all
8179 channels supported by the device, 11d scans may find some APs on
8180 frequencies which are forbidden to be used in the regulatory domain
8181 the device is operating in. If these APs are notified to the supplicant
8182 it may try to connect to these APs, thus flush out all the scan results
8183 which are present in SME after 11d scan is done.
8184
8185 \return - eHalStatus
8186
8187 --------------------------------------------------------------------------*/
8188static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8189 tANI_U32 scanId, eCsrScanStatus status)
8190{
8191 ENTER();
8192
8193 sme_ScanFlushResult(halHandle, 0);
8194
8195 EXIT();
8196
8197 return eHAL_STATUS_SUCCESS;
8198}
8199
8200/**---------------------------------------------------------------------------
8201
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 \brief hdd_wlan_startup() - HDD init function
8203
8204 This is the driver startup code executed once a WLAN device has been detected
8205
8206 \param - dev - Pointer to the underlying device
8207
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008208 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008209
8210 --------------------------------------------------------------------------*/
8211
8212int hdd_wlan_startup(struct device *dev )
8213{
8214 VOS_STATUS status;
8215 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008216 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 hdd_context_t *pHddCtx = NULL;
8218 v_CONTEXT_t pVosContext= NULL;
8219#ifdef WLAN_BTAMP_FEATURE
8220 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8221 WLANBAP_ConfigType btAmpConfig;
8222 hdd_config_t *pConfig;
8223#endif
8224 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308226 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008227
8228 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 /*
8230 * cfg80211: wiphy allocation
8231 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308232 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008233
8234 if(wiphy == NULL)
8235 {
8236 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008237 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 }
8239
8240 pHddCtx = wiphy_priv(wiphy);
8241
Jeff Johnson295189b2012-06-20 16:38:30 -07008242 //Initialize the adapter context to zeros.
8243 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8244
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308247 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008248
8249 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8250
8251 /*Get vos context here bcoz vos_open requires it*/
8252 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8253
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008254 if(pVosContext == NULL)
8255 {
8256 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8257 goto err_free_hdd_context;
8258 }
8259
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 //Save the Global VOSS context in adapter context for future.
8261 pHddCtx->pvosContext = pVosContext;
8262
8263 //Save the adapter context in global context for future.
8264 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8265
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 pHddCtx->parent_dev = dev;
8267
8268 init_completion(&pHddCtx->full_pwr_comp_var);
8269 init_completion(&pHddCtx->standby_comp_var);
8270 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008271 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008272 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308273 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308274 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008275
8276#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008277 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008278#else
8279 init_completion(&pHddCtx->driver_crda_req);
8280#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008281
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308282 spin_lock_init(&pHddCtx->schedScan_lock);
8283
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8285
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308286#ifdef FEATURE_WLAN_TDLS
8287 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8288 * invoked by other instances also) to protect the concurrent
8289 * access for the Adapters by TDLS module.
8290 */
8291 mutex_init(&pHddCtx->tdls_lock);
8292#endif
8293
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308294 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008295 // Load all config first as TL config is needed during vos_open
8296 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8297 if(pHddCtx->cfg_ini == NULL)
8298 {
8299 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8300 goto err_free_hdd_context;
8301 }
8302
8303 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8304
8305 // Read and parse the qcom_cfg.ini file
8306 status = hdd_parse_config_ini( pHddCtx );
8307 if ( VOS_STATUS_SUCCESS != status )
8308 {
8309 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8310 __func__, WLAN_INI_FILE);
8311 goto err_config;
8312 }
Arif Hussaind5218912013-12-05 01:10:55 -08008313#ifdef MEMORY_DEBUG
8314 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8315 vos_mem_init();
8316
8317 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8318 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8319#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008320
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308321 /* INI has been read, initialise the configuredMcastBcastFilter with
8322 * INI value as this will serve as the default value
8323 */
8324 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8325 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8326 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308327
8328 if (false == hdd_is_5g_supported(pHddCtx))
8329 {
8330 //5Ghz is not supported.
8331 if (1 != pHddCtx->cfg_ini->nBandCapability)
8332 {
8333 hddLog(VOS_TRACE_LEVEL_INFO,
8334 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8335 pHddCtx->cfg_ini->nBandCapability = 1;
8336 }
8337 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308338
8339 /* If SNR Monitoring is enabled, FW has to parse all beacons
8340 * for calcaluting and storing the average SNR, so set Nth beacon
8341 * filter to 1 to enable FW to parse all the beaocons
8342 */
8343 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8344 {
8345 /* The log level is deliberately set to WARN as overriding
8346 * nthBeaconFilter to 1 will increase power cosumption and this
8347 * might just prove helpful to detect the power issue.
8348 */
8349 hddLog(VOS_TRACE_LEVEL_WARN,
8350 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8351 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308354 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008356 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008358 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8359 {
8360 hddLog(VOS_TRACE_LEVEL_FATAL,
8361 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8362 goto err_config;
8363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008365
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008366 // Update VOS trace levels based upon the cfg.ini
8367 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8368 pHddCtx->cfg_ini->vosTraceEnableBAP);
8369 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8370 pHddCtx->cfg_ini->vosTraceEnableTL);
8371 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8372 pHddCtx->cfg_ini->vosTraceEnableWDI);
8373 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8374 pHddCtx->cfg_ini->vosTraceEnableHDD);
8375 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8376 pHddCtx->cfg_ini->vosTraceEnableSME);
8377 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8378 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308379 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8380 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008381 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8382 pHddCtx->cfg_ini->vosTraceEnableWDA);
8383 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8384 pHddCtx->cfg_ini->vosTraceEnableSYS);
8385 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8386 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008387 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8388 pHddCtx->cfg_ini->vosTraceEnableSAP);
8389 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8390 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008391
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 // Update WDI trace levels based upon the cfg.ini
8393 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8394 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8395 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8396 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8397 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8398 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8399 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8400 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008401
Jeff Johnson88ba7742013-02-27 14:36:02 -08008402 if (VOS_FTM_MODE == hdd_get_conparam())
8403 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8405 {
8406 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8407 goto err_free_hdd_context;
8408 }
8409 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308410
8411 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008414
Jeff Johnson88ba7742013-02-27 14:36:02 -08008415 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8417 {
8418 status = vos_watchdog_open(pVosContext,
8419 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8420
8421 if(!VOS_IS_STATUS_SUCCESS( status ))
8422 {
8423 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308424 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 }
8426 }
8427
8428 pHddCtx->isLogpInProgress = FALSE;
8429 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8430
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8432 if(!VOS_IS_STATUS_SUCCESS(status))
8433 {
8434 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 }
8437
Amar Singhala49cbc52013-10-08 18:37:44 -07008438#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008439 /* initialize the NV module. This is required so that
8440 we can initialize the channel information in wiphy
8441 from the NV.bin data. The channel information in
8442 wiphy needs to be initialized before wiphy registration */
8443
8444 status = vos_nv_open();
8445 if (!VOS_IS_STATUS_SUCCESS(status))
8446 {
8447 /* NV module cannot be initialized */
8448 hddLog( VOS_TRACE_LEVEL_FATAL,
8449 "%s: vos_nv_open failed", __func__);
8450 goto err_clkvote;
8451 }
8452
8453 status = vos_init_wiphy_from_nv_bin();
8454 if (!VOS_IS_STATUS_SUCCESS(status))
8455 {
8456 /* NV module cannot be initialized */
8457 hddLog( VOS_TRACE_LEVEL_FATAL,
8458 "%s: vos_init_wiphy failed", __func__);
8459 goto err_vos_nv_close;
8460 }
8461
Amar Singhala49cbc52013-10-08 18:37:44 -07008462#endif
8463
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308464 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 if ( !VOS_IS_STATUS_SUCCESS( status ))
8466 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008467 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308468 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 }
8470
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8472
8473 if ( NULL == pHddCtx->hHal )
8474 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008475 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 goto err_vosclose;
8477 }
8478
Mihir Shetee1093ba2014-01-21 20:13:32 +05308479#ifdef CONFIG_ENABLE_LINUX_REG
8480 /* registration of wiphy dev with cfg80211 */
8481 if (0 > wlan_hdd_cfg80211_register(wiphy))
8482 {
8483 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8484 goto err_vosclose;
8485 }
8486
8487 status = wlan_hdd_init_channels(pHddCtx);
8488 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8489 {
8490 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8491 __func__);
8492 goto err_wiphy_unregister;
8493 }
8494#endif
8495
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008496 status = vos_preStart( pHddCtx->pvosContext );
8497 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8498 {
8499 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308500 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008501 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008502
Arif Hussaineaf68602013-12-30 23:10:44 -08008503 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8504 {
8505 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8507 __func__, enable_dfs_chan_scan);
8508 }
8509 if (0 == enable_11d || 1 == enable_11d)
8510 {
8511 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8512 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8513 __func__, enable_11d);
8514 }
8515
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008516 /* Note that the vos_preStart() sequence triggers the cfg download.
8517 The cfg download must occur before we update the SME config
8518 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008519 status = hdd_set_sme_config( pHddCtx );
8520
8521 if ( VOS_STATUS_SUCCESS != status )
8522 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008523 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308524 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008526
8527 //Initialize the WMM module
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07008528 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
8529 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 if (!VOS_IS_STATUS_SUCCESS(status))
8531 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008532 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308533 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008534 }
8535
Jeff Johnson295189b2012-06-20 16:38:30 -07008536 /* In the integrated architecture we update the configuration from
8537 the INI file and from NV before vOSS has been started so that
8538 the final contents are available to send down to the cCPU */
8539
8540 // Apply the cfg.ini to cfg.dat
8541 if (FALSE == hdd_update_config_dat(pHddCtx))
8542 {
8543 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308544 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008545 }
8546
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308547 // Get mac addr from platform driver
8548 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8549
8550 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308552 /* Store the mac addr for first interface */
8553 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8554
8555 hddLog(VOS_TRACE_LEVEL_ERROR,
8556 "%s: WLAN Mac Addr: "
8557 MAC_ADDRESS_STR, __func__,
8558 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8559
8560 /* Here, passing Arg2 as 1 because we do not want to change the
8561 last 3 bytes (means non OUI bytes) of first interface mac
8562 addr.
8563 */
8564 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8565 {
8566 hddLog(VOS_TRACE_LEVEL_ERROR,
8567 "%s: Failed to generate wlan interface mac addr "
8568 "using MAC from ini file ", __func__);
8569 }
8570 }
8571 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8572 {
8573 // Apply the NV to cfg.dat
8574 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008575#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8576 /* There was not a valid set of MAC Addresses in NV. See if the
8577 default addresses were modified by the cfg.ini settings. If so,
8578 we'll use them, but if not, we'll autogenerate a set of MAC
8579 addresses based upon the device serial number */
8580
8581 static const v_MACADDR_t default_address =
8582 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008583
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308584 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8585 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 {
8587 /* cfg.ini has the default address, invoke autogen logic */
8588
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308589 /* Here, passing Arg2 as 0 because we want to change the
8590 last 3 bytes (means non OUI bytes) of all the interfaces
8591 mac addr.
8592 */
8593 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8594 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308596 hddLog(VOS_TRACE_LEVEL_ERROR,
8597 "%s: Failed to generate wlan interface mac addr "
8598 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8599 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008601 }
8602 else
8603#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8604 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008605 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 "%s: Invalid MAC address in NV, using MAC from ini file "
8607 MAC_ADDRESS_STR, __func__,
8608 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8609 }
8610 }
8611 {
8612 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308613
8614 /* Set the MAC Address Currently this is used by HAL to
8615 * add self sta. Remove this once self sta is added as
8616 * part of session open.
8617 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008618 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8619 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8620 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308621
Jeff Johnson295189b2012-06-20 16:38:30 -07008622 if (!HAL_STATUS_SUCCESS( halStatus ))
8623 {
8624 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8625 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308626 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008627 }
8628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008629
8630 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8631 Note: Firmware image will be read and downloaded inside vos_start API */
8632 status = vos_start( pHddCtx->pvosContext );
8633 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8634 {
8635 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308636 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 }
8638
Leo Chang6cec3e22014-01-21 15:33:49 -08008639#ifdef FEATURE_WLAN_CH_AVOID
8640 /* Plug in avoid channel notification callback
8641 * This should happen before ADD_SELF_STA
8642 * FW will send first IND with ADD_SELF_STA REQ from host */
8643 sme_AddChAvoidCallback(pHddCtx->hHal,
8644 hdd_hostapd_ch_avoid_cb);
8645#endif /* FEATURE_WLAN_CH_AVOID */
8646
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008647 /* Exchange capability info between Host and FW and also get versioning info from FW */
8648 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008649
8650 status = hdd_post_voss_start_config( pHddCtx );
8651 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8652 {
8653 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8654 __func__);
8655 goto err_vosstop;
8656 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008657
8658#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308659 wlan_hdd_cfg80211_update_reg_info( wiphy );
8660
8661 /* registration of wiphy dev with cfg80211 */
8662 if (0 > wlan_hdd_cfg80211_register(wiphy))
8663 {
8664 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8665 goto err_vosstop;
8666 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008667#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008668
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8670 {
8671 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8672 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8673 }
8674 else
8675 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8677 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8678 if (pAdapter != NULL)
8679 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308680 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308682 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8683 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8684 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008685
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308686 /* Generate the P2P Device Address. This consists of the device's
8687 * primary MAC address with the locally administered bit set.
8688 */
8689 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008690 }
8691 else
8692 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308693 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8694 if (p2p_dev_addr != NULL)
8695 {
8696 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8697 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8698 }
8699 else
8700 {
8701 hddLog(VOS_TRACE_LEVEL_FATAL,
8702 "%s: Failed to allocate mac_address for p2p_device",
8703 __func__);
8704 goto err_close_adapter;
8705 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008707
8708 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8709 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8710 if ( NULL == pP2pAdapter )
8711 {
8712 hddLog(VOS_TRACE_LEVEL_FATAL,
8713 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008714 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008715 goto err_close_adapter;
8716 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008717 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008719
8720 if( pAdapter == NULL )
8721 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008722 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8723 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008725
Arif Hussain66559122013-11-21 10:11:40 -08008726 if (country_code)
8727 {
8728 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008729 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008730 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8731#ifndef CONFIG_ENABLE_LINUX_REG
8732 hdd_checkandupdate_phymode(pAdapter, country_code);
8733#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008734 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8735 (void *)(tSmeChangeCountryCallback)
8736 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008737 country_code,
8738 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308739 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008740 if (eHAL_STATUS_SUCCESS == ret)
8741 {
Arif Hussaincb607082013-12-20 11:57:42 -08008742 ret = wait_for_completion_interruptible_timeout(
8743 &pAdapter->change_country_code,
8744 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8745
8746 if (0 >= ret)
8747 {
8748 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8749 "%s: SME while setting country code timed out", __func__);
8750 }
Arif Hussain66559122013-11-21 10:11:40 -08008751 }
8752 else
8753 {
Arif Hussaincb607082013-12-20 11:57:42 -08008754 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8755 "%s: SME Change Country code from module param fail ret=%d",
8756 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008757 }
8758 }
8759
Jeff Johnson295189b2012-06-20 16:38:30 -07008760#ifdef WLAN_BTAMP_FEATURE
8761 vStatus = WLANBAP_Open(pVosContext);
8762 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8763 {
8764 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8765 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008766 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 }
8768
8769 vStatus = BSL_Init(pVosContext);
8770 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8771 {
8772 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8773 "%s: Failed to Init BSL",__func__);
8774 goto err_bap_close;
8775 }
8776 vStatus = WLANBAP_Start(pVosContext);
8777 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8778 {
8779 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8780 "%s: Failed to start TL",__func__);
8781 goto err_bap_close;
8782 }
8783
8784 pConfig = pHddCtx->cfg_ini;
8785 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8786 status = WLANBAP_SetConfig(&btAmpConfig);
8787
8788#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008789
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008790#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8791 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8792 {
8793 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8794 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8795 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8796 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8797 }
8798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008799#ifdef FEATURE_WLAN_SCAN_PNO
8800 /*SME must send channel update configuration to RIVA*/
8801 sme_UpdateChannelConfig(pHddCtx->hHal);
8802#endif
8803
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308804 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8805
Jeff Johnson295189b2012-06-20 16:38:30 -07008806 /* Register with platform driver as client for Suspend/Resume */
8807 status = hddRegisterPmOps(pHddCtx);
8808 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8809 {
8810 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8811#ifdef WLAN_BTAMP_FEATURE
8812 goto err_bap_stop;
8813#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008814 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008815#endif //WLAN_BTAMP_FEATURE
8816 }
8817
Yue Ma0d4891e2013-08-06 17:01:45 -07008818 /* Open debugfs interface */
8819 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8820 {
8821 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8822 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008823 }
8824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 /* Register TM level change handler function to the platform */
8826 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8827 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8828 {
8829 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8830 goto err_unregister_pmops;
8831 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008832
8833 /* register for riva power on lock to platform driver */
8834 if (req_riva_power_on_lock("wlan"))
8835 {
8836 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8837 __func__);
8838 goto err_unregister_pmops;
8839 }
8840
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 // register net device notifier for device change notification
8842 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8843
8844 if(ret < 0)
8845 {
8846 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8847 goto err_free_power_on_lock;
8848 }
8849
8850 //Initialize the nlink service
8851 if(nl_srv_init() != 0)
8852 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308853 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 goto err_reg_netdev;
8855 }
8856
Leo Chang4ce1cc52013-10-21 18:27:15 -07008857#ifdef WLAN_KD_READY_NOTIFIER
8858 pHddCtx->kd_nl_init = 1;
8859#endif /* WLAN_KD_READY_NOTIFIER */
8860
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 //Initialize the BTC service
8862 if(btc_activate_service(pHddCtx) != 0)
8863 {
8864 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8865 goto err_nl_srv;
8866 }
8867
8868#ifdef PTT_SOCK_SVC_ENABLE
8869 //Initialize the PTT service
8870 if(ptt_sock_activate_svc(pHddCtx) != 0)
8871 {
8872 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8873 goto err_nl_srv;
8874 }
8875#endif
8876
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308877#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8878 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8879 {
8880 if(wlan_logging_sock_activate_svc(
8881 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8882 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8883 {
8884 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8885 " failed", __func__);
8886 goto err_nl_srv;
8887 }
8888 }
8889#endif
8890
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008894 /* Action frame registered in one adapter which will
8895 * applicable to all interfaces
8896 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008897 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008898 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008899
8900 mutex_init(&pHddCtx->sap_lock);
8901
Mihir Shete18156292014-03-11 15:38:30 +05308902 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008903
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008904#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008905#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8906 /* Initialize the wake lcok */
8907 wake_lock_init(&pHddCtx->rx_wake_lock,
8908 WAKE_LOCK_SUSPEND,
8909 "qcom_rx_wakelock");
8910#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008911 /* Initialize the wake lcok */
8912 wake_lock_init(&pHddCtx->sap_wake_lock,
8913 WAKE_LOCK_SUSPEND,
8914 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008915#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008916
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008917 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8918 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008919
8920 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8921 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308922#ifndef CONFIG_ENABLE_LINUX_REG
8923 /*updating wiphy so that regulatory user hints can be processed*/
8924 if (wiphy)
8925 {
8926 regulatory_hint(wiphy, "00");
8927 }
8928#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008929 // Initialize the restart logic
8930 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308931
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008932 //Register the traffic monitor timer now
8933 if ( pHddCtx->cfg_ini->dynSplitscan)
8934 {
8935 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8936 VOS_TIMER_TYPE_SW,
8937 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8938 (void *)pHddCtx);
8939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 goto success;
8941
8942err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008943#ifdef WLAN_KD_READY_NOTIFIER
8944 nl_srv_exit(pHddCtx->ptt_pid);
8945#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008947#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008948err_reg_netdev:
8949 unregister_netdevice_notifier(&hdd_netdev_notifier);
8950
8951err_free_power_on_lock:
8952 free_riva_power_on_lock("wlan");
8953
8954err_unregister_pmops:
8955 hddDevTmUnregisterNotifyCallback(pHddCtx);
8956 hddDeregisterPmOps(pHddCtx);
8957
Yue Ma0d4891e2013-08-06 17:01:45 -07008958 hdd_debugfs_exit(pHddCtx);
8959
Jeff Johnson295189b2012-06-20 16:38:30 -07008960#ifdef WLAN_BTAMP_FEATURE
8961err_bap_stop:
8962 WLANBAP_Stop(pVosContext);
8963#endif
8964
8965#ifdef WLAN_BTAMP_FEATURE
8966err_bap_close:
8967 WLANBAP_Close(pVosContext);
8968#endif
8969
Jeff Johnson295189b2012-06-20 16:38:30 -07008970err_close_adapter:
8971 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008972
8973#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308974 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008975#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008976
8977err_vosstop:
8978 vos_stop(pVosContext);
8979
Mihir Shetee1093ba2014-01-21 20:13:32 +05308980err_wiphy_unregister:
8981#ifdef CONFIG_ENABLE_LINUX_REG
8982 wiphy_unregister(wiphy);
8983#endif
8984
Amar Singhala49cbc52013-10-08 18:37:44 -07008985err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 status = vos_sched_close( pVosContext );
8987 if (!VOS_IS_STATUS_SUCCESS(status)) {
8988 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8989 "%s: Failed to close VOSS Scheduler", __func__);
8990 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8991 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008992 vos_close(pVosContext );
8993
Amar Singhal0a402232013-10-11 20:57:16 -07008994err_vos_nv_close:
8995
c_hpothue6a36282014-03-19 12:27:38 +05308996#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008997 vos_nv_close();
8998
Jeff Johnson295189b2012-06-20 16:38:30 -07008999err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309000#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009001 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009002
9003err_wdclose:
9004 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9005 vos_watchdog_close(pVosContext);
9006
Jeff Johnson295189b2012-06-20 16:38:30 -07009007err_config:
9008 kfree(pHddCtx->cfg_ini);
9009 pHddCtx->cfg_ini= NULL;
9010
9011err_free_hdd_context:
9012 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 wiphy_free(wiphy) ;
9014 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 VOS_BUG(1);
9016
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009017 if (hdd_is_ssr_required())
9018 {
9019 /* WDI timeout had happened during load, so SSR is needed here */
9020 subsystem_restart("wcnss");
9021 msleep(5000);
9022 }
9023 hdd_set_ssr_required (VOS_FALSE);
9024
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009025 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009026
9027success:
9028 EXIT();
9029 return 0;
9030}
9031
9032/**---------------------------------------------------------------------------
9033
Jeff Johnson32d95a32012-09-10 13:15:23 -07009034 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009035
Jeff Johnson32d95a32012-09-10 13:15:23 -07009036 This is the driver entry point - called in different timeline depending
9037 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009038
9039 \param - None
9040
9041 \return - 0 for success, non zero for failure
9042
9043 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009044static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009045{
9046 VOS_STATUS status;
9047 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 struct device *dev = NULL;
9049 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009050#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9051 int max_retries = 0;
9052#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009053
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309054#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9055 wlan_logging_sock_init_svc();
9056#endif
9057
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 ENTER();
9059
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009060#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009062#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009063
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309064 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9066 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9067
9068 //Power Up Libra WLAN card first if not already powered up
9069 status = vos_chipPowerUp(NULL,NULL,NULL);
9070 if (!VOS_IS_STATUS_SUCCESS(status))
9071 {
9072 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9073 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309074#ifdef WLAN_OPEN_SOURCE
9075 wake_lock_destroy(&wlan_wake_lock);
9076#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309077
9078#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9079 wlan_logging_sock_deinit_svc();
9080#endif
9081
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009082 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009083 }
9084
Jeff Johnson295189b2012-06-20 16:38:30 -07009085#ifdef ANI_BUS_TYPE_PCI
9086
9087 dev = wcnss_wlan_get_device();
9088
9089#endif // ANI_BUS_TYPE_PCI
9090
9091#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009092
9093#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9094 /* wait until WCNSS driver downloads NV */
9095 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9096 msleep(1000);
9097 }
9098 if (max_retries >= 5) {
9099 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309100#ifdef WLAN_OPEN_SOURCE
9101 wake_lock_destroy(&wlan_wake_lock);
9102#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309103
9104#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9105 wlan_logging_sock_deinit_svc();
9106#endif
9107
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009108 return -ENODEV;
9109 }
9110#endif
9111
Jeff Johnson295189b2012-06-20 16:38:30 -07009112 dev = wcnss_wlan_get_device();
9113#endif // ANI_BUS_TYPE_PLATFORM
9114
9115
9116 do {
9117 if (NULL == dev) {
9118 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9119 ret_status = -1;
9120 break;
9121 }
9122
Jeff Johnson295189b2012-06-20 16:38:30 -07009123#ifdef TIMER_MANAGER
9124 vos_timer_manager_init();
9125#endif
9126
9127 /* Preopen VOSS so that it is ready to start at least SAL */
9128 status = vos_preOpen(&pVosContext);
9129
9130 if (!VOS_IS_STATUS_SUCCESS(status))
9131 {
9132 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9133 ret_status = -1;
9134 break;
9135 }
9136
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009137#ifndef MODULE
9138 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9139 */
9140 hdd_set_conparam((v_UINT_t)con_mode);
9141#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009142
9143 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009144 if (hdd_wlan_startup(dev))
9145 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009147 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 vos_preClose( &pVosContext );
9149 ret_status = -1;
9150 break;
9151 }
9152
9153 /* Cancel the vote for XO Core ON
9154 * This is done here for safety purposes in case we re-initialize without turning
9155 * it OFF in any error scenario.
9156 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009157 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009159 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9161 {
9162 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009163 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 }
9165 } while (0);
9166
9167 if (0 != ret_status)
9168 {
9169 //Assert Deep sleep signal now to put Libra HW in lowest power state
9170 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9171 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9172
9173 //Vote off any PMIC voltage supplies
9174 vos_chipPowerDown(NULL, NULL, NULL);
9175#ifdef TIMER_MANAGER
9176 vos_timer_exit();
9177#endif
9178#ifdef MEMORY_DEBUG
9179 vos_mem_exit();
9180#endif
9181
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009182#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009183 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009184#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309185
9186#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9187 wlan_logging_sock_deinit_svc();
9188#endif
9189
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9191 }
9192 else
9193 {
9194 //Send WLAN UP indication to Nlink Service
9195 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9196
9197 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 }
9199
9200 EXIT();
9201
9202 return ret_status;
9203}
9204
Jeff Johnson32d95a32012-09-10 13:15:23 -07009205/**---------------------------------------------------------------------------
9206
9207 \brief hdd_module_init() - Init Function
9208
9209 This is the driver entry point (invoked when module is loaded using insmod)
9210
9211 \param - None
9212
9213 \return - 0 for success, non zero for failure
9214
9215 --------------------------------------------------------------------------*/
9216#ifdef MODULE
9217static int __init hdd_module_init ( void)
9218{
9219 return hdd_driver_init();
9220}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009221#else /* #ifdef MODULE */
9222static int __init hdd_module_init ( void)
9223{
9224 /* Driver initialization is delayed to fwpath_changed_handler */
9225 return 0;
9226}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009227#endif /* #ifdef MODULE */
9228
Jeff Johnson295189b2012-06-20 16:38:30 -07009229
9230/**---------------------------------------------------------------------------
9231
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009232 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009234 This is the driver exit point (invoked when module is unloaded using rmmod
9235 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009236
9237 \param - None
9238
9239 \return - None
9240
9241 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009242static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009243{
9244 hdd_context_t *pHddCtx = NULL;
9245 v_CONTEXT_t pVosContext = NULL;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309246 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009247
9248 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9249
9250 //Get the global vos context
9251 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9252
9253 if(!pVosContext)
9254 {
9255 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9256 goto done;
9257 }
9258
9259 //Get the HDD context.
9260 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9261
9262 if(!pHddCtx)
9263 {
9264 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9265 }
9266 else
9267 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309268 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9269
9270 if (pHddCtx->isLogpInProgress)
9271 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309273 "%s:SSR in Progress; block rmmod !!!", __func__);
9274 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9275 msecs_to_jiffies(30000));
9276 if(!rc)
9277 {
9278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9279 "%s:SSR timedout, fatal error", __func__);
9280 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009281 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309282 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009283
Mihir Shete18156292014-03-11 15:38:30 +05309284 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9286
9287 //Do all the cleanup before deregistering the driver
9288 hdd_wlan_exit(pHddCtx);
9289 }
9290
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 vos_preClose( &pVosContext );
9292
9293#ifdef TIMER_MANAGER
9294 vos_timer_exit();
9295#endif
9296#ifdef MEMORY_DEBUG
9297 vos_mem_exit();
9298#endif
9299
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309300#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9301 wlan_logging_sock_deinit_svc();
9302#endif
9303
Jeff Johnson295189b2012-06-20 16:38:30 -07009304done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009305#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009307#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309308
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9310}
9311
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009312/**---------------------------------------------------------------------------
9313
9314 \brief hdd_module_exit() - Exit function
9315
9316 This is the driver exit point (invoked when module is unloaded using rmmod)
9317
9318 \param - None
9319
9320 \return - None
9321
9322 --------------------------------------------------------------------------*/
9323static void __exit hdd_module_exit(void)
9324{
9325 hdd_driver_exit();
9326}
9327
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009328#ifdef MODULE
9329static int fwpath_changed_handler(const char *kmessage,
9330 struct kernel_param *kp)
9331{
Jeff Johnson76052702013-04-16 13:55:05 -07009332 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009333}
9334
9335static int con_mode_handler(const char *kmessage,
9336 struct kernel_param *kp)
9337{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009338 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009339}
9340#else /* #ifdef MODULE */
9341/**---------------------------------------------------------------------------
9342
Jeff Johnson76052702013-04-16 13:55:05 -07009343 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009344
Jeff Johnson76052702013-04-16 13:55:05 -07009345 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009346 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009347 - invoked when module parameter fwpath is modified from userspace to signal
9348 initializing the WLAN driver or when con_mode is modified from userspace
9349 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009350
9351 \return - 0 for success, non zero for failure
9352
9353 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009354static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009355{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009356 int ret_status;
9357
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009358 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009359 ret_status = hdd_driver_init();
9360 wlan_hdd_inited = ret_status ? 0 : 1;
9361 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009362 }
9363
9364 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009365
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009366 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009367
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009368 ret_status = hdd_driver_init();
9369 wlan_hdd_inited = ret_status ? 0 : 1;
9370 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009371}
9372
Jeff Johnson295189b2012-06-20 16:38:30 -07009373/**---------------------------------------------------------------------------
9374
Jeff Johnson76052702013-04-16 13:55:05 -07009375 \brief fwpath_changed_handler() - Handler Function
9376
9377 Handle changes to the fwpath parameter
9378
9379 \return - 0 for success, non zero for failure
9380
9381 --------------------------------------------------------------------------*/
9382static int fwpath_changed_handler(const char *kmessage,
9383 struct kernel_param *kp)
9384{
9385 int ret;
9386
9387 ret = param_set_copystring(kmessage, kp);
9388 if (0 == ret)
9389 ret = kickstart_driver();
9390 return ret;
9391}
9392
9393/**---------------------------------------------------------------------------
9394
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009395 \brief con_mode_handler() -
9396
9397 Handler function for module param con_mode when it is changed by userspace
9398 Dynamically linked - do nothing
9399 Statically linked - exit and init driver, as in rmmod and insmod
9400
Jeff Johnson76052702013-04-16 13:55:05 -07009401 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009402
Jeff Johnson76052702013-04-16 13:55:05 -07009403 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009404
9405 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009406static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009407{
Jeff Johnson76052702013-04-16 13:55:05 -07009408 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009409
Jeff Johnson76052702013-04-16 13:55:05 -07009410 ret = param_set_int(kmessage, kp);
9411 if (0 == ret)
9412 ret = kickstart_driver();
9413 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009414}
9415#endif /* #ifdef MODULE */
9416
9417/**---------------------------------------------------------------------------
9418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 \brief hdd_get_conparam() -
9420
9421 This is the driver exit point (invoked when module is unloaded using rmmod)
9422
9423 \param - None
9424
9425 \return - tVOS_CON_MODE
9426
9427 --------------------------------------------------------------------------*/
9428tVOS_CON_MODE hdd_get_conparam ( void )
9429{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009430#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009432#else
9433 return (tVOS_CON_MODE)curr_con_mode;
9434#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009435}
9436void hdd_set_conparam ( v_UINT_t newParam )
9437{
9438 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009439#ifndef MODULE
9440 curr_con_mode = con_mode;
9441#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009442}
9443/**---------------------------------------------------------------------------
9444
9445 \brief hdd_softap_sta_deauth() - function
9446
9447 This to take counter measure to handle deauth req from HDD
9448
9449 \param - pAdapter - Pointer to the HDD
9450
9451 \param - enable - boolean value
9452
9453 \return - None
9454
9455 --------------------------------------------------------------------------*/
9456
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009457VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009458{
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009460 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009461
9462 ENTER();
9463
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009464 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9465 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009466
9467 //Ignore request to deauth bcmc station
9468 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009469 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009471 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009472
9473 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009474 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009475}
9476
9477/**---------------------------------------------------------------------------
9478
9479 \brief hdd_softap_sta_disassoc() - function
9480
9481 This to take counter measure to handle deauth req from HDD
9482
9483 \param - pAdapter - Pointer to the HDD
9484
9485 \param - enable - boolean value
9486
9487 \return - None
9488
9489 --------------------------------------------------------------------------*/
9490
9491void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9492{
9493 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9494
9495 ENTER();
9496
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309497 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009498
9499 //Ignore request to disassoc bcmc station
9500 if( pDestMacAddress[0] & 0x1 )
9501 return;
9502
9503 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9504}
9505
9506void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9507{
9508 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9509
9510 ENTER();
9511
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309512 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009513
9514 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9515}
9516
Jeff Johnson295189b2012-06-20 16:38:30 -07009517/**---------------------------------------------------------------------------
9518 *
9519 * \brief hdd_get__concurrency_mode() -
9520 *
9521 *
9522 * \param - None
9523 *
9524 * \return - CONCURRENCY MODE
9525 *
9526 * --------------------------------------------------------------------------*/
9527tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9528{
9529 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9530 hdd_context_t *pHddCtx;
9531
9532 if (NULL != pVosContext)
9533 {
9534 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9535 if (NULL != pHddCtx)
9536 {
9537 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9538 }
9539 }
9540
9541 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009542 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 return VOS_STA;
9544}
9545
9546/* Decide whether to allow/not the apps power collapse.
9547 * Allow apps power collapse if we are in connected state.
9548 * if not, allow only if we are in IMPS */
9549v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9550{
9551 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009552 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009553 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9555 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9556 hdd_adapter_t *pAdapter = NULL;
9557 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009558 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009559
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9561 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009562
Yathish9f22e662012-12-10 14:21:35 -08009563 concurrent_state = hdd_get_concurrency_mode();
9564
9565#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9566 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9567 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9568 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9569 return TRUE;
9570#endif
9571
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 /*loop through all adapters. TBD fix for Concurrency */
9573 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9574 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9575 {
9576 pAdapter = pAdapterNode->pAdapter;
9577 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9578 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9579 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009580 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009582 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009583 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9584 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009586 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009587 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9588 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 return FALSE;
9590 }
9591 }
9592 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9593 pAdapterNode = pNext;
9594 }
9595 return TRUE;
9596}
9597
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009598/* Decides whether to send suspend notification to Riva
9599 * if any adapter is in BMPS; then it is required */
9600v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9601{
9602 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9603 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9604
9605 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9606 {
9607 return TRUE;
9608 }
9609 return FALSE;
9610}
9611
Jeff Johnson295189b2012-06-20 16:38:30 -07009612void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9613{
9614 switch(mode)
9615 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009616 case VOS_STA_MODE:
9617 case VOS_P2P_CLIENT_MODE:
9618 case VOS_P2P_GO_MODE:
9619 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009620 pHddCtx->concurrency_mode |= (1 << mode);
9621 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 break;
9623 default:
9624 break;
9625
9626 }
9627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9628 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9629}
9630
9631
9632void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9633{
9634 switch(mode)
9635 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009636 case VOS_STA_MODE:
9637 case VOS_P2P_CLIENT_MODE:
9638 case VOS_P2P_GO_MODE:
9639 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 pHddCtx->no_of_sessions[mode]--;
9641 if (!(pHddCtx->no_of_sessions[mode]))
9642 pHddCtx->concurrency_mode &= (~(1 << mode));
9643 break;
9644 default:
9645 break;
9646 }
9647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9648 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9649}
9650
Jeff Johnsone7245742012-09-05 17:12:55 -07009651/**---------------------------------------------------------------------------
9652 *
9653 * \brief wlan_hdd_restart_init
9654 *
9655 * This function initalizes restart timer/flag. An internal function.
9656 *
9657 * \param - pHddCtx
9658 *
9659 * \return - None
9660 *
9661 * --------------------------------------------------------------------------*/
9662
9663static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9664{
9665 /* Initialize */
9666 pHddCtx->hdd_restart_retries = 0;
9667 atomic_set(&pHddCtx->isRestartInProgress, 0);
9668 vos_timer_init(&pHddCtx->hdd_restart_timer,
9669 VOS_TIMER_TYPE_SW,
9670 wlan_hdd_restart_timer_cb,
9671 pHddCtx);
9672}
9673/**---------------------------------------------------------------------------
9674 *
9675 * \brief wlan_hdd_restart_deinit
9676 *
9677 * This function cleans up the resources used. An internal function.
9678 *
9679 * \param - pHddCtx
9680 *
9681 * \return - None
9682 *
9683 * --------------------------------------------------------------------------*/
9684
9685static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9686{
9687
9688 VOS_STATUS vos_status;
9689 /* Block any further calls */
9690 atomic_set(&pHddCtx->isRestartInProgress, 1);
9691 /* Cleanup */
9692 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9693 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309694 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009695 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9696 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309697 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009698
9699}
9700
9701/**---------------------------------------------------------------------------
9702 *
9703 * \brief wlan_hdd_framework_restart
9704 *
9705 * This function uses a cfg80211 API to start a framework initiated WLAN
9706 * driver module unload/load.
9707 *
9708 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9709 *
9710 *
9711 * \param - pHddCtx
9712 *
9713 * \return - VOS_STATUS_SUCCESS: Success
9714 * VOS_STATUS_E_EMPTY: Adapter is Empty
9715 * VOS_STATUS_E_NOMEM: No memory
9716
9717 * --------------------------------------------------------------------------*/
9718
9719static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9720{
9721 VOS_STATUS status = VOS_STATUS_SUCCESS;
9722 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009723 int len = (sizeof (struct ieee80211_mgmt));
9724 struct ieee80211_mgmt *mgmt = NULL;
9725
9726 /* Prepare the DEAUTH managment frame with reason code */
9727 mgmt = kzalloc(len, GFP_KERNEL);
9728 if(mgmt == NULL)
9729 {
9730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9731 "%s: memory allocation failed (%d bytes)", __func__, len);
9732 return VOS_STATUS_E_NOMEM;
9733 }
9734 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009735
9736 /* Iterate over all adapters/devices */
9737 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9738 do
9739 {
9740 if( (status == VOS_STATUS_SUCCESS) &&
9741 pAdapterNode &&
9742 pAdapterNode->pAdapter)
9743 {
9744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9745 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9746 pAdapterNode->pAdapter->dev->name,
9747 pAdapterNode->pAdapter->device_mode,
9748 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009749 /*
9750 * CFG80211 event to restart the driver
9751 *
9752 * 'cfg80211_send_unprot_deauth' sends a
9753 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9754 * of SME(Linux Kernel) state machine.
9755 *
9756 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9757 * the driver.
9758 *
9759 */
9760
9761 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009762 }
9763 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9764 pAdapterNode = pNext;
9765 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9766
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009767
9768 /* Free the allocated management frame */
9769 kfree(mgmt);
9770
Jeff Johnsone7245742012-09-05 17:12:55 -07009771 /* Retry until we unload or reach max count */
9772 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9773 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9774
9775 return status;
9776
9777}
9778/**---------------------------------------------------------------------------
9779 *
9780 * \brief wlan_hdd_restart_timer_cb
9781 *
9782 * Restart timer callback. An internal function.
9783 *
9784 * \param - User data:
9785 *
9786 * \return - None
9787 *
9788 * --------------------------------------------------------------------------*/
9789
9790void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9791{
9792 hdd_context_t *pHddCtx = usrDataForCallback;
9793 wlan_hdd_framework_restart(pHddCtx);
9794 return;
9795
9796}
9797
9798
9799/**---------------------------------------------------------------------------
9800 *
9801 * \brief wlan_hdd_restart_driver
9802 *
9803 * This function sends an event to supplicant to restart the WLAN driver.
9804 *
9805 * This function is called from vos_wlanRestart.
9806 *
9807 * \param - pHddCtx
9808 *
9809 * \return - VOS_STATUS_SUCCESS: Success
9810 * VOS_STATUS_E_EMPTY: Adapter is Empty
9811 * VOS_STATUS_E_ALREADY: Request already in progress
9812
9813 * --------------------------------------------------------------------------*/
9814VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9815{
9816 VOS_STATUS status = VOS_STATUS_SUCCESS;
9817
9818 /* A tight check to make sure reentrancy */
9819 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9820 {
9821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9822 "%s: WLAN restart is already in progress", __func__);
9823
9824 return VOS_STATUS_E_ALREADY;
9825 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009826 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009827#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009828 wcnss_reset_intr();
9829#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009830
Jeff Johnsone7245742012-09-05 17:12:55 -07009831 return status;
9832}
9833
Mihir Shetee1093ba2014-01-21 20:13:32 +05309834/**---------------------------------------------------------------------------
9835 *
9836 * \brief wlan_hdd_init_channels
9837 *
9838 * This function is used to initialize the channel list in CSR
9839 *
9840 * This function is called from hdd_wlan_startup
9841 *
9842 * \param - pHddCtx: HDD context
9843 *
9844 * \return - VOS_STATUS_SUCCESS: Success
9845 * VOS_STATUS_E_FAULT: Failure reported by SME
9846
9847 * --------------------------------------------------------------------------*/
9848static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9849{
9850 eHalStatus status;
9851
9852 status = sme_InitChannels(pHddCtx->hHal);
9853 if (HAL_STATUS_SUCCESS(status))
9854 {
9855 return VOS_STATUS_SUCCESS;
9856 }
9857 else
9858 {
9859 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9860 __func__, status);
9861 return VOS_STATUS_E_FAULT;
9862 }
9863}
9864
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009865/*
9866 * API to find if there is any STA or P2P-Client is connected
9867 */
9868VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9869{
9870 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9871}
Jeff Johnsone7245742012-09-05 17:12:55 -07009872
Jeff Johnson295189b2012-06-20 16:38:30 -07009873//Register the module init/exit functions
9874module_init(hdd_module_init);
9875module_exit(hdd_module_exit);
9876
9877MODULE_LICENSE("Dual BSD/GPL");
9878MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9879MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9880
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009881module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9882 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009883
Jeff Johnson76052702013-04-16 13:55:05 -07009884module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009885 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009886
9887module_param(enable_dfs_chan_scan, int,
9888 S_IRUSR | S_IRGRP | S_IROTH);
9889
9890module_param(enable_11d, int,
9891 S_IRUSR | S_IRGRP | S_IROTH);
9892
9893module_param(country_code, charp,
9894 S_IRUSR | S_IRGRP | S_IROTH);