blob: 4cbf81f1252fdb08f9e34bf3e080ff9334b254d8 [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 {
1782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1783 "sme_SetBatchScanReq returned success halStatus %d",
1784 halStatus);
1785 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1786 {
1787 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1788 rc = wait_for_completion_timeout(
1789 &pAdapter->hdd_set_batch_scan_req_var,
1790 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1791 if (0 == rc)
1792 {
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "%s: Timeout waiting for set batch scan to complete",
1795 __func__);
1796 ret = -EINVAL;
1797 goto exit;
1798 }
1799 }
1800 if ( !pRsp->nScansToBatch )
1801 {
1802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1803 "%s: Received set batch scan failure response from FW",
1804 __func__);
1805 ret = -EINVAL;
1806 goto exit;
1807 }
1808 /*As per the Batch Scan Framework API we should return the MIN of
1809 either MSCAN or the max # of scans firmware can cache*/
1810 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
1811
1812 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1813
1814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1815 "%s: request MSCAN %d response MSCAN %d ret %d",
1816 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
1817 }
1818 else
1819 {
1820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1821 "sme_SetBatchScanReq returned failure halStatus %d",
1822 halStatus);
1823 ret = -EINVAL;
1824 goto exit;
1825 }
1826 }
1827 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1828 {
1829 eHalStatus halStatus;
1830 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1831 pInd->param = 0;
1832
1833 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1834 {
1835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1836 "%s: Batch scan feature is not supported by FW", __func__);
1837 ret = -EINVAL;
1838 goto exit;
1839 }
1840
1841 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1842 {
1843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1844 "Batch scan is not yet enabled batch scan state %d",
1845 pAdapter->batchScanState);
1846 ret = -EINVAL;
1847 goto exit;
1848 }
1849
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001850 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1851 hdd_deinit_batch_scan(pAdapter);
1852 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1853
Rajeev Kumar8b373292014-01-08 20:36:55 -08001854 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1855
1856 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1857 pAdapter->sessionId);
1858 if ( eHAL_STATUS_SUCCESS == halStatus )
1859 {
1860 ret = 0;
1861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1862 "sme_StopBatchScanInd returned success halStatus %d",
1863 halStatus);
1864 }
1865 else
1866 {
1867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1868 "sme_StopBatchScanInd returned failure halStatus %d",
1869 halStatus);
1870 ret = -EINVAL;
1871 goto exit;
1872 }
1873 }
1874 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1875 {
1876 tANI_U32 remain_len;
1877
1878 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1879 {
1880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1881 "%s: Batch scan feature is not supported by FW", __func__);
1882 ret = -EINVAL;
1883 goto exit;
1884 }
1885
1886 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1887 {
1888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1889 "Batch scan is not yet enabled could not return results"
1890 "Batch Scan state %d",
1891 pAdapter->batchScanState);
1892 ret = -EINVAL;
1893 goto exit;
1894 }
1895
1896 pPrivdata->used_len = 16;
1897 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1898 if (remain_len < pPrivdata->total_len)
1899 {
1900 /*Clear previous batch scan response data if any*/
1901 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1902 }
1903 else
1904 {
1905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1906 "Invalid total length from user space can't fetch batch"
1907 " scan response total_len %d used_len %d remain len %d",
1908 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1909 ret = -EINVAL;
1910 goto exit;
1911 }
1912 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1913 }
1914
1915exit:
1916
1917 return ret;
1918}
1919
1920
Rajeev79dbe4c2013-10-05 11:03:42 +05301921#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1922
c_hpothu92367912014-05-01 15:18:17 +05301923static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1924{
1925 bcnMissRateContext_t *pCBCtx = (bcnMissRateContext_t *)data;
1926
1927 /* there is a race condition that exists between this callback
1928 function and the caller since the caller could time out either
1929 before or while this code is executing. we use a spinlock to
1930 serialize these actions */
1931 spin_lock(&hdd_context_lock);
1932
1933 gbcnMissRate = -1;
1934
1935 if(pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC || NULL == data)
1936 {
1937 hddLog(VOS_TRACE_LEVEL_ERROR,
1938 FL("invalid context magic: %08x data: %p"), pCBCtx->magic, data );
1939 spin_unlock(&hdd_context_lock);
1940 return ;
1941 }
1942
1943 if (VOS_STATUS_SUCCESS == status)
1944 {
1945 gbcnMissRate = bcnMissRate;
1946 }
1947 complete(&(pCBCtx->completion));
1948 spin_unlock(&hdd_context_lock);
1949
1950 return;
1951}
1952
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001953static int hdd_driver_command(hdd_adapter_t *pAdapter,
1954 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07001955{
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 hdd_priv_data_t priv_data;
1957 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001958 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001959
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001960 /*
1961 * Note that valid pointers are provided by caller
1962 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001963
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001964 /* copy to local struct to avoid numerous changes to legacy code */
1965 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07001966
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001967 if (priv_data.total_len <= 0 ||
1968 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001969 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001970 hddLog(VOS_TRACE_LEVEL_WARN,
1971 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1972 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001973 ret = -EINVAL;
1974 goto exit;
1975 }
1976
1977 /* Allocate +1 for '\0' */
1978 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 if (!command)
1980 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001981 hddLog(VOS_TRACE_LEVEL_ERROR,
1982 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001983 ret = -ENOMEM;
1984 goto exit;
1985 }
1986
1987 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1988 {
1989 ret = -EFAULT;
1990 goto exit;
1991 }
1992
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001993 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001994 command[priv_data.total_len] = '\0';
1995
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001996 /* at one time the following block of code was conditional. braces
1997 * have been retained to avoid re-indenting the legacy code
1998 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 {
2000 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2001
2002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002003 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002004
2005 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2006 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302007 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2008 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2009 pAdapter->sessionId, (unsigned)
2010 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2011 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2012 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2013 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002014 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2015 sizeof(tSirMacAddr)))
2016 {
2017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002018 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 ret = -EFAULT;
2020 }
2021 }
Amar Singhal0974e402013-02-12 14:27:46 -08002022 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 {
Amar Singhal0974e402013-02-12 14:27:46 -08002024 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002025
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002027
2028 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002029 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002031 "%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 -07002032 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002033 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302034 if(ret != 0)
2035 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002036 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002037 }
Kiet Lamf040f472013-11-20 21:15:23 +05302038 else if(strncmp(command, "SETWMMPS", 8) == 0)
2039 {
2040 tANI_U8 *ptr = command;
2041 ret = hdd_wmmps_helper(pAdapter, ptr);
2042 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002043 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2044 {
2045 char *country_code;
2046
2047 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002048
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002049 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002050 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002051#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302052 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002053#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002054 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2055 (void *)(tSmeChangeCountryCallback)
2056 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302057 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002058 if (eHAL_STATUS_SUCCESS == ret)
2059 {
2060 ret = wait_for_completion_interruptible_timeout(
2061 &pAdapter->change_country_code,
2062 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2063 if (0 >= ret)
2064 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302066 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002067 }
2068 }
2069 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002070 {
2071 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002072 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002073 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002074 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002075
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002076 }
2077 /*
2078 command should be a string having format
2079 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2080 */
Amar Singhal0974e402013-02-12 14:27:46 -08002081 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002082 {
Amar Singhal0974e402013-02-12 14:27:46 -08002083 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002084
2085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002086 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002087
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002088 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002089 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002090 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2091 {
2092 int suspend = 0;
2093 tANI_U8 *ptr = (tANI_U8*)command + 15;
2094
2095 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302096 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2097 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2098 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002099 hdd_set_wlan_suspend_mode(suspend);
2100 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002101#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2102 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2103 {
2104 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002105 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002106 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2107 eHalStatus status = eHAL_STATUS_SUCCESS;
2108
2109 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2110 value = value + 15;
2111
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002112 /* Convert the value from ascii to integer */
2113 ret = kstrtos8(value, 10, &rssi);
2114 if (ret < 0)
2115 {
2116 /* If the input value is greater than max value of datatype, then also
2117 kstrtou8 fails */
2118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2119 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002120 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002121 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2122 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2123 ret = -EINVAL;
2124 goto exit;
2125 }
2126
Srinivas Girigowdade697412013-02-14 16:31:48 -08002127 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002128
Srinivas Girigowdade697412013-02-14 16:31:48 -08002129 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2130 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2131 {
2132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2133 "Neighbor lookup threshold value %d is out of range"
2134 " (Min: %d Max: %d)", lookUpThreshold,
2135 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2136 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2137 ret = -EINVAL;
2138 goto exit;
2139 }
2140
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302141 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2142 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2143 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2145 "%s: Received Command to Set Roam trigger"
2146 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2147
2148 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2149 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2150 if (eHAL_STATUS_SUCCESS != status)
2151 {
2152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2153 "%s: Failed to set roam trigger, try again", __func__);
2154 ret = -EPERM;
2155 goto exit;
2156 }
2157
2158 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2159 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2160 }
2161 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2162 {
2163 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2164 int rssi = (-1) * lookUpThreshold;
2165 char extra[32];
2166 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2168 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2169 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002170 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002171 if (copy_to_user(priv_data.buf, &extra, len + 1))
2172 {
2173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2174 "%s: failed to copy data to user buffer", __func__);
2175 ret = -EFAULT;
2176 goto exit;
2177 }
2178 }
2179 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2180 {
2181 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002182 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002183 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002184
Srinivas Girigowdade697412013-02-14 16:31:48 -08002185 /* input refresh period is in terms of seconds */
2186 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2187 value = value + 18;
2188 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002189 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002190 if (ret < 0)
2191 {
2192 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002193 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002195 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002196 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002197 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2198 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002199 ret = -EINVAL;
2200 goto exit;
2201 }
2202
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002203 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2204 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002205 {
2206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002207 "Roam scan period value %d is out of range"
2208 " (Min: %d Max: %d)", roamScanPeriod,
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;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302213 }
2214 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2215 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2216 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002217 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002218
2219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2220 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002221 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002222
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002223 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2224 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002225 }
2226 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2227 {
2228 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2229 char extra[32];
2230 tANI_U8 len = 0;
2231
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302232 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2233 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2234 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002235 len = scnprintf(extra, sizeof(extra), "%s %d",
2236 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002237 /* Returned value is in units of seconds */
2238 if (copy_to_user(priv_data.buf, &extra, len + 1))
2239 {
2240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2241 "%s: failed to copy data to user buffer", __func__);
2242 ret = -EFAULT;
2243 goto exit;
2244 }
2245 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002246 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2247 {
2248 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002249 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002250 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002251
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002252 /* input refresh period is in terms of seconds */
2253 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2254 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002255
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002256 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002257 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002258 if (ret < 0)
2259 {
2260 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002261 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002263 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002264 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002265 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2266 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2267 ret = -EINVAL;
2268 goto exit;
2269 }
2270
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002271 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2272 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2273 {
2274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2275 "Neighbor scan results refresh period value %d is out of range"
2276 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2277 (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 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2283
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2285 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002286 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002287
2288 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2289 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2290 }
2291 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2292 {
2293 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2294 char extra[32];
2295 tANI_U8 len = 0;
2296
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002297 len = scnprintf(extra, sizeof(extra), "%s %d",
2298 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002299 /* Returned value is in units of seconds */
2300 if (copy_to_user(priv_data.buf, &extra, len + 1))
2301 {
2302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2303 "%s: failed to copy data to user buffer", __func__);
2304 ret = -EFAULT;
2305 goto exit;
2306 }
2307 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002308#ifdef FEATURE_WLAN_LFR
2309 /* SETROAMMODE */
2310 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2311 {
2312 tANI_U8 *value = command;
2313 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2314
2315 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2316 value = value + SIZE_OF_SETROAMMODE + 1;
2317
2318 /* Convert the value from ascii to integer */
2319 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2320 if (ret < 0)
2321 {
2322 /* If the input value is greater than max value of datatype, then also
2323 kstrtou8 fails */
2324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2325 "%s: kstrtou8 failed range [%d - %d]", __func__,
2326 CFG_LFR_FEATURE_ENABLED_MIN,
2327 CFG_LFR_FEATURE_ENABLED_MAX);
2328 ret = -EINVAL;
2329 goto exit;
2330 }
2331 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2332 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2333 {
2334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2335 "Roam Mode value %d is out of range"
2336 " (Min: %d Max: %d)", roamMode,
2337 CFG_LFR_FEATURE_ENABLED_MIN,
2338 CFG_LFR_FEATURE_ENABLED_MAX);
2339 ret = -EINVAL;
2340 goto exit;
2341 }
2342
2343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2344 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2345 /*
2346 * Note that
2347 * SETROAMMODE 0 is to enable LFR while
2348 * SETROAMMODE 1 is to disable LFR, but
2349 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2350 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2351 */
2352 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2353 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2354 else
2355 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2356
2357 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2358 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2359 }
2360 /* GETROAMMODE */
2361 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2362 {
2363 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2364 char extra[32];
2365 tANI_U8 len = 0;
2366
2367 /*
2368 * roamMode value shall be inverted because the sementics is different.
2369 */
2370 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2371 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2372 else
2373 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2374
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002375 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002376 if (copy_to_user(priv_data.buf, &extra, len + 1))
2377 {
2378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2379 "%s: failed to copy data to user buffer", __func__);
2380 ret = -EFAULT;
2381 goto exit;
2382 }
2383 }
2384#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002385#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002386#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002387 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2388 {
2389 tANI_U8 *value = command;
2390 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2391
2392 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2393 value = value + 13;
2394 /* Convert the value from ascii to integer */
2395 ret = kstrtou8(value, 10, &roamRssiDiff);
2396 if (ret < 0)
2397 {
2398 /* If the input value is greater than max value of datatype, then also
2399 kstrtou8 fails */
2400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2401 "%s: kstrtou8 failed range [%d - %d]", __func__,
2402 CFG_ROAM_RSSI_DIFF_MIN,
2403 CFG_ROAM_RSSI_DIFF_MAX);
2404 ret = -EINVAL;
2405 goto exit;
2406 }
2407
2408 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2409 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2410 {
2411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2412 "Roam rssi diff value %d is out of range"
2413 " (Min: %d Max: %d)", roamRssiDiff,
2414 CFG_ROAM_RSSI_DIFF_MIN,
2415 CFG_ROAM_RSSI_DIFF_MAX);
2416 ret = -EINVAL;
2417 goto exit;
2418 }
2419
2420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2421 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2422
2423 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2424 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2425 }
2426 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2427 {
2428 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2429 char extra[32];
2430 tANI_U8 len = 0;
2431
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302432 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2433 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2434 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002435 len = scnprintf(extra, sizeof(extra), "%s %d",
2436 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002437 if (copy_to_user(priv_data.buf, &extra, len + 1))
2438 {
2439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2440 "%s: failed to copy data to user buffer", __func__);
2441 ret = -EFAULT;
2442 goto exit;
2443 }
2444 }
2445#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002446#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002447 else if (strncmp(command, "GETBAND", 7) == 0)
2448 {
2449 int band = -1;
2450 char extra[32];
2451 tANI_U8 len = 0;
2452 hdd_getBand_helper(pHddCtx, &band);
2453
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302454 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2455 TRACE_CODE_HDD_GETBAND_IOCTL,
2456 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002457 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002458 if (copy_to_user(priv_data.buf, &extra, len + 1))
2459 {
2460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2461 "%s: failed to copy data to user buffer", __func__);
2462 ret = -EFAULT;
2463 goto exit;
2464 }
2465 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002466 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2467 {
2468 tANI_U8 *value = command;
2469 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2470 tANI_U8 numChannels = 0;
2471 eHalStatus status = eHAL_STATUS_SUCCESS;
2472
2473 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2474 if (eHAL_STATUS_SUCCESS != status)
2475 {
2476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2477 "%s: Failed to parse channel list information", __func__);
2478 ret = -EINVAL;
2479 goto exit;
2480 }
2481
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302482 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2483 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2484 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002485 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2486 {
2487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2488 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2489 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2490 ret = -EINVAL;
2491 goto exit;
2492 }
2493 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2494 numChannels);
2495 if (eHAL_STATUS_SUCCESS != status)
2496 {
2497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2498 "%s: Failed to update channel list information", __func__);
2499 ret = -EINVAL;
2500 goto exit;
2501 }
2502 }
2503 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2504 {
2505 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2506 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002507 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002508 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002509 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002510
2511 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2512 ChannelList, &numChannels ))
2513 {
2514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2515 "%s: failed to get roam scan channel list", __func__);
2516 ret = -EFAULT;
2517 goto exit;
2518 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302519 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2520 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2521 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002522 /* output channel list is of the format
2523 [Number of roam scan channels][Channel1][Channel2]... */
2524 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002525 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002526 for (j = 0; (j < numChannels); j++)
2527 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002528 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2529 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002530 }
2531
2532 if (copy_to_user(priv_data.buf, &extra, len + 1))
2533 {
2534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2535 "%s: failed to copy data to user buffer", __func__);
2536 ret = -EFAULT;
2537 goto exit;
2538 }
2539 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002540 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2541 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002542 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543 char extra[32];
2544 tANI_U8 len = 0;
2545
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002546 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002547 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002548 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002549 hdd_is_okc_mode_enabled(pHddCtx) &&
2550 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2551 {
2552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002553 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002554 " hence this operation is not permitted!", __func__);
2555 ret = -EPERM;
2556 goto exit;
2557 }
2558
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002559 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002560 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002561 if (copy_to_user(priv_data.buf, &extra, len + 1))
2562 {
2563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2564 "%s: failed to copy data to user buffer", __func__);
2565 ret = -EFAULT;
2566 goto exit;
2567 }
2568 }
2569 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2570 {
2571 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2572 char extra[32];
2573 tANI_U8 len = 0;
2574
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002575 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002576 then this operation is not permitted (return FAILURE) */
2577 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002578 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002579 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2580 {
2581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002582 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002583 " hence this operation is not permitted!", __func__);
2584 ret = -EPERM;
2585 goto exit;
2586 }
2587
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002588 len = scnprintf(extra, sizeof(extra), "%s %d",
2589 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002590 if (copy_to_user(priv_data.buf, &extra, len + 1))
2591 {
2592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2593 "%s: failed to copy data to user buffer", __func__);
2594 ret = -EFAULT;
2595 goto exit;
2596 }
2597 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002598 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002599 {
2600 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2601 char extra[32];
2602 tANI_U8 len = 0;
2603
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002604 len = scnprintf(extra, sizeof(extra), "%s %d",
2605 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002606 if (copy_to_user(priv_data.buf, &extra, len + 1))
2607 {
2608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2609 "%s: failed to copy data to user buffer", __func__);
2610 ret = -EFAULT;
2611 goto exit;
2612 }
2613 }
2614 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2615 {
2616 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2617 char extra[32];
2618 tANI_U8 len = 0;
2619
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002620 len = scnprintf(extra, sizeof(extra), "%s %d",
2621 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002622 if (copy_to_user(priv_data.buf, &extra, len + 1))
2623 {
2624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2625 "%s: failed to copy data to user buffer", __func__);
2626 ret = -EFAULT;
2627 goto exit;
2628 }
2629 }
2630 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2631 {
2632 tANI_U8 *value = command;
2633 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2634
2635 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2636 value = value + 26;
2637 /* Convert the value from ascii to integer */
2638 ret = kstrtou8(value, 10, &minTime);
2639 if (ret < 0)
2640 {
2641 /* If the input value is greater than max value of datatype, then also
2642 kstrtou8 fails */
2643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2644 "%s: kstrtou8 failed range [%d - %d]", __func__,
2645 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2646 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2647 ret = -EINVAL;
2648 goto exit;
2649 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002650 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2651 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2652 {
2653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2654 "scan min channel time value %d is out of range"
2655 " (Min: %d Max: %d)", minTime,
2656 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2657 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2658 ret = -EINVAL;
2659 goto exit;
2660 }
2661
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302662 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2663 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2664 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2666 "%s: Received Command to change channel min time = %d", __func__, minTime);
2667
2668 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2669 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2670 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002671 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2672 {
2673 tANI_U8 *value = command;
2674 tANI_U8 channel = 0;
2675 tANI_U8 dwellTime = 0;
2676 tANI_U8 bufLen = 0;
2677 tANI_U8 *buf = NULL;
2678 tSirMacAddr targetApBssid;
2679 eHalStatus status = eHAL_STATUS_SUCCESS;
2680 struct ieee80211_channel chan;
2681 tANI_U8 finalLen = 0;
2682 tANI_U8 *finalBuf = NULL;
2683 tANI_U8 temp = 0;
2684 u64 cookie;
2685 hdd_station_ctx_t *pHddStaCtx = NULL;
2686 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2687
2688 /* if not associated, no need to send action frame */
2689 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2690 {
2691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2692 ret = -EINVAL;
2693 goto exit;
2694 }
2695
2696 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2697 &dwellTime, &buf, &bufLen);
2698 if (eHAL_STATUS_SUCCESS != status)
2699 {
2700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2701 "%s: Failed to parse send action frame data", __func__);
2702 ret = -EINVAL;
2703 goto exit;
2704 }
2705
2706 /* if the target bssid is different from currently associated AP,
2707 then no need to send action frame */
2708 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2709 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2710 {
2711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2712 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002713 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002714 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002715 goto exit;
2716 }
2717
2718 /* if the channel number is different from operating channel then
2719 no need to send action frame */
2720 if (channel != pHddStaCtx->conn_info.operationChannel)
2721 {
2722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2723 "%s: channel(%d) is different from operating channel(%d)",
2724 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2725 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002726 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002727 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002728 goto exit;
2729 }
2730 chan.center_freq = sme_ChnToFreq(channel);
2731
2732 finalLen = bufLen + 24;
2733 finalBuf = vos_mem_malloc(finalLen);
2734 if (NULL == finalBuf)
2735 {
2736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2737 ret = -ENOMEM;
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 vos_mem_zero(finalBuf, finalLen);
2743
2744 /* Fill subtype */
2745 temp = SIR_MAC_MGMT_ACTION << 4;
2746 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2747
2748 /* Fill type */
2749 temp = SIR_MAC_MGMT_FRAME;
2750 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2751
2752 /* Fill destination address (bssid of the AP) */
2753 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2754
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002755 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002756 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2757
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002758 /* Fill BSSID (AP mac address) */
2759 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002760
2761 /* Fill received buffer from 24th address */
2762 vos_mem_copy(finalBuf + 24, buf, bufLen);
2763
Jeff Johnson11c33152013-04-16 17:52:40 -07002764 /* done with the parsed buffer */
2765 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002766 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002767
DARAM SUDHA39eede62014-02-12 11:16:40 +05302768 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002769#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2770 &(pAdapter->wdev),
2771#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002772 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002773#endif
2774 &chan, 0,
2775#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2776 NL80211_CHAN_HT20, 1,
2777#endif
2778 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002779 1, &cookie );
2780 vos_mem_free(finalBuf);
2781 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002782 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2783 {
2784 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2785 char extra[32];
2786 tANI_U8 len = 0;
2787
2788 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002789 len = scnprintf(extra, sizeof(extra), "%s %d",
2790 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302791 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2792 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2793 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002794 if (copy_to_user(priv_data.buf, &extra, len + 1))
2795 {
2796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2797 "%s: failed to copy data to user buffer", __func__);
2798 ret = -EFAULT;
2799 goto exit;
2800 }
2801 }
2802 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2803 {
2804 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002805 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002806
2807 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2808 value = value + 19;
2809 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002810 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002811 if (ret < 0)
2812 {
2813 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002814 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002816 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002817 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2818 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2819 ret = -EINVAL;
2820 goto exit;
2821 }
2822
2823 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2824 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2825 {
2826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2827 "lfr mode value %d is out of range"
2828 " (Min: %d Max: %d)", maxTime,
2829 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2830 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2831 ret = -EINVAL;
2832 goto exit;
2833 }
2834
2835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2836 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2837
2838 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2839 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2840 }
2841 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2842 {
2843 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2844 char extra[32];
2845 tANI_U8 len = 0;
2846
2847 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002848 len = scnprintf(extra, sizeof(extra), "%s %d",
2849 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002850 if (copy_to_user(priv_data.buf, &extra, len + 1))
2851 {
2852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2853 "%s: failed to copy data to user buffer", __func__);
2854 ret = -EFAULT;
2855 goto exit;
2856 }
2857 }
2858 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2859 {
2860 tANI_U8 *value = command;
2861 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2862
2863 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2864 value = value + 16;
2865 /* Convert the value from ascii to integer */
2866 ret = kstrtou16(value, 10, &val);
2867 if (ret < 0)
2868 {
2869 /* If the input value is greater than max value of datatype, then also
2870 kstrtou16 fails */
2871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2872 "%s: kstrtou16 failed range [%d - %d]", __func__,
2873 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2874 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2875 ret = -EINVAL;
2876 goto exit;
2877 }
2878
2879 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2880 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2881 {
2882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2883 "scan home time value %d is out of range"
2884 " (Min: %d Max: %d)", val,
2885 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2886 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2887 ret = -EINVAL;
2888 goto exit;
2889 }
2890
2891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2892 "%s: Received Command to change scan home time = %d", __func__, val);
2893
2894 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2895 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2896 }
2897 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2898 {
2899 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2900 char extra[32];
2901 tANI_U8 len = 0;
2902
2903 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002904 len = scnprintf(extra, sizeof(extra), "%s %d",
2905 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002906 if (copy_to_user(priv_data.buf, &extra, len + 1))
2907 {
2908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2909 "%s: failed to copy data to user buffer", __func__);
2910 ret = -EFAULT;
2911 goto exit;
2912 }
2913 }
2914 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2915 {
2916 tANI_U8 *value = command;
2917 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2918
2919 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2920 value = value + 17;
2921 /* Convert the value from ascii to integer */
2922 ret = kstrtou8(value, 10, &val);
2923 if (ret < 0)
2924 {
2925 /* If the input value is greater than max value of datatype, then also
2926 kstrtou8 fails */
2927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2928 "%s: kstrtou8 failed range [%d - %d]", __func__,
2929 CFG_ROAM_INTRA_BAND_MIN,
2930 CFG_ROAM_INTRA_BAND_MAX);
2931 ret = -EINVAL;
2932 goto exit;
2933 }
2934
2935 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2936 (val > CFG_ROAM_INTRA_BAND_MAX))
2937 {
2938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2939 "intra band mode value %d is out of range"
2940 " (Min: %d Max: %d)", val,
2941 CFG_ROAM_INTRA_BAND_MIN,
2942 CFG_ROAM_INTRA_BAND_MAX);
2943 ret = -EINVAL;
2944 goto exit;
2945 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2947 "%s: Received Command to change intra band = %d", __func__, val);
2948
2949 pHddCtx->cfg_ini->nRoamIntraBand = val;
2950 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2951 }
2952 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2953 {
2954 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2955 char extra[32];
2956 tANI_U8 len = 0;
2957
2958 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002959 len = scnprintf(extra, sizeof(extra), "%s %d",
2960 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002961 if (copy_to_user(priv_data.buf, &extra, len + 1))
2962 {
2963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2964 "%s: failed to copy data to user buffer", __func__);
2965 ret = -EFAULT;
2966 goto exit;
2967 }
2968 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002969 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2970 {
2971 tANI_U8 *value = command;
2972 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2973
2974 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2975 value = value + 15;
2976 /* Convert the value from ascii to integer */
2977 ret = kstrtou8(value, 10, &nProbes);
2978 if (ret < 0)
2979 {
2980 /* If the input value is greater than max value of datatype, then also
2981 kstrtou8 fails */
2982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2983 "%s: kstrtou8 failed range [%d - %d]", __func__,
2984 CFG_ROAM_SCAN_N_PROBES_MIN,
2985 CFG_ROAM_SCAN_N_PROBES_MAX);
2986 ret = -EINVAL;
2987 goto exit;
2988 }
2989
2990 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2991 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2992 {
2993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2994 "NProbes value %d is out of range"
2995 " (Min: %d Max: %d)", nProbes,
2996 CFG_ROAM_SCAN_N_PROBES_MIN,
2997 CFG_ROAM_SCAN_N_PROBES_MAX);
2998 ret = -EINVAL;
2999 goto exit;
3000 }
3001
3002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3003 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3004
3005 pHddCtx->cfg_ini->nProbes = nProbes;
3006 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3007 }
3008 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3009 {
3010 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3011 char extra[32];
3012 tANI_U8 len = 0;
3013
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003014 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003015 if (copy_to_user(priv_data.buf, &extra, len + 1))
3016 {
3017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3018 "%s: failed to copy data to user buffer", __func__);
3019 ret = -EFAULT;
3020 goto exit;
3021 }
3022 }
3023 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3024 {
3025 tANI_U8 *value = command;
3026 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3027
3028 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3029 /* input value is in units of msec */
3030 value = value + 20;
3031 /* Convert the value from ascii to integer */
3032 ret = kstrtou16(value, 10, &homeAwayTime);
3033 if (ret < 0)
3034 {
3035 /* If the input value is greater than max value of datatype, then also
3036 kstrtou8 fails */
3037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3038 "%s: kstrtou8 failed range [%d - %d]", __func__,
3039 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3040 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3041 ret = -EINVAL;
3042 goto exit;
3043 }
3044
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003045 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3046 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3047 {
3048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3049 "homeAwayTime value %d is out of range"
3050 " (Min: %d Max: %d)", homeAwayTime,
3051 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3052 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3053 ret = -EINVAL;
3054 goto exit;
3055 }
3056
3057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3058 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003059 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3060 {
3061 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3062 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3063 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003064 }
3065 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3066 {
3067 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3068 char extra[32];
3069 tANI_U8 len = 0;
3070
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003071 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003072 if (copy_to_user(priv_data.buf, &extra, len + 1))
3073 {
3074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3075 "%s: failed to copy data to user buffer", __func__);
3076 ret = -EFAULT;
3077 goto exit;
3078 }
3079 }
3080 else if (strncmp(command, "REASSOC", 7) == 0)
3081 {
3082 tANI_U8 *value = command;
3083 tANI_U8 channel = 0;
3084 tSirMacAddr targetApBssid;
3085 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003086#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3087 tCsrHandoffRequest handoffInfo;
3088#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003089 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003090 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3091
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003092 /* if not associated, no need to proceed with reassoc */
3093 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3094 {
3095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3096 ret = -EINVAL;
3097 goto exit;
3098 }
3099
3100 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3101 if (eHAL_STATUS_SUCCESS != status)
3102 {
3103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3104 "%s: Failed to parse reassoc command data", __func__);
3105 ret = -EINVAL;
3106 goto exit;
3107 }
3108
3109 /* if the target bssid is same as currently associated AP,
3110 then no need to proceed with reassoc */
3111 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3112 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3113 {
3114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3115 ret = -EINVAL;
3116 goto exit;
3117 }
3118
3119 /* Check channel number is a valid channel number */
3120 if(VOS_STATUS_SUCCESS !=
3121 wlan_hdd_validate_operation_channel(pAdapter, channel))
3122 {
3123 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003124 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003125 return -EINVAL;
3126 }
3127
3128 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003129#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3130 handoffInfo.channel = channel;
3131 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3132 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3133#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003134 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003135 else if (strncmp(command, "SETWESMODE", 10) == 0)
3136 {
3137 tANI_U8 *value = command;
3138 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3139
3140 /* Move pointer to ahead of SETWESMODE<delimiter> */
3141 value = value + 11;
3142 /* Convert the value from ascii to integer */
3143 ret = kstrtou8(value, 10, &wesMode);
3144 if (ret < 0)
3145 {
3146 /* If the input value is greater than max value of datatype, then also
3147 kstrtou8 fails */
3148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3149 "%s: kstrtou8 failed range [%d - %d]", __func__,
3150 CFG_ENABLE_WES_MODE_NAME_MIN,
3151 CFG_ENABLE_WES_MODE_NAME_MAX);
3152 ret = -EINVAL;
3153 goto exit;
3154 }
3155
3156 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3157 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3158 {
3159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3160 "WES Mode value %d is out of range"
3161 " (Min: %d Max: %d)", wesMode,
3162 CFG_ENABLE_WES_MODE_NAME_MIN,
3163 CFG_ENABLE_WES_MODE_NAME_MAX);
3164 ret = -EINVAL;
3165 goto exit;
3166 }
3167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3168 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3169
3170 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3171 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3172 }
3173 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3174 {
3175 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3176 char extra[32];
3177 tANI_U8 len = 0;
3178
Arif Hussain826d9412013-11-12 16:44:54 -08003179 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003180 if (copy_to_user(priv_data.buf, &extra, len + 1))
3181 {
3182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3183 "%s: failed to copy data to user buffer", __func__);
3184 ret = -EFAULT;
3185 goto exit;
3186 }
3187 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003188#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003189#ifdef FEATURE_WLAN_LFR
3190 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3191 {
3192 tANI_U8 *value = command;
3193 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3194
3195 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3196 value = value + 12;
3197 /* Convert the value from ascii to integer */
3198 ret = kstrtou8(value, 10, &lfrMode);
3199 if (ret < 0)
3200 {
3201 /* If the input value is greater than max value of datatype, then also
3202 kstrtou8 fails */
3203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3204 "%s: kstrtou8 failed range [%d - %d]", __func__,
3205 CFG_LFR_FEATURE_ENABLED_MIN,
3206 CFG_LFR_FEATURE_ENABLED_MAX);
3207 ret = -EINVAL;
3208 goto exit;
3209 }
3210
3211 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3212 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3213 {
3214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3215 "lfr mode value %d is out of range"
3216 " (Min: %d Max: %d)", lfrMode,
3217 CFG_LFR_FEATURE_ENABLED_MIN,
3218 CFG_LFR_FEATURE_ENABLED_MAX);
3219 ret = -EINVAL;
3220 goto exit;
3221 }
3222
3223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3224 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3225
3226 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3227 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3228 }
3229#endif
3230#ifdef WLAN_FEATURE_VOWIFI_11R
3231 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3232 {
3233 tANI_U8 *value = command;
3234 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3235
3236 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3237 value = value + 18;
3238 /* Convert the value from ascii to integer */
3239 ret = kstrtou8(value, 10, &ft);
3240 if (ret < 0)
3241 {
3242 /* If the input value is greater than max value of datatype, then also
3243 kstrtou8 fails */
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3245 "%s: kstrtou8 failed range [%d - %d]", __func__,
3246 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3247 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3248 ret = -EINVAL;
3249 goto exit;
3250 }
3251
3252 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3253 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3254 {
3255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3256 "ft mode value %d is out of range"
3257 " (Min: %d Max: %d)", ft,
3258 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3259 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3260 ret = -EINVAL;
3261 goto exit;
3262 }
3263
3264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3265 "%s: Received Command to change ft mode = %d", __func__, ft);
3266
3267 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3268 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3269 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303270
3271 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3272 {
3273 tANI_U8 *value = command;
3274 tSirMacAddr targetApBssid;
3275 tANI_U8 trigger = 0;
3276 eHalStatus status = eHAL_STATUS_SUCCESS;
3277 hdd_station_ctx_t *pHddStaCtx = NULL;
3278 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3279
3280 /* if not associated, no need to proceed with reassoc */
3281 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3282 {
3283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3284 ret = -EINVAL;
3285 goto exit;
3286 }
3287
3288 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3289 if (eHAL_STATUS_SUCCESS != status)
3290 {
3291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3292 "%s: Failed to parse reassoc command data", __func__);
3293 ret = -EINVAL;
3294 goto exit;
3295 }
3296
3297 /* if the target bssid is same as currently associated AP,
3298 then no need to proceed with reassoc */
3299 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3300 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3301 {
3302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3303 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3304 __func__);
3305 ret = -EINVAL;
3306 goto exit;
3307 }
3308
3309 /* Proceed with scan/roam */
3310 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3311 &targetApBssid[0],
3312 (tSmeFastRoamTrigger)(trigger));
3313 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003314#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003315#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003316 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3317 {
3318 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003319 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003320
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003321 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003322 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003323 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003324 hdd_is_okc_mode_enabled(pHddCtx) &&
3325 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3326 {
3327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003328 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003329 " hence this operation is not permitted!", __func__);
3330 ret = -EPERM;
3331 goto exit;
3332 }
3333
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003334 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3335 value = value + 11;
3336 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003337 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003338 if (ret < 0)
3339 {
3340 /* If the input value is greater than max value of datatype, then also
3341 kstrtou8 fails */
3342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3343 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003344 CFG_ESE_FEATURE_ENABLED_MIN,
3345 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003346 ret = -EINVAL;
3347 goto exit;
3348 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003349 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3350 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003351 {
3352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003353 "Ese mode value %d is out of range"
3354 " (Min: %d Max: %d)", eseMode,
3355 CFG_ESE_FEATURE_ENABLED_MIN,
3356 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003357 ret = -EINVAL;
3358 goto exit;
3359 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003361 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003362
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003363 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3364 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003365 }
3366#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003367 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3368 {
3369 tANI_U8 *value = command;
3370 tANI_BOOLEAN roamScanControl = 0;
3371
3372 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3373 value = value + 19;
3374 /* Convert the value from ascii to integer */
3375 ret = kstrtou8(value, 10, &roamScanControl);
3376 if (ret < 0)
3377 {
3378 /* If the input value is greater than max value of datatype, then also
3379 kstrtou8 fails */
3380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3381 "%s: kstrtou8 failed ", __func__);
3382 ret = -EINVAL;
3383 goto exit;
3384 }
3385
3386 if (0 != roamScanControl)
3387 {
3388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3389 "roam scan control invalid value = %d",
3390 roamScanControl);
3391 ret = -EINVAL;
3392 goto exit;
3393 }
3394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3395 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3396
3397 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3398 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003399#ifdef FEATURE_WLAN_OKC
3400 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3401 {
3402 tANI_U8 *value = command;
3403 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3404
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003405 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003406 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003407 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003408 hdd_is_okc_mode_enabled(pHddCtx) &&
3409 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3410 {
3411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003412 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003413 " hence this operation is not permitted!", __func__);
3414 ret = -EPERM;
3415 goto exit;
3416 }
3417
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003418 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3419 value = value + 11;
3420 /* Convert the value from ascii to integer */
3421 ret = kstrtou8(value, 10, &okcMode);
3422 if (ret < 0)
3423 {
3424 /* If the input value is greater than max value of datatype, then also
3425 kstrtou8 fails */
3426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3427 "%s: kstrtou8 failed range [%d - %d]", __func__,
3428 CFG_OKC_FEATURE_ENABLED_MIN,
3429 CFG_OKC_FEATURE_ENABLED_MAX);
3430 ret = -EINVAL;
3431 goto exit;
3432 }
3433
3434 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3435 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3436 {
3437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3438 "Okc mode value %d is out of range"
3439 " (Min: %d Max: %d)", okcMode,
3440 CFG_OKC_FEATURE_ENABLED_MIN,
3441 CFG_OKC_FEATURE_ENABLED_MAX);
3442 ret = -EINVAL;
3443 goto exit;
3444 }
3445
3446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3447 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3448
3449 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3450 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003451#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003452 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3453 {
3454 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3455 char extra[32];
3456 tANI_U8 len = 0;
3457
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003458 len = scnprintf(extra, sizeof(extra), "%s %d",
3459 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003460 if (copy_to_user(priv_data.buf, &extra, len + 1))
3461 {
3462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3463 "%s: failed to copy data to user buffer", __func__);
3464 ret = -EFAULT;
3465 goto exit;
3466 }
3467 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303468#ifdef WLAN_FEATURE_PACKET_FILTERING
3469 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3470 {
3471 tANI_U8 filterType = 0;
3472 tANI_U8 *value = command;
3473
3474 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3475 value = value + 22;
3476
3477 /* Convert the value from ascii to integer */
3478 ret = kstrtou8(value, 10, &filterType);
3479 if (ret < 0)
3480 {
3481 /* If the input value is greater than max value of datatype,
3482 * then also kstrtou8 fails
3483 */
3484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3485 "%s: kstrtou8 failed range ", __func__);
3486 ret = -EINVAL;
3487 goto exit;
3488 }
3489
3490 if (filterType != 0 && filterType != 1)
3491 {
3492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3493 "%s: Accepted Values are 0 and 1 ", __func__);
3494 ret = -EINVAL;
3495 goto exit;
3496 }
3497 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3498 pAdapter->sessionId);
3499 }
3500#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303501 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3502 {
3503 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303504 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303505 if ('1' == *dhcpPhase)
3506 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303508 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303509
3510 pHddCtx->btCoexModeSet = TRUE;
3511
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303512 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303513 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303514 }
3515 else if ('2' == *dhcpPhase)
3516 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303518 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303519
3520 pHddCtx->btCoexModeSet = FALSE;
3521
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303522 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303523 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303524 }
3525 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003526 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3527 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3529 FL("making default scan to ACTIVE"));
3530 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003531 }
3532 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3533 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3535 FL("making default scan to PASSIVE"));
3536 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003537 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303538 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3539 {
3540 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3541 char extra[32];
3542 tANI_U8 len = 0;
3543
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003544 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303545 (int)pCfg->nActiveMaxChnTime);
3546 if (copy_to_user(priv_data.buf, &extra, len + 1))
3547 {
3548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3549 "%s: failed to copy data to user buffer", __func__);
3550 ret = -EFAULT;
3551 goto exit;
3552 }
3553 ret = len;
3554 }
3555 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3556 {
3557 tANI_U8 *value = command;
3558 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3559 int val = 0, temp;
3560
3561 value = value + 13;
3562 temp = kstrtou32(value, 10, &val);
3563 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3564 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3565 {
3566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3567 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3568 ret = -EFAULT;
3569 goto exit;
3570 }
3571 pCfg->nActiveMaxChnTime = val;
3572 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003573 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3574 {
3575 tANI_U8 filterType = 0;
3576 tANI_U8 *value;
3577 value = command + 9;
3578
3579 /* Convert the value from ascii to integer */
3580 ret = kstrtou8(value, 10, &filterType);
3581 if (ret < 0)
3582 {
3583 /* If the input value is greater than max value of datatype,
3584 * then also kstrtou8 fails
3585 */
3586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3587 "%s: kstrtou8 failed range ", __func__);
3588 ret = -EINVAL;
3589 goto exit;
3590 }
3591 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3592 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3593 {
3594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3595 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3596 " 2-Sink ", __func__);
3597 ret = -EINVAL;
3598 goto exit;
3599 }
3600 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3601 pHddCtx->drvr_miracast = filterType;
3602 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3603 }
Leo Chang614d2072013-08-22 14:59:44 -07003604 else if (strncmp(command, "SETMCRATE", 9) == 0)
3605 {
Leo Chang614d2072013-08-22 14:59:44 -07003606 tANI_U8 *value = command;
3607 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003608 tSirRateUpdateInd *rateUpdate;
3609 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003610
3611 /* Only valid for SAP mode */
3612 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3613 {
3614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3615 "%s: SAP mode is not running", __func__);
3616 ret = -EFAULT;
3617 goto exit;
3618 }
3619
3620 /* Move pointer to ahead of SETMCRATE<delimiter> */
3621 /* input value is in units of hundred kbps */
3622 value = value + 10;
3623 /* Convert the value from ascii to integer, decimal base */
3624 ret = kstrtouint(value, 10, &targetRate);
3625
Leo Chang1f98cbd2013-10-17 15:03:52 -07003626 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3627 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003628 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003629 hddLog(VOS_TRACE_LEVEL_ERROR,
3630 "%s: SETMCRATE indication alloc fail", __func__);
3631 ret = -EFAULT;
3632 goto exit;
3633 }
3634 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3635
3636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3637 "MC Target rate %d", targetRate);
3638 /* Ignore unicast */
3639 rateUpdate->ucastDataRate = -1;
3640 rateUpdate->mcastDataRate24GHz = targetRate;
3641 rateUpdate->mcastDataRate5GHz = targetRate;
3642 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3643 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3644 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3645 if (eHAL_STATUS_SUCCESS != status)
3646 {
3647 hddLog(VOS_TRACE_LEVEL_ERROR,
3648 "%s: SET_MC_RATE failed", __func__);
3649 vos_mem_free(rateUpdate);
3650 ret = -EFAULT;
3651 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003652 }
3653 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303654#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003655 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303656 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003657 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303658 }
3659#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003660#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003661 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3662 {
3663 tANI_U8 *value = command;
3664 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3665 tANI_U8 numChannels = 0;
3666 eHalStatus status = eHAL_STATUS_SUCCESS;
3667
3668 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3669 if (eHAL_STATUS_SUCCESS != status)
3670 {
3671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3672 "%s: Failed to parse channel list information", __func__);
3673 ret = -EINVAL;
3674 goto exit;
3675 }
3676
3677 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3678 {
3679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3680 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3681 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3682 ret = -EINVAL;
3683 goto exit;
3684 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003685 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003686 ChannelList,
3687 numChannels);
3688 if (eHAL_STATUS_SUCCESS != status)
3689 {
3690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3691 "%s: Failed to update channel list information", __func__);
3692 ret = -EINVAL;
3693 goto exit;
3694 }
3695 }
3696 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3697 {
3698 tANI_U8 *value = command;
3699 char extra[128] = {0};
3700 int len = 0;
3701 tANI_U8 tid = 0;
3702 hdd_station_ctx_t *pHddStaCtx = NULL;
3703 tAniTrafStrmMetrics tsmMetrics;
3704 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3705
3706 /* if not associated, return error */
3707 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3708 {
3709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3710 ret = -EINVAL;
3711 goto exit;
3712 }
3713
3714 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3715 value = value + 12;
3716 /* Convert the value from ascii to integer */
3717 ret = kstrtou8(value, 10, &tid);
3718 if (ret < 0)
3719 {
3720 /* If the input value is greater than max value of datatype, then also
3721 kstrtou8 fails */
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3723 "%s: kstrtou8 failed range [%d - %d]", __func__,
3724 TID_MIN_VALUE,
3725 TID_MAX_VALUE);
3726 ret = -EINVAL;
3727 goto exit;
3728 }
3729
3730 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3731 {
3732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3733 "tid value %d is out of range"
3734 " (Min: %d Max: %d)", tid,
3735 TID_MIN_VALUE,
3736 TID_MAX_VALUE);
3737 ret = -EINVAL;
3738 goto exit;
3739 }
3740
3741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3742 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3743
3744 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3745 {
3746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3747 "%s: failed to get tsm stats", __func__);
3748 ret = -EFAULT;
3749 goto exit;
3750 }
3751
3752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3753 "UplinkPktQueueDly(%d)\n"
3754 "UplinkPktQueueDlyHist[0](%d)\n"
3755 "UplinkPktQueueDlyHist[1](%d)\n"
3756 "UplinkPktQueueDlyHist[2](%d)\n"
3757 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303758 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003759 "UplinkPktLoss(%d)\n"
3760 "UplinkPktCount(%d)\n"
3761 "RoamingCount(%d)\n"
3762 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3763 tsmMetrics.UplinkPktQueueDlyHist[0],
3764 tsmMetrics.UplinkPktQueueDlyHist[1],
3765 tsmMetrics.UplinkPktQueueDlyHist[2],
3766 tsmMetrics.UplinkPktQueueDlyHist[3],
3767 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3768 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3769
3770 /* Output TSM stats is of the format
3771 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3772 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003773 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003774 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3775 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3776 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3777 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3778 tsmMetrics.RoamingDly);
3779
3780 if (copy_to_user(priv_data.buf, &extra, len + 1))
3781 {
3782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3783 "%s: failed to copy data to user buffer", __func__);
3784 ret = -EFAULT;
3785 goto exit;
3786 }
3787 }
3788 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3789 {
3790 tANI_U8 *value = command;
3791 tANI_U8 *cckmIe = NULL;
3792 tANI_U8 cckmIeLen = 0;
3793 eHalStatus status = eHAL_STATUS_SUCCESS;
3794
3795 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3796 if (eHAL_STATUS_SUCCESS != status)
3797 {
3798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3799 "%s: Failed to parse cckm ie data", __func__);
3800 ret = -EINVAL;
3801 goto exit;
3802 }
3803
3804 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3805 {
3806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3807 "%s: CCKM Ie input length is more than max[%d]", __func__,
3808 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003809 vos_mem_free(cckmIe);
3810 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003811 ret = -EINVAL;
3812 goto exit;
3813 }
3814 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003815 vos_mem_free(cckmIe);
3816 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003817 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003818 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3819 {
3820 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003821 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003822 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003823 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003824 if (eHAL_STATUS_SUCCESS != status)
3825 {
3826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003827 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003828 ret = -EINVAL;
3829 goto exit;
3830 }
3831
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003832 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3833 if (eHAL_STATUS_SUCCESS != status)
3834 {
3835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3836 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3837 ret = -EINVAL;
3838 goto exit;
3839 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003840 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003841#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05303842 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
3843 {
3844 eHalStatus status;
3845 char buf[32], len;
3846 long waitRet;
3847 bcnMissRateContext_t getBcnMissRateCtx;
3848
3849 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3850
3851 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3852 {
3853 hddLog(VOS_TRACE_LEVEL_WARN,
3854 FL("GETBCNMISSRATE: STA is not in connected state"));
3855 ret = -1;
3856 goto exit;
3857 }
3858
3859 init_completion(&(getBcnMissRateCtx.completion));
3860 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
3861
3862 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
3863 pAdapter->sessionId,
3864 (void *)getBcnMissRateCB,
3865 (void *)(&getBcnMissRateCtx));
3866 if( eHAL_STATUS_SUCCESS != status)
3867 {
3868 hddLog(VOS_TRACE_LEVEL_INFO,
3869 FL("GETBCNMISSRATE: fail to post WDA cmd"));
3870 ret = -EINVAL;
3871 goto exit;
3872 }
3873
3874 waitRet = wait_for_completion_interruptible_timeout
3875 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
3876 if(waitRet <= 0)
3877 {
3878 hddLog(VOS_TRACE_LEVEL_ERROR,
3879 FL("failed to wait on bcnMissRateComp %d"), ret);
3880
3881 //Make magic number to zero so that callback is not called.
3882 spin_lock(&hdd_context_lock);
3883 getBcnMissRateCtx.magic = 0x0;
3884 spin_unlock(&hdd_context_lock);
3885 ret = -EINVAL;
3886 goto exit;
3887 }
3888
3889 hddLog(VOS_TRACE_LEVEL_INFO,
3890 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
3891
3892 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
3893 if (copy_to_user(priv_data.buf, &buf, len + 1))
3894 {
3895 hddLog(VOS_TRACE_LEVEL_ERROR,
3896 "%s: failed to copy data to user buffer", __func__);
3897 ret = -EFAULT;
3898 goto exit;
3899 }
3900 ret = len;
3901 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003902 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303903 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3904 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
3905 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003906 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3907 __func__, command);
3908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003909 }
3910exit:
3911 if (command)
3912 {
3913 kfree(command);
3914 }
3915 return ret;
3916}
3917
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003918#ifdef CONFIG_COMPAT
3919static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3920{
3921 struct {
3922 compat_uptr_t buf;
3923 int used_len;
3924 int total_len;
3925 } compat_priv_data;
3926 hdd_priv_data_t priv_data;
3927 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003928
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003929 /*
3930 * Note that pAdapter and ifr have already been verified by caller,
3931 * and HDD context has also been validated
3932 */
3933 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
3934 sizeof(compat_priv_data))) {
3935 ret = -EFAULT;
3936 goto exit;
3937 }
3938 priv_data.buf = compat_ptr(compat_priv_data.buf);
3939 priv_data.used_len = compat_priv_data.used_len;
3940 priv_data.total_len = compat_priv_data.total_len;
3941 ret = hdd_driver_command(pAdapter, &priv_data);
3942 exit:
3943 return ret;
3944}
3945#else /* CONFIG_COMPAT */
3946static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3947{
3948 /* will never be invoked */
3949 return 0;
3950}
3951#endif /* CONFIG_COMPAT */
3952
3953static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3954{
3955 hdd_priv_data_t priv_data;
3956 int ret = 0;
3957
3958 /*
3959 * Note that pAdapter and ifr have already been verified by caller,
3960 * and HDD context has also been validated
3961 */
3962 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
3963 ret = -EFAULT;
3964 } else {
3965 ret = hdd_driver_command(pAdapter, &priv_data);
3966 }
3967 return ret;
3968}
3969
3970int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
3971{
3972 hdd_adapter_t *pAdapter;
3973 hdd_context_t *pHddCtx;
3974 int ret;
3975
3976 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3977 if (NULL == pAdapter) {
3978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3979 "%s: HDD adapter context is Null", __func__);
3980 ret = -ENODEV;
3981 goto exit;
3982 }
3983 if (dev != pAdapter->dev) {
3984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3985 "%s: HDD adapter/dev inconsistency", __func__);
3986 ret = -ENODEV;
3987 goto exit;
3988 }
3989
3990 if ((!ifr) || (!ifr->ifr_data)) {
3991 ret = -EINVAL;
3992 goto exit;
3993 }
3994
3995 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3996 ret = wlan_hdd_validate_context(pHddCtx);
3997 if (ret) {
3998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3999 "%s: invalid context", __func__);
4000 ret = -EBUSY;
4001 goto exit;
4002 }
4003
4004 switch (cmd) {
4005 case (SIOCDEVPRIVATE + 1):
4006 if (is_compat_task())
4007 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4008 else
4009 ret = hdd_driver_ioctl(pAdapter, ifr);
4010 break;
4011 default:
4012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4013 __func__, cmd);
4014 ret = -EINVAL;
4015 break;
4016 }
4017 exit:
4018 return ret;
4019}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004020
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004021#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004022/**---------------------------------------------------------------------------
4023
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004024 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004025
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004026 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004027 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4028 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4029 <space>Scan Mode N<space>Meas Duration N
4030 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4031 then take N.
4032 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4033 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4034 This function does not take care of removing duplicate channels from the list
4035
4036 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004037 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004038
4039 \return - 0 for success non-zero for failure
4040
4041 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004042static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4043 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004044{
4045 tANI_U8 *inPtr = pValue;
4046 int tempInt = 0;
4047 int j = 0, i = 0, v = 0;
4048 char buf[32];
4049
4050 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4051 /*no argument after the command*/
4052 if (NULL == inPtr)
4053 {
4054 return -EINVAL;
4055 }
4056 /*no space after the command*/
4057 else if (SPACE_ASCII_VALUE != *inPtr)
4058 {
4059 return -EINVAL;
4060 }
4061
4062 /*removing empty spaces*/
4063 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4064
4065 /*no argument followed by spaces*/
4066 if ('\0' == *inPtr) return -EINVAL;
4067
4068 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004069 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004070 if (1 != v) return -EINVAL;
4071
4072 v = kstrtos32(buf, 10, &tempInt);
4073 if ( v < 0) return -EINVAL;
4074
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004075 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004076
4077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004078 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004079
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004080 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004081 {
4082 for (i = 0; i < 4; i++)
4083 {
4084 /*inPtr pointing to the beginning of first space after number of ie fields*/
4085 inPtr = strpbrk( inPtr, " " );
4086 /*no ie data after the number of ie fields argument*/
4087 if (NULL == inPtr) return -EINVAL;
4088
4089 /*removing empty space*/
4090 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4091
4092 /*no ie data after the number of ie fields argument and spaces*/
4093 if ( '\0' == *inPtr ) return -EINVAL;
4094
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004095 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004096 if (1 != v) return -EINVAL;
4097
4098 v = kstrtos32(buf, 10, &tempInt);
4099 if (v < 0) return -EINVAL;
4100
4101 switch (i)
4102 {
4103 case 0: /* Measurement token */
4104 if (tempInt <= 0)
4105 {
4106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4107 "Invalid Measurement Token(%d)", tempInt);
4108 return -EINVAL;
4109 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004110 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004111 break;
4112
4113 case 1: /* Channel number */
4114 if ((tempInt <= 0) ||
4115 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4116 {
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4118 "Invalid Channel Number(%d)", tempInt);
4119 return -EINVAL;
4120 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004121 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004122 break;
4123
4124 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004125 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004126 {
4127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4128 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4129 return -EINVAL;
4130 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004131 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004132 break;
4133
4134 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004135 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4136 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004137 {
4138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4139 "Invalid Measurement Duration(%d)", tempInt);
4140 return -EINVAL;
4141 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004142 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004143 break;
4144 }
4145 }
4146 }
4147
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004148 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004149 {
4150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304151 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004152 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004153 pEseBcnReq->bcnReq[j].measurementToken,
4154 pEseBcnReq->bcnReq[j].channel,
4155 pEseBcnReq->bcnReq[j].scanMode,
4156 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004157 }
4158
4159 return VOS_STATUS_SUCCESS;
4160}
4161
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004162static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4163{
4164 struct statsContext *pStatsContext = NULL;
4165 hdd_adapter_t *pAdapter = NULL;
4166
4167 if (NULL == pContext)
4168 {
4169 hddLog(VOS_TRACE_LEVEL_ERROR,
4170 "%s: Bad param, pContext [%p]",
4171 __func__, pContext);
4172 return;
4173 }
4174
Jeff Johnson72a40512013-12-19 10:14:15 -08004175 /* there is a race condition that exists between this callback
4176 function and the caller since the caller could time out either
4177 before or while this code is executing. we use a spinlock to
4178 serialize these actions */
4179 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004180
4181 pStatsContext = pContext;
4182 pAdapter = pStatsContext->pAdapter;
4183 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4184 {
4185 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004186 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004187 hddLog(VOS_TRACE_LEVEL_WARN,
4188 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4189 __func__, pAdapter, pStatsContext->magic);
4190 return;
4191 }
4192
Jeff Johnson72a40512013-12-19 10:14:15 -08004193 /* context is valid so caller is still waiting */
4194
4195 /* paranoia: invalidate the magic */
4196 pStatsContext->magic = 0;
4197
4198 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004199 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4200 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4201 tsmMetrics.UplinkPktQueueDlyHist,
4202 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4203 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4204 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4205 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4206 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4207 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4208 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4209
Jeff Johnson72a40512013-12-19 10:14:15 -08004210 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004211 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004212
4213 /* serialization is complete */
4214 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004215}
4216
4217
4218
4219static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4220 tAniTrafStrmMetrics* pTsmMetrics)
4221{
4222 hdd_station_ctx_t *pHddStaCtx = NULL;
4223 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004224 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004225 long lrc;
4226 struct statsContext context;
4227 hdd_context_t *pHddCtx = NULL;
4228
4229 if (NULL == pAdapter)
4230 {
4231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4232 return VOS_STATUS_E_FAULT;
4233 }
4234
4235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4236 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4237
4238 /* we are connected prepare our callback context */
4239 init_completion(&context.completion);
4240 context.pAdapter = pAdapter;
4241 context.magic = STATS_CONTEXT_MAGIC;
4242
4243 /* query tsm stats */
4244 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4245 pHddStaCtx->conn_info.staId[ 0 ],
4246 pHddStaCtx->conn_info.bssId,
4247 &context, pHddCtx->pvosContext, tid);
4248
4249 if (eHAL_STATUS_SUCCESS != hstatus)
4250 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4252 __func__);
4253 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004254 }
4255 else
4256 {
4257 /* request was sent -- wait for the response */
4258 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4259 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004260 if (lrc <= 0)
4261 {
4262 hddLog(VOS_TRACE_LEVEL_ERROR,
4263 "%s: SME %s while retrieving statistics",
4264 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004265 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004266 }
4267 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004268
Jeff Johnson72a40512013-12-19 10:14:15 -08004269 /* either we never sent a request, we sent a request and received a
4270 response or we sent a request and timed out. if we never sent a
4271 request or if we sent a request and got a response, we want to
4272 clear the magic out of paranoia. if we timed out there is a
4273 race condition such that the callback function could be
4274 executing at the same time we are. of primary concern is if the
4275 callback function had already verified the "magic" but had not
4276 yet set the completion variable when a timeout occurred. we
4277 serialize these activities by invalidating the magic while
4278 holding a shared spinlock which will cause us to block if the
4279 callback is currently executing */
4280 spin_lock(&hdd_context_lock);
4281 context.magic = 0;
4282 spin_unlock(&hdd_context_lock);
4283
4284 if (VOS_STATUS_SUCCESS == vstatus)
4285 {
4286 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4287 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4288 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4289 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4290 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4291 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4292 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4293 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4294 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4295 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4296 }
4297 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004298}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004299#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004300
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004301#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004302void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4303{
4304 eCsrBand band = -1;
4305 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4306 switch (band)
4307 {
4308 case eCSR_BAND_ALL:
4309 *pBand = WLAN_HDD_UI_BAND_AUTO;
4310 break;
4311
4312 case eCSR_BAND_24:
4313 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4314 break;
4315
4316 case eCSR_BAND_5G:
4317 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4318 break;
4319
4320 default:
4321 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4322 *pBand = -1;
4323 break;
4324 }
4325}
4326
4327/**---------------------------------------------------------------------------
4328
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004329 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4330
4331 This function parses the send action frame data passed in the format
4332 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4333
Srinivas Girigowda56076852013-08-20 14:00:50 -07004334 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004335 \param - pTargetApBssid Pointer to target Ap bssid
4336 \param - pChannel Pointer to the Target AP channel
4337 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4338 \param - pBuf Pointer to data
4339 \param - pBufLen Pointer to data length
4340
4341 \return - 0 for success non-zero for failure
4342
4343 --------------------------------------------------------------------------*/
4344VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4345 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4346{
4347 tANI_U8 *inPtr = pValue;
4348 tANI_U8 *dataEnd;
4349 int tempInt;
4350 int j = 0;
4351 int i = 0;
4352 int v = 0;
4353 tANI_U8 tempBuf[32];
4354 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004355 /* 12 hexa decimal digits, 5 ':' and '\0' */
4356 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004357
4358 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4359 /*no argument after the command*/
4360 if (NULL == inPtr)
4361 {
4362 return -EINVAL;
4363 }
4364
4365 /*no space after the command*/
4366 else if (SPACE_ASCII_VALUE != *inPtr)
4367 {
4368 return -EINVAL;
4369 }
4370
4371 /*removing empty spaces*/
4372 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4373
4374 /*no argument followed by spaces*/
4375 if ('\0' == *inPtr)
4376 {
4377 return -EINVAL;
4378 }
4379
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004380 v = sscanf(inPtr, "%17s", macAddress);
4381 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004382 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4384 "Invalid MAC address or All hex inputs are not read (%d)", v);
4385 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004386 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004387
4388 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4389 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4390 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4391 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4392 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4393 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004394
4395 /* point to the next argument */
4396 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4397 /*no argument after the command*/
4398 if (NULL == inPtr) return -EINVAL;
4399
4400 /*removing empty spaces*/
4401 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4402
4403 /*no argument followed by spaces*/
4404 if ('\0' == *inPtr)
4405 {
4406 return -EINVAL;
4407 }
4408
4409 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004410 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004411 if (1 != v) return -EINVAL;
4412
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004413 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304414 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304415 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004416
4417 *pChannel = tempInt;
4418
4419 /* point to the next argument */
4420 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4421 /*no argument after the command*/
4422 if (NULL == inPtr) return -EINVAL;
4423 /*removing empty spaces*/
4424 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4425
4426 /*no argument followed by spaces*/
4427 if ('\0' == *inPtr)
4428 {
4429 return -EINVAL;
4430 }
4431
4432 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004433 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004434 if (1 != v) return -EINVAL;
4435
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004436 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004437 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004438
4439 *pDwellTime = tempInt;
4440
4441 /* point to the next argument */
4442 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4443 /*no argument after the command*/
4444 if (NULL == inPtr) return -EINVAL;
4445 /*removing empty spaces*/
4446 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4447
4448 /*no argument followed by spaces*/
4449 if ('\0' == *inPtr)
4450 {
4451 return -EINVAL;
4452 }
4453
4454 /* find the length of data */
4455 dataEnd = inPtr;
4456 while(('\0' != *dataEnd) )
4457 {
4458 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004459 }
Kiet Lambe150c22013-11-21 16:30:32 +05304460 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004461 if ( *pBufLen <= 0) return -EINVAL;
4462
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004463 /* Allocate the number of bytes based on the number of input characters
4464 whether it is even or odd.
4465 if the number of input characters are even, then we need N/2 byte.
4466 if the number of input characters are odd, then we need do (N+1)/2 to
4467 compensate rounding off.
4468 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4469 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4470 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004471 if (NULL == *pBuf)
4472 {
4473 hddLog(VOS_TRACE_LEVEL_FATAL,
4474 "%s: vos_mem_alloc failed ", __func__);
4475 return -EINVAL;
4476 }
4477
4478 /* the buffer received from the upper layer is character buffer,
4479 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4480 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4481 and f0 in 3rd location */
4482 for (i = 0, j = 0; j < *pBufLen; j += 2)
4483 {
Kiet Lambe150c22013-11-21 16:30:32 +05304484 if( j+1 == *pBufLen)
4485 {
4486 tempByte = hdd_parse_hex(inPtr[j]);
4487 }
4488 else
4489 {
4490 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4491 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004492 (*pBuf)[i++] = tempByte;
4493 }
4494 *pBufLen = i;
4495 return VOS_STATUS_SUCCESS;
4496}
4497
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004498/**---------------------------------------------------------------------------
4499
Srinivas Girigowdade697412013-02-14 16:31:48 -08004500 \brief hdd_parse_channellist() - HDD Parse channel list
4501
4502 This function parses the channel list passed in the format
4503 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004504 if the Number of channels (N) does not match with the actual number of channels passed
4505 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4506 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4507 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4508 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004509
4510 \param - pValue Pointer to input channel list
4511 \param - ChannelList Pointer to local output array to record channel list
4512 \param - pNumChannels Pointer to number of roam scan channels
4513
4514 \return - 0 for success non-zero for failure
4515
4516 --------------------------------------------------------------------------*/
4517VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4518{
4519 tANI_U8 *inPtr = pValue;
4520 int tempInt;
4521 int j = 0;
4522 int v = 0;
4523 char buf[32];
4524
4525 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4526 /*no argument after the command*/
4527 if (NULL == inPtr)
4528 {
4529 return -EINVAL;
4530 }
4531
4532 /*no space after the command*/
4533 else if (SPACE_ASCII_VALUE != *inPtr)
4534 {
4535 return -EINVAL;
4536 }
4537
4538 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004539 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004540
4541 /*no argument followed by spaces*/
4542 if ('\0' == *inPtr)
4543 {
4544 return -EINVAL;
4545 }
4546
4547 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004548 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004549 if (1 != v) return -EINVAL;
4550
Srinivas Girigowdade697412013-02-14 16:31:48 -08004551 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004552 if ((v < 0) ||
4553 (tempInt <= 0) ||
4554 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4555 {
4556 return -EINVAL;
4557 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004558
4559 *pNumChannels = tempInt;
4560
4561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4562 "Number of channels are: %d", *pNumChannels);
4563
4564 for (j = 0; j < (*pNumChannels); j++)
4565 {
4566 /*inPtr pointing to the beginning of first space after number of channels*/
4567 inPtr = strpbrk( inPtr, " " );
4568 /*no channel list after the number of channels argument*/
4569 if (NULL == inPtr)
4570 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004571 if (0 != j)
4572 {
4573 *pNumChannels = j;
4574 return VOS_STATUS_SUCCESS;
4575 }
4576 else
4577 {
4578 return -EINVAL;
4579 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004580 }
4581
4582 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004583 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004584
4585 /*no channel list after the number of channels argument and spaces*/
4586 if ( '\0' == *inPtr )
4587 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004588 if (0 != j)
4589 {
4590 *pNumChannels = j;
4591 return VOS_STATUS_SUCCESS;
4592 }
4593 else
4594 {
4595 return -EINVAL;
4596 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004597 }
4598
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004599 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004600 if (1 != v) return -EINVAL;
4601
Srinivas Girigowdade697412013-02-14 16:31:48 -08004602 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004603 if ((v < 0) ||
4604 (tempInt <= 0) ||
4605 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4606 {
4607 return -EINVAL;
4608 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004609 pChannelList[j] = tempInt;
4610
4611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4612 "Channel %d added to preferred channel list",
4613 pChannelList[j] );
4614 }
4615
Srinivas Girigowdade697412013-02-14 16:31:48 -08004616 return VOS_STATUS_SUCCESS;
4617}
4618
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004619
4620/**---------------------------------------------------------------------------
4621
4622 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4623
4624 This function parses the reasoc command data passed in the format
4625 REASSOC<space><bssid><space><channel>
4626
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004627 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004628 \param - pTargetApBssid Pointer to target Ap bssid
4629 \param - pChannel Pointer to the Target AP channel
4630
4631 \return - 0 for success non-zero for failure
4632
4633 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004634VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4635 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004636{
4637 tANI_U8 *inPtr = pValue;
4638 int tempInt;
4639 int v = 0;
4640 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004641 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004642 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004643
4644 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4645 /*no argument after the command*/
4646 if (NULL == inPtr)
4647 {
4648 return -EINVAL;
4649 }
4650
4651 /*no space after the command*/
4652 else if (SPACE_ASCII_VALUE != *inPtr)
4653 {
4654 return -EINVAL;
4655 }
4656
4657 /*removing empty spaces*/
4658 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4659
4660 /*no argument followed by spaces*/
4661 if ('\0' == *inPtr)
4662 {
4663 return -EINVAL;
4664 }
4665
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004666 v = sscanf(inPtr, "%17s", macAddress);
4667 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004668 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4670 "Invalid MAC address or All hex inputs are not read (%d)", v);
4671 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004672 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004673
4674 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4675 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4676 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4677 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4678 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4679 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004680
4681 /* point to the next argument */
4682 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4683 /*no argument after the command*/
4684 if (NULL == inPtr) return -EINVAL;
4685
4686 /*removing empty spaces*/
4687 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4688
4689 /*no argument followed by spaces*/
4690 if ('\0' == *inPtr)
4691 {
4692 return -EINVAL;
4693 }
4694
4695 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004696 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004697 if (1 != v) return -EINVAL;
4698
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004699 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004700 if ((v < 0) ||
4701 (tempInt <= 0) ||
4702 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4703 {
4704 return -EINVAL;
4705 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004706
4707 *pChannel = tempInt;
4708 return VOS_STATUS_SUCCESS;
4709}
4710
4711#endif
4712
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004713#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004714/**---------------------------------------------------------------------------
4715
4716 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4717
4718 This function parses the SETCCKM IE command
4719 SETCCKMIE<space><ie data>
4720
4721 \param - pValue Pointer to input data
4722 \param - pCckmIe Pointer to output cckm Ie
4723 \param - pCckmIeLen Pointer to output cckm ie length
4724
4725 \return - 0 for success non-zero for failure
4726
4727 --------------------------------------------------------------------------*/
4728VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4729 tANI_U8 *pCckmIeLen)
4730{
4731 tANI_U8 *inPtr = pValue;
4732 tANI_U8 *dataEnd;
4733 int j = 0;
4734 int i = 0;
4735 tANI_U8 tempByte = 0;
4736
4737 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4738 /*no argument after the command*/
4739 if (NULL == inPtr)
4740 {
4741 return -EINVAL;
4742 }
4743
4744 /*no space after the command*/
4745 else if (SPACE_ASCII_VALUE != *inPtr)
4746 {
4747 return -EINVAL;
4748 }
4749
4750 /*removing empty spaces*/
4751 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4752
4753 /*no argument followed by spaces*/
4754 if ('\0' == *inPtr)
4755 {
4756 return -EINVAL;
4757 }
4758
4759 /* find the length of data */
4760 dataEnd = inPtr;
4761 while(('\0' != *dataEnd) )
4762 {
4763 dataEnd++;
4764 ++(*pCckmIeLen);
4765 }
4766 if ( *pCckmIeLen <= 0) return -EINVAL;
4767
4768 /* Allocate the number of bytes based on the number of input characters
4769 whether it is even or odd.
4770 if the number of input characters are even, then we need N/2 byte.
4771 if the number of input characters are odd, then we need do (N+1)/2 to
4772 compensate rounding off.
4773 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4774 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4775 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4776 if (NULL == *pCckmIe)
4777 {
4778 hddLog(VOS_TRACE_LEVEL_FATAL,
4779 "%s: vos_mem_alloc failed ", __func__);
4780 return -EINVAL;
4781 }
4782 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4783 /* the buffer received from the upper layer is character buffer,
4784 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4785 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4786 and f0 in 3rd location */
4787 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4788 {
4789 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4790 (*pCckmIe)[i++] = tempByte;
4791 }
4792 *pCckmIeLen = i;
4793
4794 return VOS_STATUS_SUCCESS;
4795}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004796#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004797
Jeff Johnson295189b2012-06-20 16:38:30 -07004798/**---------------------------------------------------------------------------
4799
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004800 \brief hdd_is_valid_mac_address() - Validate MAC address
4801
4802 This function validates whether the given MAC address is valid or not
4803 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4804 where X is the hexa decimal digit character and separated by ':'
4805 This algorithm works even if MAC address is not separated by ':'
4806
4807 This code checks given input string mac contains exactly 12 hexadecimal digits.
4808 and a separator colon : appears in the input string only after
4809 an even number of hex digits.
4810
4811 \param - pMacAddr pointer to the input MAC address
4812 \return - 1 for valid and 0 for invalid
4813
4814 --------------------------------------------------------------------------*/
4815
4816v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4817{
4818 int xdigit = 0;
4819 int separator = 0;
4820 while (*pMacAddr)
4821 {
4822 if (isxdigit(*pMacAddr))
4823 {
4824 xdigit++;
4825 }
4826 else if (':' == *pMacAddr)
4827 {
4828 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4829 break;
4830
4831 ++separator;
4832 }
4833 else
4834 {
4835 separator = -1;
4836 /* Invalid MAC found */
4837 return 0;
4838 }
4839 ++pMacAddr;
4840 }
4841 return (xdigit == 12 && (separator == 5 || separator == 0));
4842}
4843
4844/**---------------------------------------------------------------------------
4845
Jeff Johnson295189b2012-06-20 16:38:30 -07004846 \brief hdd_open() - HDD Open function
4847
4848 This is called in response to ifconfig up
4849
4850 \param - dev Pointer to net_device structure
4851
4852 \return - 0 for success non-zero for failure
4853
4854 --------------------------------------------------------------------------*/
4855int hdd_open (struct net_device *dev)
4856{
4857 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4858 hdd_context_t *pHddCtx;
4859 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4860 VOS_STATUS status;
4861 v_BOOL_t in_standby = TRUE;
4862
4863 if (NULL == pAdapter)
4864 {
4865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304866 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 return -ENODEV;
4868 }
4869
4870 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304871 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4872 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004873 if (NULL == pHddCtx)
4874 {
4875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004876 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004877 return -ENODEV;
4878 }
4879
4880 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4881 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4882 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004883 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4884 {
4885 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304886 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004887 in_standby = FALSE;
4888 break;
4889 }
4890 else
4891 {
4892 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4893 pAdapterNode = pNext;
4894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004895 }
4896
4897 if (TRUE == in_standby)
4898 {
4899 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4900 {
4901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4902 "wlan out of power save", __func__);
4903 return -EINVAL;
4904 }
4905 }
4906
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004907 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004908 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4909 {
4910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004911 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004912 /* Enable TX queues only when we are connected */
4913 netif_tx_start_all_queues(dev);
4914 }
4915
4916 return 0;
4917}
4918
4919int hdd_mon_open (struct net_device *dev)
4920{
4921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4922
4923 if(pAdapter == NULL) {
4924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004925 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004926 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004927 }
4928
4929 netif_start_queue(dev);
4930
4931 return 0;
4932}
4933/**---------------------------------------------------------------------------
4934
4935 \brief hdd_stop() - HDD stop function
4936
4937 This is called in response to ifconfig down
4938
4939 \param - dev Pointer to net_device structure
4940
4941 \return - 0 for success non-zero for failure
4942
4943 --------------------------------------------------------------------------*/
4944
4945int hdd_stop (struct net_device *dev)
4946{
4947 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4948 hdd_context_t *pHddCtx;
4949 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4950 VOS_STATUS status;
4951 v_BOOL_t enter_standby = TRUE;
4952
4953 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004954 if (NULL == pAdapter)
4955 {
4956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304957 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 return -ENODEV;
4959 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304960 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4961 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4963 if (NULL == pHddCtx)
4964 {
4965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004966 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004967 return -ENODEV;
4968 }
4969
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004970 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004971 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4972 netif_tx_disable(pAdapter->dev);
4973 netif_carrier_off(pAdapter->dev);
4974
4975
4976 /* SoftAP ifaces should never go in power save mode
4977 making sure same here. */
4978 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4979 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004980 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004981 )
4982 {
4983 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4985 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 EXIT();
4987 return 0;
4988 }
4989
4990 /* Find if any iface is up then
4991 if any iface is up then can't put device to sleep/ power save mode. */
4992 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4993 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4994 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004995 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4996 {
4997 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304998 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004999 enter_standby = FALSE;
5000 break;
5001 }
5002 else
5003 {
5004 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5005 pAdapterNode = pNext;
5006 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 }
5008
5009 if (TRUE == enter_standby)
5010 {
5011 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5012 "entering standby", __func__);
5013 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5014 {
5015 /*log and return success*/
5016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5017 "wlan in power save", __func__);
5018 }
5019 }
5020
5021 EXIT();
5022 return 0;
5023}
5024
5025/**---------------------------------------------------------------------------
5026
5027 \brief hdd_uninit() - HDD uninit function
5028
5029 This is called during the netdev unregister to uninitialize all data
5030associated with the device
5031
5032 \param - dev Pointer to net_device structure
5033
5034 \return - void
5035
5036 --------------------------------------------------------------------------*/
5037static void hdd_uninit (struct net_device *dev)
5038{
5039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5040
5041 ENTER();
5042
5043 do
5044 {
5045 if (NULL == pAdapter)
5046 {
5047 hddLog(VOS_TRACE_LEVEL_FATAL,
5048 "%s: NULL pAdapter", __func__);
5049 break;
5050 }
5051
5052 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5053 {
5054 hddLog(VOS_TRACE_LEVEL_FATAL,
5055 "%s: Invalid magic", __func__);
5056 break;
5057 }
5058
5059 if (NULL == pAdapter->pHddCtx)
5060 {
5061 hddLog(VOS_TRACE_LEVEL_FATAL,
5062 "%s: NULL pHddCtx", __func__);
5063 break;
5064 }
5065
5066 if (dev != pAdapter->dev)
5067 {
5068 hddLog(VOS_TRACE_LEVEL_FATAL,
5069 "%s: Invalid device reference", __func__);
5070 /* we haven't validated all cases so let this go for now */
5071 }
5072
5073 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5074
5075 /* after uninit our adapter structure will no longer be valid */
5076 pAdapter->dev = NULL;
5077 pAdapter->magic = 0;
5078 } while (0);
5079
5080 EXIT();
5081}
5082
5083/**---------------------------------------------------------------------------
5084
5085 \brief hdd_release_firmware() -
5086
5087 This function calls the release firmware API to free the firmware buffer.
5088
5089 \param - pFileName Pointer to the File Name.
5090 pCtx - Pointer to the adapter .
5091
5092
5093 \return - 0 for success, non zero for failure
5094
5095 --------------------------------------------------------------------------*/
5096
5097VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5098{
5099 VOS_STATUS status = VOS_STATUS_SUCCESS;
5100 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5101 ENTER();
5102
5103
5104 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5105
5106 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5107
5108 if(pHddCtx->fw) {
5109 release_firmware(pHddCtx->fw);
5110 pHddCtx->fw = NULL;
5111 }
5112 else
5113 status = VOS_STATUS_E_FAILURE;
5114 }
5115 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5116 if(pHddCtx->nv) {
5117 release_firmware(pHddCtx->nv);
5118 pHddCtx->nv = NULL;
5119 }
5120 else
5121 status = VOS_STATUS_E_FAILURE;
5122
5123 }
5124
5125 EXIT();
5126 return status;
5127}
5128
5129/**---------------------------------------------------------------------------
5130
5131 \brief hdd_request_firmware() -
5132
5133 This function reads the firmware file using the request firmware
5134 API and returns the the firmware data and the firmware file size.
5135
5136 \param - pfileName - Pointer to the file name.
5137 - pCtx - Pointer to the adapter .
5138 - ppfw_data - Pointer to the pointer of the firmware data.
5139 - pSize - Pointer to the file size.
5140
5141 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5142
5143 --------------------------------------------------------------------------*/
5144
5145
5146VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5147{
5148 int status;
5149 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5150 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5151 ENTER();
5152
5153 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5154
5155 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5156
5157 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5158 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5159 __func__, pfileName);
5160 retval = VOS_STATUS_E_FAILURE;
5161 }
5162
5163 else {
5164 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5165 *pSize = pHddCtx->fw->size;
5166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5167 __func__, *pSize);
5168 }
5169 }
5170 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5171
5172 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5173
5174 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5175 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5176 __func__, pfileName);
5177 retval = VOS_STATUS_E_FAILURE;
5178 }
5179
5180 else {
5181 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5182 *pSize = pHddCtx->nv->size;
5183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5184 __func__, *pSize);
5185 }
5186 }
5187
5188 EXIT();
5189 return retval;
5190}
5191/**---------------------------------------------------------------------------
5192 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5193
5194 This is the function invoked by SME to inform the result of a full power
5195 request issued by HDD
5196
5197 \param - callbackcontext - Pointer to cookie
5198 status - result of request
5199
5200 \return - None
5201
5202--------------------------------------------------------------------------*/
5203void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5204{
5205 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5206
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005207 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 if(&pHddCtx->full_pwr_comp_var)
5209 {
5210 complete(&pHddCtx->full_pwr_comp_var);
5211 }
5212}
5213
5214/**---------------------------------------------------------------------------
5215
5216 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5217
5218 This is the function invoked by SME to inform the result of BMPS
5219 request issued by HDD
5220
5221 \param - callbackcontext - Pointer to cookie
5222 status - result of request
5223
5224 \return - None
5225
5226--------------------------------------------------------------------------*/
5227void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5228{
5229
5230 struct completion *completion_var = (struct completion*) callbackContext;
5231
Arif Hussain6d2a3322013-11-17 19:50:10 -08005232 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 if(completion_var != NULL)
5234 {
5235 complete(completion_var);
5236 }
5237}
5238
5239/**---------------------------------------------------------------------------
5240
5241 \brief hdd_get_cfg_file_size() -
5242
5243 This function reads the configuration file using the request firmware
5244 API and returns the configuration file size.
5245
5246 \param - pCtx - Pointer to the adapter .
5247 - pFileName - Pointer to the file name.
5248 - pBufSize - Pointer to the buffer size.
5249
5250 \return - 0 for success, non zero for failure
5251
5252 --------------------------------------------------------------------------*/
5253
5254VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5255{
5256 int status;
5257 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5258
5259 ENTER();
5260
5261 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5262
5263 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5264 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5265 status = VOS_STATUS_E_FAILURE;
5266 }
5267 else {
5268 *pBufSize = pHddCtx->fw->size;
5269 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5270 release_firmware(pHddCtx->fw);
5271 pHddCtx->fw = NULL;
5272 }
5273
5274 EXIT();
5275 return VOS_STATUS_SUCCESS;
5276}
5277
5278/**---------------------------------------------------------------------------
5279
5280 \brief hdd_read_cfg_file() -
5281
5282 This function reads the configuration file using the request firmware
5283 API and returns the cfg data and the buffer size of the configuration file.
5284
5285 \param - pCtx - Pointer to the adapter .
5286 - pFileName - Pointer to the file name.
5287 - pBuffer - Pointer to the data buffer.
5288 - pBufSize - Pointer to the buffer size.
5289
5290 \return - 0 for success, non zero for failure
5291
5292 --------------------------------------------------------------------------*/
5293
5294VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5295 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5296{
5297 int status;
5298 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5299
5300 ENTER();
5301
5302 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5303
5304 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5305 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5306 return VOS_STATUS_E_FAILURE;
5307 }
5308 else {
5309 if(*pBufSize != pHddCtx->fw->size) {
5310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5311 "file size", __func__);
5312 release_firmware(pHddCtx->fw);
5313 pHddCtx->fw = NULL;
5314 return VOS_STATUS_E_FAILURE;
5315 }
5316 else {
5317 if(pBuffer) {
5318 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5319 }
5320 release_firmware(pHddCtx->fw);
5321 pHddCtx->fw = NULL;
5322 }
5323 }
5324
5325 EXIT();
5326
5327 return VOS_STATUS_SUCCESS;
5328}
5329
5330/**---------------------------------------------------------------------------
5331
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 \brief hdd_set_mac_address() -
5333
5334 This function sets the user specified mac address using
5335 the command ifconfig wlanX hw ether <mac adress>.
5336
5337 \param - dev - Pointer to the net device.
5338 - addr - Pointer to the sockaddr.
5339 \return - 0 for success, non zero for failure
5340
5341 --------------------------------------------------------------------------*/
5342
5343static int hdd_set_mac_address(struct net_device *dev, void *addr)
5344{
5345 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5346 struct sockaddr *psta_mac_addr = addr;
5347 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5348
5349 ENTER();
5350
5351 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5352
5353#ifdef HDD_SESSIONIZE
5354 // set the MAC address though the STA ID CFG.
5355 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5356 (v_U8_t *)&pAdapter->macAddressCurrent,
5357 sizeof( pAdapter->macAddressCurrent ),
5358 hdd_set_mac_addr_cb, VOS_FALSE );
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305359
5360 if(eHAL_STATUS_SUCCESS != halStatus)
5361 {
5362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5363 "%s: failed to set MAC address in CFG", __func__);
5364 }
5365
Jeff Johnson295189b2012-06-20 16:38:30 -07005366#endif
5367
5368 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5369
5370 EXIT();
5371 return halStatus;
5372}
5373
5374tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5375{
5376 int i;
5377 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5378 {
Abhishek Singheb183782014-02-06 13:37:21 +05305379 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 break;
5381 }
5382
5383 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5384 return NULL;
5385
5386 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5387 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5388}
5389
5390void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5391{
5392 int i;
5393 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5394 {
5395 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5396 {
5397 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5398 break;
5399 }
5400 }
5401 return;
5402}
5403
5404#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5405 static struct net_device_ops wlan_drv_ops = {
5406 .ndo_open = hdd_open,
5407 .ndo_stop = hdd_stop,
5408 .ndo_uninit = hdd_uninit,
5409 .ndo_start_xmit = hdd_hard_start_xmit,
5410 .ndo_tx_timeout = hdd_tx_timeout,
5411 .ndo_get_stats = hdd_stats,
5412 .ndo_do_ioctl = hdd_ioctl,
5413 .ndo_set_mac_address = hdd_set_mac_address,
5414 .ndo_select_queue = hdd_select_queue,
5415#ifdef WLAN_FEATURE_PACKET_FILTERING
5416#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5417 .ndo_set_rx_mode = hdd_set_multicast_list,
5418#else
5419 .ndo_set_multicast_list = hdd_set_multicast_list,
5420#endif //LINUX_VERSION_CODE
5421#endif
5422 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 static struct net_device_ops wlan_mon_drv_ops = {
5424 .ndo_open = hdd_mon_open,
5425 .ndo_stop = hdd_stop,
5426 .ndo_uninit = hdd_uninit,
5427 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5428 .ndo_tx_timeout = hdd_tx_timeout,
5429 .ndo_get_stats = hdd_stats,
5430 .ndo_do_ioctl = hdd_ioctl,
5431 .ndo_set_mac_address = hdd_set_mac_address,
5432 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005433
5434#endif
5435
5436void hdd_set_station_ops( struct net_device *pWlanDev )
5437{
5438#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 pWlanDev->netdev_ops = &wlan_drv_ops;
5440#else
5441 pWlanDev->open = hdd_open;
5442 pWlanDev->stop = hdd_stop;
5443 pWlanDev->uninit = hdd_uninit;
5444 pWlanDev->hard_start_xmit = NULL;
5445 pWlanDev->tx_timeout = hdd_tx_timeout;
5446 pWlanDev->get_stats = hdd_stats;
5447 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 pWlanDev->set_mac_address = hdd_set_mac_address;
5449#endif
5450}
5451
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005452static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005453{
5454 struct net_device *pWlanDev = NULL;
5455 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 /*
5457 * cfg80211 initialization and registration....
5458 */
5459 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5460
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 if(pWlanDev != NULL)
5462 {
5463
5464 //Save the pointer to the net_device in the HDD adapter
5465 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5466
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5468
5469 pAdapter->dev = pWlanDev;
5470 pAdapter->pHddCtx = pHddCtx;
5471 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5472
5473 init_completion(&pAdapter->session_open_comp_var);
5474 init_completion(&pAdapter->session_close_comp_var);
5475 init_completion(&pAdapter->disconnect_comp_var);
5476 init_completion(&pAdapter->linkup_event_var);
5477 init_completion(&pAdapter->cancel_rem_on_chan_var);
5478 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305479 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005480#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5481 init_completion(&pAdapter->offchannel_tx_event);
5482#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005484#ifdef FEATURE_WLAN_TDLS
5485 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005486 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005487 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305488 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005489#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 init_completion(&pHddCtx->mc_sus_event_var);
5491 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305492 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005493 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005494 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005495
Rajeev79dbe4c2013-10-05 11:03:42 +05305496#ifdef FEATURE_WLAN_BATCH_SCAN
5497 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5498 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5499 pAdapter->pBatchScanRsp = NULL;
5500 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005501 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005502 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305503 mutex_init(&pAdapter->hdd_batch_scan_lock);
5504#endif
5505
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 pAdapter->isLinkUpSvcNeeded = FALSE;
5507 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5508 //Init the net_device structure
5509 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5510
5511 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5512 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5513 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5514 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5515
5516 hdd_set_station_ops( pAdapter->dev );
5517
5518 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5520 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5521 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 /* set pWlanDev's parent to underlying device */
5523 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5524 }
5525
5526 return pAdapter;
5527}
5528
5529VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5530{
5531 struct net_device *pWlanDev = pAdapter->dev;
5532 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5533 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5534 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5535
5536 if( rtnl_lock_held )
5537 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005538 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5540 {
5541 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5542 return VOS_STATUS_E_FAILURE;
5543 }
5544 }
5545 if (register_netdevice(pWlanDev))
5546 {
5547 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5548 return VOS_STATUS_E_FAILURE;
5549 }
5550 }
5551 else
5552 {
5553 if(register_netdev(pWlanDev))
5554 {
5555 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5556 return VOS_STATUS_E_FAILURE;
5557 }
5558 }
5559 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5560
5561 return VOS_STATUS_SUCCESS;
5562}
5563
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005564static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005565{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005566 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005567
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005568 if (NULL == pAdapter)
5569 {
5570 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5571 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005573
5574 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5575 {
5576 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5577 return eHAL_STATUS_NOT_INITIALIZED;
5578 }
5579
5580 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5581
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005582#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005583 /* need to make sure all of our scheduled work has completed.
5584 * This callback is called from MC thread context, so it is safe to
5585 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005586 *
5587 * Even though this is called from MC thread context, if there is a faulty
5588 * work item in the system, that can hang this call forever. So flushing
5589 * this global work queue is not safe; and now we make sure that
5590 * individual work queues are stopped correctly. But the cancel work queue
5591 * is a GPL only API, so the proprietary version of the driver would still
5592 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005593 */
5594 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005595#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005596
5597 /* We can be blocked while waiting for scheduled work to be
5598 * flushed, and the adapter structure can potentially be freed, in
5599 * which case the magic will have been reset. So make sure the
5600 * magic is still good, and hence the adapter structure is still
5601 * valid, before signaling completion */
5602 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5603 {
5604 complete(&pAdapter->session_close_comp_var);
5605 }
5606
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 return eHAL_STATUS_SUCCESS;
5608}
5609
5610VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5611{
5612 struct net_device *pWlanDev = pAdapter->dev;
5613 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5614 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5615 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5616 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305617 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005618
5619 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005620 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 //Open a SME session for future operation
5622 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005623 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5625 {
5626 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005627 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 halStatus, halStatus );
5629 status = VOS_STATUS_E_FAILURE;
5630 goto error_sme_open;
5631 }
5632
5633 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305634 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005635 &pAdapter->session_open_comp_var,
5636 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305637 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 {
5639 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305640 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 status = VOS_STATUS_E_FAILURE;
5642 goto error_sme_open;
5643 }
5644
5645 // Register wireless extensions
5646 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5647 {
5648 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005649 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 halStatus, halStatus );
5651 status = VOS_STATUS_E_FAILURE;
5652 goto error_register_wext;
5653 }
5654 //Safe to register the hard_start_xmit function again
5655#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5656 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5657#else
5658 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5659#endif
5660
5661 //Set the Connection State to Not Connected
5662 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5663
5664 //Set the default operation channel
5665 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5666
5667 /* Make the default Auth Type as OPEN*/
5668 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5669
5670 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5671 {
5672 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005673 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005674 status, status );
5675 goto error_init_txrx;
5676 }
5677
5678 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5679
5680 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5681 {
5682 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005683 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005684 status, status );
5685 goto error_wmm_init;
5686 }
5687
5688 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5689
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005690#ifdef FEATURE_WLAN_TDLS
5691 if(0 != wlan_hdd_tdls_init(pAdapter))
5692 {
5693 status = VOS_STATUS_E_FAILURE;
5694 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5695 goto error_tdls_init;
5696 }
5697 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5698#endif
5699
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 return VOS_STATUS_SUCCESS;
5701
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005702#ifdef FEATURE_WLAN_TDLS
5703error_tdls_init:
5704 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5705 hdd_wmm_adapter_close(pAdapter);
5706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005707error_wmm_init:
5708 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5709 hdd_deinit_tx_rx(pAdapter);
5710error_init_txrx:
5711 hdd_UnregisterWext(pWlanDev);
5712error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005713 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 {
5715 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005716 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005718 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305720 unsigned long rc;
5721
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305723 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005725 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305726 if (rc <= 0)
5727 hddLog(VOS_TRACE_LEVEL_ERROR,
5728 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 }
5730}
5731error_sme_open:
5732 return status;
5733}
5734
Jeff Johnson295189b2012-06-20 16:38:30 -07005735void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5736{
5737 hdd_cfg80211_state_t *cfgState;
5738
5739 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5740
5741 if( NULL != cfgState->buf )
5742 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305743 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5745 rc = wait_for_completion_interruptible_timeout(
5746 &pAdapter->tx_action_cnf_event,
5747 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305748 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305751 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5752 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 }
5754 }
5755 return;
5756}
Jeff Johnson295189b2012-06-20 16:38:30 -07005757
5758void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5759{
5760 ENTER();
5761 switch ( pAdapter->device_mode )
5762 {
5763 case WLAN_HDD_INFRA_STATION:
5764 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005765 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 {
5767 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5768 {
5769 hdd_deinit_tx_rx( pAdapter );
5770 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5771 }
5772
5773 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5774 {
5775 hdd_wmm_adapter_close( pAdapter );
5776 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5777 }
5778
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005780#ifdef FEATURE_WLAN_TDLS
5781 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5782 {
5783 wlan_hdd_tdls_exit(pAdapter);
5784 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5785 }
5786#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005787
5788 break;
5789 }
5790
5791 case WLAN_HDD_SOFTAP:
5792 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305794
5795 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5796 {
5797 hdd_wmm_adapter_close( pAdapter );
5798 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5799 }
5800
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005802
5803 hdd_unregister_hostapd(pAdapter);
5804 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 break;
5807 }
5808
5809 case WLAN_HDD_MONITOR:
5810 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005812 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5813 {
5814 hdd_deinit_tx_rx( pAdapter );
5815 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5816 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 if(NULL != pAdapterforTx)
5818 {
5819 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5820 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 break;
5822 }
5823
5824
5825 default:
5826 break;
5827 }
5828
5829 EXIT();
5830}
5831
5832void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5833{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005834 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305835
5836 ENTER();
5837 if (NULL == pAdapter)
5838 {
5839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5840 "%s: HDD adapter is Null", __func__);
5841 return;
5842 }
5843
5844 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005845
Rajeev79dbe4c2013-10-05 11:03:42 +05305846#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305847 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5848 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005849 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305850 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5851 )
5852 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005853 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305854 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005855 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5856 {
5857 hdd_deinit_batch_scan(pAdapter);
5858 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305859 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005860 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305861#endif
5862
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5864 if( rtnl_held )
5865 {
5866 unregister_netdevice(pWlanDev);
5867 }
5868 else
5869 {
5870 unregister_netdev(pWlanDev);
5871 }
5872 // note that the pAdapter is no longer valid at this point
5873 // since the memory has been reclaimed
5874 }
5875
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305876 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005877}
5878
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005879void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5880{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305881 VOS_STATUS status;
5882 hdd_adapter_t *pAdapter = NULL;
5883 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005884
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305885 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005886
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305887 /*loop through all adapters.*/
5888 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005889 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305890 pAdapter = pAdapterNode->pAdapter;
5891 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5892 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005893
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305894 { // we skip this registration for modes other than STA and P2P client modes.
5895 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5896 pAdapterNode = pNext;
5897 continue;
5898 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005899
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305900 //Apply Dynamic DTIM For P2P
5901 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5902 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5903 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5904 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5905 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5906 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5907 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5908 (eConnectionState_Associated ==
5909 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5910 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5911 {
5912 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005913
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305914 powerRequest.uIgnoreDTIM = 1;
5915 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5916
5917 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5918 {
5919 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5920 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5921 }
5922 else
5923 {
5924 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5925 }
5926
5927 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5928 * specified during Enter/Exit BMPS when LCD off*/
5929 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5930 NULL, eANI_BOOLEAN_FALSE);
5931 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5932 NULL, eANI_BOOLEAN_FALSE);
5933
5934 /* switch to the DTIM specified in cfg.ini */
5935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5936 "Switch to DTIM %d", powerRequest.uListenInterval);
5937 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5938 break;
5939
5940 }
5941
5942 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5943 pAdapterNode = pNext;
5944 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005945}
5946
5947void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5948{
5949 /*Switch back to DTIM 1*/
5950 tSirSetPowerParamsReq powerRequest = { 0 };
5951
5952 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5953 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005954 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005955
5956 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5957 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5958 NULL, eANI_BOOLEAN_FALSE);
5959 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5960 NULL, eANI_BOOLEAN_FALSE);
5961
5962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5963 "Switch to DTIM%d",powerRequest.uListenInterval);
5964 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5965
5966}
5967
Jeff Johnson295189b2012-06-20 16:38:30 -07005968VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5969{
5970 VOS_STATUS status = VOS_STATUS_SUCCESS;
5971
5972 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5973 {
5974 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5975 }
5976
5977 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5978 {
5979 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5980 }
5981
5982 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5983 {
5984 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5985 }
5986
5987 return status;
5988}
5989
5990VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5991{
5992 hdd_adapter_t *pAdapter = NULL;
5993 eHalStatus halStatus;
5994 VOS_STATUS status = VOS_STATUS_E_INVAL;
5995 v_BOOL_t disableBmps = FALSE;
5996 v_BOOL_t disableImps = FALSE;
5997
5998 switch(session_type)
5999 {
6000 case WLAN_HDD_INFRA_STATION:
6001 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 case WLAN_HDD_P2P_CLIENT:
6003 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 //Exit BMPS -> Is Sta/P2P Client is already connected
6005 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6006 if((NULL != pAdapter)&&
6007 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6008 {
6009 disableBmps = TRUE;
6010 }
6011
6012 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6013 if((NULL != pAdapter)&&
6014 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6015 {
6016 disableBmps = TRUE;
6017 }
6018
6019 //Exit both Bmps and Imps incase of Go/SAP Mode
6020 if((WLAN_HDD_SOFTAP == session_type) ||
6021 (WLAN_HDD_P2P_GO == session_type))
6022 {
6023 disableBmps = TRUE;
6024 disableImps = TRUE;
6025 }
6026
6027 if(TRUE == disableImps)
6028 {
6029 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6030 {
6031 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6032 }
6033 }
6034
6035 if(TRUE == disableBmps)
6036 {
6037 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6038 {
6039 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6040
6041 if(eHAL_STATUS_SUCCESS != halStatus)
6042 {
6043 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006044 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 VOS_ASSERT(0);
6046 return status;
6047 }
6048 }
6049
6050 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6051 {
6052 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6053
6054 if(eHAL_STATUS_SUCCESS != halStatus)
6055 {
6056 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006057 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 VOS_ASSERT(0);
6059 return status;
6060 }
6061 }
6062 }
6063
6064 if((TRUE == disableBmps) ||
6065 (TRUE == disableImps))
6066 {
6067 /* Now, get the chip into Full Power now */
6068 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6069 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6070 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6071
6072 if(halStatus != eHAL_STATUS_SUCCESS)
6073 {
6074 if(halStatus == eHAL_STATUS_PMC_PENDING)
6075 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306076 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306078 ret = wait_for_completion_interruptible_timeout(
6079 &pHddCtx->full_pwr_comp_var,
6080 msecs_to_jiffies(1000));
6081 if (ret <= 0)
6082 {
6083 hddLog(VOS_TRACE_LEVEL_ERROR,
6084 "%s: wait on full_pwr_comp_var failed %ld",
6085 __func__, ret);
6086 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 }
6088 else
6089 {
6090 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006091 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006092 VOS_ASSERT(0);
6093 return status;
6094 }
6095 }
6096
6097 status = VOS_STATUS_SUCCESS;
6098 }
6099
6100 break;
6101 }
6102 return status;
6103}
6104
6105hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006106 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006107 tANI_U8 rtnl_held )
6108{
6109 hdd_adapter_t *pAdapter = NULL;
6110 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6111 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6112 VOS_STATUS exitbmpsStatus;
6113
Arif Hussain6d2a3322013-11-17 19:50:10 -08006114 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006115
Nirav Shah436658f2014-02-28 17:05:45 +05306116 if(macAddr == NULL)
6117 {
6118 /* Not received valid macAddr */
6119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6120 "%s:Unable to add virtual intf: Not able to get"
6121 "valid mac address",__func__);
6122 return NULL;
6123 }
6124
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 //Disable BMPS incase of Concurrency
6126 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6127
6128 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6129 {
6130 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306131 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006132 VOS_ASSERT(0);
6133 return NULL;
6134 }
6135
6136 switch(session_type)
6137 {
6138 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006139 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006140 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006141 {
6142 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6143
6144 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306145 {
6146 hddLog(VOS_TRACE_LEVEL_FATAL,
6147 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006150
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306151#ifdef FEATURE_WLAN_TDLS
6152 /* A Mutex Lock is introduced while changing/initializing the mode to
6153 * protect the concurrent access for the Adapters by TDLS module.
6154 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306155 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306156#endif
6157
Jeff Johnsone7245742012-09-05 17:12:55 -07006158 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6159 NL80211_IFTYPE_P2P_CLIENT:
6160 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006161
Jeff Johnson295189b2012-06-20 16:38:30 -07006162 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306163#ifdef FEATURE_WLAN_TDLS
6164 mutex_unlock(&pHddCtx->tdls_lock);
6165#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306166
6167 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 if( VOS_STATUS_SUCCESS != status )
6169 goto err_free_netdev;
6170
6171 status = hdd_register_interface( pAdapter, rtnl_held );
6172 if( VOS_STATUS_SUCCESS != status )
6173 {
6174 hdd_deinit_adapter(pHddCtx, pAdapter);
6175 goto err_free_netdev;
6176 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306177
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306178 // Workqueue which gets scheduled in IPv4 notification callback.
6179 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6180
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306181#ifdef WLAN_NS_OFFLOAD
6182 // Workqueue which gets scheduled in IPv6 notification callback.
6183 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6184#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 //Stop the Interface TX queue.
6186 netif_tx_disable(pAdapter->dev);
6187 //netif_tx_disable(pWlanDev);
6188 netif_carrier_off(pAdapter->dev);
6189
6190 break;
6191 }
6192
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 case WLAN_HDD_SOFTAP:
6195 {
6196 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6197 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306198 {
6199 hddLog(VOS_TRACE_LEVEL_FATAL,
6200 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306202 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006203
Jeff Johnson295189b2012-06-20 16:38:30 -07006204 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6205 NL80211_IFTYPE_AP:
6206 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006207 pAdapter->device_mode = session_type;
6208
6209 status = hdd_init_ap_mode(pAdapter);
6210 if( VOS_STATUS_SUCCESS != status )
6211 goto err_free_netdev;
6212
6213 status = hdd_register_hostapd( pAdapter, rtnl_held );
6214 if( VOS_STATUS_SUCCESS != status )
6215 {
6216 hdd_deinit_adapter(pHddCtx, pAdapter);
6217 goto err_free_netdev;
6218 }
6219
6220 netif_tx_disable(pAdapter->dev);
6221 netif_carrier_off(pAdapter->dev);
6222
6223 hdd_set_conparam( 1 );
6224 break;
6225 }
6226 case WLAN_HDD_MONITOR:
6227 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6229 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306230 {
6231 hddLog(VOS_TRACE_LEVEL_FATAL,
6232 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006233 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006235
6236 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6237 pAdapter->device_mode = session_type;
6238 status = hdd_register_interface( pAdapter, rtnl_held );
6239#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6240 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6241#else
6242 pAdapter->dev->open = hdd_mon_open;
6243 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6244#endif
6245 hdd_init_tx_rx( pAdapter );
6246 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6247 //Set adapter to be used for data tx. It will use either GO or softap.
6248 pAdapter->sessionCtx.monitor.pAdapterForTx =
6249 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6251 {
6252 pAdapter->sessionCtx.monitor.pAdapterForTx =
6253 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6254 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 /* This workqueue will be used to transmit management packet over
6256 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006257 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6258 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6259 return NULL;
6260 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006261
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6263 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 }
6265 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 case WLAN_HDD_FTM:
6267 {
6268 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6269
6270 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306271 {
6272 hddLog(VOS_TRACE_LEVEL_FATAL,
6273 FL("failed to allocate adapter for session %d"), session_type);
6274 return NULL;
6275 }
6276
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6278 * message while loading driver in FTM mode. */
6279 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6280 pAdapter->device_mode = session_type;
6281 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306282
6283 hdd_init_tx_rx( pAdapter );
6284
6285 //Stop the Interface TX queue.
6286 netif_tx_disable(pAdapter->dev);
6287 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 }
6289 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 default:
6291 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306292 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6293 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 VOS_ASSERT(0);
6295 return NULL;
6296 }
6297 }
6298
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 if( VOS_STATUS_SUCCESS == status )
6300 {
6301 //Add it to the hdd's session list.
6302 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6303 if( NULL == pHddAdapterNode )
6304 {
6305 status = VOS_STATUS_E_NOMEM;
6306 }
6307 else
6308 {
6309 pHddAdapterNode->pAdapter = pAdapter;
6310 status = hdd_add_adapter_back ( pHddCtx,
6311 pHddAdapterNode );
6312 }
6313 }
6314
6315 if( VOS_STATUS_SUCCESS != status )
6316 {
6317 if( NULL != pAdapter )
6318 {
6319 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6320 pAdapter = NULL;
6321 }
6322 if( NULL != pHddAdapterNode )
6323 {
6324 vos_mem_free( pHddAdapterNode );
6325 }
6326
6327 goto resume_bmps;
6328 }
6329
6330 if(VOS_STATUS_SUCCESS == status)
6331 {
6332 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6333
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006334 //Initialize the WoWL service
6335 if(!hdd_init_wowl(pAdapter))
6336 {
6337 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6338 goto err_free_netdev;
6339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 return pAdapter;
6342
6343err_free_netdev:
6344 free_netdev(pAdapter->dev);
6345 wlan_hdd_release_intf_addr( pHddCtx,
6346 pAdapter->macAddressCurrent.bytes );
6347
6348resume_bmps:
6349 //If bmps disabled enable it
6350 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6351 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306352 if (pHddCtx->hdd_wlan_suspended)
6353 {
6354 hdd_set_pwrparams(pHddCtx);
6355 }
6356 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 }
6358 return NULL;
6359}
6360
6361VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6362 tANI_U8 rtnl_held )
6363{
6364 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6365 VOS_STATUS status;
6366
6367 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6368 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306369 {
6370 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6371 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006374
6375 while ( pCurrent->pAdapter != pAdapter )
6376 {
6377 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6378 if( VOS_STATUS_SUCCESS != status )
6379 break;
6380
6381 pCurrent = pNext;
6382 }
6383 pAdapterNode = pCurrent;
6384 if( VOS_STATUS_SUCCESS == status )
6385 {
6386 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6387 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306388
6389#ifdef FEATURE_WLAN_TDLS
6390
6391 /* A Mutex Lock is introduced while changing/initializing the mode to
6392 * protect the concurrent access for the Adapters by TDLS module.
6393 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306394 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306395#endif
6396
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 hdd_remove_adapter( pHddCtx, pAdapterNode );
6398 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006399 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006400
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306401#ifdef FEATURE_WLAN_TDLS
6402 mutex_unlock(&pHddCtx->tdls_lock);
6403#endif
6404
Jeff Johnson295189b2012-06-20 16:38:30 -07006405
6406 /* If there is a single session of STA/P2P client, re-enable BMPS */
6407 if ((!vos_concurrent_sessions_running()) &&
6408 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6409 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6410 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306411 if (pHddCtx->hdd_wlan_suspended)
6412 {
6413 hdd_set_pwrparams(pHddCtx);
6414 }
6415 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 }
6417
6418 return VOS_STATUS_SUCCESS;
6419 }
6420
6421 return VOS_STATUS_E_FAILURE;
6422}
6423
6424VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6425{
6426 hdd_adapter_list_node_t *pHddAdapterNode;
6427 VOS_STATUS status;
6428
6429 ENTER();
6430
6431 do
6432 {
6433 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6434 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6435 {
6436 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6437 vos_mem_free( pHddAdapterNode );
6438 }
6439 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6440
6441 EXIT();
6442
6443 return VOS_STATUS_SUCCESS;
6444}
6445
6446void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6447{
6448 v_U8_t addIE[1] = {0};
6449
6450 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6451 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6452 eANI_BOOLEAN_FALSE) )
6453 {
6454 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006455 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 }
6457
6458 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6459 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6460 eANI_BOOLEAN_FALSE) )
6461 {
6462 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006463 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 }
6465
6466 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6467 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6468 eANI_BOOLEAN_FALSE) )
6469 {
6470 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006471 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 }
6473}
6474
6475VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6476{
6477 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6478 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6479 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306480 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306481 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006482
6483 ENTER();
6484
6485 switch(pAdapter->device_mode)
6486 {
6487 case WLAN_HDD_INFRA_STATION:
6488 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006489 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306490 {
6491 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6492 if( hdd_connIsConnected(pstation) ||
6493 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 {
6495 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6496 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6497 pAdapter->sessionId,
6498 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6499 else
6500 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6501 pAdapter->sessionId,
6502 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6503 //success implies disconnect command got queued up successfully
6504 if(halStatus == eHAL_STATUS_SUCCESS)
6505 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306506 ret = wait_for_completion_interruptible_timeout(
6507 &pAdapter->disconnect_comp_var,
6508 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6509 if (ret <= 0)
6510 {
6511 hddLog(VOS_TRACE_LEVEL_ERROR,
6512 "%s: wait on disconnect_comp_var failed %ld",
6513 __func__, ret);
6514 }
6515 }
6516 else
6517 {
6518 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6519 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006520 }
6521 memset(&wrqu, '\0', sizeof(wrqu));
6522 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6523 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6524 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6525 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306526 else if(pstation->conn_info.connState ==
6527 eConnectionState_Disconnecting)
6528 {
6529 ret = wait_for_completion_interruptible_timeout(
6530 &pAdapter->disconnect_comp_var,
6531 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6532 if (ret <= 0)
6533 {
6534 hddLog(VOS_TRACE_LEVEL_ERROR,
6535 FL("wait on disconnect_comp_var failed %ld"), ret);
6536 }
6537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 else
6539 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306540 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6541 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306543 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6544 {
6545 while (pAdapter->is_roc_inprogress)
6546 {
6547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6548 "%s: ROC in progress for session %d!!!",
6549 __func__, pAdapter->sessionId);
6550 // waiting for ROC to expire
6551 msleep(500);
6552 /* In GO present case , if retry exceeds 3,
6553 it means something went wrong. */
6554 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6555 {
6556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6557 "%s: ROC completion is not received.!!!", __func__);
6558 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6559 pAdapter->sessionId);
6560 wait_for_completion_interruptible_timeout(
6561 &pAdapter->cancel_rem_on_chan_var,
6562 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6563 break;
6564 }
6565 }
6566 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306567#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306568#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306569 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6570#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306571 if (pAdapter->ipv6_notifier_registered)
6572 {
6573 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6574 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6575 pAdapter->ipv6_notifier_registered = false;
6576 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306577#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306578 if (pAdapter->ipv4_notifier_registered)
6579 {
6580 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6581 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6582 pAdapter->ipv4_notifier_registered = false;
6583 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306584#ifdef WLAN_OPEN_SOURCE
6585 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6586#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006587 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6588 {
6589 INIT_COMPLETION(pAdapter->session_close_comp_var);
6590 if (eHAL_STATUS_SUCCESS ==
6591 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6592 hdd_smeCloseSessionCallback, pAdapter))
6593 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306594 unsigned long ret;
6595
Jeff Johnson295189b2012-06-20 16:38:30 -07006596 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306597 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 &pAdapter->session_close_comp_var,
6599 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306600 if ( 0 >= ret)
6601 {
6602 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6603 __func__, ret);
6604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006605 }
6606 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006608 break;
6609
6610 case WLAN_HDD_SOFTAP:
6611 case WLAN_HDD_P2P_GO:
6612 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306613 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6614 while (pAdapter->is_roc_inprogress) {
6615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6616 "%s: ROC in progress for session %d!!!",
6617 __func__, pAdapter->sessionId);
6618 msleep(500);
6619 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6621 "%s: ROC completion is not received.!!!", __func__);
6622 WLANSAP_CancelRemainOnChannel(
6623 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6624 wait_for_completion_interruptible_timeout(
6625 &pAdapter->cancel_rem_on_chan_var,
6626 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6627 break;
6628 }
6629 }
6630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 mutex_lock(&pHddCtx->sap_lock);
6632 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6633 {
6634 VOS_STATUS status;
6635 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6636
6637 //Stop Bss.
6638 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6639 if (VOS_IS_STATUS_SUCCESS(status))
6640 {
6641 hdd_hostapd_state_t *pHostapdState =
6642 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6643
6644 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6645
6646 if (!VOS_IS_STATUS_SUCCESS(status))
6647 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306648 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6649 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 }
6651 }
6652 else
6653 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006654 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 }
6656 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6657
6658 if (eHAL_STATUS_FAILURE ==
6659 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6660 0, NULL, eANI_BOOLEAN_FALSE))
6661 {
6662 hddLog(LOGE,
6663 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006664 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 }
6666
6667 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6668 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6669 eANI_BOOLEAN_FALSE) )
6670 {
6671 hddLog(LOGE,
6672 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6673 }
6674
6675 // Reset WNI_CFG_PROBE_RSP Flags
6676 wlan_hdd_reset_prob_rspies(pAdapter);
6677 kfree(pAdapter->sessionCtx.ap.beacon);
6678 pAdapter->sessionCtx.ap.beacon = NULL;
6679 }
6680 mutex_unlock(&pHddCtx->sap_lock);
6681 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006682
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006684#ifdef WLAN_OPEN_SOURCE
6685 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6686#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006687 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006688
Jeff Johnson295189b2012-06-20 16:38:30 -07006689 default:
6690 break;
6691 }
6692
6693 EXIT();
6694 return VOS_STATUS_SUCCESS;
6695}
6696
6697VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6698{
6699 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6700 VOS_STATUS status;
6701 hdd_adapter_t *pAdapter;
6702
6703 ENTER();
6704
6705 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6706
6707 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6708 {
6709 pAdapter = pAdapterNode->pAdapter;
6710 netif_tx_disable(pAdapter->dev);
6711 netif_carrier_off(pAdapter->dev);
6712
6713 hdd_stop_adapter( pHddCtx, pAdapter );
6714
6715 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6716 pAdapterNode = pNext;
6717 }
6718
6719 EXIT();
6720
6721 return VOS_STATUS_SUCCESS;
6722}
6723
Rajeev Kumarf999e582014-01-09 17:33:29 -08006724
6725#ifdef FEATURE_WLAN_BATCH_SCAN
6726/**---------------------------------------------------------------------------
6727
6728 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6729 structures
6730
6731 \param - pAdapter Pointer to HDD adapter
6732
6733 \return - None
6734
6735 --------------------------------------------------------------------------*/
6736void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6737{
6738 tHddBatchScanRsp *pNode;
6739 tHddBatchScanRsp *pPrev;
6740
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306741 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006742 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306743 hddLog(VOS_TRACE_LEVEL_ERROR,
6744 "%s: Adapter context is Null", __func__);
6745 return;
6746 }
6747
6748 pNode = pAdapter->pBatchScanRsp;
6749 while (pNode)
6750 {
6751 pPrev = pNode;
6752 pNode = pNode->pNext;
6753 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006754 }
6755
6756 pAdapter->pBatchScanRsp = NULL;
6757 pAdapter->numScanList = 0;
6758 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6759 pAdapter->prev_batch_id = 0;
6760
6761 return;
6762}
6763#endif
6764
6765
Jeff Johnson295189b2012-06-20 16:38:30 -07006766VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6767{
6768 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6769 VOS_STATUS status;
6770 hdd_adapter_t *pAdapter;
6771
6772 ENTER();
6773
6774 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6775
6776 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6777 {
6778 pAdapter = pAdapterNode->pAdapter;
6779 netif_tx_disable(pAdapter->dev);
6780 netif_carrier_off(pAdapter->dev);
6781
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006782 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6783
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306785 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6786 {
6787 hdd_wmm_adapter_close( pAdapter );
6788 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6789 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006790
Rajeev Kumarf999e582014-01-09 17:33:29 -08006791#ifdef FEATURE_WLAN_BATCH_SCAN
6792 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6793 {
6794 hdd_deinit_batch_scan(pAdapter);
6795 }
6796#endif
6797
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6799 pAdapterNode = pNext;
6800 }
6801
6802 EXIT();
6803
6804 return VOS_STATUS_SUCCESS;
6805}
6806
6807VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6808{
6809 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6810 VOS_STATUS status;
6811 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306812 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006813
6814 ENTER();
6815
6816 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6817
6818 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6819 {
6820 pAdapter = pAdapterNode->pAdapter;
6821
6822 switch(pAdapter->device_mode)
6823 {
6824 case WLAN_HDD_INFRA_STATION:
6825 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006826 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306827
6828 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6829
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 hdd_init_station_mode(pAdapter);
6831 /* Open the gates for HDD to receive Wext commands */
6832 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006833 pHddCtx->scan_info.mScanPending = FALSE;
6834 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006835
6836 //Trigger the initial scan
6837 hdd_wlan_initial_scan(pAdapter);
6838
6839 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306840 if (eConnectionState_Associated == connState ||
6841 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 {
6843 union iwreq_data wrqu;
6844 memset(&wrqu, '\0', sizeof(wrqu));
6845 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6846 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6847 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006848 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006849
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 /* indicate disconnected event to nl80211 */
6851 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6852 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306854 else if (eConnectionState_Connecting == connState)
6855 {
6856 /*
6857 * Indicate connect failure to supplicant if we were in the
6858 * process of connecting
6859 */
6860 cfg80211_connect_result(pAdapter->dev, NULL,
6861 NULL, 0, NULL, 0,
6862 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6863 GFP_KERNEL);
6864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 break;
6866
6867 case WLAN_HDD_SOFTAP:
6868 /* softAP can handle SSR */
6869 break;
6870
6871 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006874 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 break;
6876
6877 case WLAN_HDD_MONITOR:
6878 /* monitor interface start */
6879 break;
6880 default:
6881 break;
6882 }
6883
6884 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6885 pAdapterNode = pNext;
6886 }
6887
6888 EXIT();
6889
6890 return VOS_STATUS_SUCCESS;
6891}
6892
6893VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6894{
6895 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6896 hdd_adapter_t *pAdapter;
6897 VOS_STATUS status;
6898 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306899 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006900
6901 ENTER();
6902
6903 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6904
6905 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6906 {
6907 pAdapter = pAdapterNode->pAdapter;
6908
6909 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6910 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6911 {
6912 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6913 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6914
6915 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6916 init_completion(&pAdapter->disconnect_comp_var);
6917 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6918 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6919
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306920 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 &pAdapter->disconnect_comp_var,
6922 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306923 if (0 >= ret)
6924 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6925 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006926
6927 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6928 pHddCtx->isAmpAllowed = VOS_FALSE;
6929 sme_RoamConnect(pHddCtx->hHal,
6930 pAdapter->sessionId, &(pWextState->roamProfile),
6931 &roamId);
6932 }
6933
6934 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6935 pAdapterNode = pNext;
6936 }
6937
6938 EXIT();
6939
6940 return VOS_STATUS_SUCCESS;
6941}
6942
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006943void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6944{
6945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6946 VOS_STATUS status;
6947 hdd_adapter_t *pAdapter;
6948 hdd_station_ctx_t *pHddStaCtx;
6949 hdd_ap_ctx_t *pHddApCtx;
6950 hdd_hostapd_state_t * pHostapdState;
6951 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6952 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6953 const char *p2pMode = "DEV";
6954 const char *ccMode = "Standalone";
6955 int n;
6956
6957 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6958 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6959 {
6960 pAdapter = pAdapterNode->pAdapter;
6961 switch (pAdapter->device_mode) {
6962 case WLAN_HDD_INFRA_STATION:
6963 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6964 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6965 staChannel = pHddStaCtx->conn_info.operationChannel;
6966 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6967 }
6968 break;
6969 case WLAN_HDD_P2P_CLIENT:
6970 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6971 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6972 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6973 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6974 p2pMode = "CLI";
6975 }
6976 break;
6977 case WLAN_HDD_P2P_GO:
6978 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6979 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6980 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6981 p2pChannel = pHddApCtx->operatingChannel;
6982 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6983 }
6984 p2pMode = "GO";
6985 break;
6986 case WLAN_HDD_SOFTAP:
6987 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6988 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6989 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6990 apChannel = pHddApCtx->operatingChannel;
6991 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6992 }
6993 break;
6994 default:
6995 break;
6996 }
6997 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6998 pAdapterNode = pNext;
6999 }
7000 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7001 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7002 }
7003 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7004 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7005 if (p2pChannel > 0) {
7006 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7007 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7008 }
7009 if (apChannel > 0) {
7010 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7011 apChannel, MAC_ADDR_ARRAY(apBssid));
7012 }
7013
7014 if (p2pChannel > 0 && apChannel > 0) {
7015 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7016 }
7017}
7018
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007019bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007020{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007021 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007022}
7023
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007024/* Once SSR is disabled then it cannot be set. */
7025void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007026{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007027 if (HDD_SSR_DISABLED == isSsrRequired)
7028 return;
7029
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 isSsrRequired = value;
7031}
7032
7033VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7034 hdd_adapter_list_node_t** ppAdapterNode)
7035{
7036 VOS_STATUS status;
7037 spin_lock(&pHddCtx->hddAdapters.lock);
7038 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7039 (hdd_list_node_t**) ppAdapterNode );
7040 spin_unlock(&pHddCtx->hddAdapters.lock);
7041 return status;
7042}
7043
7044VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7045 hdd_adapter_list_node_t* pAdapterNode,
7046 hdd_adapter_list_node_t** pNextAdapterNode)
7047{
7048 VOS_STATUS status;
7049 spin_lock(&pHddCtx->hddAdapters.lock);
7050 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7051 (hdd_list_node_t*) pAdapterNode,
7052 (hdd_list_node_t**)pNextAdapterNode );
7053
7054 spin_unlock(&pHddCtx->hddAdapters.lock);
7055 return status;
7056}
7057
7058VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7059 hdd_adapter_list_node_t* pAdapterNode)
7060{
7061 VOS_STATUS status;
7062 spin_lock(&pHddCtx->hddAdapters.lock);
7063 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7064 &pAdapterNode->node );
7065 spin_unlock(&pHddCtx->hddAdapters.lock);
7066 return status;
7067}
7068
7069VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7070 hdd_adapter_list_node_t** ppAdapterNode)
7071{
7072 VOS_STATUS status;
7073 spin_lock(&pHddCtx->hddAdapters.lock);
7074 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7075 (hdd_list_node_t**) ppAdapterNode );
7076 spin_unlock(&pHddCtx->hddAdapters.lock);
7077 return status;
7078}
7079
7080VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7081 hdd_adapter_list_node_t* pAdapterNode)
7082{
7083 VOS_STATUS status;
7084 spin_lock(&pHddCtx->hddAdapters.lock);
7085 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7086 (hdd_list_node_t*) pAdapterNode );
7087 spin_unlock(&pHddCtx->hddAdapters.lock);
7088 return status;
7089}
7090
7091VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7092 hdd_adapter_list_node_t* pAdapterNode)
7093{
7094 VOS_STATUS status;
7095 spin_lock(&pHddCtx->hddAdapters.lock);
7096 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7097 (hdd_list_node_t*) pAdapterNode );
7098 spin_unlock(&pHddCtx->hddAdapters.lock);
7099 return status;
7100}
7101
7102hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7103 tSirMacAddr macAddr )
7104{
7105 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7106 hdd_adapter_t *pAdapter;
7107 VOS_STATUS status;
7108
7109 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7110
7111 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7112 {
7113 pAdapter = pAdapterNode->pAdapter;
7114
7115 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7116 macAddr, sizeof(tSirMacAddr) ) )
7117 {
7118 return pAdapter;
7119 }
7120 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7121 pAdapterNode = pNext;
7122 }
7123
7124 return NULL;
7125
7126}
7127
7128hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7129{
7130 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7131 hdd_adapter_t *pAdapter;
7132 VOS_STATUS status;
7133
7134 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7135
7136 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7137 {
7138 pAdapter = pAdapterNode->pAdapter;
7139
7140 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7141 IFNAMSIZ ) )
7142 {
7143 return pAdapter;
7144 }
7145 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7146 pAdapterNode = pNext;
7147 }
7148
7149 return NULL;
7150
7151}
7152
7153hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7154{
7155 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7156 hdd_adapter_t *pAdapter;
7157 VOS_STATUS status;
7158
7159 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7160
7161 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7162 {
7163 pAdapter = pAdapterNode->pAdapter;
7164
7165 if( pAdapter && (mode == pAdapter->device_mode) )
7166 {
7167 return pAdapter;
7168 }
7169 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7170 pAdapterNode = pNext;
7171 }
7172
7173 return NULL;
7174
7175}
7176
7177//Remove this function later
7178hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7179{
7180 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7181 hdd_adapter_t *pAdapter;
7182 VOS_STATUS status;
7183
7184 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7185
7186 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7187 {
7188 pAdapter = pAdapterNode->pAdapter;
7189
7190 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7191 {
7192 return pAdapter;
7193 }
7194
7195 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7196 pAdapterNode = pNext;
7197 }
7198
7199 return NULL;
7200
7201}
7202
Jeff Johnson295189b2012-06-20 16:38:30 -07007203/**---------------------------------------------------------------------------
7204
7205 \brief hdd_set_monitor_tx_adapter() -
7206
7207 This API initializes the adapter to be used while transmitting on monitor
7208 adapter.
7209
7210 \param - pHddCtx - Pointer to the HDD context.
7211 pAdapter - Adapter that will used for TX. This can be NULL.
7212 \return - None.
7213 --------------------------------------------------------------------------*/
7214void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7215{
7216 hdd_adapter_t *pMonAdapter;
7217
7218 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7219
7220 if( NULL != pMonAdapter )
7221 {
7222 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7223 }
7224}
Jeff Johnson295189b2012-06-20 16:38:30 -07007225/**---------------------------------------------------------------------------
7226
7227 \brief hdd_select_queue() -
7228
7229 This API returns the operating channel of the requested device mode
7230
7231 \param - pHddCtx - Pointer to the HDD context.
7232 - mode - Device mode for which operating channel is required
7233 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7234 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7235 \return - channel number. "0" id the requested device is not found OR it is not connected.
7236 --------------------------------------------------------------------------*/
7237v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7238{
7239 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7240 VOS_STATUS status;
7241 hdd_adapter_t *pAdapter;
7242 v_U8_t operatingChannel = 0;
7243
7244 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7245
7246 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7247 {
7248 pAdapter = pAdapterNode->pAdapter;
7249
7250 if( mode == pAdapter->device_mode )
7251 {
7252 switch(pAdapter->device_mode)
7253 {
7254 case WLAN_HDD_INFRA_STATION:
7255 case WLAN_HDD_P2P_CLIENT:
7256 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7257 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7258 break;
7259 case WLAN_HDD_SOFTAP:
7260 case WLAN_HDD_P2P_GO:
7261 /*softap connection info */
7262 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7263 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7264 break;
7265 default:
7266 break;
7267 }
7268
7269 break; //Found the device of interest. break the loop
7270 }
7271
7272 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7273 pAdapterNode = pNext;
7274 }
7275 return operatingChannel;
7276}
7277
7278#ifdef WLAN_FEATURE_PACKET_FILTERING
7279/**---------------------------------------------------------------------------
7280
7281 \brief hdd_set_multicast_list() -
7282
7283 This used to set the multicast address list.
7284
7285 \param - dev - Pointer to the WLAN device.
7286 - skb - Pointer to OS packet (sk_buff).
7287 \return - success/fail
7288
7289 --------------------------------------------------------------------------*/
7290static void hdd_set_multicast_list(struct net_device *dev)
7291{
7292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 int mc_count;
7294 int i = 0;
7295 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307296
7297 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 {
7299 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307300 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007301 return;
7302 }
7303
7304 if (dev->flags & IFF_ALLMULTI)
7305 {
7306 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007307 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307308 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 }
7310 else
7311 {
7312 mc_count = netdev_mc_count(dev);
7313 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007314 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7316 {
7317 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007318 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307319 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 return;
7321 }
7322
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307323 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007324
7325 netdev_for_each_mc_addr(ha, dev) {
7326 if (i == mc_count)
7327 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307328 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7329 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307332 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 i++;
7334 }
7335 }
7336 return;
7337}
7338#endif
7339
7340/**---------------------------------------------------------------------------
7341
7342 \brief hdd_select_queue() -
7343
7344 This function is registered with the Linux OS for network
7345 core to decide which queue to use first.
7346
7347 \param - dev - Pointer to the WLAN device.
7348 - skb - Pointer to OS packet (sk_buff).
7349 \return - ac, Queue Index/access category corresponding to UP in IP header
7350
7351 --------------------------------------------------------------------------*/
7352v_U16_t hdd_select_queue(struct net_device *dev,
7353 struct sk_buff *skb)
7354{
7355 return hdd_wmm_select_queue(dev, skb);
7356}
7357
7358
7359/**---------------------------------------------------------------------------
7360
7361 \brief hdd_wlan_initial_scan() -
7362
7363 This function triggers the initial scan
7364
7365 \param - pAdapter - Pointer to the HDD adapter.
7366
7367 --------------------------------------------------------------------------*/
7368void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7369{
7370 tCsrScanRequest scanReq;
7371 tCsrChannelInfo channelInfo;
7372 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007373 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7375
7376 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7377 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7378 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7379
7380 if(sme_Is11dSupported(pHddCtx->hHal))
7381 {
7382 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7383 if ( HAL_STATUS_SUCCESS( halStatus ) )
7384 {
7385 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7386 if( !scanReq.ChannelInfo.ChannelList )
7387 {
7388 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7389 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007390 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 return;
7392 }
7393 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7394 channelInfo.numOfChannels);
7395 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7396 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007397 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007398 }
7399
7400 scanReq.scanType = eSIR_PASSIVE_SCAN;
7401 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7402 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7403 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7404 }
7405 else
7406 {
7407 scanReq.scanType = eSIR_ACTIVE_SCAN;
7408 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7409 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7410 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7411 }
7412
7413 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7414 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7415 {
7416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7417 __func__, halStatus );
7418 }
7419
7420 if(sme_Is11dSupported(pHddCtx->hHal))
7421 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7422}
7423
Jeff Johnson295189b2012-06-20 16:38:30 -07007424/**---------------------------------------------------------------------------
7425
7426 \brief hdd_full_power_callback() - HDD full power callback function
7427
7428 This is the function invoked by SME to inform the result of a full power
7429 request issued by HDD
7430
7431 \param - callbackcontext - Pointer to cookie
7432 \param - status - result of request
7433
7434 \return - None
7435
7436 --------------------------------------------------------------------------*/
7437static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7438{
Jeff Johnson72a40512013-12-19 10:14:15 -08007439 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007440
7441 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307442 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007443
7444 if (NULL == callbackContext)
7445 {
7446 hddLog(VOS_TRACE_LEVEL_ERROR,
7447 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007448 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 return;
7450 }
7451
Jeff Johnson72a40512013-12-19 10:14:15 -08007452 /* there is a race condition that exists between this callback
7453 function and the caller since the caller could time out either
7454 before or while this code is executing. we use a spinlock to
7455 serialize these actions */
7456 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007457
7458 if (POWER_CONTEXT_MAGIC != pContext->magic)
7459 {
7460 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007461 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007462 hddLog(VOS_TRACE_LEVEL_WARN,
7463 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007464 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007465 return;
7466 }
7467
Jeff Johnson72a40512013-12-19 10:14:15 -08007468 /* context is valid so caller is still waiting */
7469
7470 /* paranoia: invalidate the magic */
7471 pContext->magic = 0;
7472
7473 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007474 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007475
7476 /* serialization is complete */
7477 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007478}
7479
7480/**---------------------------------------------------------------------------
7481
7482 \brief hdd_wlan_exit() - HDD WLAN exit function
7483
7484 This is the driver exit point (invoked during rmmod)
7485
7486 \param - pHddCtx - Pointer to the HDD Context
7487
7488 \return - None
7489
7490 --------------------------------------------------------------------------*/
7491void hdd_wlan_exit(hdd_context_t *pHddCtx)
7492{
7493 eHalStatus halStatus;
7494 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7495 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307496 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007497 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007498 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007499 long lrc;
7500
7501 ENTER();
7502
Jeff Johnson88ba7742013-02-27 14:36:02 -08007503 if (VOS_FTM_MODE != hdd_get_conparam())
7504 {
7505 // Unloading, restart logic is no more required.
7506 wlan_hdd_restart_deinit(pHddCtx);
7507 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007508
Jeff Johnson295189b2012-06-20 16:38:30 -07007509 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007510 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007511 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 {
7513 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7514 WLAN_HDD_INFRA_STATION);
7515 if (pAdapter == NULL)
7516 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7517
7518 if (pAdapter != NULL)
7519 {
7520 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7521 hdd_UnregisterWext(pAdapter->dev);
7522 }
7523 }
7524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007527 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307528 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007529 wlan_hdd_ftm_close(pHddCtx);
7530 goto free_hdd_ctx;
7531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 //Stop the Interface TX queue.
7533 //netif_tx_disable(pWlanDev);
7534 //netif_carrier_off(pWlanDev);
7535
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7537 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307538 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007539 pAdapter = hdd_get_adapter(pHddCtx,
7540 WLAN_HDD_SOFTAP);
7541 }
7542 else
7543 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007545 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307546 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 pAdapter = hdd_get_adapter(pHddCtx,
7548 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007549 if (pAdapter == NULL)
7550 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007551 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307553
7554 if(NULL == pAdapter)
7555 {
7556 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7557 goto free_hdd_ctx;
7558 }
7559
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 /* DeRegister with platform driver as client for Suspend/Resume */
7561 vosStatus = hddDeregisterPmOps(pHddCtx);
7562 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7563 {
7564 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7565 VOS_ASSERT(0);
7566 }
7567
7568 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7569 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7570 {
7571 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007573
7574 // Cancel any outstanding scan requests. We are about to close all
7575 // of our adapters, but an adapter structure is what SME passes back
7576 // to our callback function. Hence if there are any outstanding scan
7577 // requests then there is a race condition between when the adapter
7578 // is closed and when the callback is invoked. We try to resolve that
7579 // race condition here by canceling any outstanding scans before we
7580 // close the adapters.
7581 // Note that the scans may be cancelled in an asynchronous manner, so
7582 // ideally there needs to be some kind of synchronization. Rather than
7583 // introduce a new synchronization here, we will utilize the fact that
7584 // we are about to Request Full Power, and since that is synchronized,
7585 // the expectation is that by the time Request Full Power has completed,
7586 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007587 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307588 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007589 else
7590 hddLog(VOS_TRACE_LEVEL_ERROR,
7591 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007592
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007593 //Stop the traffic monitor timer
7594 if ( VOS_TIMER_STATE_RUNNING ==
7595 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7596 {
7597 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7598 }
7599
7600 // Destroy the traffic monitor timer
7601 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7602 &pHddCtx->tx_rx_trafficTmr)))
7603 {
7604 hddLog(VOS_TRACE_LEVEL_ERROR,
7605 "%s: Cannot deallocate Traffic monitor timer", __func__);
7606 }
7607
Jeff Johnson295189b2012-06-20 16:38:30 -07007608 //Disable IMPS/BMPS as we do not want the device to enter any power
7609 //save mode during shutdown
7610 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7611 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7612 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7613
7614 //Ensure that device is in full power as we will touch H/W during vos_Stop
7615 init_completion(&powerContext.completion);
7616 powerContext.magic = POWER_CONTEXT_MAGIC;
7617
7618 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7619 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7620
7621 if (eHAL_STATUS_SUCCESS != halStatus)
7622 {
7623 if (eHAL_STATUS_PMC_PENDING == halStatus)
7624 {
7625 /* request was sent -- wait for the response */
7626 lrc = wait_for_completion_interruptible_timeout(
7627 &powerContext.completion,
7628 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 if (lrc <= 0)
7630 {
7631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007632 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 }
7634 }
7635 else
7636 {
7637 hddLog(VOS_TRACE_LEVEL_ERROR,
7638 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007639 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 /* continue -- need to clean up as much as possible */
7641 }
7642 }
7643
Jeff Johnson72a40512013-12-19 10:14:15 -08007644 /* either we never sent a request, we sent a request and received a
7645 response or we sent a request and timed out. if we never sent a
7646 request or if we sent a request and got a response, we want to
7647 clear the magic out of paranoia. if we timed out there is a
7648 race condition such that the callback function could be
7649 executing at the same time we are. of primary concern is if the
7650 callback function had already verified the "magic" but had not
7651 yet set the completion variable when a timeout occurred. we
7652 serialize these activities by invalidating the magic while
7653 holding a shared spinlock which will cause us to block if the
7654 callback is currently executing */
7655 spin_lock(&hdd_context_lock);
7656 powerContext.magic = 0;
7657 spin_unlock(&hdd_context_lock);
7658
Yue Ma0d4891e2013-08-06 17:01:45 -07007659 hdd_debugfs_exit(pHddCtx);
7660
Jeff Johnson295189b2012-06-20 16:38:30 -07007661 // Unregister the Net Device Notifier
7662 unregister_netdevice_notifier(&hdd_netdev_notifier);
7663
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 hdd_stop_all_adapters( pHddCtx );
7665
Jeff Johnson295189b2012-06-20 16:38:30 -07007666#ifdef WLAN_BTAMP_FEATURE
7667 vosStatus = WLANBAP_Stop(pVosContext);
7668 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7669 {
7670 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7671 "%s: Failed to stop BAP",__func__);
7672 }
7673#endif //WLAN_BTAMP_FEATURE
7674
7675 //Stop all the modules
7676 vosStatus = vos_stop( pVosContext );
7677 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7678 {
7679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7680 "%s: Failed to stop VOSS",__func__);
7681 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7682 }
7683
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 //Assert Deep sleep signal now to put Libra HW in lowest power state
7685 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7686 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7687
7688 //Vote off any PMIC voltage supplies
7689 vos_chipPowerDown(NULL, NULL, NULL);
7690
7691 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7692
Leo Chang59cdc7e2013-07-10 10:08:21 -07007693
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007696
7697 //Close the scheduler before calling vos_close to make sure no thread is
7698 // scheduled after the each module close is called i.e after all the data
7699 // structures are freed.
7700 vosStatus = vos_sched_close( pVosContext );
7701 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7702 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7703 "%s: Failed to close VOSS Scheduler",__func__);
7704 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7705 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007706#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007707#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7708 /* Destroy the wake lock */
7709 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7710#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007711 /* Destroy the wake lock */
7712 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007713#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007714
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307715#ifdef CONFIG_ENABLE_LINUX_REG
7716 vosStatus = vos_nv_close();
7717 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7718 {
7719 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7720 "%s: Failed to close NV", __func__);
7721 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7722 }
7723#endif
7724
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 //Close VOSS
7726 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7727 vos_close(pVosContext);
7728
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 //Close Watchdog
7730 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7731 vos_watchdog_close(pVosContext);
7732
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307733 //Clean up HDD Nlink Service
7734 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007735#ifdef WLAN_KD_READY_NOTIFIER
7736 nl_srv_exit(pHddCtx->ptt_pid);
7737#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307738 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007739#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307740
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307741#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
7742 if(pHddCtx->cfg_ini->wlanLoggingEnable)
7743 {
7744 wlan_logging_sock_deactivate_svc();
7745 }
7746#endif
7747
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 /* Cancel the vote for XO Core ON.
7749 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7750 * exited at this point
7751 */
7752 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007753 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7755 {
7756 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7757 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007758 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 }
7760
7761 hdd_close_all_adapters( pHddCtx );
7762
7763
7764 //Free up dynamically allocated members inside HDD Adapter
7765 kfree(pHddCtx->cfg_ini);
7766 pHddCtx->cfg_ini= NULL;
7767
7768 /* free the power on lock from platform driver */
7769 if (free_riva_power_on_lock("wlan"))
7770 {
7771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7772 __func__);
7773 }
7774
Jeff Johnson88ba7742013-02-27 14:36:02 -08007775free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007776 /* FTM mode, WIPHY did not registered
7777 If un-register here, system crash will happen */
7778 if (VOS_FTM_MODE != hdd_get_conparam())
7779 {
7780 wiphy_unregister(wiphy) ;
7781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007782 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 if (hdd_is_ssr_required())
7784 {
7785 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007786 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 msleep(5000);
7788 }
7789 hdd_set_ssr_required (VOS_FALSE);
7790}
7791
7792
7793/**---------------------------------------------------------------------------
7794
7795 \brief hdd_update_config_from_nv() - Function to update the contents of
7796 the running configuration with parameters taken from NV storage
7797
7798 \param - pHddCtx - Pointer to the HDD global context
7799
7800 \return - VOS_STATUS_SUCCESS if successful
7801
7802 --------------------------------------------------------------------------*/
7803static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7804{
Jeff Johnson295189b2012-06-20 16:38:30 -07007805 v_BOOL_t itemIsValid = VOS_FALSE;
7806 VOS_STATUS status;
7807 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7808 v_U8_t macLoop;
7809
7810 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7811 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7812 if(status != VOS_STATUS_SUCCESS)
7813 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007814 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 return VOS_STATUS_E_FAILURE;
7816 }
7817
7818 if (itemIsValid == VOS_TRUE)
7819 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007820 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007821 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7822 VOS_MAX_CONCURRENCY_PERSONA);
7823 if(status != VOS_STATUS_SUCCESS)
7824 {
7825 /* Get MAC from NV fail, not update CFG info
7826 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007827 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007828 return VOS_STATUS_E_FAILURE;
7829 }
7830
7831 /* If first MAC is not valid, treat all others are not valid
7832 * Then all MACs will be got from ini file */
7833 if(vos_is_macaddr_zero(&macFromNV[0]))
7834 {
7835 /* MAC address in NV file is not configured yet */
7836 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7837 return VOS_STATUS_E_INVAL;
7838 }
7839
7840 /* Get MAC address from NV, update CFG info */
7841 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7842 {
7843 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7844 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307845 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 /* This MAC is not valid, skip it
7847 * This MAC will be got from ini file */
7848 }
7849 else
7850 {
7851 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7852 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7853 VOS_MAC_ADDR_SIZE);
7854 }
7855 }
7856 }
7857 else
7858 {
7859 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7860 return VOS_STATUS_E_FAILURE;
7861 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007862
Jeff Johnson295189b2012-06-20 16:38:30 -07007863
7864 return VOS_STATUS_SUCCESS;
7865}
7866
7867/**---------------------------------------------------------------------------
7868
7869 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7870
7871 \param - pAdapter - Pointer to the HDD
7872
7873 \return - None
7874
7875 --------------------------------------------------------------------------*/
7876VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7877{
7878 eHalStatus halStatus;
7879 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307880 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007881
Jeff Johnson295189b2012-06-20 16:38:30 -07007882
7883 // Send ready indication to the HDD. This will kick off the MAC
7884 // into a 'running' state and should kick off an initial scan.
7885 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7886 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7887 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307888 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 "code %08d [x%08x]",__func__, halStatus, halStatus );
7890 return VOS_STATUS_E_FAILURE;
7891 }
7892
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307893 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7895 // And RIVA will crash
7896 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7897 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307898 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7899 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7900
7901
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 return VOS_STATUS_SUCCESS;
7903}
7904
Jeff Johnson295189b2012-06-20 16:38:30 -07007905/* wake lock APIs for HDD */
7906void hdd_prevent_suspend(void)
7907{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007908#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007910#else
7911 wcnss_prevent_suspend();
7912#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007913}
7914
7915void hdd_allow_suspend(void)
7916{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007917#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007919#else
7920 wcnss_allow_suspend();
7921#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007922}
7923
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307924void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007925{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007926#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007927 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007928#else
7929 /* Do nothing as there is no API in wcnss for timeout*/
7930#endif
7931}
7932
Jeff Johnson295189b2012-06-20 16:38:30 -07007933/**---------------------------------------------------------------------------
7934
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007935 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7936 information between Host and Riva
7937
7938 This function gets reported version of FW
7939 It also finds the version of Riva headers used to compile the host
7940 It compares the above two and prints a warning if they are different
7941 It gets the SW and HW version string
7942 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7943 indicating the features they support through a bitmap
7944
7945 \param - pHddCtx - Pointer to HDD context
7946
7947 \return - void
7948
7949 --------------------------------------------------------------------------*/
7950
7951void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7952{
7953
7954 tSirVersionType versionCompiled;
7955 tSirVersionType versionReported;
7956 tSirVersionString versionString;
7957 tANI_U8 fwFeatCapsMsgSupported = 0;
7958 VOS_STATUS vstatus;
7959
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007960 memset(&versionCompiled, 0, sizeof(versionCompiled));
7961 memset(&versionReported, 0, sizeof(versionReported));
7962
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007963 /* retrieve and display WCNSS version information */
7964 do {
7965
7966 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7967 &versionCompiled);
7968 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7969 {
7970 hddLog(VOS_TRACE_LEVEL_FATAL,
7971 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007972 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007973 break;
7974 }
7975
7976 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7977 &versionReported);
7978 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7979 {
7980 hddLog(VOS_TRACE_LEVEL_FATAL,
7981 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007982 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007983 break;
7984 }
7985
7986 if ((versionCompiled.major != versionReported.major) ||
7987 (versionCompiled.minor != versionReported.minor) ||
7988 (versionCompiled.version != versionReported.version) ||
7989 (versionCompiled.revision != versionReported.revision))
7990 {
7991 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7992 "Host expected %u.%u.%u.%u\n",
7993 WLAN_MODULE_NAME,
7994 (int)versionReported.major,
7995 (int)versionReported.minor,
7996 (int)versionReported.version,
7997 (int)versionReported.revision,
7998 (int)versionCompiled.major,
7999 (int)versionCompiled.minor,
8000 (int)versionCompiled.version,
8001 (int)versionCompiled.revision);
8002 }
8003 else
8004 {
8005 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8006 WLAN_MODULE_NAME,
8007 (int)versionReported.major,
8008 (int)versionReported.minor,
8009 (int)versionReported.version,
8010 (int)versionReported.revision);
8011 }
8012
8013 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8014 versionString,
8015 sizeof(versionString));
8016 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8017 {
8018 hddLog(VOS_TRACE_LEVEL_FATAL,
8019 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008020 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008021 break;
8022 }
8023
8024 pr_info("%s: WCNSS software version %s\n",
8025 WLAN_MODULE_NAME, versionString);
8026
8027 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8028 versionString,
8029 sizeof(versionString));
8030 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8031 {
8032 hddLog(VOS_TRACE_LEVEL_FATAL,
8033 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008034 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008035 break;
8036 }
8037
8038 pr_info("%s: WCNSS hardware version %s\n",
8039 WLAN_MODULE_NAME, versionString);
8040
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008041 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8042 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008043 send the message only if it the riva is 1.1
8044 minor numbers for different riva branches:
8045 0 -> (1.0)Mainline Build
8046 1 -> (1.1)Mainline Build
8047 2->(1.04) Stability Build
8048 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008049 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008050 ((versionReported.minor>=1) && (versionReported.version>=1)))
8051 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8052 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008053
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008054 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008055 {
8056#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8057 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8058 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8059#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008060 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8061 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8062 {
8063 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8064 }
8065
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008066 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008067 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008068
8069 } while (0);
8070
8071}
8072
8073/**---------------------------------------------------------------------------
8074
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308075 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8076
8077 \param - pHddCtx - Pointer to the hdd context
8078
8079 \return - true if hardware supports 5GHz
8080
8081 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308082boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308083{
8084 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8085 * then hardware support 5Ghz.
8086 */
8087 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8088 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308090 return true;
8091 }
8092 else
8093 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308095 __func__);
8096 return false;
8097 }
8098}
8099
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308100/**---------------------------------------------------------------------------
8101
8102 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8103 generate function
8104
8105 This is generate the random mac address for WLAN interface
8106
8107 \param - pHddCtx - Pointer to HDD context
8108 idx - Start interface index to get auto
8109 generated mac addr.
8110 mac_addr - Mac address
8111
8112 \return - 0 for success, < 0 for failure
8113
8114 --------------------------------------------------------------------------*/
8115
8116static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8117 int idx, v_MACADDR_t mac_addr)
8118{
8119 int i;
8120 unsigned int serialno;
8121 serialno = wcnss_get_serial_number();
8122
8123 if (0 != serialno)
8124 {
8125 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8126 bytes of the serial number that can be used to generate
8127 the other 3 bytes of the MAC address. Mask off all but
8128 the lower 3 bytes (this will also make sure we don't
8129 overflow in the next step) */
8130 serialno &= 0x00FFFFFF;
8131
8132 /* we need a unique address for each session */
8133 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8134
8135 /* autogen other Mac addresses */
8136 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8137 {
8138 /* start with the entire default address */
8139 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8140 /* then replace the lower 3 bytes */
8141 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8142 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8143 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8144
8145 serialno++;
8146 hddLog(VOS_TRACE_LEVEL_ERROR,
8147 "%s: Derived Mac Addr: "
8148 MAC_ADDRESS_STR, __func__,
8149 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8150 }
8151
8152 }
8153 else
8154 {
8155 hddLog(LOGE, FL("Failed to Get Serial NO"));
8156 return -1;
8157 }
8158 return 0;
8159}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308160
8161/**---------------------------------------------------------------------------
8162
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308163 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8164 completed to flush out the scan results
8165
8166 11d scan is done during driver load and is a passive scan on all
8167 channels supported by the device, 11d scans may find some APs on
8168 frequencies which are forbidden to be used in the regulatory domain
8169 the device is operating in. If these APs are notified to the supplicant
8170 it may try to connect to these APs, thus flush out all the scan results
8171 which are present in SME after 11d scan is done.
8172
8173 \return - eHalStatus
8174
8175 --------------------------------------------------------------------------*/
8176static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8177 tANI_U32 scanId, eCsrScanStatus status)
8178{
8179 ENTER();
8180
8181 sme_ScanFlushResult(halHandle, 0);
8182
8183 EXIT();
8184
8185 return eHAL_STATUS_SUCCESS;
8186}
8187
8188/**---------------------------------------------------------------------------
8189
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 \brief hdd_wlan_startup() - HDD init function
8191
8192 This is the driver startup code executed once a WLAN device has been detected
8193
8194 \param - dev - Pointer to the underlying device
8195
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008196 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008197
8198 --------------------------------------------------------------------------*/
8199
8200int hdd_wlan_startup(struct device *dev )
8201{
8202 VOS_STATUS status;
8203 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008204 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 hdd_context_t *pHddCtx = NULL;
8206 v_CONTEXT_t pVosContext= NULL;
8207#ifdef WLAN_BTAMP_FEATURE
8208 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8209 WLANBAP_ConfigType btAmpConfig;
8210 hdd_config_t *pConfig;
8211#endif
8212 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308214 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008215
8216 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 /*
8218 * cfg80211: wiphy allocation
8219 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308220 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008221
8222 if(wiphy == NULL)
8223 {
8224 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008225 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008226 }
8227
8228 pHddCtx = wiphy_priv(wiphy);
8229
Jeff Johnson295189b2012-06-20 16:38:30 -07008230 //Initialize the adapter context to zeros.
8231 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308235 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008236
8237 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8238
8239 /*Get vos context here bcoz vos_open requires it*/
8240 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8241
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008242 if(pVosContext == NULL)
8243 {
8244 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8245 goto err_free_hdd_context;
8246 }
8247
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 //Save the Global VOSS context in adapter context for future.
8249 pHddCtx->pvosContext = pVosContext;
8250
8251 //Save the adapter context in global context for future.
8252 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8253
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 pHddCtx->parent_dev = dev;
8255
8256 init_completion(&pHddCtx->full_pwr_comp_var);
8257 init_completion(&pHddCtx->standby_comp_var);
8258 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008259 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008260 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308261 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308262 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008263
8264#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008265 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008266#else
8267 init_completion(&pHddCtx->driver_crda_req);
8268#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008269
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308270 spin_lock_init(&pHddCtx->schedScan_lock);
8271
Jeff Johnson295189b2012-06-20 16:38:30 -07008272 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8273
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308274#ifdef FEATURE_WLAN_TDLS
8275 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8276 * invoked by other instances also) to protect the concurrent
8277 * access for the Adapters by TDLS module.
8278 */
8279 mutex_init(&pHddCtx->tdls_lock);
8280#endif
8281
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308282 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 // Load all config first as TL config is needed during vos_open
8284 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8285 if(pHddCtx->cfg_ini == NULL)
8286 {
8287 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8288 goto err_free_hdd_context;
8289 }
8290
8291 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8292
8293 // Read and parse the qcom_cfg.ini file
8294 status = hdd_parse_config_ini( pHddCtx );
8295 if ( VOS_STATUS_SUCCESS != status )
8296 {
8297 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8298 __func__, WLAN_INI_FILE);
8299 goto err_config;
8300 }
Arif Hussaind5218912013-12-05 01:10:55 -08008301#ifdef MEMORY_DEBUG
8302 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8303 vos_mem_init();
8304
8305 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8306 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8307#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008308
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308309 /* INI has been read, initialise the configuredMcastBcastFilter with
8310 * INI value as this will serve as the default value
8311 */
8312 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8313 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8314 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308315
8316 if (false == hdd_is_5g_supported(pHddCtx))
8317 {
8318 //5Ghz is not supported.
8319 if (1 != pHddCtx->cfg_ini->nBandCapability)
8320 {
8321 hddLog(VOS_TRACE_LEVEL_INFO,
8322 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8323 pHddCtx->cfg_ini->nBandCapability = 1;
8324 }
8325 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308326
8327 /* If SNR Monitoring is enabled, FW has to parse all beacons
8328 * for calcaluting and storing the average SNR, so set Nth beacon
8329 * filter to 1 to enable FW to parse all the beaocons
8330 */
8331 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8332 {
8333 /* The log level is deliberately set to WARN as overriding
8334 * nthBeaconFilter to 1 will increase power cosumption and this
8335 * might just prove helpful to detect the power issue.
8336 */
8337 hddLog(VOS_TRACE_LEVEL_WARN,
8338 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8339 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8340 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308342 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008344 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008346 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8347 {
8348 hddLog(VOS_TRACE_LEVEL_FATAL,
8349 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8350 goto err_config;
8351 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008353
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008354 // Update VOS trace levels based upon the cfg.ini
8355 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8356 pHddCtx->cfg_ini->vosTraceEnableBAP);
8357 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8358 pHddCtx->cfg_ini->vosTraceEnableTL);
8359 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8360 pHddCtx->cfg_ini->vosTraceEnableWDI);
8361 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8362 pHddCtx->cfg_ini->vosTraceEnableHDD);
8363 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8364 pHddCtx->cfg_ini->vosTraceEnableSME);
8365 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8366 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308367 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8368 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008369 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8370 pHddCtx->cfg_ini->vosTraceEnableWDA);
8371 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8372 pHddCtx->cfg_ini->vosTraceEnableSYS);
8373 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8374 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008375 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8376 pHddCtx->cfg_ini->vosTraceEnableSAP);
8377 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8378 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008379
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 // Update WDI trace levels based upon the cfg.ini
8381 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8382 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8383 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8384 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8385 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8386 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8387 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8388 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008389
Jeff Johnson88ba7742013-02-27 14:36:02 -08008390 if (VOS_FTM_MODE == hdd_get_conparam())
8391 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8393 {
8394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8395 goto err_free_hdd_context;
8396 }
8397 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308398
8399 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008402
Jeff Johnson88ba7742013-02-27 14:36:02 -08008403 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8405 {
8406 status = vos_watchdog_open(pVosContext,
8407 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8408
8409 if(!VOS_IS_STATUS_SUCCESS( status ))
8410 {
8411 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308412 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008413 }
8414 }
8415
8416 pHddCtx->isLogpInProgress = FALSE;
8417 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8420 if(!VOS_IS_STATUS_SUCCESS(status))
8421 {
8422 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 }
8425
Amar Singhala49cbc52013-10-08 18:37:44 -07008426#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008427 /* initialize the NV module. This is required so that
8428 we can initialize the channel information in wiphy
8429 from the NV.bin data. The channel information in
8430 wiphy needs to be initialized before wiphy registration */
8431
8432 status = vos_nv_open();
8433 if (!VOS_IS_STATUS_SUCCESS(status))
8434 {
8435 /* NV module cannot be initialized */
8436 hddLog( VOS_TRACE_LEVEL_FATAL,
8437 "%s: vos_nv_open failed", __func__);
8438 goto err_clkvote;
8439 }
8440
8441 status = vos_init_wiphy_from_nv_bin();
8442 if (!VOS_IS_STATUS_SUCCESS(status))
8443 {
8444 /* NV module cannot be initialized */
8445 hddLog( VOS_TRACE_LEVEL_FATAL,
8446 "%s: vos_init_wiphy failed", __func__);
8447 goto err_vos_nv_close;
8448 }
8449
Amar Singhala49cbc52013-10-08 18:37:44 -07008450#endif
8451
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308452 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 if ( !VOS_IS_STATUS_SUCCESS( status ))
8454 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008455 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308456 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 }
8458
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8460
8461 if ( NULL == pHddCtx->hHal )
8462 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008463 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 goto err_vosclose;
8465 }
8466
Mihir Shetee1093ba2014-01-21 20:13:32 +05308467#ifdef CONFIG_ENABLE_LINUX_REG
8468 /* registration of wiphy dev with cfg80211 */
8469 if (0 > wlan_hdd_cfg80211_register(wiphy))
8470 {
8471 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8472 goto err_vosclose;
8473 }
8474
8475 status = wlan_hdd_init_channels(pHddCtx);
8476 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8477 {
8478 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8479 __func__);
8480 goto err_wiphy_unregister;
8481 }
8482#endif
8483
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008484 status = vos_preStart( pHddCtx->pvosContext );
8485 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8486 {
8487 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308488 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008489 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008490
Arif Hussaineaf68602013-12-30 23:10:44 -08008491 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8492 {
8493 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8494 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8495 __func__, enable_dfs_chan_scan);
8496 }
8497 if (0 == enable_11d || 1 == enable_11d)
8498 {
8499 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8500 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8501 __func__, enable_11d);
8502 }
8503
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008504 /* Note that the vos_preStart() sequence triggers the cfg download.
8505 The cfg download must occur before we update the SME config
8506 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008507 status = hdd_set_sme_config( pHddCtx );
8508
8509 if ( VOS_STATUS_SUCCESS != status )
8510 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008511 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308512 goto err_wiphy_unregister;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008514
8515 //Initialize the WMM module
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07008516 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
8517 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 if (!VOS_IS_STATUS_SUCCESS(status))
8519 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008520 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308521 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008522 }
8523
Jeff Johnson295189b2012-06-20 16:38:30 -07008524 /* In the integrated architecture we update the configuration from
8525 the INI file and from NV before vOSS has been started so that
8526 the final contents are available to send down to the cCPU */
8527
8528 // Apply the cfg.ini to cfg.dat
8529 if (FALSE == hdd_update_config_dat(pHddCtx))
8530 {
8531 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308532 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 }
8534
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308535 // Get mac addr from platform driver
8536 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8537
8538 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008539 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308540 /* Store the mac addr for first interface */
8541 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8542
8543 hddLog(VOS_TRACE_LEVEL_ERROR,
8544 "%s: WLAN Mac Addr: "
8545 MAC_ADDRESS_STR, __func__,
8546 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8547
8548 /* Here, passing Arg2 as 1 because we do not want to change the
8549 last 3 bytes (means non OUI bytes) of first interface mac
8550 addr.
8551 */
8552 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8553 {
8554 hddLog(VOS_TRACE_LEVEL_ERROR,
8555 "%s: Failed to generate wlan interface mac addr "
8556 "using MAC from ini file ", __func__);
8557 }
8558 }
8559 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8560 {
8561 // Apply the NV to cfg.dat
8562 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008563#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8564 /* There was not a valid set of MAC Addresses in NV. See if the
8565 default addresses were modified by the cfg.ini settings. If so,
8566 we'll use them, but if not, we'll autogenerate a set of MAC
8567 addresses based upon the device serial number */
8568
8569 static const v_MACADDR_t default_address =
8570 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008571
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308572 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8573 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 {
8575 /* cfg.ini has the default address, invoke autogen logic */
8576
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308577 /* Here, passing Arg2 as 0 because we want to change the
8578 last 3 bytes (means non OUI bytes) of all the interfaces
8579 mac addr.
8580 */
8581 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8582 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008583 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308584 hddLog(VOS_TRACE_LEVEL_ERROR,
8585 "%s: Failed to generate wlan interface mac addr "
8586 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8587 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 }
8590 else
8591#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8592 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008593 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 "%s: Invalid MAC address in NV, using MAC from ini file "
8595 MAC_ADDRESS_STR, __func__,
8596 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8597 }
8598 }
8599 {
8600 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308601
8602 /* Set the MAC Address Currently this is used by HAL to
8603 * add self sta. Remove this once self sta is added as
8604 * part of session open.
8605 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8607 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8608 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308609
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 if (!HAL_STATUS_SUCCESS( halStatus ))
8611 {
8612 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8613 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mihir Shetee1093ba2014-01-21 20:13:32 +05308614 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008615 }
8616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008617
8618 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8619 Note: Firmware image will be read and downloaded inside vos_start API */
8620 status = vos_start( pHddCtx->pvosContext );
8621 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8622 {
8623 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308624 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 }
8626
Leo Chang6cec3e22014-01-21 15:33:49 -08008627#ifdef FEATURE_WLAN_CH_AVOID
8628 /* Plug in avoid channel notification callback
8629 * This should happen before ADD_SELF_STA
8630 * FW will send first IND with ADD_SELF_STA REQ from host */
8631 sme_AddChAvoidCallback(pHddCtx->hHal,
8632 hdd_hostapd_ch_avoid_cb);
8633#endif /* FEATURE_WLAN_CH_AVOID */
8634
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008635 /* Exchange capability info between Host and FW and also get versioning info from FW */
8636 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008637
8638 status = hdd_post_voss_start_config( pHddCtx );
8639 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8640 {
8641 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8642 __func__);
8643 goto err_vosstop;
8644 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008645
8646#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308647 wlan_hdd_cfg80211_update_reg_info( wiphy );
8648
8649 /* registration of wiphy dev with cfg80211 */
8650 if (0 > wlan_hdd_cfg80211_register(wiphy))
8651 {
8652 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8653 goto err_vosstop;
8654 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008655#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008656
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8658 {
8659 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8660 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8661 }
8662 else
8663 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008664 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8665 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8666 if (pAdapter != NULL)
8667 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308668 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308670 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8671 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8672 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008673
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308674 /* Generate the P2P Device Address. This consists of the device's
8675 * primary MAC address with the locally administered bit set.
8676 */
8677 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008678 }
8679 else
8680 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308681 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8682 if (p2p_dev_addr != NULL)
8683 {
8684 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8685 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8686 }
8687 else
8688 {
8689 hddLog(VOS_TRACE_LEVEL_FATAL,
8690 "%s: Failed to allocate mac_address for p2p_device",
8691 __func__);
8692 goto err_close_adapter;
8693 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008695
8696 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8697 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8698 if ( NULL == pP2pAdapter )
8699 {
8700 hddLog(VOS_TRACE_LEVEL_FATAL,
8701 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008702 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008703 goto err_close_adapter;
8704 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008705 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008707
8708 if( pAdapter == NULL )
8709 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008710 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8711 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008713
Arif Hussain66559122013-11-21 10:11:40 -08008714 if (country_code)
8715 {
8716 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008717 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008718 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8719#ifndef CONFIG_ENABLE_LINUX_REG
8720 hdd_checkandupdate_phymode(pAdapter, country_code);
8721#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008722 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8723 (void *)(tSmeChangeCountryCallback)
8724 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008725 country_code,
8726 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308727 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008728 if (eHAL_STATUS_SUCCESS == ret)
8729 {
Arif Hussaincb607082013-12-20 11:57:42 -08008730 ret = wait_for_completion_interruptible_timeout(
8731 &pAdapter->change_country_code,
8732 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8733
8734 if (0 >= ret)
8735 {
8736 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8737 "%s: SME while setting country code timed out", __func__);
8738 }
Arif Hussain66559122013-11-21 10:11:40 -08008739 }
8740 else
8741 {
Arif Hussaincb607082013-12-20 11:57:42 -08008742 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8743 "%s: SME Change Country code from module param fail ret=%d",
8744 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008745 }
8746 }
8747
Jeff Johnson295189b2012-06-20 16:38:30 -07008748#ifdef WLAN_BTAMP_FEATURE
8749 vStatus = WLANBAP_Open(pVosContext);
8750 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8751 {
8752 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8753 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008754 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 }
8756
8757 vStatus = BSL_Init(pVosContext);
8758 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8759 {
8760 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8761 "%s: Failed to Init BSL",__func__);
8762 goto err_bap_close;
8763 }
8764 vStatus = WLANBAP_Start(pVosContext);
8765 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8766 {
8767 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8768 "%s: Failed to start TL",__func__);
8769 goto err_bap_close;
8770 }
8771
8772 pConfig = pHddCtx->cfg_ini;
8773 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8774 status = WLANBAP_SetConfig(&btAmpConfig);
8775
8776#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008777
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008778#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8779 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8780 {
8781 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8782 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8783 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8784 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8785 }
8786#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008787#ifdef FEATURE_WLAN_SCAN_PNO
8788 /*SME must send channel update configuration to RIVA*/
8789 sme_UpdateChannelConfig(pHddCtx->hHal);
8790#endif
8791
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308792 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8793
Jeff Johnson295189b2012-06-20 16:38:30 -07008794 /* Register with platform driver as client for Suspend/Resume */
8795 status = hddRegisterPmOps(pHddCtx);
8796 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8797 {
8798 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8799#ifdef WLAN_BTAMP_FEATURE
8800 goto err_bap_stop;
8801#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008802 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008803#endif //WLAN_BTAMP_FEATURE
8804 }
8805
Yue Ma0d4891e2013-08-06 17:01:45 -07008806 /* Open debugfs interface */
8807 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8808 {
8809 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8810 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008811 }
8812
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 /* Register TM level change handler function to the platform */
8814 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8815 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8816 {
8817 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8818 goto err_unregister_pmops;
8819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008820
8821 /* register for riva power on lock to platform driver */
8822 if (req_riva_power_on_lock("wlan"))
8823 {
8824 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8825 __func__);
8826 goto err_unregister_pmops;
8827 }
8828
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 // register net device notifier for device change notification
8830 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8831
8832 if(ret < 0)
8833 {
8834 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8835 goto err_free_power_on_lock;
8836 }
8837
8838 //Initialize the nlink service
8839 if(nl_srv_init() != 0)
8840 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308841 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 goto err_reg_netdev;
8843 }
8844
Leo Chang4ce1cc52013-10-21 18:27:15 -07008845#ifdef WLAN_KD_READY_NOTIFIER
8846 pHddCtx->kd_nl_init = 1;
8847#endif /* WLAN_KD_READY_NOTIFIER */
8848
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 //Initialize the BTC service
8850 if(btc_activate_service(pHddCtx) != 0)
8851 {
8852 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8853 goto err_nl_srv;
8854 }
8855
8856#ifdef PTT_SOCK_SVC_ENABLE
8857 //Initialize the PTT service
8858 if(ptt_sock_activate_svc(pHddCtx) != 0)
8859 {
8860 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8861 goto err_nl_srv;
8862 }
8863#endif
8864
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308865#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8866 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8867 {
8868 if(wlan_logging_sock_activate_svc(
8869 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8870 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8871 {
8872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8873 " failed", __func__);
8874 goto err_nl_srv;
8875 }
8876 }
8877#endif
8878
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008882 /* Action frame registered in one adapter which will
8883 * applicable to all interfaces
8884 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008885 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008887
8888 mutex_init(&pHddCtx->sap_lock);
8889
Mihir Shete18156292014-03-11 15:38:30 +05308890 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008891
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008892#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008893#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8894 /* Initialize the wake lcok */
8895 wake_lock_init(&pHddCtx->rx_wake_lock,
8896 WAKE_LOCK_SUSPEND,
8897 "qcom_rx_wakelock");
8898#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008899 /* Initialize the wake lcok */
8900 wake_lock_init(&pHddCtx->sap_wake_lock,
8901 WAKE_LOCK_SUSPEND,
8902 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008903#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008904
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008905 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8906 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008907
8908 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8909 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308910#ifndef CONFIG_ENABLE_LINUX_REG
8911 /*updating wiphy so that regulatory user hints can be processed*/
8912 if (wiphy)
8913 {
8914 regulatory_hint(wiphy, "00");
8915 }
8916#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008917 // Initialize the restart logic
8918 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308919
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008920 //Register the traffic monitor timer now
8921 if ( pHddCtx->cfg_ini->dynSplitscan)
8922 {
8923 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8924 VOS_TIMER_TYPE_SW,
8925 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8926 (void *)pHddCtx);
8927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 goto success;
8929
8930err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008931#ifdef WLAN_KD_READY_NOTIFIER
8932 nl_srv_exit(pHddCtx->ptt_pid);
8933#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008935#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008936err_reg_netdev:
8937 unregister_netdevice_notifier(&hdd_netdev_notifier);
8938
8939err_free_power_on_lock:
8940 free_riva_power_on_lock("wlan");
8941
8942err_unregister_pmops:
8943 hddDevTmUnregisterNotifyCallback(pHddCtx);
8944 hddDeregisterPmOps(pHddCtx);
8945
Yue Ma0d4891e2013-08-06 17:01:45 -07008946 hdd_debugfs_exit(pHddCtx);
8947
Jeff Johnson295189b2012-06-20 16:38:30 -07008948#ifdef WLAN_BTAMP_FEATURE
8949err_bap_stop:
8950 WLANBAP_Stop(pVosContext);
8951#endif
8952
8953#ifdef WLAN_BTAMP_FEATURE
8954err_bap_close:
8955 WLANBAP_Close(pVosContext);
8956#endif
8957
Jeff Johnson295189b2012-06-20 16:38:30 -07008958err_close_adapter:
8959 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008960
8961#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308962 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008963#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008964
8965err_vosstop:
8966 vos_stop(pVosContext);
8967
Mihir Shetee1093ba2014-01-21 20:13:32 +05308968err_wiphy_unregister:
8969#ifdef CONFIG_ENABLE_LINUX_REG
8970 wiphy_unregister(wiphy);
8971#endif
8972
Amar Singhala49cbc52013-10-08 18:37:44 -07008973err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 status = vos_sched_close( pVosContext );
8975 if (!VOS_IS_STATUS_SUCCESS(status)) {
8976 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8977 "%s: Failed to close VOSS Scheduler", __func__);
8978 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8979 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008980 vos_close(pVosContext );
8981
Amar Singhal0a402232013-10-11 20:57:16 -07008982err_vos_nv_close:
8983
c_hpothue6a36282014-03-19 12:27:38 +05308984#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008985 vos_nv_close();
8986
Jeff Johnson295189b2012-06-20 16:38:30 -07008987err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05308988#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008989 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008990
8991err_wdclose:
8992 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8993 vos_watchdog_close(pVosContext);
8994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995err_config:
8996 kfree(pHddCtx->cfg_ini);
8997 pHddCtx->cfg_ini= NULL;
8998
8999err_free_hdd_context:
9000 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 wiphy_free(wiphy) ;
9002 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 VOS_BUG(1);
9004
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009005 if (hdd_is_ssr_required())
9006 {
9007 /* WDI timeout had happened during load, so SSR is needed here */
9008 subsystem_restart("wcnss");
9009 msleep(5000);
9010 }
9011 hdd_set_ssr_required (VOS_FALSE);
9012
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009013 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009014
9015success:
9016 EXIT();
9017 return 0;
9018}
9019
9020/**---------------------------------------------------------------------------
9021
Jeff Johnson32d95a32012-09-10 13:15:23 -07009022 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009023
Jeff Johnson32d95a32012-09-10 13:15:23 -07009024 This is the driver entry point - called in different timeline depending
9025 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009026
9027 \param - None
9028
9029 \return - 0 for success, non zero for failure
9030
9031 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009032static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009033{
9034 VOS_STATUS status;
9035 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009036 struct device *dev = NULL;
9037 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009038#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9039 int max_retries = 0;
9040#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009041
Gopichand Nakkalad0774962013-05-24 11:32:21 +05309042#ifdef WCONN_TRACE_KMSG_LOG_BUFF
9043 vos_wconn_trace_init();
9044#endif
9045
Jeff Johnson295189b2012-06-20 16:38:30 -07009046 ENTER();
9047
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009048#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009050#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009051
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309052 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009053 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9054 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9055
9056 //Power Up Libra WLAN card first if not already powered up
9057 status = vos_chipPowerUp(NULL,NULL,NULL);
9058 if (!VOS_IS_STATUS_SUCCESS(status))
9059 {
9060 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9061 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309062#ifdef WLAN_OPEN_SOURCE
9063 wake_lock_destroy(&wlan_wake_lock);
9064#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009065 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009066 }
9067
Jeff Johnson295189b2012-06-20 16:38:30 -07009068#ifdef ANI_BUS_TYPE_PCI
9069
9070 dev = wcnss_wlan_get_device();
9071
9072#endif // ANI_BUS_TYPE_PCI
9073
9074#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009075
9076#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9077 /* wait until WCNSS driver downloads NV */
9078 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9079 msleep(1000);
9080 }
9081 if (max_retries >= 5) {
9082 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309083#ifdef WLAN_OPEN_SOURCE
9084 wake_lock_destroy(&wlan_wake_lock);
9085#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009086 return -ENODEV;
9087 }
9088#endif
9089
Jeff Johnson295189b2012-06-20 16:38:30 -07009090 dev = wcnss_wlan_get_device();
9091#endif // ANI_BUS_TYPE_PLATFORM
9092
9093
9094 do {
9095 if (NULL == dev) {
9096 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9097 ret_status = -1;
9098 break;
9099 }
9100
Jeff Johnson295189b2012-06-20 16:38:30 -07009101#ifdef TIMER_MANAGER
9102 vos_timer_manager_init();
9103#endif
9104
9105 /* Preopen VOSS so that it is ready to start at least SAL */
9106 status = vos_preOpen(&pVosContext);
9107
9108 if (!VOS_IS_STATUS_SUCCESS(status))
9109 {
9110 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9111 ret_status = -1;
9112 break;
9113 }
9114
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009115#ifndef MODULE
9116 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9117 */
9118 hdd_set_conparam((v_UINT_t)con_mode);
9119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009120
9121 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009122 if (hdd_wlan_startup(dev))
9123 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009125 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 vos_preClose( &pVosContext );
9127 ret_status = -1;
9128 break;
9129 }
9130
9131 /* Cancel the vote for XO Core ON
9132 * This is done here for safety purposes in case we re-initialize without turning
9133 * it OFF in any error scenario.
9134 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009135 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009137 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9139 {
9140 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009141 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 }
9143 } while (0);
9144
9145 if (0 != ret_status)
9146 {
9147 //Assert Deep sleep signal now to put Libra HW in lowest power state
9148 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9149 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9150
9151 //Vote off any PMIC voltage supplies
9152 vos_chipPowerDown(NULL, NULL, NULL);
9153#ifdef TIMER_MANAGER
9154 vos_timer_exit();
9155#endif
9156#ifdef MEMORY_DEBUG
9157 vos_mem_exit();
9158#endif
9159
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009160#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009162#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9164 }
9165 else
9166 {
9167 //Send WLAN UP indication to Nlink Service
9168 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9169
9170 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 }
9172
9173 EXIT();
9174
9175 return ret_status;
9176}
9177
Jeff Johnson32d95a32012-09-10 13:15:23 -07009178/**---------------------------------------------------------------------------
9179
9180 \brief hdd_module_init() - Init Function
9181
9182 This is the driver entry point (invoked when module is loaded using insmod)
9183
9184 \param - None
9185
9186 \return - 0 for success, non zero for failure
9187
9188 --------------------------------------------------------------------------*/
9189#ifdef MODULE
9190static int __init hdd_module_init ( void)
9191{
9192 return hdd_driver_init();
9193}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009194#else /* #ifdef MODULE */
9195static int __init hdd_module_init ( void)
9196{
9197 /* Driver initialization is delayed to fwpath_changed_handler */
9198 return 0;
9199}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009200#endif /* #ifdef MODULE */
9201
Jeff Johnson295189b2012-06-20 16:38:30 -07009202
9203/**---------------------------------------------------------------------------
9204
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009205 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009206
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009207 This is the driver exit point (invoked when module is unloaded using rmmod
9208 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009209
9210 \param - None
9211
9212 \return - None
9213
9214 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009215static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009216{
9217 hdd_context_t *pHddCtx = NULL;
9218 v_CONTEXT_t pVosContext = NULL;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309219 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009220
9221 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9222
9223 //Get the global vos context
9224 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9225
9226 if(!pVosContext)
9227 {
9228 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9229 goto done;
9230 }
9231
9232 //Get the HDD context.
9233 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9234
9235 if(!pHddCtx)
9236 {
9237 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9238 }
9239 else
9240 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309241 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9242
9243 if (pHddCtx->isLogpInProgress)
9244 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309246 "%s:SSR in Progress; block rmmod !!!", __func__);
9247 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9248 msecs_to_jiffies(30000));
9249 if(!rc)
9250 {
9251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9252 "%s:SSR timedout, fatal error", __func__);
9253 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009254 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309255 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009256
Mihir Shete18156292014-03-11 15:38:30 +05309257 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9259
9260 //Do all the cleanup before deregistering the driver
9261 hdd_wlan_exit(pHddCtx);
9262 }
9263
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 vos_preClose( &pVosContext );
9265
9266#ifdef TIMER_MANAGER
9267 vos_timer_exit();
9268#endif
9269#ifdef MEMORY_DEBUG
9270 vos_mem_exit();
9271#endif
9272
Gopichand Nakkalad0774962013-05-24 11:32:21 +05309273#ifdef WCONN_TRACE_KMSG_LOG_BUFF
9274 vos_wconn_trace_exit();
9275#endif
9276
Jeff Johnson295189b2012-06-20 16:38:30 -07009277done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009278#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009280#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9282}
9283
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009284/**---------------------------------------------------------------------------
9285
9286 \brief hdd_module_exit() - Exit function
9287
9288 This is the driver exit point (invoked when module is unloaded using rmmod)
9289
9290 \param - None
9291
9292 \return - None
9293
9294 --------------------------------------------------------------------------*/
9295static void __exit hdd_module_exit(void)
9296{
9297 hdd_driver_exit();
9298}
9299
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009300#ifdef MODULE
9301static int fwpath_changed_handler(const char *kmessage,
9302 struct kernel_param *kp)
9303{
Jeff Johnson76052702013-04-16 13:55:05 -07009304 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009305}
9306
9307static int con_mode_handler(const char *kmessage,
9308 struct kernel_param *kp)
9309{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009310 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009311}
9312#else /* #ifdef MODULE */
9313/**---------------------------------------------------------------------------
9314
Jeff Johnson76052702013-04-16 13:55:05 -07009315 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009316
Jeff Johnson76052702013-04-16 13:55:05 -07009317 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009318 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009319 - invoked when module parameter fwpath is modified from userspace to signal
9320 initializing the WLAN driver or when con_mode is modified from userspace
9321 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009322
9323 \return - 0 for success, non zero for failure
9324
9325 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009326static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009327{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009328 int ret_status;
9329
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009330 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009331 ret_status = hdd_driver_init();
9332 wlan_hdd_inited = ret_status ? 0 : 1;
9333 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009334 }
9335
9336 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009337
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009338 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009339
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009340 ret_status = hdd_driver_init();
9341 wlan_hdd_inited = ret_status ? 0 : 1;
9342 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009343}
9344
Jeff Johnson295189b2012-06-20 16:38:30 -07009345/**---------------------------------------------------------------------------
9346
Jeff Johnson76052702013-04-16 13:55:05 -07009347 \brief fwpath_changed_handler() - Handler Function
9348
9349 Handle changes to the fwpath parameter
9350
9351 \return - 0 for success, non zero for failure
9352
9353 --------------------------------------------------------------------------*/
9354static int fwpath_changed_handler(const char *kmessage,
9355 struct kernel_param *kp)
9356{
9357 int ret;
9358
9359 ret = param_set_copystring(kmessage, kp);
9360 if (0 == ret)
9361 ret = kickstart_driver();
9362 return ret;
9363}
9364
9365/**---------------------------------------------------------------------------
9366
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009367 \brief con_mode_handler() -
9368
9369 Handler function for module param con_mode when it is changed by userspace
9370 Dynamically linked - do nothing
9371 Statically linked - exit and init driver, as in rmmod and insmod
9372
Jeff Johnson76052702013-04-16 13:55:05 -07009373 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009374
Jeff Johnson76052702013-04-16 13:55:05 -07009375 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009376
9377 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009378static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009379{
Jeff Johnson76052702013-04-16 13:55:05 -07009380 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009381
Jeff Johnson76052702013-04-16 13:55:05 -07009382 ret = param_set_int(kmessage, kp);
9383 if (0 == ret)
9384 ret = kickstart_driver();
9385 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009386}
9387#endif /* #ifdef MODULE */
9388
9389/**---------------------------------------------------------------------------
9390
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 \brief hdd_get_conparam() -
9392
9393 This is the driver exit point (invoked when module is unloaded using rmmod)
9394
9395 \param - None
9396
9397 \return - tVOS_CON_MODE
9398
9399 --------------------------------------------------------------------------*/
9400tVOS_CON_MODE hdd_get_conparam ( void )
9401{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009402#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009404#else
9405 return (tVOS_CON_MODE)curr_con_mode;
9406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009407}
9408void hdd_set_conparam ( v_UINT_t newParam )
9409{
9410 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009411#ifndef MODULE
9412 curr_con_mode = con_mode;
9413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009414}
9415/**---------------------------------------------------------------------------
9416
9417 \brief hdd_softap_sta_deauth() - function
9418
9419 This to take counter measure to handle deauth req from HDD
9420
9421 \param - pAdapter - Pointer to the HDD
9422
9423 \param - enable - boolean value
9424
9425 \return - None
9426
9427 --------------------------------------------------------------------------*/
9428
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009429VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009430{
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009432 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009433
9434 ENTER();
9435
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009436 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9437 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009438
9439 //Ignore request to deauth bcmc station
9440 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009441 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009442
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009443 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009444
9445 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009446 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009447}
9448
9449/**---------------------------------------------------------------------------
9450
9451 \brief hdd_softap_sta_disassoc() - function
9452
9453 This to take counter measure to handle deauth req from HDD
9454
9455 \param - pAdapter - Pointer to the HDD
9456
9457 \param - enable - boolean value
9458
9459 \return - None
9460
9461 --------------------------------------------------------------------------*/
9462
9463void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9464{
9465 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9466
9467 ENTER();
9468
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309469 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
9471 //Ignore request to disassoc bcmc station
9472 if( pDestMacAddress[0] & 0x1 )
9473 return;
9474
9475 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9476}
9477
9478void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9479{
9480 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9481
9482 ENTER();
9483
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309484 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009485
9486 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9487}
9488
Jeff Johnson295189b2012-06-20 16:38:30 -07009489/**---------------------------------------------------------------------------
9490 *
9491 * \brief hdd_get__concurrency_mode() -
9492 *
9493 *
9494 * \param - None
9495 *
9496 * \return - CONCURRENCY MODE
9497 *
9498 * --------------------------------------------------------------------------*/
9499tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9500{
9501 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9502 hdd_context_t *pHddCtx;
9503
9504 if (NULL != pVosContext)
9505 {
9506 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9507 if (NULL != pHddCtx)
9508 {
9509 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9510 }
9511 }
9512
9513 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009514 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 return VOS_STA;
9516}
9517
9518/* Decide whether to allow/not the apps power collapse.
9519 * Allow apps power collapse if we are in connected state.
9520 * if not, allow only if we are in IMPS */
9521v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9522{
9523 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009524 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009525 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009526 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9527 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9528 hdd_adapter_t *pAdapter = NULL;
9529 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009530 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009531
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9533 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009534
Yathish9f22e662012-12-10 14:21:35 -08009535 concurrent_state = hdd_get_concurrency_mode();
9536
9537#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9538 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9539 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9540 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9541 return TRUE;
9542#endif
9543
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 /*loop through all adapters. TBD fix for Concurrency */
9545 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9546 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9547 {
9548 pAdapter = pAdapterNode->pAdapter;
9549 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9550 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9551 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009552 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009554 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009555 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9556 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009558 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009559 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9560 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 return FALSE;
9562 }
9563 }
9564 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9565 pAdapterNode = pNext;
9566 }
9567 return TRUE;
9568}
9569
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009570/* Decides whether to send suspend notification to Riva
9571 * if any adapter is in BMPS; then it is required */
9572v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9573{
9574 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9575 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9576
9577 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9578 {
9579 return TRUE;
9580 }
9581 return FALSE;
9582}
9583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9585{
9586 switch(mode)
9587 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009588 case VOS_STA_MODE:
9589 case VOS_P2P_CLIENT_MODE:
9590 case VOS_P2P_GO_MODE:
9591 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009592 pHddCtx->concurrency_mode |= (1 << mode);
9593 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 break;
9595 default:
9596 break;
9597
9598 }
9599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9600 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9601}
9602
9603
9604void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9605{
9606 switch(mode)
9607 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009608 case VOS_STA_MODE:
9609 case VOS_P2P_CLIENT_MODE:
9610 case VOS_P2P_GO_MODE:
9611 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 pHddCtx->no_of_sessions[mode]--;
9613 if (!(pHddCtx->no_of_sessions[mode]))
9614 pHddCtx->concurrency_mode &= (~(1 << mode));
9615 break;
9616 default:
9617 break;
9618 }
9619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9620 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9621}
9622
Jeff Johnsone7245742012-09-05 17:12:55 -07009623/**---------------------------------------------------------------------------
9624 *
9625 * \brief wlan_hdd_restart_init
9626 *
9627 * This function initalizes restart timer/flag. An internal function.
9628 *
9629 * \param - pHddCtx
9630 *
9631 * \return - None
9632 *
9633 * --------------------------------------------------------------------------*/
9634
9635static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9636{
9637 /* Initialize */
9638 pHddCtx->hdd_restart_retries = 0;
9639 atomic_set(&pHddCtx->isRestartInProgress, 0);
9640 vos_timer_init(&pHddCtx->hdd_restart_timer,
9641 VOS_TIMER_TYPE_SW,
9642 wlan_hdd_restart_timer_cb,
9643 pHddCtx);
9644}
9645/**---------------------------------------------------------------------------
9646 *
9647 * \brief wlan_hdd_restart_deinit
9648 *
9649 * This function cleans up the resources used. An internal function.
9650 *
9651 * \param - pHddCtx
9652 *
9653 * \return - None
9654 *
9655 * --------------------------------------------------------------------------*/
9656
9657static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9658{
9659
9660 VOS_STATUS vos_status;
9661 /* Block any further calls */
9662 atomic_set(&pHddCtx->isRestartInProgress, 1);
9663 /* Cleanup */
9664 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9665 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309666 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009667 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9668 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309669 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009670
9671}
9672
9673/**---------------------------------------------------------------------------
9674 *
9675 * \brief wlan_hdd_framework_restart
9676 *
9677 * This function uses a cfg80211 API to start a framework initiated WLAN
9678 * driver module unload/load.
9679 *
9680 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9681 *
9682 *
9683 * \param - pHddCtx
9684 *
9685 * \return - VOS_STATUS_SUCCESS: Success
9686 * VOS_STATUS_E_EMPTY: Adapter is Empty
9687 * VOS_STATUS_E_NOMEM: No memory
9688
9689 * --------------------------------------------------------------------------*/
9690
9691static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9692{
9693 VOS_STATUS status = VOS_STATUS_SUCCESS;
9694 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009695 int len = (sizeof (struct ieee80211_mgmt));
9696 struct ieee80211_mgmt *mgmt = NULL;
9697
9698 /* Prepare the DEAUTH managment frame with reason code */
9699 mgmt = kzalloc(len, GFP_KERNEL);
9700 if(mgmt == NULL)
9701 {
9702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9703 "%s: memory allocation failed (%d bytes)", __func__, len);
9704 return VOS_STATUS_E_NOMEM;
9705 }
9706 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009707
9708 /* Iterate over all adapters/devices */
9709 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9710 do
9711 {
9712 if( (status == VOS_STATUS_SUCCESS) &&
9713 pAdapterNode &&
9714 pAdapterNode->pAdapter)
9715 {
9716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9717 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9718 pAdapterNode->pAdapter->dev->name,
9719 pAdapterNode->pAdapter->device_mode,
9720 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009721 /*
9722 * CFG80211 event to restart the driver
9723 *
9724 * 'cfg80211_send_unprot_deauth' sends a
9725 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9726 * of SME(Linux Kernel) state machine.
9727 *
9728 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9729 * the driver.
9730 *
9731 */
9732
9733 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009734 }
9735 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9736 pAdapterNode = pNext;
9737 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9738
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009739
9740 /* Free the allocated management frame */
9741 kfree(mgmt);
9742
Jeff Johnsone7245742012-09-05 17:12:55 -07009743 /* Retry until we unload or reach max count */
9744 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9745 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9746
9747 return status;
9748
9749}
9750/**---------------------------------------------------------------------------
9751 *
9752 * \brief wlan_hdd_restart_timer_cb
9753 *
9754 * Restart timer callback. An internal function.
9755 *
9756 * \param - User data:
9757 *
9758 * \return - None
9759 *
9760 * --------------------------------------------------------------------------*/
9761
9762void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9763{
9764 hdd_context_t *pHddCtx = usrDataForCallback;
9765 wlan_hdd_framework_restart(pHddCtx);
9766 return;
9767
9768}
9769
9770
9771/**---------------------------------------------------------------------------
9772 *
9773 * \brief wlan_hdd_restart_driver
9774 *
9775 * This function sends an event to supplicant to restart the WLAN driver.
9776 *
9777 * This function is called from vos_wlanRestart.
9778 *
9779 * \param - pHddCtx
9780 *
9781 * \return - VOS_STATUS_SUCCESS: Success
9782 * VOS_STATUS_E_EMPTY: Adapter is Empty
9783 * VOS_STATUS_E_ALREADY: Request already in progress
9784
9785 * --------------------------------------------------------------------------*/
9786VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9787{
9788 VOS_STATUS status = VOS_STATUS_SUCCESS;
9789
9790 /* A tight check to make sure reentrancy */
9791 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9792 {
9793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9794 "%s: WLAN restart is already in progress", __func__);
9795
9796 return VOS_STATUS_E_ALREADY;
9797 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009798 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009799#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009800 wcnss_reset_intr();
9801#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009802
Jeff Johnsone7245742012-09-05 17:12:55 -07009803 return status;
9804}
9805
Mihir Shetee1093ba2014-01-21 20:13:32 +05309806/**---------------------------------------------------------------------------
9807 *
9808 * \brief wlan_hdd_init_channels
9809 *
9810 * This function is used to initialize the channel list in CSR
9811 *
9812 * This function is called from hdd_wlan_startup
9813 *
9814 * \param - pHddCtx: HDD context
9815 *
9816 * \return - VOS_STATUS_SUCCESS: Success
9817 * VOS_STATUS_E_FAULT: Failure reported by SME
9818
9819 * --------------------------------------------------------------------------*/
9820static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9821{
9822 eHalStatus status;
9823
9824 status = sme_InitChannels(pHddCtx->hHal);
9825 if (HAL_STATUS_SUCCESS(status))
9826 {
9827 return VOS_STATUS_SUCCESS;
9828 }
9829 else
9830 {
9831 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9832 __func__, status);
9833 return VOS_STATUS_E_FAULT;
9834 }
9835}
9836
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009837/*
9838 * API to find if there is any STA or P2P-Client is connected
9839 */
9840VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9841{
9842 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9843}
Jeff Johnsone7245742012-09-05 17:12:55 -07009844
Jeff Johnson295189b2012-06-20 16:38:30 -07009845//Register the module init/exit functions
9846module_init(hdd_module_init);
9847module_exit(hdd_module_exit);
9848
9849MODULE_LICENSE("Dual BSD/GPL");
9850MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9851MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9852
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009853module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9854 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009855
Jeff Johnson76052702013-04-16 13:55:05 -07009856module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009857 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009858
9859module_param(enable_dfs_chan_scan, int,
9860 S_IRUSR | S_IRGRP | S_IROTH);
9861
9862module_param(enable_11d, int,
9863 S_IRUSR | S_IRGRP | S_IROTH);
9864
9865module_param(country_code, charp,
9866 S_IRUSR | S_IRGRP | S_IROTH);