blob: 3730c1865b920b482c954b2d40f5cff346fc0675 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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 Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
210 struct sk_buff *skb);
211
212#ifdef WLAN_FEATURE_PACKET_FILTERING
213static void hdd_set_multicast_list(struct net_device *dev);
214#endif
215
216void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
217
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800218#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800219void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
220static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700221static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
222 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
223 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700224static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
225 tANI_U8 *pTargetApBssid,
226 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800227#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530228
229/* Store WLAN driver info in a global variable such that crash debugger
230 can extract it from driver debug symbol and crashdump for post processing */
231tANI_U8 g_wlan_driver[ ] = "pronto_driver";
232
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530238const char * hdd_device_modetoString(v_U8_t device_mode)
239{
240 switch(device_mode)
241 {
242 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
243 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
246 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
247 CASE_RETURN_STRING( WLAN_HDD_FTM );
248 CASE_RETURN_STRING( WLAN_HDD_IBSS );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
250 default:
251 return "device_mode Unknown";
252 }
253}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530254
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530255static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700256 unsigned long state,
257 void *ndev)
258{
259 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#ifdef WLAN_BTAMP_FEATURE
263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530265 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
267 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700269 (strncmp(dev->name, "p2p", 3)))
270 return NOTIFY_DONE;
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 VOS_ASSERT(0);
279 return NOTIFY_DONE;
280 }
281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
283 if (NULL == pHddCtx)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
286 VOS_ASSERT(0);
287 return NOTIFY_DONE;
288 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800289 if (pHddCtx->isLogpInProgress)
290 return NOTIFY_DONE;
291
Jeff Johnson27cee452013-03-27 11:10:24 -0700292
293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
294 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 switch (state) {
297 case NETDEV_REGISTER:
298 break;
299
300 case NETDEV_UNREGISTER:
301 break;
302
303 case NETDEV_UP:
304 break;
305
306 case NETDEV_DOWN:
307 break;
308
309 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700310 if(TRUE == pAdapter->isLinkUpSvcNeeded)
311 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 break;
313
314 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530316 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
319 "%s: Timeout occurred while waiting for abortscan %ld",
320 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 }
322 else
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530325 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 status = WLANBAP_StopAmp();
330 if(VOS_STATUS_SUCCESS != status )
331 {
332 pHddCtx->isAmpAllowed = VOS_TRUE;
333 hddLog(VOS_TRACE_LEVEL_FATAL,
334 "%s: Failed to stop AMP", __func__);
335 }
336 else
337 {
338 //a state m/c implementation in PAL is TBD to avoid this delay
339 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700340 if ( pHddCtx->isAmpAllowed )
341 {
342 WLANBAP_DeregisterFromHCI();
343 pHddCtx->isAmpAllowed = VOS_FALSE;
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346#endif //WLAN_BTAMP_FEATURE
347 break;
348
349 default:
350 break;
351 }
352
353 return NOTIFY_DONE;
354}
355
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530356static int hdd_netdev_notifier_call(struct notifier_block * nb,
357 unsigned long state,
358 void *ndev)
359{
360 int ret;
361 vos_ssr_protect(__func__);
362 ret = __hdd_netdev_notifier_call( nb, state, ndev);
363 vos_ssr_unprotect(__func__);
364 return ret;
365}
366
Jeff Johnson295189b2012-06-20 16:38:30 -0700367struct notifier_block hdd_netdev_notifier = {
368 .notifier_call = hdd_netdev_notifier_call,
369};
370
371/*---------------------------------------------------------------------------
372 * Function definitions
373 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700374void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
375void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700377static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700378#ifndef MODULE
379/* current con_mode - used only for statically linked driver
380 * con_mode is changed by userspace to indicate a mode change which will
381 * result in calling the module exit and init functions. The module
382 * exit function will clean up based on the value of con_mode prior to it
383 * being changed by userspace. So curr_con_mode records the current con_mode
384 * for exit when con_mode becomes the next mode for init
385 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700386static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700387#endif
388
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800389/**---------------------------------------------------------------------------
390
391 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
392
393 Called immediately after the cfg.ini is read in order to configure
394 the desired trace levels.
395
396 \param - moduleId - module whose trace level is being configured
397 \param - bitmask - bitmask of log levels to be enabled
398
399 \return - void
400
401 --------------------------------------------------------------------------*/
402static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
403{
404 wpt_tracelevel level;
405
406 /* if the bitmask is the default value, then a bitmask was not
407 specified in cfg.ini, so leave the logging level alone (it
408 will remain at the "compiled in" default value) */
409 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
410 {
411 return;
412 }
413
414 /* a mask was specified. start by disabling all logging */
415 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
416
417 /* now cycle through the bitmask until all "set" bits are serviced */
418 level = VOS_TRACE_LEVEL_FATAL;
419 while (0 != bitmask)
420 {
421 if (bitmask & 1)
422 {
423 vos_trace_setValue(moduleId, level, 1);
424 }
425 level++;
426 bitmask >>= 1;
427 }
428}
429
430
Jeff Johnson295189b2012-06-20 16:38:30 -0700431/**---------------------------------------------------------------------------
432
433 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
434
435 Called immediately after the cfg.ini is read in order to configure
436 the desired trace levels in the WDI.
437
438 \param - moduleId - module whose trace level is being configured
439 \param - bitmask - bitmask of log levels to be enabled
440
441 \return - void
442
443 --------------------------------------------------------------------------*/
444static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
445{
446 wpt_tracelevel level;
447
448 /* if the bitmask is the default value, then a bitmask was not
449 specified in cfg.ini, so leave the logging level alone (it
450 will remain at the "compiled in" default value) */
451 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
452 {
453 return;
454 }
455
456 /* a mask was specified. start by disabling all logging */
457 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
458
459 /* now cycle through the bitmask until all "set" bits are serviced */
460 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
461 while (0 != bitmask)
462 {
463 if (bitmask & 1)
464 {
465 wpalTraceSetLevel(moduleId, level, 1);
466 }
467 level++;
468 bitmask >>= 1;
469 }
470}
Jeff Johnson295189b2012-06-20 16:38:30 -0700471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530472/*
473 * FUNCTION: wlan_hdd_validate_context
474 * This function is used to check the HDD context
475 */
476int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
477{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478
479 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
480 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 "%s: HDD context is Null", __func__);
483 return -ENODEV;
484 }
485
486 if (pHddCtx->isLogpInProgress)
487 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530489 "%s: LOGP %s. Ignore!!", __func__,
490 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
491 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 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 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530498 "%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
Agarwal Ashish738843c2014-09-25 12:27:56 +0530682 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
683 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700684 {
685 /*New country doesn't support DFS */
686 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
687 }
688 else
689 {
690 /*New country Supports DFS as well resetting value back from .ini*/
691 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
692 }
693
694}
695
Rajeev79dbe4c2013-10-05 11:03:42 +0530696#ifdef FEATURE_WLAN_BATCH_SCAN
697
698/**---------------------------------------------------------------------------
699
700 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
701 input string
702
703 This function extracts assigned integer from string in below format:
704 "STRING=10" : extracts integer 10 from this string
705
706 \param - pInPtr Pointer to input string
707 \param - base Base for string to int conversion(10 for decimal 16 for hex)
708 \param - pOutPtr Pointer to variable in which extracted integer needs to be
709 assigned
710 \param - pLastArg to tell whether it is last arguement in input string or
711 not
712
713 \return - NULL for failure cases
714 pointer to next arguement in input string for success cases
715 --------------------------------------------------------------------------*/
716static tANI_U8 *
717hdd_extract_assigned_int_from_str
718(
719 tANI_U8 *pInPtr,
720 tANI_U8 base,
721 tANI_U32 *pOutPtr,
722 tANI_U8 *pLastArg
723)
724{
725 int tempInt;
726 int v = 0;
727 char buf[32];
728 int val = 0;
729 *pLastArg = FALSE;
730
731 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
732 if (NULL == pInPtr)
733 {
734 return NULL;
735 }
736
737 pInPtr++;
738
739 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
740
741 val = sscanf(pInPtr, "%32s ", buf);
742 if (val < 0 && val > strlen(pInPtr))
743 {
744 return NULL;
745 }
746 pInPtr += val;
747 v = kstrtos32(buf, base, &tempInt);
748 if (v < 0)
749 {
750 return NULL;
751 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800752 if (tempInt < 0)
753 {
754 tempInt = 0;
755 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530756 *pOutPtr = tempInt;
757
758 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
759 if (NULL == pInPtr)
760 {
761 *pLastArg = TRUE;
762 return NULL;
763 }
764 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
765
766 return pInPtr;
767}
768
769/**---------------------------------------------------------------------------
770
771 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
772 input string
773
774 This function extracts assigned character from string in below format:
775 "STRING=A" : extracts char 'A' from this string
776
777 \param - pInPtr Pointer to input string
778 \param - pOutPtr Pointer to variable in which extracted char needs to be
779 assigned
780 \param - pLastArg to tell whether it is last arguement in input string or
781 not
782
783 \return - NULL for failure cases
784 pointer to next arguement in input string for success cases
785 --------------------------------------------------------------------------*/
786static tANI_U8 *
787hdd_extract_assigned_char_from_str
788(
789 tANI_U8 *pInPtr,
790 tANI_U8 *pOutPtr,
791 tANI_U8 *pLastArg
792)
793{
794 *pLastArg = FALSE;
795
796 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
797 if (NULL == pInPtr)
798 {
799 return NULL;
800 }
801
802 pInPtr++;
803
804 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
805
806 *pOutPtr = *pInPtr;
807
808 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
809 if (NULL == pInPtr)
810 {
811 *pLastArg = TRUE;
812 return NULL;
813 }
814 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
815
816 return pInPtr;
817}
818
819
820/**---------------------------------------------------------------------------
821
822 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
823
824 This function parses set batch scan command in below format:
825 WLS_BATCHING_SET <space> followed by below arguements
826 "SCANFREQ=XX" : Optional defaults to 30 sec
827 "MSCAN=XX" : Required number of scans to attempt to batch
828 "BESTN=XX" : Best Network (RSSI) defaults to 16
829 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
830 A. implies only 5 GHz , B. implies only 2.4GHz
831 "RTT=X" : optional defaults to 0
832 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
833 error
834
835 For example input commands:
836 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
837 translated into set batch scan with following parameters:
838 a) Frequence 60 seconds
839 b) Batch 10 scans together
840 c) Best RSSI to be 20
841 d) 5GHz band only
842 e) RTT is equal to 0
843
844 \param - pValue Pointer to input channel list
845 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
846
847 \return - 0 for success non-zero for failure
848
849 --------------------------------------------------------------------------*/
850static int
851hdd_parse_set_batchscan_command
852(
853 tANI_U8 *pValue,
854 tSirSetBatchScanReq *pHddSetBatchScanReq
855)
856{
857 tANI_U8 *inPtr = pValue;
858 tANI_U8 val = 0;
859 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 tANI_U32 nScanFreq;
861 tANI_U32 nMscan;
862 tANI_U32 nBestN;
863 tANI_U8 ucRfBand;
864 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800865 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530866
867 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800868 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
869 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
870 nRtt = 0;
871 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530872
873 /*go to space after WLS_BATCHING_SET command*/
874 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
875 /*no argument after the command*/
876 if (NULL == inPtr)
877 {
878 return -EINVAL;
879 }
880
881 /*no space after the command*/
882 else if (SPACE_ASCII_VALUE != *inPtr)
883 {
884 return -EINVAL;
885 }
886
887 /*removing empty spaces*/
888 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
889
890 /*no argument followed by spaces*/
891 if ('\0' == *inPtr)
892 {
893 return -EINVAL;
894 }
895
896 /*check and parse SCANFREQ*/
897 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
898 {
899 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901
Rajeev Kumarc933d982013-11-18 20:04:20 -0800902 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800904 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800905 }
906
Rajeev79dbe4c2013-10-05 11:03:42 +0530907 if ( (NULL == inPtr) || (TRUE == lastArg))
908 {
909 return -EINVAL;
910 }
911 }
912
913 /*check and parse MSCAN*/
914 if ((strncmp(inPtr, "MSCAN", 5) == 0))
915 {
916 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800917 &nMscan, &lastArg);
918
919 if (0 == nMscan)
920 {
921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
922 "invalid MSCAN=%d", nMscan);
923 return -EINVAL;
924 }
925
Rajeev79dbe4c2013-10-05 11:03:42 +0530926 if (TRUE == lastArg)
927 {
928 goto done;
929 }
930 else if (NULL == inPtr)
931 {
932 return -EINVAL;
933 }
934 }
935 else
936 {
937 return -EINVAL;
938 }
939
940 /*check and parse BESTN*/
941 if ((strncmp(inPtr, "BESTN", 5) == 0))
942 {
943 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945
Rajeev Kumarc933d982013-11-18 20:04:20 -0800946 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800947 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800948 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800949 }
950
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 if (TRUE == lastArg)
952 {
953 goto done;
954 }
955 else if (NULL == inPtr)
956 {
957 return -EINVAL;
958 }
959 }
960
961 /*check and parse CHANNEL*/
962 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
963 {
964 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800965
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 if (('A' == val) || ('a' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else if (('B' == val) || ('b' == val))
971 {
c_hpothuebf89732014-02-25 13:00:24 +0530972 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 }
974 else
975 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800976 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
977 }
978
979 if (TRUE == lastArg)
980 {
981 goto done;
982 }
983 else if (NULL == inPtr)
984 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530985 return -EINVAL;
986 }
987 }
988
989 /*check and parse RTT*/
990 if ((strncmp(inPtr, "RTT", 3) == 0))
991 {
992 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530994 if (TRUE == lastArg)
995 {
996 goto done;
997 }
998 if (NULL == inPtr)
999 {
1000 return -EINVAL;
1001 }
1002 }
1003
1004
1005done:
1006
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001007 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1008 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1009 pHddSetBatchScanReq->bestNetwork = nBestN;
1010 pHddSetBatchScanReq->rfBand = ucRfBand;
1011 pHddSetBatchScanReq->rtt = nRtt;
1012
Rajeev79dbe4c2013-10-05 11:03:42 +05301013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1014 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1015 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1016 pHddSetBatchScanReq->scanFrequency,
1017 pHddSetBatchScanReq->numberOfScansToBatch,
1018 pHddSetBatchScanReq->bestNetwork,
1019 pHddSetBatchScanReq->rfBand,
1020 pHddSetBatchScanReq->rtt);
1021
1022 return 0;
1023}/*End of hdd_parse_set_batchscan_command*/
1024
1025/**---------------------------------------------------------------------------
1026
1027 \brief hdd_set_batch_scan_req_callback () - This function is called after
1028 receiving set batch scan response from FW and it saves set batch scan
1029 response data FW to HDD context and sets the completion event on
1030 which hdd_ioctl is waiting
1031
1032 \param - callbackContext Pointer to HDD adapter
1033 \param - pRsp Pointer to set batch scan response data received from FW
1034
1035 \return - nothing
1036
1037 --------------------------------------------------------------------------*/
1038static void hdd_set_batch_scan_req_callback
1039(
1040 void *callbackContext,
1041 tSirSetBatchScanRsp *pRsp
1042)
1043{
1044 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1045 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1046
1047 /*sanity check*/
1048 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1049 {
1050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1051 "%s: Invalid pAdapter magic", __func__);
1052 VOS_ASSERT(0);
1053 return;
1054 }
1055 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1056
1057 /*save set batch scan response*/
1058 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1059
1060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1061 "Received set batch scan rsp from FW with nScansToBatch=%d",
1062 pHddSetBatchScanRsp->nScansToBatch);
1063
1064 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1065 complete(&pAdapter->hdd_set_batch_scan_req_var);
1066
1067 return;
1068}/*End of hdd_set_batch_scan_req_callback*/
1069
1070
1071/**---------------------------------------------------------------------------
1072
1073 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1074 info in hdd batch scan response queue
1075
1076 \param - pAdapter Pointer to hdd adapter
1077 \param - pAPMetaInfo Pointer to access point meta info
1078 \param - scanId scan ID of batch scan response
1079 \param - isLastAp tells whether AP is last AP in batch scan response or not
1080
1081 \return - nothing
1082
1083 --------------------------------------------------------------------------*/
1084static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1085 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1086{
1087 tHddBatchScanRsp *pHead;
1088 tHddBatchScanRsp *pNode;
1089 tHddBatchScanRsp *pPrev;
1090 tHddBatchScanRsp *pTemp;
1091 tANI_U8 ssidLen;
1092
1093 /*head of hdd batch scan response queue*/
1094 pHead = pAdapter->pBatchScanRsp;
1095
1096 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1097 if (NULL == pNode)
1098 {
1099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1100 "%s: Could not allocate memory", __func__);
1101 VOS_ASSERT(0);
1102 return;
1103 }
1104
1105 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1106 sizeof(pNode->ApInfo.bssid));
1107 ssidLen = strlen(pApMetaInfo->ssid);
1108 if (SIR_MAX_SSID_SIZE < ssidLen)
1109 {
1110 /*invalid scan result*/
1111 vos_mem_free(pNode);
1112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1113 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1114 return;
1115 }
1116 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1117 /*null terminate ssid*/
1118 pNode->ApInfo.ssid[ssidLen] = '\0';
1119 pNode->ApInfo.ch = pApMetaInfo->ch;
1120 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1121 pNode->ApInfo.age = pApMetaInfo->timestamp;
1122 pNode->ApInfo.batchId = scanId;
1123 pNode->ApInfo.isLastAp = isLastAp;
1124
1125 pNode->pNext = NULL;
1126 if (NULL == pHead)
1127 {
1128 pAdapter->pBatchScanRsp = pNode;
1129 }
1130 else
1131 {
1132 pTemp = pHead;
1133 while (NULL != pTemp)
1134 {
1135 pPrev = pTemp;
1136 pTemp = pTemp->pNext;
1137 }
1138 pPrev->pNext = pNode;
1139 }
1140
1141 return;
1142}/*End of hdd_populate_batch_scan_rsp_queue*/
1143
1144/**---------------------------------------------------------------------------
1145
1146 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1147 receiving batch scan response indication from FW. It saves get batch scan
1148 response data in HDD batch scan response queue. This callback sets the
1149 completion event on which hdd_ioctl is waiting only after getting complete
1150 batch scan response data from FW
1151
1152 \param - callbackContext Pointer to HDD adapter
1153 \param - pRsp Pointer to get batch scan response data received from FW
1154
1155 \return - nothing
1156
1157 --------------------------------------------------------------------------*/
1158static void hdd_batch_scan_result_ind_callback
1159(
1160 void *callbackContext,
1161 void *pRsp
1162)
1163{
1164 v_BOOL_t isLastAp;
1165 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001166 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301167 tANI_U32 numberScanList;
1168 tANI_U32 nextScanListOffset;
1169 tANI_U32 nextApMetaInfoOffset;
1170 hdd_adapter_t* pAdapter;
1171 tpSirBatchScanList pScanList;
1172 tpSirBatchScanNetworkInfo pApMetaInfo;
1173 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1174 tSirSetBatchScanReq *pReq;
1175
1176 pAdapter = (hdd_adapter_t *)callbackContext;
1177 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001178 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301179 {
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1181 "%s: Invalid pAdapter magic", __func__);
1182 VOS_ASSERT(0);
1183 return;
1184 }
1185
1186 /*initialize locals*/
1187 pReq = &pAdapter->hddSetBatchScanReq;
1188 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1189 isLastAp = FALSE;
1190 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001191 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301192 numberScanList = 0;
1193 nextScanListOffset = 0;
1194 nextApMetaInfoOffset = 0;
1195 pScanList = NULL;
1196 pApMetaInfo = NULL;
1197
1198 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1202 isLastAp = TRUE;
1203 goto done;
1204 }
1205
1206 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1208 "Batch scan rsp: numberScalList %d", numberScanList);
1209
1210 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1211 {
1212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1213 "%s: numberScanList %d", __func__, numberScanList);
1214 isLastAp = TRUE;
1215 goto done;
1216 }
1217
1218 while (numberScanList)
1219 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001220 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301221 nextScanListOffset);
1222 if (NULL == pScanList)
1223 {
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1225 "%s: pScanList is %p", __func__, pScanList);
1226 isLastAp = TRUE;
1227 goto done;
1228 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001229 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001231 "Batch scan rsp: numApMetaInfo %d scanId %d",
1232 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301233
1234 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1235 {
1236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1237 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1238 isLastAp = TRUE;
1239 goto done;
1240 }
1241
Rajeev Kumarce651e42013-10-21 18:57:15 -07001242 /*Initialize next AP meta info offset for next scan list*/
1243 nextApMetaInfoOffset = 0;
1244
Rajeev79dbe4c2013-10-05 11:03:42 +05301245 while (numApMetaInfo)
1246 {
1247 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1248 nextApMetaInfoOffset);
1249 if (NULL == pApMetaInfo)
1250 {
1251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1252 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1253 isLastAp = TRUE;
1254 goto done;
1255 }
1256 /*calculate AP age*/
1257 pApMetaInfo->timestamp =
1258 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1259
1260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001261 "%s: bssId "MAC_ADDRESS_STR
1262 " ch %d rssi %d timestamp %d", __func__,
1263 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1264 pApMetaInfo->ch, pApMetaInfo->rssi,
1265 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301266
1267 /*mark last AP in batch scan response*/
1268 if ((TRUE == pBatchScanRsp->isLastResult) &&
1269 (1 == numberScanList) && (1 == numApMetaInfo))
1270 {
1271 isLastAp = TRUE;
1272 }
1273
1274 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1275 /*store batch scan repsonse in hdd queue*/
1276 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1277 pScanList->scanId, isLastAp);
1278 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1279
1280 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1281 numApMetaInfo--;
1282 }
1283
Rajeev Kumarce651e42013-10-21 18:57:15 -07001284 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1285 + (sizeof(tSirBatchScanNetworkInfo)
1286 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301287 numberScanList--;
1288 }
1289
1290done:
1291
1292 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1293 requested from hdd_ioctl*/
1294 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1295 (TRUE == isLastAp))
1296 {
1297 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1298 complete(&pAdapter->hdd_get_batch_scan_req_var);
1299 }
1300
1301 return;
1302}/*End of hdd_batch_scan_result_ind_callback*/
1303
1304/**---------------------------------------------------------------------------
1305
1306 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1307 response as per batch scan FR request format by putting proper markers
1308
1309 \param - pDest pointer to destination buffer
1310 \param - cur_len current length
1311 \param - tot_len total remaining size which can be written to user space
1312 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1313 \param - pAdapter Pointer to HDD adapter
1314
1315 \return - ret no of characters written
1316
1317 --------------------------------------------------------------------------*/
1318static tANI_U32
1319hdd_format_batch_scan_rsp
1320(
1321 tANI_U8 *pDest,
1322 tANI_U32 cur_len,
1323 tANI_U32 tot_len,
1324 tHddBatchScanRsp *pApMetaInfo,
1325 hdd_adapter_t* pAdapter
1326)
1327{
1328 tANI_U32 ret = 0;
1329 tANI_U32 rem_len = 0;
1330 tANI_U8 temp_len = 0;
1331 tANI_U8 temp_total_len = 0;
1332 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1333 tANI_U8 *pTemp = temp;
1334
1335 /*Batch scan reponse needs to be returned to user space in
1336 following format:
1337 "scancount=X\n" where X is the number of scans in current batch
1338 batch
1339 "trunc\n" optional present if current scan truncated
1340 "bssid=XX:XX:XX:XX:XX:XX\n"
1341 "ssid=XXXX\n"
1342 "freq=X\n" frequency in Mhz
1343 "level=XX\n"
1344 "age=X\n" ms
1345 "dist=X\n" cm (-1 if not available)
1346 "errror=X\n" (-1if not available)
1347 "====\n" (end of ap marker)
1348 "####\n" (end of scan marker)
1349 "----\n" (end of results)*/
1350 /*send scan result in above format to user space based on
1351 available length*/
1352 /*The GET response may have more data than the driver can return in its
1353 buffer. In that case the buffer should be filled to the nearest complete
1354 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1355 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1356 The final buffer should end with "----\n"*/
1357
1358 /*sanity*/
1359 if (cur_len > tot_len)
1360 {
1361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1362 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1363 return 0;
1364 }
1365 else
1366 {
1367 rem_len = (tot_len - cur_len);
1368 }
1369
1370 /*end scan marker*/
1371 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1372 {
1373 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1374 pTemp += temp_len;
1375 temp_total_len += temp_len;
1376 }
1377
1378 /*bssid*/
1379 temp_len = snprintf(pTemp, sizeof(temp),
1380 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1381 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1382 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1383 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1384 pTemp += temp_len;
1385 temp_total_len += temp_len;
1386
1387 /*ssid*/
1388 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1389 pApMetaInfo->ApInfo.ssid);
1390 pTemp += temp_len;
1391 temp_total_len += temp_len;
1392
1393 /*freq*/
1394 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001395 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*level*/
1400 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1401 pApMetaInfo->ApInfo.rssi);
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404
1405 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001406 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301407 pApMetaInfo->ApInfo.age);
1408 pTemp += temp_len;
1409 temp_total_len += temp_len;
1410
1411 /*dist*/
1412 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1413 pTemp += temp_len;
1414 temp_total_len += temp_len;
1415
1416 /*error*/
1417 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1418 pTemp += temp_len;
1419 temp_total_len += temp_len;
1420
1421 /*end AP marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*last AP in batch scan response*/
1427 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1428 {
1429 /*end scan marker*/
1430 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1431 pTemp += temp_len;
1432 temp_total_len += temp_len;
1433
1434 /*end batch scan result marker*/
1435 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1436 pTemp += temp_len;
1437 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001438
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
1440
1441 if (temp_total_len < rem_len)
1442 {
1443 ret = temp_total_len + 1;
1444 strlcpy(pDest, temp, ret);
1445 pAdapter->isTruncated = FALSE;
1446 }
1447 else
1448 {
1449 pAdapter->isTruncated = TRUE;
1450 if (rem_len >= strlen("%%%%"))
1451 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001452 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301453 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001454 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301455 {
1456 ret = 0;
1457 }
1458 }
1459
1460 return ret;
1461
1462}/*End of hdd_format_batch_scan_rsp*/
1463
1464/**---------------------------------------------------------------------------
1465
1466 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1467 buffer starting with head of hdd batch scan response queue
1468
1469 \param - pAdapter Pointer to HDD adapter
1470 \param - pDest Pointer to user data buffer
1471 \param - cur_len current offset in user buffer
1472 \param - rem_len remaining no of bytes in user buffer
1473
1474 \return - number of bytes written in user buffer
1475
1476 --------------------------------------------------------------------------*/
1477
1478tANI_U32 hdd_populate_user_batch_scan_rsp
1479(
1480 hdd_adapter_t* pAdapter,
1481 tANI_U8 *pDest,
1482 tANI_U32 cur_len,
1483 tANI_U32 rem_len
1484)
1485{
1486 tHddBatchScanRsp *pHead;
1487 tHddBatchScanRsp *pPrev;
1488 tANI_U32 len;
1489
Rajeev79dbe4c2013-10-05 11:03:42 +05301490 pAdapter->isTruncated = FALSE;
1491
1492 /*head of hdd batch scan response queue*/
1493 pHead = pAdapter->pBatchScanRsp;
1494 while (pHead)
1495 {
1496 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1497 pAdapter);
1498 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001499 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301500 cur_len += len;
1501 if(TRUE == pAdapter->isTruncated)
1502 {
1503 /*result is truncated return rest of scan rsp in next req*/
1504 cur_len = rem_len;
1505 break;
1506 }
1507 pPrev = pHead;
1508 pHead = pHead->pNext;
1509 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001510 if (TRUE == pPrev->ApInfo.isLastAp)
1511 {
1512 pAdapter->prev_batch_id = 0;
1513 }
1514 else
1515 {
1516 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1517 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301518 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001519 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 }
1521
1522 return cur_len;
1523}/*End of hdd_populate_user_batch_scan_rsp*/
1524
1525/**---------------------------------------------------------------------------
1526
1527 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1528 scan response data from HDD queue to user space
1529 It does following in detail:
1530 a) if HDD has enough data in its queue then it 1st copies data to user
1531 space and then send get batch scan indication message to FW. In this
1532 case it does not wait on any event and batch scan response data will
1533 be populated in HDD response queue in MC thread context after receiving
1534 indication from FW
1535 b) else send get batch scan indication message to FW and wait on an event
1536 which will be set once HDD receives complete batch scan response from
1537 FW and then this function returns batch scan response to user space
1538
1539 \param - pAdapter Pointer to HDD adapter
1540 \param - pPrivData Pointer to priv_data
1541
1542 \return - 0 for success -EFAULT for failure
1543
1544 --------------------------------------------------------------------------*/
1545
1546int hdd_return_batch_scan_rsp_to_user
1547(
1548 hdd_adapter_t* pAdapter,
1549 hdd_priv_data_t *pPrivData,
1550 tANI_U8 *command
1551)
1552{
1553 tANI_U8 *pDest;
1554 tANI_U32 count = 0;
1555 tANI_U32 len = 0;
1556 tANI_U32 cur_len = 0;
1557 tANI_U32 rem_len = 0;
1558 eHalStatus halStatus;
1559 unsigned long rc;
1560 tSirTriggerBatchScanResultInd *pReq;
1561
1562 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1563 pReq->param = 0;/*batch scan client*/
1564 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1565 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1566
1567 cur_len = pPrivData->used_len;
1568 if (pPrivData->total_len > pPrivData->used_len)
1569 {
1570 rem_len = pPrivData->total_len - pPrivData->used_len;
1571 }
1572 else
1573 {
1574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1575 "%s: Invalid user data buffer total_len %d used_len %d",
1576 __func__, pPrivData->total_len, pPrivData->used_len);
1577 return -EFAULT;
1578 }
1579
1580 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1581 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1582 cur_len, rem_len);
1583 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1584
1585 /*enough scan result available in cache to return to user space or
1586 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001587 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301588 {
1589 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1590 halStatus = sme_TriggerBatchScanResultInd(
1591 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1592 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1593 pAdapter);
1594 if ( eHAL_STATUS_SUCCESS == halStatus )
1595 {
1596 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1597 {
1598 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1599 rc = wait_for_completion_timeout(
1600 &pAdapter->hdd_get_batch_scan_req_var,
1601 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1602 if (0 == rc)
1603 {
1604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1605 "%s: Timeout waiting to fetch batch scan rsp from fw",
1606 __func__);
1607 return -EFAULT;
1608 }
1609 }
1610
1611 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001612 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301613 pDest += len;
1614 cur_len += len;
1615
1616 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1617 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1618 cur_len, rem_len);
1619 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1620
1621 count = 0;
1622 len = (len - pPrivData->used_len);
1623 pDest = (command + pPrivData->used_len);
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001625 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301626 while(count < len)
1627 {
1628 printk("%c", *(pDest + count));
1629 count++;
1630 }
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: copy %d data to user buffer", __func__, len);
1633 if (copy_to_user(pPrivData->buf, pDest, len))
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "%s: failed to copy data to user buffer", __func__);
1637 return -EFAULT;
1638 }
1639 }
1640 else
1641 {
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1643 "sme_GetBatchScanScan returned failure halStatus %d",
1644 halStatus);
1645 return -EINVAL;
1646 }
1647 }
1648 else
1649 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301650 count = 0;
1651 len = (len - pPrivData->used_len);
1652 pDest = (command + pPrivData->used_len);
1653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001654 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 while(count < len)
1656 {
1657 printk("%c", *(pDest + count));
1658 count++;
1659 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301662 if (copy_to_user(pPrivData->buf, pDest, len))
1663 {
1664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 "%s: failed to copy data to user buffer", __func__);
1666 return -EFAULT;
1667 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301668 }
1669
1670 return 0;
1671} /*End of hdd_return_batch_scan_rsp_to_user*/
1672
Rajeev Kumar8b373292014-01-08 20:36:55 -08001673
1674/**---------------------------------------------------------------------------
1675
1676 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1677 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1678 WLS_BATCHING VERSION
1679 WLS_BATCHING SET
1680 WLS_BATCHING GET
1681 WLS_BATCHING STOP
1682
1683 \param - pAdapter Pointer to HDD adapter
1684 \param - pPrivdata Pointer to priv_data
1685 \param - command Pointer to command
1686
1687 \return - 0 for success -EFAULT for failure
1688
1689 --------------------------------------------------------------------------*/
1690
1691int hdd_handle_batch_scan_ioctl
1692(
1693 hdd_adapter_t *pAdapter,
1694 hdd_priv_data_t *pPrivdata,
1695 tANI_U8 *command
1696)
1697{
1698 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001699 hdd_context_t *pHddCtx;
1700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301701 ENTER();
1702
Yue Mae36e3552014-03-05 17:06:20 -08001703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1704 ret = wlan_hdd_validate_context(pHddCtx);
1705 if (ret)
1706 {
Yue Mae36e3552014-03-05 17:06:20 -08001707 goto exit;
1708 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001709
1710 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1711 {
1712 char extra[32];
1713 tANI_U8 len = 0;
1714 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1715
1716 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1717 {
1718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1719 "%s: Batch scan feature is not supported by FW", __func__);
1720 ret = -EINVAL;
1721 goto exit;
1722 }
1723
1724 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1725 version);
1726 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1727 {
1728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1729 "%s: failed to copy data to user buffer", __func__);
1730 ret = -EFAULT;
1731 goto exit;
1732 }
1733 ret = HDD_BATCH_SCAN_VERSION;
1734 }
1735 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1736 {
1737 int status;
1738 tANI_U8 *value = (command + 16);
1739 eHalStatus halStatus;
1740 unsigned long rc;
1741 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1742 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1743
1744 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1745 {
1746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1747 "%s: Batch scan feature is not supported by FW", __func__);
1748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1753 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1754 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1755 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1756 {
1757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301758 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001759 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301760 hdd_device_modetoString(pAdapter->device_mode),
1761 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001762 ret = -EINVAL;
1763 goto exit;
1764 }
1765
1766 status = hdd_parse_set_batchscan_command(value, pReq);
1767 if (status)
1768 {
1769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "Invalid WLS_BATCHING SET command");
1771 ret = -EINVAL;
1772 goto exit;
1773 }
1774
1775
1776 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1777 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1778 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1779 pAdapter);
1780
1781 if ( eHAL_STATUS_SUCCESS == halStatus )
1782 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301783 char extra[32];
1784 tANI_U8 len = 0;
1785 tANI_U8 mScan = 0;
1786
Rajeev Kumar8b373292014-01-08 20:36:55 -08001787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1788 "sme_SetBatchScanReq returned success halStatus %d",
1789 halStatus);
1790 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1791 {
1792 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1793 rc = wait_for_completion_timeout(
1794 &pAdapter->hdd_set_batch_scan_req_var,
1795 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1796 if (0 == rc)
1797 {
1798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: Timeout waiting for set batch scan to complete",
1800 __func__);
1801 ret = -EINVAL;
1802 goto exit;
1803 }
1804 }
1805 if ( !pRsp->nScansToBatch )
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1808 "%s: Received set batch scan failure response from FW",
1809 __func__);
1810 ret = -EINVAL;
1811 goto exit;
1812 }
1813 /*As per the Batch Scan Framework API we should return the MIN of
1814 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301815 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816
1817 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1818
1819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301821 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1822 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1823 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: failed to copy MSCAN value to user buffer", __func__);
1827 ret = -EFAULT;
1828 goto exit;
1829 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001830 }
1831 else
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "sme_SetBatchScanReq returned failure halStatus %d",
1835 halStatus);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839 }
1840 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1841 {
1842 eHalStatus halStatus;
1843 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1844 pInd->param = 0;
1845
1846 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "%s: Batch scan feature is not supported by FW", __func__);
1850 ret = -EINVAL;
1851 goto exit;
1852 }
1853
1854 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1855 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001857 "Batch scan is not yet enabled batch scan state %d",
1858 pAdapter->batchScanState);
1859 ret = -EINVAL;
1860 goto exit;
1861 }
1862
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 hdd_deinit_batch_scan(pAdapter);
1865 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1866
Rajeev Kumar8b373292014-01-08 20:36:55 -08001867 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1868
1869 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1870 pAdapter->sessionId);
1871 if ( eHAL_STATUS_SUCCESS == halStatus )
1872 {
1873 ret = 0;
1874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1875 "sme_StopBatchScanInd returned success halStatus %d",
1876 halStatus);
1877 }
1878 else
1879 {
1880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1881 "sme_StopBatchScanInd returned failure halStatus %d",
1882 halStatus);
1883 ret = -EINVAL;
1884 goto exit;
1885 }
1886 }
1887 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1888 {
1889 tANI_U32 remain_len;
1890
1891 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "%s: Batch scan feature is not supported by FW", __func__);
1895 ret = -EINVAL;
1896 goto exit;
1897 }
1898
1899 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1900 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001902 "Batch scan is not yet enabled could not return results"
1903 "Batch Scan state %d",
1904 pAdapter->batchScanState);
1905 ret = -EINVAL;
1906 goto exit;
1907 }
1908
1909 pPrivdata->used_len = 16;
1910 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1911 if (remain_len < pPrivdata->total_len)
1912 {
1913 /*Clear previous batch scan response data if any*/
1914 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1915 }
1916 else
1917 {
1918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1919 "Invalid total length from user space can't fetch batch"
1920 " scan response total_len %d used_len %d remain len %d",
1921 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1922 ret = -EINVAL;
1923 goto exit;
1924 }
1925 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1926 }
1927
1928exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301929 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001930 return ret;
1931}
1932
1933
Rajeev79dbe4c2013-10-05 11:03:42 +05301934#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1935
c_hpothu92367912014-05-01 15:18:17 +05301936static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1937{
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 bcnMissRateContext_t *pCBCtx;
1939
1940 if (NULL == data)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1943 return;
1944 }
c_hpothu92367912014-05-01 15:18:17 +05301945
1946 /* there is a race condition that exists between this callback
1947 function and the caller since the caller could time out either
1948 before or while this code is executing. we use a spinlock to
1949 serialize these actions */
1950 spin_lock(&hdd_context_lock);
1951
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301953 gbcnMissRate = -1;
1954
c_hpothu39eb1e32014-06-26 16:31:50 +05301955 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301958 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301959 spin_unlock(&hdd_context_lock);
1960 return ;
1961 }
1962
1963 if (VOS_STATUS_SUCCESS == status)
1964 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301965 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301966 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301967 else
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1970 }
1971
c_hpothu92367912014-05-01 15:18:17 +05301972 complete(&(pCBCtx->completion));
1973 spin_unlock(&hdd_context_lock);
1974
1975 return;
1976}
1977
Abhishek Singh08aa7762014-12-16 13:59:03 +05301978void hdd_FWStatisCB( VOS_STATUS status,
1979 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301980{
1981 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301982 hdd_adapter_t *pAdapter;
1983
1984 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1985
Abhishek Singh08aa7762014-12-16 13:59:03 +05301986 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1989 return;
1990 }
1991 /* there is a race condition that exists between this callback
1992 function and the caller since the caller could time out either
1993 before or while this code is executing. we use a spinlock to
1994 serialize these actions */
1995 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301996 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301997 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_ERROR,
2000 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2001 spin_unlock(&hdd_context_lock);
2002 return;
2003 }
2004 pAdapter = fwStatsCtx->pAdapter;
2005 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("pAdapter returned is NULL or invalid"));
2009 spin_unlock(&hdd_context_lock);
2010 return;
2011 }
2012 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302013 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302014 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302015 switch( fwStatsResult->type )
2016 {
2017 case FW_UBSP_STATS:
2018 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302019 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 hddLog(VOS_TRACE_LEVEL_INFO,
2021 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302022 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2023 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302024 }
2025 break;
2026 default:
2027 {
2028 hddLog(VOS_TRACE_LEVEL_ERROR,
2029 FL(" No handling for stats type %d"),fwStatsResult->type);
2030 }
2031 }
2032 }
2033 complete(&(fwStatsCtx->completion));
2034 spin_unlock(&hdd_context_lock);
2035 return;
2036}
2037
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302038static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2039{
2040 int ret = 0;
2041
2042 if (!pCfg || !command || !extra || !len)
2043 {
2044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2045 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2046 ret = -EINVAL;
2047 return ret;
2048 }
2049
2050 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2051 {
2052 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2053 (int)pCfg->nActiveMaxChnTime);
2054 return ret;
2055 }
2056 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2057 {
2058 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2059 (int)pCfg->nActiveMinChnTime);
2060 return ret;
2061 }
2062 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2063 {
2064 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2065 (int)pCfg->nPassiveMaxChnTime);
2066 return ret;
2067 }
2068 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2069 {
2070 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2071 (int)pCfg->nPassiveMinChnTime);
2072 return ret;
2073 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302074 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2075 {
2076 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2077 (int)pCfg->nActiveMaxChnTime);
2078 return ret;
2079 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080 else
2081 {
2082 ret = -EINVAL;
2083 }
2084
2085 return ret;
2086}
2087
2088static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2089{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091 hdd_config_t *pCfg;
2092 tANI_U8 *value = command;
2093 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302094 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302095
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302096 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2097 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302098 {
2099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2100 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2101 ret = -EINVAL;
2102 return ret;
2103 }
2104
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302105 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2106 sme_GetConfigParam(hHal, &smeConfig);
2107
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302108 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2109 {
2110 value = value + 24;
2111 temp = kstrtou32(value, 10, &val);
2112 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2113 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2114 {
2115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2116 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2117 ret = -EFAULT;
2118 return ret;
2119 }
2120 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302121 smeConfig.csrConfig.nActiveMaxChnTime = val;
2122 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302123 }
2124 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2125 {
2126 value = value + 24;
2127 temp = kstrtou32(value, 10, &val);
2128 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2129 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2130 {
2131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2132 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2133 ret = -EFAULT;
2134 return ret;
2135 }
2136 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302137 smeConfig.csrConfig.nActiveMinChnTime = val;
2138 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302139 }
2140 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2141 {
2142 value = value + 25;
2143 temp = kstrtou32(value, 10, &val);
2144 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2145 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2146 {
2147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2148 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2149 ret = -EFAULT;
2150 return ret;
2151 }
2152 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302153 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2154 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302155 }
2156 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2157 {
2158 value = value + 25;
2159 temp = kstrtou32(value, 10, &val);
2160 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2161 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2165 ret = -EFAULT;
2166 return ret;
2167 }
2168 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302169 smeConfig.csrConfig.nPassiveMinChnTime = val;
2170 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302171 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302172 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2173 {
2174 value = value + 13;
2175 temp = kstrtou32(value, 10, &val);
2176 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2177 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2178 {
2179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2180 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2181 ret = -EFAULT;
2182 return ret;
2183 }
2184 pCfg->nActiveMaxChnTime = val;
2185 smeConfig.csrConfig.nActiveMaxChnTime = val;
2186 sme_UpdateConfig(hHal, &smeConfig);
2187 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302188 else
2189 {
2190 ret = -EINVAL;
2191 }
2192
2193 return ret;
2194}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302195static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2196 tANI_U8 cmd_len)
2197{
2198 tANI_U8 *value;
2199 tANI_U8 fcc_constraint;
2200
2201 eHalStatus status;
2202 int ret = 0;
2203 value = cmd + cmd_len + 1;
2204
2205 ret = kstrtou8(value, 10, &fcc_constraint);
2206 if ((ret < 0) || (fcc_constraint > 1)) {
2207 /*
2208 * If the input value is greater than max value of datatype,
2209 * then also it is a failure
2210 */
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 "%s: value out of range", __func__);
2213 return -EINVAL;
2214 }
2215
2216 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2217 if (status != eHAL_STATUS_SUCCESS)
2218 ret = -EPERM;
2219
2220 return ret;
2221}
2222
2223
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302224
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002225static int hdd_driver_command(hdd_adapter_t *pAdapter,
2226 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002227{
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 hdd_priv_data_t priv_data;
2229 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302230 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2231 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002232 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302233 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302234
2235 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002236 /*
2237 * Note that valid pointers are provided by caller
2238 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002239
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002240 /* copy to local struct to avoid numerous changes to legacy code */
2241 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002242
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002243 if (priv_data.total_len <= 0 ||
2244 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002245 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002246 hddLog(VOS_TRACE_LEVEL_WARN,
2247 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2248 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002249 ret = -EINVAL;
2250 goto exit;
2251 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302252 status = wlan_hdd_validate_context(pHddCtx);
2253 if (0 != status)
2254 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302255 ret = -EINVAL;
2256 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302257 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002258 /* Allocate +1 for '\0' */
2259 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 if (!command)
2261 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002264 ret = -ENOMEM;
2265 goto exit;
2266 }
2267
2268 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2269 {
2270 ret = -EFAULT;
2271 goto exit;
2272 }
2273
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002274 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002275 command[priv_data.total_len] = '\0';
2276
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002277 /* at one time the following block of code was conditional. braces
2278 * have been retained to avoid re-indenting the legacy code
2279 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 {
2281 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2282
2283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002284 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002285
2286 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2287 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2289 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2290 pAdapter->sessionId, (unsigned)
2291 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2292 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2293 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2294 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2296 sizeof(tSirMacAddr)))
2297 {
2298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002299 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 ret = -EFAULT;
2301 }
2302 }
Amar Singhal0974e402013-02-12 14:27:46 -08002303 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002304 {
Amar Singhal0974e402013-02-12 14:27:46 -08002305 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002306
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002308
2309 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002312 "%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 -07002313 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002314 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302315 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302316 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002317 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002318 }
Kiet Lamf040f472013-11-20 21:15:23 +05302319 else if(strncmp(command, "SETWMMPS", 8) == 0)
2320 {
2321 tANI_U8 *ptr = command;
2322 ret = hdd_wmmps_helper(pAdapter, ptr);
2323 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302324
2325 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2326 {
2327 tANI_U8 *ptr = command;
2328 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2329 }
2330
Jeff Johnson32d95a32012-09-10 13:15:23 -07002331 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2332 {
2333 char *country_code;
2334
2335 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002336
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002337 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002338 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002339#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302340 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002341#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002342 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2343 (void *)(tSmeChangeCountryCallback)
2344 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302345 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002346 if (eHAL_STATUS_SUCCESS == ret)
2347 {
2348 ret = wait_for_completion_interruptible_timeout(
2349 &pAdapter->change_country_code,
2350 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2351 if (0 >= ret)
2352 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002353 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302354 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002355 }
2356 }
2357 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002358 {
2359 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002360 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002361 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002362 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002363
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002364 }
2365 /*
2366 command should be a string having format
2367 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2368 */
Amar Singhal0974e402013-02-12 14:27:46 -08002369 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002370 {
Amar Singhal0974e402013-02-12 14:27:46 -08002371 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002372
2373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002374 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002375
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002376 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002377 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002378 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2379 {
2380 int suspend = 0;
2381 tANI_U8 *ptr = (tANI_U8*)command + 15;
2382
2383 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302384 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2385 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2386 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002387 hdd_set_wlan_suspend_mode(suspend);
2388 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002389#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2390 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2391 {
2392 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002393 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002394 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2395 eHalStatus status = eHAL_STATUS_SUCCESS;
2396
2397 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2398 value = value + 15;
2399
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002400 /* Convert the value from ascii to integer */
2401 ret = kstrtos8(value, 10, &rssi);
2402 if (ret < 0)
2403 {
2404 /* If the input value is greater than max value of datatype, then also
2405 kstrtou8 fails */
2406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2407 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002408 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002409 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2410 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2411 ret = -EINVAL;
2412 goto exit;
2413 }
2414
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002416
Srinivas Girigowdade697412013-02-14 16:31:48 -08002417 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2418 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2419 {
2420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2421 "Neighbor lookup threshold value %d is out of range"
2422 " (Min: %d Max: %d)", lookUpThreshold,
2423 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2424 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2425 ret = -EINVAL;
2426 goto exit;
2427 }
2428
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302429 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2430 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2431 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2433 "%s: Received Command to Set Roam trigger"
2434 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2435
2436 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2437 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2438 if (eHAL_STATUS_SUCCESS != status)
2439 {
2440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2441 "%s: Failed to set roam trigger, try again", __func__);
2442 ret = -EPERM;
2443 goto exit;
2444 }
2445
2446 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302447 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002448 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2449 }
2450 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2451 {
2452 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2453 int rssi = (-1) * lookUpThreshold;
2454 char extra[32];
2455 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302456 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2457 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2458 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002459 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002460 if (copy_to_user(priv_data.buf, &extra, len + 1))
2461 {
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2463 "%s: failed to copy data to user buffer", __func__);
2464 ret = -EFAULT;
2465 goto exit;
2466 }
2467 }
2468 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2469 {
2470 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002471 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002472 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002473
Srinivas Girigowdade697412013-02-14 16:31:48 -08002474 /* input refresh period is in terms of seconds */
2475 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2476 value = value + 18;
2477 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002478 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002479 if (ret < 0)
2480 {
2481 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002482 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002484 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002485 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002486 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2487 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002488 ret = -EINVAL;
2489 goto exit;
2490 }
2491
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002492 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2493 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002494 {
2495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 "Roam scan period value %d is out of range"
2497 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002498 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2499 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002500 ret = -EINVAL;
2501 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302502 }
2503 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2504 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2505 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002506 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002507
2508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2509 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002511
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002512 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2513 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002514 }
2515 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2516 {
2517 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2518 char extra[32];
2519 tANI_U8 len = 0;
2520
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302521 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2522 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2523 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002524 len = scnprintf(extra, sizeof(extra), "%s %d",
2525 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002526 /* Returned value is in units of seconds */
2527 if (copy_to_user(priv_data.buf, &extra, len + 1))
2528 {
2529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2530 "%s: failed to copy data to user buffer", __func__);
2531 ret = -EFAULT;
2532 goto exit;
2533 }
2534 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002535 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2536 {
2537 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002538 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002539 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002540
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002541 /* input refresh period is in terms of seconds */
2542 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2543 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002546 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002547 if (ret < 0)
2548 {
2549 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002550 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002552 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002553 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002554 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2555 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2556 ret = -EINVAL;
2557 goto exit;
2558 }
2559
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002560 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2561 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2562 {
2563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2564 "Neighbor scan results refresh period value %d is out of range"
2565 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2566 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2567 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2568 ret = -EINVAL;
2569 goto exit;
2570 }
2571 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2572
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2574 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002575 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002576
2577 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2578 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2579 }
2580 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2581 {
2582 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2583 char extra[32];
2584 tANI_U8 len = 0;
2585
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002586 len = scnprintf(extra, sizeof(extra), "%s %d",
2587 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002588 /* Returned value is in units of seconds */
2589 if (copy_to_user(priv_data.buf, &extra, len + 1))
2590 {
2591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2592 "%s: failed to copy data to user buffer", __func__);
2593 ret = -EFAULT;
2594 goto exit;
2595 }
2596 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002597#ifdef FEATURE_WLAN_LFR
2598 /* SETROAMMODE */
2599 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2600 {
2601 tANI_U8 *value = command;
2602 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2603
2604 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2605 value = value + SIZE_OF_SETROAMMODE + 1;
2606
2607 /* Convert the value from ascii to integer */
2608 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2609 if (ret < 0)
2610 {
2611 /* If the input value is greater than max value of datatype, then also
2612 kstrtou8 fails */
2613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2614 "%s: kstrtou8 failed range [%d - %d]", __func__,
2615 CFG_LFR_FEATURE_ENABLED_MIN,
2616 CFG_LFR_FEATURE_ENABLED_MAX);
2617 ret = -EINVAL;
2618 goto exit;
2619 }
2620 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2621 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2622 {
2623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2624 "Roam Mode value %d is out of range"
2625 " (Min: %d Max: %d)", roamMode,
2626 CFG_LFR_FEATURE_ENABLED_MIN,
2627 CFG_LFR_FEATURE_ENABLED_MAX);
2628 ret = -EINVAL;
2629 goto exit;
2630 }
2631
2632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2633 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2634 /*
2635 * Note that
2636 * SETROAMMODE 0 is to enable LFR while
2637 * SETROAMMODE 1 is to disable LFR, but
2638 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2639 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2640 */
2641 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2642 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2643 else
2644 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2645
2646 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2647 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2648 }
2649 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302650 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002651 {
2652 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2653 char extra[32];
2654 tANI_U8 len = 0;
2655
2656 /*
2657 * roamMode value shall be inverted because the sementics is different.
2658 */
2659 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2660 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2661 else
2662 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2663
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002664 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002665 if (copy_to_user(priv_data.buf, &extra, len + 1))
2666 {
2667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2668 "%s: failed to copy data to user buffer", __func__);
2669 ret = -EFAULT;
2670 goto exit;
2671 }
2672 }
2673#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002674#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002675#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002676 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2677 {
2678 tANI_U8 *value = command;
2679 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2680
2681 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2682 value = value + 13;
2683 /* Convert the value from ascii to integer */
2684 ret = kstrtou8(value, 10, &roamRssiDiff);
2685 if (ret < 0)
2686 {
2687 /* If the input value is greater than max value of datatype, then also
2688 kstrtou8 fails */
2689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2690 "%s: kstrtou8 failed range [%d - %d]", __func__,
2691 CFG_ROAM_RSSI_DIFF_MIN,
2692 CFG_ROAM_RSSI_DIFF_MAX);
2693 ret = -EINVAL;
2694 goto exit;
2695 }
2696
2697 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2698 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2699 {
2700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2701 "Roam rssi diff value %d is out of range"
2702 " (Min: %d Max: %d)", roamRssiDiff,
2703 CFG_ROAM_RSSI_DIFF_MIN,
2704 CFG_ROAM_RSSI_DIFF_MAX);
2705 ret = -EINVAL;
2706 goto exit;
2707 }
2708
2709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2710 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2711
2712 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2713 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2714 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302715 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002716 {
2717 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2718 char extra[32];
2719 tANI_U8 len = 0;
2720
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302721 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2722 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2723 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002724 len = scnprintf(extra, sizeof(extra), "%s %d",
2725 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002726 if (copy_to_user(priv_data.buf, &extra, len + 1))
2727 {
2728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2729 "%s: failed to copy data to user buffer", __func__);
2730 ret = -EFAULT;
2731 goto exit;
2732 }
2733 }
2734#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002735#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002736 else if (strncmp(command, "GETBAND", 7) == 0)
2737 {
2738 int band = -1;
2739 char extra[32];
2740 tANI_U8 len = 0;
2741 hdd_getBand_helper(pHddCtx, &band);
2742
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302743 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2744 TRACE_CODE_HDD_GETBAND_IOCTL,
2745 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002746 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002747 if (copy_to_user(priv_data.buf, &extra, len + 1))
2748 {
2749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2750 "%s: failed to copy data to user buffer", __func__);
2751 ret = -EFAULT;
2752 goto exit;
2753 }
2754 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002755 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2756 {
2757 tANI_U8 *value = command;
2758 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2759 tANI_U8 numChannels = 0;
2760 eHalStatus status = eHAL_STATUS_SUCCESS;
2761
2762 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2763 if (eHAL_STATUS_SUCCESS != status)
2764 {
2765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2766 "%s: Failed to parse channel list information", __func__);
2767 ret = -EINVAL;
2768 goto exit;
2769 }
2770
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302771 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2772 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2773 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002774 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2775 {
2776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2777 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2778 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2779 ret = -EINVAL;
2780 goto exit;
2781 }
2782 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2783 numChannels);
2784 if (eHAL_STATUS_SUCCESS != status)
2785 {
2786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2787 "%s: Failed to update channel list information", __func__);
2788 ret = -EINVAL;
2789 goto exit;
2790 }
2791 }
2792 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2793 {
2794 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2795 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002796 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002797 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002798 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002799
2800 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2801 ChannelList, &numChannels ))
2802 {
2803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2804 "%s: failed to get roam scan channel list", __func__);
2805 ret = -EFAULT;
2806 goto exit;
2807 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302808 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2809 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2810 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002811 /* output channel list is of the format
2812 [Number of roam scan channels][Channel1][Channel2]... */
2813 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002814 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 for (j = 0; (j < numChannels); j++)
2816 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002817 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2818 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002819 }
2820
2821 if (copy_to_user(priv_data.buf, &extra, len + 1))
2822 {
2823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2824 "%s: failed to copy data to user buffer", __func__);
2825 ret = -EFAULT;
2826 goto exit;
2827 }
2828 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002829 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2830 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002831 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002832 char extra[32];
2833 tANI_U8 len = 0;
2834
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002835 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002836 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002837 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002838 hdd_is_okc_mode_enabled(pHddCtx) &&
2839 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2840 {
2841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002842 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002843 " hence this operation is not permitted!", __func__);
2844 ret = -EPERM;
2845 goto exit;
2846 }
2847
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002848 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002849 "GETCCXMODE", eseMode);
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, "GETOKCMODE", 10) == 0)
2859 {
2860 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2861 char extra[32];
2862 tANI_U8 len = 0;
2863
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002864 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002865 then this operation is not permitted (return FAILURE) */
2866 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002867 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002868 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2869 {
2870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002871 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002872 " hence this operation is not permitted!", __func__);
2873 ret = -EPERM;
2874 goto exit;
2875 }
2876
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002877 len = scnprintf(extra, sizeof(extra), "%s %d",
2878 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002879 if (copy_to_user(priv_data.buf, &extra, len + 1))
2880 {
2881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2882 "%s: failed to copy data to user buffer", __func__);
2883 ret = -EFAULT;
2884 goto exit;
2885 }
2886 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002887 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002888 {
2889 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2890 char extra[32];
2891 tANI_U8 len = 0;
2892
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002893 len = scnprintf(extra, sizeof(extra), "%s %d",
2894 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002895 if (copy_to_user(priv_data.buf, &extra, len + 1))
2896 {
2897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2898 "%s: failed to copy data to user buffer", __func__);
2899 ret = -EFAULT;
2900 goto exit;
2901 }
2902 }
2903 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2904 {
2905 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2906 char extra[32];
2907 tANI_U8 len = 0;
2908
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002909 len = scnprintf(extra, sizeof(extra), "%s %d",
2910 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002911 if (copy_to_user(priv_data.buf, &extra, len + 1))
2912 {
2913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2914 "%s: failed to copy data to user buffer", __func__);
2915 ret = -EFAULT;
2916 goto exit;
2917 }
2918 }
2919 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2920 {
2921 tANI_U8 *value = command;
2922 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2923
2924 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2925 value = value + 26;
2926 /* Convert the value from ascii to integer */
2927 ret = kstrtou8(value, 10, &minTime);
2928 if (ret < 0)
2929 {
2930 /* If the input value is greater than max value of datatype, then also
2931 kstrtou8 fails */
2932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2933 "%s: kstrtou8 failed range [%d - %d]", __func__,
2934 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2935 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2936 ret = -EINVAL;
2937 goto exit;
2938 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002939 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2940 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2941 {
2942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2943 "scan min channel time value %d is out of range"
2944 " (Min: %d Max: %d)", minTime,
2945 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2946 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2947 ret = -EINVAL;
2948 goto exit;
2949 }
2950
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302951 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2952 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2953 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2955 "%s: Received Command to change channel min time = %d", __func__, minTime);
2956
2957 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2958 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2959 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002960 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2961 {
2962 tANI_U8 *value = command;
2963 tANI_U8 channel = 0;
2964 tANI_U8 dwellTime = 0;
2965 tANI_U8 bufLen = 0;
2966 tANI_U8 *buf = NULL;
2967 tSirMacAddr targetApBssid;
2968 eHalStatus status = eHAL_STATUS_SUCCESS;
2969 struct ieee80211_channel chan;
2970 tANI_U8 finalLen = 0;
2971 tANI_U8 *finalBuf = NULL;
2972 tANI_U8 temp = 0;
2973 u64 cookie;
2974 hdd_station_ctx_t *pHddStaCtx = NULL;
2975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2976
2977 /* if not associated, no need to send action frame */
2978 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2979 {
2980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2981 ret = -EINVAL;
2982 goto exit;
2983 }
2984
2985 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2986 &dwellTime, &buf, &bufLen);
2987 if (eHAL_STATUS_SUCCESS != status)
2988 {
2989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2990 "%s: Failed to parse send action frame data", __func__);
2991 ret = -EINVAL;
2992 goto exit;
2993 }
2994
2995 /* if the target bssid is different from currently associated AP,
2996 then no need to send action frame */
2997 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2998 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2999 {
3000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3001 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003002 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003003 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003004 goto exit;
3005 }
3006
3007 /* if the channel number is different from operating channel then
3008 no need to send action frame */
3009 if (channel != pHddStaCtx->conn_info.operationChannel)
3010 {
3011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3012 "%s: channel(%d) is different from operating channel(%d)",
3013 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3014 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003015 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003016 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003017 goto exit;
3018 }
3019 chan.center_freq = sme_ChnToFreq(channel);
3020
3021 finalLen = bufLen + 24;
3022 finalBuf = vos_mem_malloc(finalLen);
3023 if (NULL == finalBuf)
3024 {
3025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3026 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003027 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003028 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003029 goto exit;
3030 }
3031 vos_mem_zero(finalBuf, finalLen);
3032
3033 /* Fill subtype */
3034 temp = SIR_MAC_MGMT_ACTION << 4;
3035 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3036
3037 /* Fill type */
3038 temp = SIR_MAC_MGMT_FRAME;
3039 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3040
3041 /* Fill destination address (bssid of the AP) */
3042 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3043
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003044 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003045 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3046
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003047 /* Fill BSSID (AP mac address) */
3048 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003049
3050 /* Fill received buffer from 24th address */
3051 vos_mem_copy(finalBuf + 24, buf, bufLen);
3052
Jeff Johnson11c33152013-04-16 17:52:40 -07003053 /* done with the parsed buffer */
3054 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003055 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003056
DARAM SUDHA39eede62014-02-12 11:16:40 +05303057 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3059 &(pAdapter->wdev),
3060#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003061 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003062#endif
3063 &chan, 0,
3064#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3065 NL80211_CHAN_HT20, 1,
3066#endif
3067 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003068 1, &cookie );
3069 vos_mem_free(finalBuf);
3070 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003071 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3072 {
3073 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3074 char extra[32];
3075 tANI_U8 len = 0;
3076
3077 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003078 len = scnprintf(extra, sizeof(extra), "%s %d",
3079 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303080 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3081 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3082 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003083 if (copy_to_user(priv_data.buf, &extra, len + 1))
3084 {
3085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3086 "%s: failed to copy data to user buffer", __func__);
3087 ret = -EFAULT;
3088 goto exit;
3089 }
3090 }
3091 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3092 {
3093 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003094 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003095
3096 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3097 value = value + 19;
3098 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003099 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003100 if (ret < 0)
3101 {
3102 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003103 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003105 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003106 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3107 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3108 ret = -EINVAL;
3109 goto exit;
3110 }
3111
3112 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3113 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3114 {
3115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3116 "lfr mode value %d is out of range"
3117 " (Min: %d Max: %d)", maxTime,
3118 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3119 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3120 ret = -EINVAL;
3121 goto exit;
3122 }
3123
3124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3125 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3126
3127 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3128 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3129 }
3130 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3131 {
3132 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3133 char extra[32];
3134 tANI_U8 len = 0;
3135
3136 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003137 len = scnprintf(extra, sizeof(extra), "%s %d",
3138 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003139 if (copy_to_user(priv_data.buf, &extra, len + 1))
3140 {
3141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3142 "%s: failed to copy data to user buffer", __func__);
3143 ret = -EFAULT;
3144 goto exit;
3145 }
3146 }
3147 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3148 {
3149 tANI_U8 *value = command;
3150 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3151
3152 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3153 value = value + 16;
3154 /* Convert the value from ascii to integer */
3155 ret = kstrtou16(value, 10, &val);
3156 if (ret < 0)
3157 {
3158 /* If the input value is greater than max value of datatype, then also
3159 kstrtou16 fails */
3160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3161 "%s: kstrtou16 failed range [%d - %d]", __func__,
3162 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3163 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3164 ret = -EINVAL;
3165 goto exit;
3166 }
3167
3168 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3169 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3170 {
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "scan home time value %d is out of range"
3173 " (Min: %d Max: %d)", val,
3174 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3175 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3176 ret = -EINVAL;
3177 goto exit;
3178 }
3179
3180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3181 "%s: Received Command to change scan home time = %d", __func__, val);
3182
3183 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3184 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3185 }
3186 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3187 {
3188 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3189 char extra[32];
3190 tANI_U8 len = 0;
3191
3192 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003193 len = scnprintf(extra, sizeof(extra), "%s %d",
3194 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003195 if (copy_to_user(priv_data.buf, &extra, len + 1))
3196 {
3197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3198 "%s: failed to copy data to user buffer", __func__);
3199 ret = -EFAULT;
3200 goto exit;
3201 }
3202 }
3203 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3204 {
3205 tANI_U8 *value = command;
3206 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3207
3208 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3209 value = value + 17;
3210 /* Convert the value from ascii to integer */
3211 ret = kstrtou8(value, 10, &val);
3212 if (ret < 0)
3213 {
3214 /* If the input value is greater than max value of datatype, then also
3215 kstrtou8 fails */
3216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3217 "%s: kstrtou8 failed range [%d - %d]", __func__,
3218 CFG_ROAM_INTRA_BAND_MIN,
3219 CFG_ROAM_INTRA_BAND_MAX);
3220 ret = -EINVAL;
3221 goto exit;
3222 }
3223
3224 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3225 (val > CFG_ROAM_INTRA_BAND_MAX))
3226 {
3227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3228 "intra band mode value %d is out of range"
3229 " (Min: %d Max: %d)", val,
3230 CFG_ROAM_INTRA_BAND_MIN,
3231 CFG_ROAM_INTRA_BAND_MAX);
3232 ret = -EINVAL;
3233 goto exit;
3234 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3236 "%s: Received Command to change intra band = %d", __func__, val);
3237
3238 pHddCtx->cfg_ini->nRoamIntraBand = val;
3239 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3240 }
3241 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3242 {
3243 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3244 char extra[32];
3245 tANI_U8 len = 0;
3246
3247 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003248 len = scnprintf(extra, sizeof(extra), "%s %d",
3249 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003250 if (copy_to_user(priv_data.buf, &extra, len + 1))
3251 {
3252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3253 "%s: failed to copy data to user buffer", __func__);
3254 ret = -EFAULT;
3255 goto exit;
3256 }
3257 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003258 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3259 {
3260 tANI_U8 *value = command;
3261 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3262
3263 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3264 value = value + 15;
3265 /* Convert the value from ascii to integer */
3266 ret = kstrtou8(value, 10, &nProbes);
3267 if (ret < 0)
3268 {
3269 /* If the input value is greater than max value of datatype, then also
3270 kstrtou8 fails */
3271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3272 "%s: kstrtou8 failed range [%d - %d]", __func__,
3273 CFG_ROAM_SCAN_N_PROBES_MIN,
3274 CFG_ROAM_SCAN_N_PROBES_MAX);
3275 ret = -EINVAL;
3276 goto exit;
3277 }
3278
3279 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3280 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3281 {
3282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3283 "NProbes value %d is out of range"
3284 " (Min: %d Max: %d)", nProbes,
3285 CFG_ROAM_SCAN_N_PROBES_MIN,
3286 CFG_ROAM_SCAN_N_PROBES_MAX);
3287 ret = -EINVAL;
3288 goto exit;
3289 }
3290
3291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3292 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3293
3294 pHddCtx->cfg_ini->nProbes = nProbes;
3295 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3296 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303297 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003298 {
3299 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3300 char extra[32];
3301 tANI_U8 len = 0;
3302
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003303 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003304 if (copy_to_user(priv_data.buf, &extra, len + 1))
3305 {
3306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3307 "%s: failed to copy data to user buffer", __func__);
3308 ret = -EFAULT;
3309 goto exit;
3310 }
3311 }
3312 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3313 {
3314 tANI_U8 *value = command;
3315 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3316
3317 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3318 /* input value is in units of msec */
3319 value = value + 20;
3320 /* Convert the value from ascii to integer */
3321 ret = kstrtou16(value, 10, &homeAwayTime);
3322 if (ret < 0)
3323 {
3324 /* If the input value is greater than max value of datatype, then also
3325 kstrtou8 fails */
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "%s: kstrtou8 failed range [%d - %d]", __func__,
3328 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3329 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3330 ret = -EINVAL;
3331 goto exit;
3332 }
3333
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003334 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3335 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3336 {
3337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3338 "homeAwayTime value %d is out of range"
3339 " (Min: %d Max: %d)", homeAwayTime,
3340 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3341 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3342 ret = -EINVAL;
3343 goto exit;
3344 }
3345
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3347 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003348 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3349 {
3350 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3351 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3352 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003353 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303354 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003355 {
3356 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3357 char extra[32];
3358 tANI_U8 len = 0;
3359
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003360 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003361 if (copy_to_user(priv_data.buf, &extra, len + 1))
3362 {
3363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3364 "%s: failed to copy data to user buffer", __func__);
3365 ret = -EFAULT;
3366 goto exit;
3367 }
3368 }
3369 else if (strncmp(command, "REASSOC", 7) == 0)
3370 {
3371 tANI_U8 *value = command;
3372 tANI_U8 channel = 0;
3373 tSirMacAddr targetApBssid;
3374 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003375#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3376 tCsrHandoffRequest handoffInfo;
3377#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003378 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003379 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3380
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003381 /* if not associated, no need to proceed with reassoc */
3382 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3383 {
3384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3385 ret = -EINVAL;
3386 goto exit;
3387 }
3388
3389 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3390 if (eHAL_STATUS_SUCCESS != status)
3391 {
3392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3393 "%s: Failed to parse reassoc command data", __func__);
3394 ret = -EINVAL;
3395 goto exit;
3396 }
3397
3398 /* if the target bssid is same as currently associated AP,
3399 then no need to proceed with reassoc */
3400 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3401 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3402 {
3403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3404 ret = -EINVAL;
3405 goto exit;
3406 }
3407
3408 /* Check channel number is a valid channel number */
3409 if(VOS_STATUS_SUCCESS !=
3410 wlan_hdd_validate_operation_channel(pAdapter, channel))
3411 {
3412 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003413 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003414 return -EINVAL;
3415 }
3416
3417 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003418#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3419 handoffInfo.channel = channel;
3420 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3421 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3422#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003423 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003424 else if (strncmp(command, "SETWESMODE", 10) == 0)
3425 {
3426 tANI_U8 *value = command;
3427 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3428
3429 /* Move pointer to ahead of SETWESMODE<delimiter> */
3430 value = value + 11;
3431 /* Convert the value from ascii to integer */
3432 ret = kstrtou8(value, 10, &wesMode);
3433 if (ret < 0)
3434 {
3435 /* If the input value is greater than max value of datatype, then also
3436 kstrtou8 fails */
3437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3438 "%s: kstrtou8 failed range [%d - %d]", __func__,
3439 CFG_ENABLE_WES_MODE_NAME_MIN,
3440 CFG_ENABLE_WES_MODE_NAME_MAX);
3441 ret = -EINVAL;
3442 goto exit;
3443 }
3444
3445 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3446 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3447 {
3448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3449 "WES Mode value %d is out of range"
3450 " (Min: %d Max: %d)", wesMode,
3451 CFG_ENABLE_WES_MODE_NAME_MIN,
3452 CFG_ENABLE_WES_MODE_NAME_MAX);
3453 ret = -EINVAL;
3454 goto exit;
3455 }
3456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3457 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3458
3459 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3460 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3461 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303462 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003463 {
3464 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3465 char extra[32];
3466 tANI_U8 len = 0;
3467
Arif Hussain826d9412013-11-12 16:44:54 -08003468 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003469 if (copy_to_user(priv_data.buf, &extra, len + 1))
3470 {
3471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3472 "%s: failed to copy data to user buffer", __func__);
3473 ret = -EFAULT;
3474 goto exit;
3475 }
3476 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003477#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003478#ifdef FEATURE_WLAN_LFR
3479 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3480 {
3481 tANI_U8 *value = command;
3482 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3483
3484 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3485 value = value + 12;
3486 /* Convert the value from ascii to integer */
3487 ret = kstrtou8(value, 10, &lfrMode);
3488 if (ret < 0)
3489 {
3490 /* If the input value is greater than max value of datatype, then also
3491 kstrtou8 fails */
3492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3493 "%s: kstrtou8 failed range [%d - %d]", __func__,
3494 CFG_LFR_FEATURE_ENABLED_MIN,
3495 CFG_LFR_FEATURE_ENABLED_MAX);
3496 ret = -EINVAL;
3497 goto exit;
3498 }
3499
3500 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3501 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3502 {
3503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3504 "lfr mode value %d is out of range"
3505 " (Min: %d Max: %d)", lfrMode,
3506 CFG_LFR_FEATURE_ENABLED_MIN,
3507 CFG_LFR_FEATURE_ENABLED_MAX);
3508 ret = -EINVAL;
3509 goto exit;
3510 }
3511
3512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3513 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3514
3515 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3516 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3517 }
3518#endif
3519#ifdef WLAN_FEATURE_VOWIFI_11R
3520 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3521 {
3522 tANI_U8 *value = command;
3523 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3524
3525 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3526 value = value + 18;
3527 /* Convert the value from ascii to integer */
3528 ret = kstrtou8(value, 10, &ft);
3529 if (ret < 0)
3530 {
3531 /* If the input value is greater than max value of datatype, then also
3532 kstrtou8 fails */
3533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3534 "%s: kstrtou8 failed range [%d - %d]", __func__,
3535 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3536 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3537 ret = -EINVAL;
3538 goto exit;
3539 }
3540
3541 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3542 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3543 {
3544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3545 "ft mode value %d is out of range"
3546 " (Min: %d Max: %d)", ft,
3547 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3548 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3549 ret = -EINVAL;
3550 goto exit;
3551 }
3552
3553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3554 "%s: Received Command to change ft mode = %d", __func__, ft);
3555
3556 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3557 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3558 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303559 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3560 {
3561 tANI_U8 *value = command;
3562 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303563
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303564 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3565 value = value + 15;
3566 /* Convert the value from ascii to integer */
3567 ret = kstrtou8(value, 10, &dfsScanMode);
3568 if (ret < 0)
3569 {
3570 /* If the input value is greater than max value of
3571 datatype, then also kstrtou8 fails
3572 */
3573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3574 "%s: kstrtou8 failed range [%d - %d]", __func__,
3575 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3576 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3577 ret = -EINVAL;
3578 goto exit;
3579 }
3580
3581 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3582 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3583 {
3584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3585 "dfsScanMode value %d is out of range"
3586 " (Min: %d Max: %d)", dfsScanMode,
3587 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3588 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3589 ret = -EINVAL;
3590 goto exit;
3591 }
3592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3593 "%s: Received Command to Set DFS Scan Mode = %d",
3594 __func__, dfsScanMode);
3595
3596 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3597 }
3598 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3599 {
3600 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3601 char extra[32];
3602 tANI_U8 len = 0;
3603
3604 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3605 if (copy_to_user(priv_data.buf, &extra, len + 1))
3606 {
3607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3608 "%s: failed to copy data to user buffer", __func__);
3609 ret = -EFAULT;
3610 goto exit;
3611 }
3612 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303613 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3614 {
3615 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303616 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303617 tSirMacAddr targetApBssid;
3618 tANI_U8 trigger = 0;
3619 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303620 tHalHandle hHal;
3621 v_U32_t roamId = 0;
3622 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303623 hdd_station_ctx_t *pHddStaCtx = NULL;
3624 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303625 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303626
3627 /* if not associated, no need to proceed with reassoc */
3628 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3629 {
3630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3631 ret = -EINVAL;
3632 goto exit;
3633 }
3634
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303635 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303636 if (eHAL_STATUS_SUCCESS != status)
3637 {
3638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3639 "%s: Failed to parse reassoc command data", __func__);
3640 ret = -EINVAL;
3641 goto exit;
3642 }
3643
3644 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303645 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303646 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3647 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3648 {
3649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3650 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3651 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303652 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3653 &modProfileFields);
3654 sme_RoamReassoc(hHal, pAdapter->sessionId,
3655 NULL, modProfileFields, &roamId, 1);
3656 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303657 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303658
3659 /* Check channel number is a valid channel number */
3660 if(VOS_STATUS_SUCCESS !=
3661 wlan_hdd_validate_operation_channel(pAdapter, channel))
3662 {
3663 hddLog(VOS_TRACE_LEVEL_ERROR,
3664 "%s: Invalid Channel [%d]", __func__, channel);
3665 return -EINVAL;
3666 }
3667
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303668 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303669
3670 /* Proceed with scan/roam */
3671 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3672 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303673 (tSmeFastRoamTrigger)(trigger),
3674 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303675 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003676#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003677#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003678 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3679 {
3680 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003681 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003682
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003683 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003684 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003685 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003686 hdd_is_okc_mode_enabled(pHddCtx) &&
3687 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3688 {
3689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003690 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003691 " hence this operation is not permitted!", __func__);
3692 ret = -EPERM;
3693 goto exit;
3694 }
3695
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003696 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3697 value = value + 11;
3698 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003699 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003700 if (ret < 0)
3701 {
3702 /* If the input value is greater than max value of datatype, then also
3703 kstrtou8 fails */
3704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3705 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003706 CFG_ESE_FEATURE_ENABLED_MIN,
3707 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003708 ret = -EINVAL;
3709 goto exit;
3710 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003711 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3712 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003713 {
3714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003715 "Ese mode value %d is out of range"
3716 " (Min: %d Max: %d)", eseMode,
3717 CFG_ESE_FEATURE_ENABLED_MIN,
3718 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003719 ret = -EINVAL;
3720 goto exit;
3721 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003723 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003724
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003725 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3726 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003727 }
3728#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003729 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3730 {
3731 tANI_U8 *value = command;
3732 tANI_BOOLEAN roamScanControl = 0;
3733
3734 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3735 value = value + 19;
3736 /* Convert the value from ascii to integer */
3737 ret = kstrtou8(value, 10, &roamScanControl);
3738 if (ret < 0)
3739 {
3740 /* If the input value is greater than max value of datatype, then also
3741 kstrtou8 fails */
3742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3743 "%s: kstrtou8 failed ", __func__);
3744 ret = -EINVAL;
3745 goto exit;
3746 }
3747
3748 if (0 != roamScanControl)
3749 {
3750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3751 "roam scan control invalid value = %d",
3752 roamScanControl);
3753 ret = -EINVAL;
3754 goto exit;
3755 }
3756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3757 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3758
3759 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3760 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003761#ifdef FEATURE_WLAN_OKC
3762 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3763 {
3764 tANI_U8 *value = command;
3765 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3766
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003767 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003768 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003769 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003770 hdd_is_okc_mode_enabled(pHddCtx) &&
3771 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3772 {
3773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003774 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003775 " hence this operation is not permitted!", __func__);
3776 ret = -EPERM;
3777 goto exit;
3778 }
3779
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003780 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3781 value = value + 11;
3782 /* Convert the value from ascii to integer */
3783 ret = kstrtou8(value, 10, &okcMode);
3784 if (ret < 0)
3785 {
3786 /* If the input value is greater than max value of datatype, then also
3787 kstrtou8 fails */
3788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3789 "%s: kstrtou8 failed range [%d - %d]", __func__,
3790 CFG_OKC_FEATURE_ENABLED_MIN,
3791 CFG_OKC_FEATURE_ENABLED_MAX);
3792 ret = -EINVAL;
3793 goto exit;
3794 }
3795
3796 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3797 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3798 {
3799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3800 "Okc mode value %d is out of range"
3801 " (Min: %d Max: %d)", okcMode,
3802 CFG_OKC_FEATURE_ENABLED_MIN,
3803 CFG_OKC_FEATURE_ENABLED_MAX);
3804 ret = -EINVAL;
3805 goto exit;
3806 }
3807
3808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3809 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3810
3811 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3812 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003813#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303814 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003815 {
3816 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3817 char extra[32];
3818 tANI_U8 len = 0;
3819
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003820 len = scnprintf(extra, sizeof(extra), "%s %d",
3821 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003822 if (copy_to_user(priv_data.buf, &extra, len + 1))
3823 {
3824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3825 "%s: failed to copy data to user buffer", __func__);
3826 ret = -EFAULT;
3827 goto exit;
3828 }
3829 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303830#ifdef WLAN_FEATURE_PACKET_FILTERING
3831 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3832 {
3833 tANI_U8 filterType = 0;
3834 tANI_U8 *value = command;
3835
3836 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3837 value = value + 22;
3838
3839 /* Convert the value from ascii to integer */
3840 ret = kstrtou8(value, 10, &filterType);
3841 if (ret < 0)
3842 {
3843 /* If the input value is greater than max value of datatype,
3844 * then also kstrtou8 fails
3845 */
3846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3847 "%s: kstrtou8 failed range ", __func__);
3848 ret = -EINVAL;
3849 goto exit;
3850 }
3851
3852 if (filterType != 0 && filterType != 1)
3853 {
3854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3855 "%s: Accepted Values are 0 and 1 ", __func__);
3856 ret = -EINVAL;
3857 goto exit;
3858 }
3859 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3860 pAdapter->sessionId);
3861 }
3862#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303863 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3864 {
Kiet Lamad161252014-07-22 11:23:32 -07003865 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303866 int ret;
3867
Kiet Lamad161252014-07-22 11:23:32 -07003868 dhcpPhase = command + 11;
3869 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303870 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003872 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303873
3874 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003875
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303876 ret = wlan_hdd_scan_abort(pAdapter);
3877 if (ret < 0)
3878 {
3879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3880 FL("failed to abort existing scan %d"), ret);
3881 }
3882
Kiet Lamad161252014-07-22 11:23:32 -07003883 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3884 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303885 }
Kiet Lamad161252014-07-22 11:23:32 -07003886 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303887 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003889 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303890
3891 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003892
3893 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3894 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303895 }
3896 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003897 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3898 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3900 FL("making default scan to ACTIVE"));
3901 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003902 }
3903 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3904 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3906 FL("making default scan to PASSIVE"));
3907 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003908 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303909 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3910 {
3911 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3912 char extra[32];
3913 tANI_U8 len = 0;
3914
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303915 memset(extra, 0, sizeof(extra));
3916 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3917 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303918 {
3919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3920 "%s: failed to copy data to user buffer", __func__);
3921 ret = -EFAULT;
3922 goto exit;
3923 }
3924 ret = len;
3925 }
3926 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3927 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303928 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303929 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003930 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3931 {
3932 tANI_U8 filterType = 0;
3933 tANI_U8 *value;
3934 value = command + 9;
3935
3936 /* Convert the value from ascii to integer */
3937 ret = kstrtou8(value, 10, &filterType);
3938 if (ret < 0)
3939 {
3940 /* If the input value is greater than max value of datatype,
3941 * then also kstrtou8 fails
3942 */
3943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3944 "%s: kstrtou8 failed range ", __func__);
3945 ret = -EINVAL;
3946 goto exit;
3947 }
3948 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3949 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3950 {
3951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3952 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3953 " 2-Sink ", __func__);
3954 ret = -EINVAL;
3955 goto exit;
3956 }
3957 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3958 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303959 pScanInfo = &pHddCtx->scan_info;
3960 if (filterType && pScanInfo != NULL &&
3961 pHddCtx->scan_info.mScanPending)
3962 {
3963 /*Miracast Session started. Abort Scan */
3964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3965 "%s, Aborting Scan For Miracast",__func__);
3966 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3967 eCSR_SCAN_ABORT_DEFAULT);
3968 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003969 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303970 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003971 }
Leo Chang614d2072013-08-22 14:59:44 -07003972 else if (strncmp(command, "SETMCRATE", 9) == 0)
3973 {
Leo Chang614d2072013-08-22 14:59:44 -07003974 tANI_U8 *value = command;
3975 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003976 tSirRateUpdateInd *rateUpdate;
3977 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003978
3979 /* Only valid for SAP mode */
3980 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3981 {
3982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3983 "%s: SAP mode is not running", __func__);
3984 ret = -EFAULT;
3985 goto exit;
3986 }
3987
3988 /* Move pointer to ahead of SETMCRATE<delimiter> */
3989 /* input value is in units of hundred kbps */
3990 value = value + 10;
3991 /* Convert the value from ascii to integer, decimal base */
3992 ret = kstrtouint(value, 10, &targetRate);
3993
Leo Chang1f98cbd2013-10-17 15:03:52 -07003994 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3995 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003996 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003997 hddLog(VOS_TRACE_LEVEL_ERROR,
3998 "%s: SETMCRATE indication alloc fail", __func__);
3999 ret = -EFAULT;
4000 goto exit;
4001 }
4002 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4003
4004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4005 "MC Target rate %d", targetRate);
4006 /* Ignore unicast */
4007 rateUpdate->ucastDataRate = -1;
4008 rateUpdate->mcastDataRate24GHz = targetRate;
4009 rateUpdate->mcastDataRate5GHz = targetRate;
4010 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4011 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4012 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4013 if (eHAL_STATUS_SUCCESS != status)
4014 {
4015 hddLog(VOS_TRACE_LEVEL_ERROR,
4016 "%s: SET_MC_RATE failed", __func__);
4017 vos_mem_free(rateUpdate);
4018 ret = -EFAULT;
4019 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004020 }
4021 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304022#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004023 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304024 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004025 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304026 }
4027#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004028#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004029 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4030 {
4031 tANI_U8 *value = command;
4032 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4033 tANI_U8 numChannels = 0;
4034 eHalStatus status = eHAL_STATUS_SUCCESS;
4035
4036 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4037 if (eHAL_STATUS_SUCCESS != status)
4038 {
4039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4040 "%s: Failed to parse channel list information", __func__);
4041 ret = -EINVAL;
4042 goto exit;
4043 }
4044
4045 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4046 {
4047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4048 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4049 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4050 ret = -EINVAL;
4051 goto exit;
4052 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004053 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004054 ChannelList,
4055 numChannels);
4056 if (eHAL_STATUS_SUCCESS != status)
4057 {
4058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4059 "%s: Failed to update channel list information", __func__);
4060 ret = -EINVAL;
4061 goto exit;
4062 }
4063 }
4064 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4065 {
4066 tANI_U8 *value = command;
4067 char extra[128] = {0};
4068 int len = 0;
4069 tANI_U8 tid = 0;
4070 hdd_station_ctx_t *pHddStaCtx = NULL;
4071 tAniTrafStrmMetrics tsmMetrics;
4072 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4073
4074 /* if not associated, return error */
4075 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4076 {
4077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4078 ret = -EINVAL;
4079 goto exit;
4080 }
4081
4082 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4083 value = value + 12;
4084 /* Convert the value from ascii to integer */
4085 ret = kstrtou8(value, 10, &tid);
4086 if (ret < 0)
4087 {
4088 /* If the input value is greater than max value of datatype, then also
4089 kstrtou8 fails */
4090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4091 "%s: kstrtou8 failed range [%d - %d]", __func__,
4092 TID_MIN_VALUE,
4093 TID_MAX_VALUE);
4094 ret = -EINVAL;
4095 goto exit;
4096 }
4097
4098 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4099 {
4100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4101 "tid value %d is out of range"
4102 " (Min: %d Max: %d)", tid,
4103 TID_MIN_VALUE,
4104 TID_MAX_VALUE);
4105 ret = -EINVAL;
4106 goto exit;
4107 }
4108
4109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4110 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4111
4112 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4113 {
4114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4115 "%s: failed to get tsm stats", __func__);
4116 ret = -EFAULT;
4117 goto exit;
4118 }
4119
4120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4121 "UplinkPktQueueDly(%d)\n"
4122 "UplinkPktQueueDlyHist[0](%d)\n"
4123 "UplinkPktQueueDlyHist[1](%d)\n"
4124 "UplinkPktQueueDlyHist[2](%d)\n"
4125 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304126 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004127 "UplinkPktLoss(%d)\n"
4128 "UplinkPktCount(%d)\n"
4129 "RoamingCount(%d)\n"
4130 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4131 tsmMetrics.UplinkPktQueueDlyHist[0],
4132 tsmMetrics.UplinkPktQueueDlyHist[1],
4133 tsmMetrics.UplinkPktQueueDlyHist[2],
4134 tsmMetrics.UplinkPktQueueDlyHist[3],
4135 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4136 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4137
4138 /* Output TSM stats is of the format
4139 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4140 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004141 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004142 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4143 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4144 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4145 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4146 tsmMetrics.RoamingDly);
4147
4148 if (copy_to_user(priv_data.buf, &extra, len + 1))
4149 {
4150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4151 "%s: failed to copy data to user buffer", __func__);
4152 ret = -EFAULT;
4153 goto exit;
4154 }
4155 }
4156 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4157 {
4158 tANI_U8 *value = command;
4159 tANI_U8 *cckmIe = NULL;
4160 tANI_U8 cckmIeLen = 0;
4161 eHalStatus status = eHAL_STATUS_SUCCESS;
4162
4163 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4164 if (eHAL_STATUS_SUCCESS != status)
4165 {
4166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4167 "%s: Failed to parse cckm ie data", __func__);
4168 ret = -EINVAL;
4169 goto exit;
4170 }
4171
4172 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4173 {
4174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4175 "%s: CCKM Ie input length is more than max[%d]", __func__,
4176 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004177 vos_mem_free(cckmIe);
4178 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004179 ret = -EINVAL;
4180 goto exit;
4181 }
4182 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004183 vos_mem_free(cckmIe);
4184 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004185 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004186 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4187 {
4188 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004189 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004190 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004191
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004192 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004193 if (eHAL_STATUS_SUCCESS != status)
4194 {
4195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004196 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004197 ret = -EINVAL;
4198 goto exit;
4199 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004200 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4202 hdd_indicateEseBcnReportNoResults (pAdapter,
4203 eseBcnReq.bcnReq[0].measurementToken,
4204 0x02, //BIT(1) set for measurement done
4205 0); // no BSS
4206 goto exit;
4207 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004208
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004209 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4210 if (eHAL_STATUS_SUCCESS != status)
4211 {
4212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4213 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4214 ret = -EINVAL;
4215 goto exit;
4216 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004217 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004218#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304219 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4220 {
4221 eHalStatus status;
4222 char buf[32], len;
4223 long waitRet;
4224 bcnMissRateContext_t getBcnMissRateCtx;
4225
4226 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4227
4228 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4229 {
4230 hddLog(VOS_TRACE_LEVEL_WARN,
4231 FL("GETBCNMISSRATE: STA is not in connected state"));
4232 ret = -1;
4233 goto exit;
4234 }
4235
4236 init_completion(&(getBcnMissRateCtx.completion));
4237 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4238
4239 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4240 pAdapter->sessionId,
4241 (void *)getBcnMissRateCB,
4242 (void *)(&getBcnMissRateCtx));
4243 if( eHAL_STATUS_SUCCESS != status)
4244 {
4245 hddLog(VOS_TRACE_LEVEL_INFO,
4246 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4247 ret = -EINVAL;
4248 goto exit;
4249 }
4250
4251 waitRet = wait_for_completion_interruptible_timeout
4252 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4253 if(waitRet <= 0)
4254 {
4255 hddLog(VOS_TRACE_LEVEL_ERROR,
4256 FL("failed to wait on bcnMissRateComp %d"), ret);
4257
4258 //Make magic number to zero so that callback is not called.
4259 spin_lock(&hdd_context_lock);
4260 getBcnMissRateCtx.magic = 0x0;
4261 spin_unlock(&hdd_context_lock);
4262 ret = -EINVAL;
4263 goto exit;
4264 }
4265
4266 hddLog(VOS_TRACE_LEVEL_INFO,
4267 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4268
4269 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4270 if (copy_to_user(priv_data.buf, &buf, len + 1))
4271 {
4272 hddLog(VOS_TRACE_LEVEL_ERROR,
4273 "%s: failed to copy data to user buffer", __func__);
4274 ret = -EFAULT;
4275 goto exit;
4276 }
4277 ret = len;
4278 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304279#ifdef FEATURE_WLAN_TDLS
4280 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4281 tANI_U8 *value = command;
4282 int set_value;
4283 /* Move pointer to ahead of TDLSOFFCH*/
4284 value += 26;
4285 sscanf(value, "%d", &set_value);
4286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4287 "%s: Tdls offchannel offset:%d",
4288 __func__, set_value);
4289 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4290 if (ret < 0)
4291 {
4292 ret = -EINVAL;
4293 goto exit;
4294 }
4295
4296 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4297 tANI_U8 *value = command;
4298 int set_value;
4299 /* Move pointer to ahead of tdlsoffchnmode*/
4300 value += 18;
4301 sscanf(value, "%d", &set_value);
4302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4303 "%s: Tdls offchannel mode:%d",
4304 __func__, set_value);
4305 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4306 if (ret < 0)
4307 {
4308 ret = -EINVAL;
4309 goto exit;
4310 }
4311 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4312 tANI_U8 *value = command;
4313 int set_value;
4314 /* Move pointer to ahead of TDLSOFFCH*/
4315 value += 14;
4316 sscanf(value, "%d", &set_value);
4317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4318 "%s: Tdls offchannel num: %d",
4319 __func__, set_value);
4320 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4321 if (ret < 0)
4322 {
4323 ret = -EINVAL;
4324 goto exit;
4325 }
4326 }
4327#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304328 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4329 {
4330 eHalStatus status;
4331 char *buf = NULL;
4332 char len;
4333 long waitRet;
4334 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304335 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304336 tANI_U8 *ptr = command;
4337 int stats = *(ptr + 11) - '0';
4338
4339 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4340 if (!IS_FEATURE_FW_STATS_ENABLE)
4341 {
4342 hddLog(VOS_TRACE_LEVEL_INFO,
4343 FL("Get Firmware stats feature not supported"));
4344 ret = -EINVAL;
4345 goto exit;
4346 }
4347
4348 if (FW_STATS_MAX <= stats || 0 >= stats)
4349 {
4350 hddLog(VOS_TRACE_LEVEL_INFO,
4351 FL(" stats %d not supported"),stats);
4352 ret = -EINVAL;
4353 goto exit;
4354 }
4355
4356 init_completion(&(fwStatsCtx.completion));
4357 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4358 fwStatsCtx.pAdapter = pAdapter;
4359 fwStatsRsp->type = 0;
4360 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304361 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304362 if (eHAL_STATUS_SUCCESS != status)
4363 {
4364 hddLog(VOS_TRACE_LEVEL_ERROR,
4365 FL(" fail to post WDA cmd status = %d"), status);
4366 ret = -EINVAL;
4367 goto exit;
4368 }
4369 waitRet = wait_for_completion_timeout
4370 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4371 if (waitRet <= 0)
4372 {
4373 hddLog(VOS_TRACE_LEVEL_ERROR,
4374 FL("failed to wait on GwtFwstats"));
4375 //Make magic number to zero so that callback is not executed.
4376 spin_lock(&hdd_context_lock);
4377 fwStatsCtx.magic = 0x0;
4378 spin_unlock(&hdd_context_lock);
4379 ret = -EINVAL;
4380 goto exit;
4381 }
4382 if (fwStatsRsp->type)
4383 {
4384 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4385 if (!buf)
4386 {
4387 hddLog(VOS_TRACE_LEVEL_ERROR,
4388 FL(" failed to allocate memory"));
4389 ret = -ENOMEM;
4390 goto exit;
4391 }
4392 switch( fwStatsRsp->type )
4393 {
4394 case FW_UBSP_STATS:
4395 {
4396 len = snprintf(buf, FW_STATE_RSP_LEN,
4397 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304398 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4399 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304400 }
4401 break;
4402 default:
4403 {
4404 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4405 ret = -EFAULT;
4406 kfree(buf);
4407 goto exit;
4408 }
4409 }
4410 if (copy_to_user(priv_data.buf, buf, len + 1))
4411 {
4412 hddLog(VOS_TRACE_LEVEL_ERROR,
4413 FL(" failed to copy data to user buffer"));
4414 ret = -EFAULT;
4415 kfree(buf);
4416 goto exit;
4417 }
4418 ret = len;
4419 kfree(buf);
4420 }
4421 else
4422 {
4423 hddLog(VOS_TRACE_LEVEL_ERROR,
4424 FL("failed to fetch the stats"));
4425 ret = -EFAULT;
4426 goto exit;
4427 }
4428
4429 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304430 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4431 {
4432 /*
4433 * this command wld be called by user-space when it detects WLAN
4434 * ON after airplane mode is set. When APM is set, WLAN turns off.
4435 * But it can be turned back on. Otherwise; when APM is turned back
4436 * off, WLAN wld turn back on. So at that point the command is
4437 * expected to come down. 0 means disable, 1 means enable. The
4438 * constraint is removed when parameter 1 is set or different
4439 * country code is set
4440 */
4441 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4442 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004443 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304444 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4445 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4446 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304447 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4448 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004450 }
4451exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304452 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 if (command)
4454 {
4455 kfree(command);
4456 }
4457 return ret;
4458}
4459
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004460#ifdef CONFIG_COMPAT
4461static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4462{
4463 struct {
4464 compat_uptr_t buf;
4465 int used_len;
4466 int total_len;
4467 } compat_priv_data;
4468 hdd_priv_data_t priv_data;
4469 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004470
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004471 /*
4472 * Note that pAdapter and ifr have already been verified by caller,
4473 * and HDD context has also been validated
4474 */
4475 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4476 sizeof(compat_priv_data))) {
4477 ret = -EFAULT;
4478 goto exit;
4479 }
4480 priv_data.buf = compat_ptr(compat_priv_data.buf);
4481 priv_data.used_len = compat_priv_data.used_len;
4482 priv_data.total_len = compat_priv_data.total_len;
4483 ret = hdd_driver_command(pAdapter, &priv_data);
4484 exit:
4485 return ret;
4486}
4487#else /* CONFIG_COMPAT */
4488static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4489{
4490 /* will never be invoked */
4491 return 0;
4492}
4493#endif /* CONFIG_COMPAT */
4494
4495static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4496{
4497 hdd_priv_data_t priv_data;
4498 int ret = 0;
4499
4500 /*
4501 * Note that pAdapter and ifr have already been verified by caller,
4502 * and HDD context has also been validated
4503 */
4504 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4505 ret = -EFAULT;
4506 } else {
4507 ret = hdd_driver_command(pAdapter, &priv_data);
4508 }
4509 return ret;
4510}
4511
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304512int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004513{
4514 hdd_adapter_t *pAdapter;
4515 hdd_context_t *pHddCtx;
4516 int ret;
4517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304518 ENTER();
4519
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004520 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4521 if (NULL == pAdapter) {
4522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4523 "%s: HDD adapter context is Null", __func__);
4524 ret = -ENODEV;
4525 goto exit;
4526 }
4527 if (dev != pAdapter->dev) {
4528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4529 "%s: HDD adapter/dev inconsistency", __func__);
4530 ret = -ENODEV;
4531 goto exit;
4532 }
4533
4534 if ((!ifr) || (!ifr->ifr_data)) {
4535 ret = -EINVAL;
4536 goto exit;
4537 }
4538
4539 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4540 ret = wlan_hdd_validate_context(pHddCtx);
4541 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004542 ret = -EBUSY;
4543 goto exit;
4544 }
4545
4546 switch (cmd) {
4547 case (SIOCDEVPRIVATE + 1):
4548 if (is_compat_task())
4549 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4550 else
4551 ret = hdd_driver_ioctl(pAdapter, ifr);
4552 break;
4553 default:
4554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4555 __func__, cmd);
4556 ret = -EINVAL;
4557 break;
4558 }
4559 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304560 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004561 return ret;
4562}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004563
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304564int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4565{
4566 int ret;
4567
4568 vos_ssr_protect(__func__);
4569 ret = __hdd_ioctl(dev, ifr, cmd);
4570 vos_ssr_unprotect(__func__);
4571
4572 return ret;
4573}
4574
Katya Nigame7b69a82015-04-28 15:24:06 +05304575int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4576{
4577 return 0;
4578}
4579
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004580#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004581/**---------------------------------------------------------------------------
4582
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004583 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004584
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004585 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004586 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4587 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4588 <space>Scan Mode N<space>Meas Duration N
4589 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4590 then take N.
4591 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4592 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4593 This function does not take care of removing duplicate channels from the list
4594
4595 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004596 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004597
4598 \return - 0 for success non-zero for failure
4599
4600 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004601static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4602 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004603{
4604 tANI_U8 *inPtr = pValue;
4605 int tempInt = 0;
4606 int j = 0, i = 0, v = 0;
4607 char buf[32];
4608
4609 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4610 /*no argument after the command*/
4611 if (NULL == inPtr)
4612 {
4613 return -EINVAL;
4614 }
4615 /*no space after the command*/
4616 else if (SPACE_ASCII_VALUE != *inPtr)
4617 {
4618 return -EINVAL;
4619 }
4620
4621 /*removing empty spaces*/
4622 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4623
4624 /*no argument followed by spaces*/
4625 if ('\0' == *inPtr) return -EINVAL;
4626
4627 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004628 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004629 if (1 != v) return -EINVAL;
4630
4631 v = kstrtos32(buf, 10, &tempInt);
4632 if ( v < 0) return -EINVAL;
4633
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004634 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004635
4636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004637 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004638
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004639 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004640 {
4641 for (i = 0; i < 4; i++)
4642 {
4643 /*inPtr pointing to the beginning of first space after number of ie fields*/
4644 inPtr = strpbrk( inPtr, " " );
4645 /*no ie data after the number of ie fields argument*/
4646 if (NULL == inPtr) return -EINVAL;
4647
4648 /*removing empty space*/
4649 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4650
4651 /*no ie data after the number of ie fields argument and spaces*/
4652 if ( '\0' == *inPtr ) return -EINVAL;
4653
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004654 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004655 if (1 != v) return -EINVAL;
4656
4657 v = kstrtos32(buf, 10, &tempInt);
4658 if (v < 0) return -EINVAL;
4659
4660 switch (i)
4661 {
4662 case 0: /* Measurement token */
4663 if (tempInt <= 0)
4664 {
4665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4666 "Invalid Measurement Token(%d)", tempInt);
4667 return -EINVAL;
4668 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004669 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004670 break;
4671
4672 case 1: /* Channel number */
4673 if ((tempInt <= 0) ||
4674 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4675 {
4676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4677 "Invalid Channel Number(%d)", tempInt);
4678 return -EINVAL;
4679 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004680 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004681 break;
4682
4683 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004684 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004685 {
4686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4687 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4688 return -EINVAL;
4689 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004690 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004691 break;
4692
4693 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004694 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4695 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004696 {
4697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4698 "Invalid Measurement Duration(%d)", tempInt);
4699 return -EINVAL;
4700 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004701 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004702 break;
4703 }
4704 }
4705 }
4706
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004707 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004708 {
4709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304710 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004711 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004712 pEseBcnReq->bcnReq[j].measurementToken,
4713 pEseBcnReq->bcnReq[j].channel,
4714 pEseBcnReq->bcnReq[j].scanMode,
4715 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004716 }
4717
4718 return VOS_STATUS_SUCCESS;
4719}
4720
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004721static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4722{
4723 struct statsContext *pStatsContext = NULL;
4724 hdd_adapter_t *pAdapter = NULL;
4725
4726 if (NULL == pContext)
4727 {
4728 hddLog(VOS_TRACE_LEVEL_ERROR,
4729 "%s: Bad param, pContext [%p]",
4730 __func__, pContext);
4731 return;
4732 }
4733
Jeff Johnson72a40512013-12-19 10:14:15 -08004734 /* there is a race condition that exists between this callback
4735 function and the caller since the caller could time out either
4736 before or while this code is executing. we use a spinlock to
4737 serialize these actions */
4738 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004739
4740 pStatsContext = pContext;
4741 pAdapter = pStatsContext->pAdapter;
4742 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4743 {
4744 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004745 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004746 hddLog(VOS_TRACE_LEVEL_WARN,
4747 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4748 __func__, pAdapter, pStatsContext->magic);
4749 return;
4750 }
4751
Jeff Johnson72a40512013-12-19 10:14:15 -08004752 /* context is valid so caller is still waiting */
4753
4754 /* paranoia: invalidate the magic */
4755 pStatsContext->magic = 0;
4756
4757 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004758 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4759 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4760 tsmMetrics.UplinkPktQueueDlyHist,
4761 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4762 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4763 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4764 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4765 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4766 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4767 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4768
Jeff Johnson72a40512013-12-19 10:14:15 -08004769 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004770 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004771
4772 /* serialization is complete */
4773 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004774}
4775
4776
4777
4778static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4779 tAniTrafStrmMetrics* pTsmMetrics)
4780{
4781 hdd_station_ctx_t *pHddStaCtx = NULL;
4782 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004783 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004784 long lrc;
4785 struct statsContext context;
4786 hdd_context_t *pHddCtx = NULL;
4787
4788 if (NULL == pAdapter)
4789 {
4790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4791 return VOS_STATUS_E_FAULT;
4792 }
4793
4794 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4795 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4796
4797 /* we are connected prepare our callback context */
4798 init_completion(&context.completion);
4799 context.pAdapter = pAdapter;
4800 context.magic = STATS_CONTEXT_MAGIC;
4801
4802 /* query tsm stats */
4803 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4804 pHddStaCtx->conn_info.staId[ 0 ],
4805 pHddStaCtx->conn_info.bssId,
4806 &context, pHddCtx->pvosContext, tid);
4807
4808 if (eHAL_STATUS_SUCCESS != hstatus)
4809 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004810 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4811 __func__);
4812 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004813 }
4814 else
4815 {
4816 /* request was sent -- wait for the response */
4817 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4818 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004819 if (lrc <= 0)
4820 {
4821 hddLog(VOS_TRACE_LEVEL_ERROR,
4822 "%s: SME %s while retrieving statistics",
4823 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004824 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004825 }
4826 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004827
Jeff Johnson72a40512013-12-19 10:14:15 -08004828 /* either we never sent a request, we sent a request and received a
4829 response or we sent a request and timed out. if we never sent a
4830 request or if we sent a request and got a response, we want to
4831 clear the magic out of paranoia. if we timed out there is a
4832 race condition such that the callback function could be
4833 executing at the same time we are. of primary concern is if the
4834 callback function had already verified the "magic" but had not
4835 yet set the completion variable when a timeout occurred. we
4836 serialize these activities by invalidating the magic while
4837 holding a shared spinlock which will cause us to block if the
4838 callback is currently executing */
4839 spin_lock(&hdd_context_lock);
4840 context.magic = 0;
4841 spin_unlock(&hdd_context_lock);
4842
4843 if (VOS_STATUS_SUCCESS == vstatus)
4844 {
4845 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4846 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4847 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4848 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4849 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4850 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4851 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4852 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4853 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4854 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4855 }
4856 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004857}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004858#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004859
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004860#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004861void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4862{
4863 eCsrBand band = -1;
4864 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4865 switch (band)
4866 {
4867 case eCSR_BAND_ALL:
4868 *pBand = WLAN_HDD_UI_BAND_AUTO;
4869 break;
4870
4871 case eCSR_BAND_24:
4872 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4873 break;
4874
4875 case eCSR_BAND_5G:
4876 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4877 break;
4878
4879 default:
4880 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4881 *pBand = -1;
4882 break;
4883 }
4884}
4885
4886/**---------------------------------------------------------------------------
4887
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004888 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4889
4890 This function parses the send action frame data passed in the format
4891 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4892
Srinivas Girigowda56076852013-08-20 14:00:50 -07004893 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004894 \param - pTargetApBssid Pointer to target Ap bssid
4895 \param - pChannel Pointer to the Target AP channel
4896 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4897 \param - pBuf Pointer to data
4898 \param - pBufLen Pointer to data length
4899
4900 \return - 0 for success non-zero for failure
4901
4902 --------------------------------------------------------------------------*/
4903VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4904 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4905{
4906 tANI_U8 *inPtr = pValue;
4907 tANI_U8 *dataEnd;
4908 int tempInt;
4909 int j = 0;
4910 int i = 0;
4911 int v = 0;
4912 tANI_U8 tempBuf[32];
4913 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004914 /* 12 hexa decimal digits, 5 ':' and '\0' */
4915 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004916
4917 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4918 /*no argument after the command*/
4919 if (NULL == inPtr)
4920 {
4921 return -EINVAL;
4922 }
4923
4924 /*no space after the command*/
4925 else if (SPACE_ASCII_VALUE != *inPtr)
4926 {
4927 return -EINVAL;
4928 }
4929
4930 /*removing empty spaces*/
4931 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4932
4933 /*no argument followed by spaces*/
4934 if ('\0' == *inPtr)
4935 {
4936 return -EINVAL;
4937 }
4938
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004939 v = sscanf(inPtr, "%17s", macAddress);
4940 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004941 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4943 "Invalid MAC address or All hex inputs are not read (%d)", v);
4944 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004945 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004946
4947 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4948 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4949 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4950 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4951 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4952 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004953
4954 /* point to the next argument */
4955 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4956 /*no argument after the command*/
4957 if (NULL == inPtr) return -EINVAL;
4958
4959 /*removing empty spaces*/
4960 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4961
4962 /*no argument followed by spaces*/
4963 if ('\0' == *inPtr)
4964 {
4965 return -EINVAL;
4966 }
4967
4968 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004969 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004970 if (1 != v) return -EINVAL;
4971
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004972 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304973 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304974 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004975
4976 *pChannel = tempInt;
4977
4978 /* point to the next argument */
4979 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4980 /*no argument after the command*/
4981 if (NULL == inPtr) return -EINVAL;
4982 /*removing empty spaces*/
4983 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4984
4985 /*no argument followed by spaces*/
4986 if ('\0' == *inPtr)
4987 {
4988 return -EINVAL;
4989 }
4990
4991 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004992 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004993 if (1 != v) return -EINVAL;
4994
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004995 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004996 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004997
4998 *pDwellTime = tempInt;
4999
5000 /* point to the next argument */
5001 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5002 /*no argument after the command*/
5003 if (NULL == inPtr) return -EINVAL;
5004 /*removing empty spaces*/
5005 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5006
5007 /*no argument followed by spaces*/
5008 if ('\0' == *inPtr)
5009 {
5010 return -EINVAL;
5011 }
5012
5013 /* find the length of data */
5014 dataEnd = inPtr;
5015 while(('\0' != *dataEnd) )
5016 {
5017 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005018 }
Kiet Lambe150c22013-11-21 16:30:32 +05305019 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005020 if ( *pBufLen <= 0) return -EINVAL;
5021
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005022 /* Allocate the number of bytes based on the number of input characters
5023 whether it is even or odd.
5024 if the number of input characters are even, then we need N/2 byte.
5025 if the number of input characters are odd, then we need do (N+1)/2 to
5026 compensate rounding off.
5027 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5028 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5029 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005030 if (NULL == *pBuf)
5031 {
5032 hddLog(VOS_TRACE_LEVEL_FATAL,
5033 "%s: vos_mem_alloc failed ", __func__);
5034 return -EINVAL;
5035 }
5036
5037 /* the buffer received from the upper layer is character buffer,
5038 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5039 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5040 and f0 in 3rd location */
5041 for (i = 0, j = 0; j < *pBufLen; j += 2)
5042 {
Kiet Lambe150c22013-11-21 16:30:32 +05305043 if( j+1 == *pBufLen)
5044 {
5045 tempByte = hdd_parse_hex(inPtr[j]);
5046 }
5047 else
5048 {
5049 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5050 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005051 (*pBuf)[i++] = tempByte;
5052 }
5053 *pBufLen = i;
5054 return VOS_STATUS_SUCCESS;
5055}
5056
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005057/**---------------------------------------------------------------------------
5058
Srinivas Girigowdade697412013-02-14 16:31:48 -08005059 \brief hdd_parse_channellist() - HDD Parse channel list
5060
5061 This function parses the channel list passed in the format
5062 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005063 if the Number of channels (N) does not match with the actual number of channels passed
5064 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5065 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5066 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5067 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005068
5069 \param - pValue Pointer to input channel list
5070 \param - ChannelList Pointer to local output array to record channel list
5071 \param - pNumChannels Pointer to number of roam scan channels
5072
5073 \return - 0 for success non-zero for failure
5074
5075 --------------------------------------------------------------------------*/
5076VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5077{
5078 tANI_U8 *inPtr = pValue;
5079 int tempInt;
5080 int j = 0;
5081 int v = 0;
5082 char buf[32];
5083
5084 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5085 /*no argument after the command*/
5086 if (NULL == inPtr)
5087 {
5088 return -EINVAL;
5089 }
5090
5091 /*no space after the command*/
5092 else if (SPACE_ASCII_VALUE != *inPtr)
5093 {
5094 return -EINVAL;
5095 }
5096
5097 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005098 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005099
5100 /*no argument followed by spaces*/
5101 if ('\0' == *inPtr)
5102 {
5103 return -EINVAL;
5104 }
5105
5106 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005107 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005108 if (1 != v) return -EINVAL;
5109
Srinivas Girigowdade697412013-02-14 16:31:48 -08005110 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005111 if ((v < 0) ||
5112 (tempInt <= 0) ||
5113 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5114 {
5115 return -EINVAL;
5116 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005117
5118 *pNumChannels = tempInt;
5119
5120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5121 "Number of channels are: %d", *pNumChannels);
5122
5123 for (j = 0; j < (*pNumChannels); j++)
5124 {
5125 /*inPtr pointing to the beginning of first space after number of channels*/
5126 inPtr = strpbrk( inPtr, " " );
5127 /*no channel list after the number of channels argument*/
5128 if (NULL == inPtr)
5129 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005130 if (0 != j)
5131 {
5132 *pNumChannels = j;
5133 return VOS_STATUS_SUCCESS;
5134 }
5135 else
5136 {
5137 return -EINVAL;
5138 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005139 }
5140
5141 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005142 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005143
5144 /*no channel list after the number of channels argument and spaces*/
5145 if ( '\0' == *inPtr )
5146 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005147 if (0 != j)
5148 {
5149 *pNumChannels = j;
5150 return VOS_STATUS_SUCCESS;
5151 }
5152 else
5153 {
5154 return -EINVAL;
5155 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005156 }
5157
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005158 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005159 if (1 != v) return -EINVAL;
5160
Srinivas Girigowdade697412013-02-14 16:31:48 -08005161 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005162 if ((v < 0) ||
5163 (tempInt <= 0) ||
5164 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5165 {
5166 return -EINVAL;
5167 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005168 pChannelList[j] = tempInt;
5169
5170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5171 "Channel %d added to preferred channel list",
5172 pChannelList[j] );
5173 }
5174
Srinivas Girigowdade697412013-02-14 16:31:48 -08005175 return VOS_STATUS_SUCCESS;
5176}
5177
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005178
5179/**---------------------------------------------------------------------------
5180
5181 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5182
5183 This function parses the reasoc command data passed in the format
5184 REASSOC<space><bssid><space><channel>
5185
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005186 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005187 \param - pTargetApBssid Pointer to target Ap bssid
5188 \param - pChannel Pointer to the Target AP channel
5189
5190 \return - 0 for success non-zero for failure
5191
5192 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005193VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5194 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005195{
5196 tANI_U8 *inPtr = pValue;
5197 int tempInt;
5198 int v = 0;
5199 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005200 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005201 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005202
5203 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5204 /*no argument after the command*/
5205 if (NULL == inPtr)
5206 {
5207 return -EINVAL;
5208 }
5209
5210 /*no space after the command*/
5211 else if (SPACE_ASCII_VALUE != *inPtr)
5212 {
5213 return -EINVAL;
5214 }
5215
5216 /*removing empty spaces*/
5217 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5218
5219 /*no argument followed by spaces*/
5220 if ('\0' == *inPtr)
5221 {
5222 return -EINVAL;
5223 }
5224
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005225 v = sscanf(inPtr, "%17s", macAddress);
5226 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005227 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5229 "Invalid MAC address or All hex inputs are not read (%d)", v);
5230 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005231 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005232
5233 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5234 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5235 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5236 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5237 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5238 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005239
5240 /* point to the next argument */
5241 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5242 /*no argument after the command*/
5243 if (NULL == inPtr) return -EINVAL;
5244
5245 /*removing empty spaces*/
5246 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5247
5248 /*no argument followed by spaces*/
5249 if ('\0' == *inPtr)
5250 {
5251 return -EINVAL;
5252 }
5253
5254 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005255 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005256 if (1 != v) return -EINVAL;
5257
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005258 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005259 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305260 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005261 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5262 {
5263 return -EINVAL;
5264 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005265
5266 *pChannel = tempInt;
5267 return VOS_STATUS_SUCCESS;
5268}
5269
5270#endif
5271
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005272#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005273/**---------------------------------------------------------------------------
5274
5275 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5276
5277 This function parses the SETCCKM IE command
5278 SETCCKMIE<space><ie data>
5279
5280 \param - pValue Pointer to input data
5281 \param - pCckmIe Pointer to output cckm Ie
5282 \param - pCckmIeLen Pointer to output cckm ie length
5283
5284 \return - 0 for success non-zero for failure
5285
5286 --------------------------------------------------------------------------*/
5287VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5288 tANI_U8 *pCckmIeLen)
5289{
5290 tANI_U8 *inPtr = pValue;
5291 tANI_U8 *dataEnd;
5292 int j = 0;
5293 int i = 0;
5294 tANI_U8 tempByte = 0;
5295
5296 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5297 /*no argument after the command*/
5298 if (NULL == inPtr)
5299 {
5300 return -EINVAL;
5301 }
5302
5303 /*no space after the command*/
5304 else if (SPACE_ASCII_VALUE != *inPtr)
5305 {
5306 return -EINVAL;
5307 }
5308
5309 /*removing empty spaces*/
5310 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5311
5312 /*no argument followed by spaces*/
5313 if ('\0' == *inPtr)
5314 {
5315 return -EINVAL;
5316 }
5317
5318 /* find the length of data */
5319 dataEnd = inPtr;
5320 while(('\0' != *dataEnd) )
5321 {
5322 dataEnd++;
5323 ++(*pCckmIeLen);
5324 }
5325 if ( *pCckmIeLen <= 0) return -EINVAL;
5326
5327 /* Allocate the number of bytes based on the number of input characters
5328 whether it is even or odd.
5329 if the number of input characters are even, then we need N/2 byte.
5330 if the number of input characters are odd, then we need do (N+1)/2 to
5331 compensate rounding off.
5332 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5333 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5334 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5335 if (NULL == *pCckmIe)
5336 {
5337 hddLog(VOS_TRACE_LEVEL_FATAL,
5338 "%s: vos_mem_alloc failed ", __func__);
5339 return -EINVAL;
5340 }
5341 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5342 /* the buffer received from the upper layer is character buffer,
5343 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5344 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5345 and f0 in 3rd location */
5346 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5347 {
5348 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5349 (*pCckmIe)[i++] = tempByte;
5350 }
5351 *pCckmIeLen = i;
5352
5353 return VOS_STATUS_SUCCESS;
5354}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005355#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005356
Jeff Johnson295189b2012-06-20 16:38:30 -07005357/**---------------------------------------------------------------------------
5358
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005359 \brief hdd_is_valid_mac_address() - Validate MAC address
5360
5361 This function validates whether the given MAC address is valid or not
5362 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5363 where X is the hexa decimal digit character and separated by ':'
5364 This algorithm works even if MAC address is not separated by ':'
5365
5366 This code checks given input string mac contains exactly 12 hexadecimal digits.
5367 and a separator colon : appears in the input string only after
5368 an even number of hex digits.
5369
5370 \param - pMacAddr pointer to the input MAC address
5371 \return - 1 for valid and 0 for invalid
5372
5373 --------------------------------------------------------------------------*/
5374
5375v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5376{
5377 int xdigit = 0;
5378 int separator = 0;
5379 while (*pMacAddr)
5380 {
5381 if (isxdigit(*pMacAddr))
5382 {
5383 xdigit++;
5384 }
5385 else if (':' == *pMacAddr)
5386 {
5387 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5388 break;
5389
5390 ++separator;
5391 }
5392 else
5393 {
5394 separator = -1;
5395 /* Invalid MAC found */
5396 return 0;
5397 }
5398 ++pMacAddr;
5399 }
5400 return (xdigit == 12 && (separator == 5 || separator == 0));
5401}
5402
5403/**---------------------------------------------------------------------------
5404
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305405 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005406
5407 \param - dev Pointer to net_device structure
5408
5409 \return - 0 for success non-zero for failure
5410
5411 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305412int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005413{
5414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5415 hdd_context_t *pHddCtx;
5416 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5417 VOS_STATUS status;
5418 v_BOOL_t in_standby = TRUE;
5419
5420 if (NULL == pAdapter)
5421 {
5422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305423 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 return -ENODEV;
5425 }
5426
5427 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305428 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5429 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 if (NULL == pHddCtx)
5431 {
5432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005433 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 return -ENODEV;
5435 }
5436
5437 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5438 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5439 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005440 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5441 {
5442 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305443 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005444 in_standby = FALSE;
5445 break;
5446 }
5447 else
5448 {
5449 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5450 pAdapterNode = pNext;
5451 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 }
5453
5454 if (TRUE == in_standby)
5455 {
5456 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5457 {
5458 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5459 "wlan out of power save", __func__);
5460 return -EINVAL;
5461 }
5462 }
5463
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005464 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5466 {
5467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005468 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305470 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005471 netif_tx_start_all_queues(dev);
5472 }
5473
5474 return 0;
5475}
5476
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305477/**---------------------------------------------------------------------------
5478
5479 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5480
5481 This is called in response to ifconfig up
5482
5483 \param - dev Pointer to net_device structure
5484
5485 \return - 0 for success non-zero for failure
5486
5487 --------------------------------------------------------------------------*/
5488int hdd_open(struct net_device *dev)
5489{
5490 int ret;
5491
5492 vos_ssr_protect(__func__);
5493 ret = __hdd_open(dev);
5494 vos_ssr_unprotect(__func__);
5495
5496 return ret;
5497}
5498
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305499int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005500{
5501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5502
5503 if(pAdapter == NULL) {
5504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005505 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005506 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 }
5508
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 return 0;
5510}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305511
5512int hdd_mon_open (struct net_device *dev)
5513{
5514 int ret;
5515
5516 vos_ssr_protect(__func__);
5517 ret = __hdd_mon_open(dev);
5518 vos_ssr_unprotect(__func__);
5519
5520 return ret;
5521}
5522
Katya Nigame7b69a82015-04-28 15:24:06 +05305523int hdd_mon_stop(struct net_device *dev)
5524{
5525 return 0;
5526}
5527
Jeff Johnson295189b2012-06-20 16:38:30 -07005528/**---------------------------------------------------------------------------
5529
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305530 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005531
5532 \param - dev Pointer to net_device structure
5533
5534 \return - 0 for success non-zero for failure
5535
5536 --------------------------------------------------------------------------*/
5537
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305538int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005539{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305540 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5542 hdd_context_t *pHddCtx;
5543 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5544 VOS_STATUS status;
5545 v_BOOL_t enter_standby = TRUE;
5546
5547 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 if (NULL == pAdapter)
5549 {
5550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305551 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 return -ENODEV;
5553 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305554 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305555 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305556
5557 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5558 ret = wlan_hdd_validate_context(pHddCtx);
5559 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305561 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 }
5563
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305564 /* Nothing to be done if the interface is not opened */
5565 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5566 {
5567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5568 "%s: NETDEV Interface is not OPENED", __func__);
5569 return -ENODEV;
5570 }
5571
5572 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005573 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305575
5576 /* Disable TX on the interface, after this hard_start_xmit() will not
5577 * be called on that interface
5578 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305579 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005580 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305581
5582 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 netif_carrier_off(pAdapter->dev);
5584
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305585 /* The interface is marked as down for outside world (aka kernel)
5586 * But the driver is pretty much alive inside. The driver needs to
5587 * tear down the existing connection on the netdev (session)
5588 * cleanup the data pipes and wait until the control plane is stabilized
5589 * for this interface. The call also needs to wait until the above
5590 * mentioned actions are completed before returning to the caller.
5591 * Notice that the hdd_stop_adapter is requested not to close the session
5592 * That is intentional to be able to scan if it is a STA/P2P interface
5593 */
5594 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305595#ifdef FEATURE_WLAN_TDLS
5596 mutex_lock(&pHddCtx->tdls_lock);
5597#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305598 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305599 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305600#ifdef FEATURE_WLAN_TDLS
5601 mutex_unlock(&pHddCtx->tdls_lock);
5602#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 /* SoftAP ifaces should never go in power save mode
5604 making sure same here. */
5605 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5606 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 )
5609 {
5610 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5612 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005613 EXIT();
5614 return 0;
5615 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305616 /* Find if any iface is up. If any iface is up then can't put device to
5617 * sleep/power save mode
5618 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5620 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5621 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005622 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5623 {
5624 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305625 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005626 enter_standby = FALSE;
5627 break;
5628 }
5629 else
5630 {
5631 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5632 pAdapterNode = pNext;
5633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005634 }
5635
5636 if (TRUE == enter_standby)
5637 {
5638 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5639 "entering standby", __func__);
5640 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5641 {
5642 /*log and return success*/
5643 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5644 "wlan in power save", __func__);
5645 }
5646 }
5647
5648 EXIT();
5649 return 0;
5650}
5651
5652/**---------------------------------------------------------------------------
5653
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305654 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005655
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305656 This is called in response to ifconfig down
5657
5658 \param - dev Pointer to net_device structure
5659
5660 \return - 0 for success non-zero for failure
5661-----------------------------------------------------------------------------*/
5662int hdd_stop (struct net_device *dev)
5663{
5664 int ret;
5665
5666 vos_ssr_protect(__func__);
5667 ret = __hdd_stop(dev);
5668 vos_ssr_unprotect(__func__);
5669
5670 return ret;
5671}
5672
5673/**---------------------------------------------------------------------------
5674
5675 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005676
5677 \param - dev Pointer to net_device structure
5678
5679 \return - void
5680
5681 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305682static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005683{
5684 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305685 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 ENTER();
5687
5688 do
5689 {
5690 if (NULL == pAdapter)
5691 {
5692 hddLog(VOS_TRACE_LEVEL_FATAL,
5693 "%s: NULL pAdapter", __func__);
5694 break;
5695 }
5696
5697 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5698 {
5699 hddLog(VOS_TRACE_LEVEL_FATAL,
5700 "%s: Invalid magic", __func__);
5701 break;
5702 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5704 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 {
5706 hddLog(VOS_TRACE_LEVEL_FATAL,
5707 "%s: NULL pHddCtx", __func__);
5708 break;
5709 }
5710
5711 if (dev != pAdapter->dev)
5712 {
5713 hddLog(VOS_TRACE_LEVEL_FATAL,
5714 "%s: Invalid device reference", __func__);
5715 /* we haven't validated all cases so let this go for now */
5716 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305717#ifdef FEATURE_WLAN_TDLS
5718 mutex_lock(&pHddCtx->tdls_lock);
5719#endif
c_hpothu002231a2015-02-05 14:58:51 +05305720 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305721#ifdef FEATURE_WLAN_TDLS
5722 mutex_unlock(&pHddCtx->tdls_lock);
5723#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005724
5725 /* after uninit our adapter structure will no longer be valid */
5726 pAdapter->dev = NULL;
5727 pAdapter->magic = 0;
5728 } while (0);
5729
5730 EXIT();
5731}
5732
5733/**---------------------------------------------------------------------------
5734
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305735 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5736
5737 This is called during the netdev unregister to uninitialize all data
5738associated with the device
5739
5740 \param - dev Pointer to net_device structure
5741
5742 \return - void
5743
5744 --------------------------------------------------------------------------*/
5745static void hdd_uninit (struct net_device *dev)
5746{
5747 vos_ssr_protect(__func__);
5748 __hdd_uninit(dev);
5749 vos_ssr_unprotect(__func__);
5750}
5751
5752/**---------------------------------------------------------------------------
5753
Jeff Johnson295189b2012-06-20 16:38:30 -07005754 \brief hdd_release_firmware() -
5755
5756 This function calls the release firmware API to free the firmware buffer.
5757
5758 \param - pFileName Pointer to the File Name.
5759 pCtx - Pointer to the adapter .
5760
5761
5762 \return - 0 for success, non zero for failure
5763
5764 --------------------------------------------------------------------------*/
5765
5766VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5767{
5768 VOS_STATUS status = VOS_STATUS_SUCCESS;
5769 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5770 ENTER();
5771
5772
5773 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5774
5775 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5776
5777 if(pHddCtx->fw) {
5778 release_firmware(pHddCtx->fw);
5779 pHddCtx->fw = NULL;
5780 }
5781 else
5782 status = VOS_STATUS_E_FAILURE;
5783 }
5784 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5785 if(pHddCtx->nv) {
5786 release_firmware(pHddCtx->nv);
5787 pHddCtx->nv = NULL;
5788 }
5789 else
5790 status = VOS_STATUS_E_FAILURE;
5791
5792 }
5793
5794 EXIT();
5795 return status;
5796}
5797
5798/**---------------------------------------------------------------------------
5799
5800 \brief hdd_request_firmware() -
5801
5802 This function reads the firmware file using the request firmware
5803 API and returns the the firmware data and the firmware file size.
5804
5805 \param - pfileName - Pointer to the file name.
5806 - pCtx - Pointer to the adapter .
5807 - ppfw_data - Pointer to the pointer of the firmware data.
5808 - pSize - Pointer to the file size.
5809
5810 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5811
5812 --------------------------------------------------------------------------*/
5813
5814
5815VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5816{
5817 int status;
5818 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5819 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5820 ENTER();
5821
5822 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5823
5824 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5825
5826 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5827 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5828 __func__, pfileName);
5829 retval = VOS_STATUS_E_FAILURE;
5830 }
5831
5832 else {
5833 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5834 *pSize = pHddCtx->fw->size;
5835 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5836 __func__, *pSize);
5837 }
5838 }
5839 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5840
5841 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5842
5843 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5844 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5845 __func__, pfileName);
5846 retval = VOS_STATUS_E_FAILURE;
5847 }
5848
5849 else {
5850 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5851 *pSize = pHddCtx->nv->size;
5852 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5853 __func__, *pSize);
5854 }
5855 }
5856
5857 EXIT();
5858 return retval;
5859}
5860/**---------------------------------------------------------------------------
5861 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5862
5863 This is the function invoked by SME to inform the result of a full power
5864 request issued by HDD
5865
5866 \param - callbackcontext - Pointer to cookie
5867 status - result of request
5868
5869 \return - None
5870
5871--------------------------------------------------------------------------*/
5872void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5873{
5874 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5875
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005876 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005877 if(&pHddCtx->full_pwr_comp_var)
5878 {
5879 complete(&pHddCtx->full_pwr_comp_var);
5880 }
5881}
5882
5883/**---------------------------------------------------------------------------
5884
5885 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5886
5887 This is the function invoked by SME to inform the result of BMPS
5888 request issued by HDD
5889
5890 \param - callbackcontext - Pointer to cookie
5891 status - result of request
5892
5893 \return - None
5894
5895--------------------------------------------------------------------------*/
5896void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5897{
5898
5899 struct completion *completion_var = (struct completion*) callbackContext;
5900
Arif Hussain6d2a3322013-11-17 19:50:10 -08005901 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 if(completion_var != NULL)
5903 {
5904 complete(completion_var);
5905 }
5906}
5907
5908/**---------------------------------------------------------------------------
5909
5910 \brief hdd_get_cfg_file_size() -
5911
5912 This function reads the configuration file using the request firmware
5913 API and returns the configuration file size.
5914
5915 \param - pCtx - Pointer to the adapter .
5916 - pFileName - Pointer to the file name.
5917 - pBufSize - Pointer to the buffer size.
5918
5919 \return - 0 for success, non zero for failure
5920
5921 --------------------------------------------------------------------------*/
5922
5923VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5924{
5925 int status;
5926 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5927
5928 ENTER();
5929
5930 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5931
5932 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5933 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5934 status = VOS_STATUS_E_FAILURE;
5935 }
5936 else {
5937 *pBufSize = pHddCtx->fw->size;
5938 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5939 release_firmware(pHddCtx->fw);
5940 pHddCtx->fw = NULL;
5941 }
5942
5943 EXIT();
5944 return VOS_STATUS_SUCCESS;
5945}
5946
5947/**---------------------------------------------------------------------------
5948
5949 \brief hdd_read_cfg_file() -
5950
5951 This function reads the configuration file using the request firmware
5952 API and returns the cfg data and the buffer size of the configuration file.
5953
5954 \param - pCtx - Pointer to the adapter .
5955 - pFileName - Pointer to the file name.
5956 - pBuffer - Pointer to the data buffer.
5957 - pBufSize - Pointer to the buffer size.
5958
5959 \return - 0 for success, non zero for failure
5960
5961 --------------------------------------------------------------------------*/
5962
5963VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5964 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5965{
5966 int status;
5967 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5968
5969 ENTER();
5970
5971 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5972
5973 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5974 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5975 return VOS_STATUS_E_FAILURE;
5976 }
5977 else {
5978 if(*pBufSize != pHddCtx->fw->size) {
5979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5980 "file size", __func__);
5981 release_firmware(pHddCtx->fw);
5982 pHddCtx->fw = NULL;
5983 return VOS_STATUS_E_FAILURE;
5984 }
5985 else {
5986 if(pBuffer) {
5987 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5988 }
5989 release_firmware(pHddCtx->fw);
5990 pHddCtx->fw = NULL;
5991 }
5992 }
5993
5994 EXIT();
5995
5996 return VOS_STATUS_SUCCESS;
5997}
5998
5999/**---------------------------------------------------------------------------
6000
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306001 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006002
6003 This function sets the user specified mac address using
6004 the command ifconfig wlanX hw ether <mac adress>.
6005
6006 \param - dev - Pointer to the net device.
6007 - addr - Pointer to the sockaddr.
6008 \return - 0 for success, non zero for failure
6009
6010 --------------------------------------------------------------------------*/
6011
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306012static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006013{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306014 hdd_adapter_t *pAdapter;
6015 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 struct sockaddr *psta_mac_addr = addr;
6017 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306018 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006019
6020 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306021 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6022 if (NULL == pAdapter)
6023 {
6024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6025 "%s: Adapter is NULL",__func__);
6026 return -EINVAL;
6027 }
6028 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6029 ret = wlan_hdd_validate_context(pHddCtx);
6030 if (0 != ret)
6031 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306032 return ret;
6033 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006034
6035 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6037
6038 EXIT();
6039 return halStatus;
6040}
6041
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306042/**---------------------------------------------------------------------------
6043
6044 \brief hdd_set_mac_address() -
6045
6046 Wrapper function to protect __hdd_set_mac_address() function from ssr
6047
6048 \param - dev - Pointer to the net device.
6049 - addr - Pointer to the sockaddr.
6050 \return - 0 for success, non zero for failure
6051
6052 --------------------------------------------------------------------------*/
6053static int hdd_set_mac_address(struct net_device *dev, void *addr)
6054{
6055 int ret;
6056
6057 vos_ssr_protect(__func__);
6058 ret = __hdd_set_mac_address(dev, addr);
6059 vos_ssr_unprotect(__func__);
6060
6061 return ret;
6062}
6063
Jeff Johnson295189b2012-06-20 16:38:30 -07006064tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6065{
6066 int i;
6067 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6068 {
Abhishek Singheb183782014-02-06 13:37:21 +05306069 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006070 break;
6071 }
6072
6073 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6074 return NULL;
6075
6076 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6077 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6078}
6079
6080void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6081{
6082 int i;
6083 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6084 {
6085 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6086 {
6087 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6088 break;
6089 }
6090 }
6091 return;
6092}
6093
6094#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6095 static struct net_device_ops wlan_drv_ops = {
6096 .ndo_open = hdd_open,
6097 .ndo_stop = hdd_stop,
6098 .ndo_uninit = hdd_uninit,
6099 .ndo_start_xmit = hdd_hard_start_xmit,
6100 .ndo_tx_timeout = hdd_tx_timeout,
6101 .ndo_get_stats = hdd_stats,
6102 .ndo_do_ioctl = hdd_ioctl,
6103 .ndo_set_mac_address = hdd_set_mac_address,
6104 .ndo_select_queue = hdd_select_queue,
6105#ifdef WLAN_FEATURE_PACKET_FILTERING
6106#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6107 .ndo_set_rx_mode = hdd_set_multicast_list,
6108#else
6109 .ndo_set_multicast_list = hdd_set_multicast_list,
6110#endif //LINUX_VERSION_CODE
6111#endif
6112 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 static struct net_device_ops wlan_mon_drv_ops = {
6114 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306115 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006116 .ndo_uninit = hdd_uninit,
6117 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6118 .ndo_tx_timeout = hdd_tx_timeout,
6119 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306120 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006121 .ndo_set_mac_address = hdd_set_mac_address,
6122 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306123
Jeff Johnson295189b2012-06-20 16:38:30 -07006124#endif
6125
6126void hdd_set_station_ops( struct net_device *pWlanDev )
6127{
6128#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 pWlanDev->netdev_ops = &wlan_drv_ops;
6130#else
6131 pWlanDev->open = hdd_open;
6132 pWlanDev->stop = hdd_stop;
6133 pWlanDev->uninit = hdd_uninit;
6134 pWlanDev->hard_start_xmit = NULL;
6135 pWlanDev->tx_timeout = hdd_tx_timeout;
6136 pWlanDev->get_stats = hdd_stats;
6137 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 pWlanDev->set_mac_address = hdd_set_mac_address;
6139#endif
6140}
6141
Katya Nigam1fd24402015-02-16 14:52:19 +05306142void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6143{
6144 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6145 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6146 #else
6147 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6148 #endif
6149}
6150
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006151static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006152{
6153 struct net_device *pWlanDev = NULL;
6154 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 /*
6156 * cfg80211 initialization and registration....
6157 */
6158 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6159
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 if(pWlanDev != NULL)
6161 {
6162
6163 //Save the pointer to the net_device in the HDD adapter
6164 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6165
Jeff Johnson295189b2012-06-20 16:38:30 -07006166 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6167
6168 pAdapter->dev = pWlanDev;
6169 pAdapter->pHddCtx = pHddCtx;
6170 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306171 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006172
6173 init_completion(&pAdapter->session_open_comp_var);
6174 init_completion(&pAdapter->session_close_comp_var);
6175 init_completion(&pAdapter->disconnect_comp_var);
6176 init_completion(&pAdapter->linkup_event_var);
6177 init_completion(&pAdapter->cancel_rem_on_chan_var);
6178 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306179 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6181 init_completion(&pAdapter->offchannel_tx_event);
6182#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006184#ifdef FEATURE_WLAN_TDLS
6185 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006186 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006187 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306188 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006189#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 init_completion(&pHddCtx->mc_sus_event_var);
6191 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306192 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006193 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006194 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006195
Rajeev79dbe4c2013-10-05 11:03:42 +05306196#ifdef FEATURE_WLAN_BATCH_SCAN
6197 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6198 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6199 pAdapter->pBatchScanRsp = NULL;
6200 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006201 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006202 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306203 mutex_init(&pAdapter->hdd_batch_scan_lock);
6204#endif
6205
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 pAdapter->isLinkUpSvcNeeded = FALSE;
6207 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6208 //Init the net_device structure
6209 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6210
6211 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6212 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6213 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6214 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6215
6216 hdd_set_station_ops( pAdapter->dev );
6217
6218 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006219 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6220 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6221 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 /* set pWlanDev's parent to underlying device */
6223 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006224
6225 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 }
6227
6228 return pAdapter;
6229}
6230
6231VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6232{
6233 struct net_device *pWlanDev = pAdapter->dev;
6234 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6235 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6236 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6237
6238 if( rtnl_lock_held )
6239 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006240 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6242 {
6243 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6244 return VOS_STATUS_E_FAILURE;
6245 }
6246 }
6247 if (register_netdevice(pWlanDev))
6248 {
6249 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6250 return VOS_STATUS_E_FAILURE;
6251 }
6252 }
6253 else
6254 {
6255 if(register_netdev(pWlanDev))
6256 {
6257 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6258 return VOS_STATUS_E_FAILURE;
6259 }
6260 }
6261 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6262
6263 return VOS_STATUS_SUCCESS;
6264}
6265
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006266static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006267{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006268 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006269
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006270 if (NULL == pAdapter)
6271 {
6272 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6273 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006275
6276 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6277 {
6278 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6279 return eHAL_STATUS_NOT_INITIALIZED;
6280 }
6281
6282 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6283
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006284#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006285 /* need to make sure all of our scheduled work has completed.
6286 * This callback is called from MC thread context, so it is safe to
6287 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006288 *
6289 * Even though this is called from MC thread context, if there is a faulty
6290 * work item in the system, that can hang this call forever. So flushing
6291 * this global work queue is not safe; and now we make sure that
6292 * individual work queues are stopped correctly. But the cancel work queue
6293 * is a GPL only API, so the proprietary version of the driver would still
6294 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006295 */
6296 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006297#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006298
6299 /* We can be blocked while waiting for scheduled work to be
6300 * flushed, and the adapter structure can potentially be freed, in
6301 * which case the magic will have been reset. So make sure the
6302 * magic is still good, and hence the adapter structure is still
6303 * valid, before signaling completion */
6304 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6305 {
6306 complete(&pAdapter->session_close_comp_var);
6307 }
6308
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 return eHAL_STATUS_SUCCESS;
6310}
6311
6312VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6313{
6314 struct net_device *pWlanDev = pAdapter->dev;
6315 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6316 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6317 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6318 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306319 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006320
Nirav Shah7e3c8132015-06-22 23:51:42 +05306321 spin_lock_init( &pAdapter->sta_hash_lock);
6322 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6323
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006325 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 //Open a SME session for future operation
6327 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006328 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6330 {
6331 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006332 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 halStatus, halStatus );
6334 status = VOS_STATUS_E_FAILURE;
6335 goto error_sme_open;
6336 }
6337
6338 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306339 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 &pAdapter->session_open_comp_var,
6341 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306342 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 {
6344 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306345 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 status = VOS_STATUS_E_FAILURE;
6347 goto error_sme_open;
6348 }
6349
6350 // Register wireless extensions
6351 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6352 {
6353 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006354 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 halStatus, halStatus );
6356 status = VOS_STATUS_E_FAILURE;
6357 goto error_register_wext;
6358 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306359
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306361 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6362 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6363 #else
6364 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6365 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006366
6367 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306368 hddLog(VOS_TRACE_LEVEL_INFO,
6369 "%s: Set HDD connState to eConnectionState_NotConnected",
6370 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6372
6373 //Set the default operation channel
6374 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6375
6376 /* Make the default Auth Type as OPEN*/
6377 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6378
6379 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6380 {
6381 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006382 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 status, status );
6384 goto error_init_txrx;
6385 }
6386
6387 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6388
6389 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6390 {
6391 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006392 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 status, status );
6394 goto error_wmm_init;
6395 }
6396
6397 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6398
6399 return VOS_STATUS_SUCCESS;
6400
6401error_wmm_init:
6402 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6403 hdd_deinit_tx_rx(pAdapter);
6404error_init_txrx:
6405 hdd_UnregisterWext(pWlanDev);
6406error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006407 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 {
6409 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006410 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306411 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006412 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306414 unsigned long rc;
6415
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306417 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006419 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306420 if (rc <= 0)
6421 hddLog(VOS_TRACE_LEVEL_ERROR,
6422 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 }
6424}
6425error_sme_open:
6426 return status;
6427}
6428
Jeff Johnson295189b2012-06-20 16:38:30 -07006429void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6430{
6431 hdd_cfg80211_state_t *cfgState;
6432
6433 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6434
6435 if( NULL != cfgState->buf )
6436 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306437 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6439 rc = wait_for_completion_interruptible_timeout(
6440 &pAdapter->tx_action_cnf_event,
6441 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306442 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306445 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6446 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 }
6448 }
6449 return;
6450}
Jeff Johnson295189b2012-06-20 16:38:30 -07006451
c_hpothu002231a2015-02-05 14:58:51 +05306452void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006453{
6454 ENTER();
6455 switch ( pAdapter->device_mode )
6456 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306457 case WLAN_HDD_IBSS:
6458 {
6459 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6460 {
6461 hdd_ibss_deinit_tx_rx( pAdapter );
6462 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6463 }
6464 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 case WLAN_HDD_INFRA_STATION:
6466 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006467 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 {
6469 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6470 {
6471 hdd_deinit_tx_rx( pAdapter );
6472 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6473 }
6474
6475 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6476 {
6477 hdd_wmm_adapter_close( pAdapter );
6478 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6479 }
6480
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 break;
6483 }
6484
6485 case WLAN_HDD_SOFTAP:
6486 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306488
6489 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6490 {
6491 hdd_wmm_adapter_close( pAdapter );
6492 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6493 }
6494
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006496
c_hpothu002231a2015-02-05 14:58:51 +05306497 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006498 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 break;
6500 }
6501
6502 case WLAN_HDD_MONITOR:
6503 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6505 {
6506 hdd_deinit_tx_rx( pAdapter );
6507 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6508 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 break;
6510 }
6511
6512
6513 default:
6514 break;
6515 }
6516
6517 EXIT();
6518}
6519
6520void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6521{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006522 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306523
6524 ENTER();
6525 if (NULL == pAdapter)
6526 {
6527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6528 "%s: HDD adapter is Null", __func__);
6529 return;
6530 }
6531
6532 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006533
Rajeev79dbe4c2013-10-05 11:03:42 +05306534#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306535 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6536 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006537 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306538 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6539 )
6540 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006541 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306542 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006543 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6544 {
6545 hdd_deinit_batch_scan(pAdapter);
6546 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306547 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006548 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306549#endif
6550
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6552 if( rtnl_held )
6553 {
6554 unregister_netdevice(pWlanDev);
6555 }
6556 else
6557 {
6558 unregister_netdev(pWlanDev);
6559 }
6560 // note that the pAdapter is no longer valid at this point
6561 // since the memory has been reclaimed
6562 }
6563
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306564 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006565}
6566
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006567void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6568{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306569 VOS_STATUS status;
6570 hdd_adapter_t *pAdapter = NULL;
6571 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006572
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306573 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006574
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306575 /*loop through all adapters.*/
6576 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006577 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306578 pAdapter = pAdapterNode->pAdapter;
6579 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6580 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006581
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306582 { // we skip this registration for modes other than STA and P2P client modes.
6583 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6584 pAdapterNode = pNext;
6585 continue;
6586 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006587
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306588 //Apply Dynamic DTIM For P2P
6589 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6590 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6591 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6592 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6593 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6594 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6595 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6596 (eConnectionState_Associated ==
6597 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6598 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6599 {
6600 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006601
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306602 powerRequest.uIgnoreDTIM = 1;
6603 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6604
6605 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6606 {
6607 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6608 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6609 }
6610 else
6611 {
6612 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6613 }
6614
6615 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6616 * specified during Enter/Exit BMPS when LCD off*/
6617 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6618 NULL, eANI_BOOLEAN_FALSE);
6619 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6620 NULL, eANI_BOOLEAN_FALSE);
6621
6622 /* switch to the DTIM specified in cfg.ini */
6623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6624 "Switch to DTIM %d", powerRequest.uListenInterval);
6625 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6626 break;
6627
6628 }
6629
6630 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6631 pAdapterNode = pNext;
6632 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006633}
6634
6635void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6636{
6637 /*Switch back to DTIM 1*/
6638 tSirSetPowerParamsReq powerRequest = { 0 };
6639
6640 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6641 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006642 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006643
6644 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6645 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6646 NULL, eANI_BOOLEAN_FALSE);
6647 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6648 NULL, eANI_BOOLEAN_FALSE);
6649
6650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6651 "Switch to DTIM%d",powerRequest.uListenInterval);
6652 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6653
6654}
6655
Jeff Johnson295189b2012-06-20 16:38:30 -07006656VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6657{
6658 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306659 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6660 {
6661 hddLog( LOGE, FL("Wlan Unload in progress"));
6662 return VOS_STATUS_E_PERM;
6663 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006664 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6665 {
6666 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6667 }
6668
6669 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6670 {
6671 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6672 }
6673
6674 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6675 {
6676 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6677 }
6678
6679 return status;
6680}
6681
6682VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6683{
6684 hdd_adapter_t *pAdapter = NULL;
6685 eHalStatus halStatus;
6686 VOS_STATUS status = VOS_STATUS_E_INVAL;
6687 v_BOOL_t disableBmps = FALSE;
6688 v_BOOL_t disableImps = FALSE;
6689
6690 switch(session_type)
6691 {
6692 case WLAN_HDD_INFRA_STATION:
6693 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006694 case WLAN_HDD_P2P_CLIENT:
6695 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006696 //Exit BMPS -> Is Sta/P2P Client is already connected
6697 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6698 if((NULL != pAdapter)&&
6699 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6700 {
6701 disableBmps = TRUE;
6702 }
6703
6704 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6705 if((NULL != pAdapter)&&
6706 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6707 {
6708 disableBmps = TRUE;
6709 }
6710
6711 //Exit both Bmps and Imps incase of Go/SAP Mode
6712 if((WLAN_HDD_SOFTAP == session_type) ||
6713 (WLAN_HDD_P2P_GO == session_type))
6714 {
6715 disableBmps = TRUE;
6716 disableImps = TRUE;
6717 }
6718
6719 if(TRUE == disableImps)
6720 {
6721 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6722 {
6723 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6724 }
6725 }
6726
6727 if(TRUE == disableBmps)
6728 {
6729 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6730 {
6731 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6732
6733 if(eHAL_STATUS_SUCCESS != halStatus)
6734 {
6735 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006736 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 VOS_ASSERT(0);
6738 return status;
6739 }
6740 }
6741
6742 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6743 {
6744 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6745
6746 if(eHAL_STATUS_SUCCESS != halStatus)
6747 {
6748 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006749 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006750 VOS_ASSERT(0);
6751 return status;
6752 }
6753 }
6754 }
6755
6756 if((TRUE == disableBmps) ||
6757 (TRUE == disableImps))
6758 {
6759 /* Now, get the chip into Full Power now */
6760 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6761 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6762 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6763
6764 if(halStatus != eHAL_STATUS_SUCCESS)
6765 {
6766 if(halStatus == eHAL_STATUS_PMC_PENDING)
6767 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306768 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306770 ret = wait_for_completion_interruptible_timeout(
6771 &pHddCtx->full_pwr_comp_var,
6772 msecs_to_jiffies(1000));
6773 if (ret <= 0)
6774 {
6775 hddLog(VOS_TRACE_LEVEL_ERROR,
6776 "%s: wait on full_pwr_comp_var failed %ld",
6777 __func__, ret);
6778 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 }
6780 else
6781 {
6782 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006783 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 VOS_ASSERT(0);
6785 return status;
6786 }
6787 }
6788
6789 status = VOS_STATUS_SUCCESS;
6790 }
6791
6792 break;
6793 }
6794 return status;
6795}
Katya Nigame7b69a82015-04-28 15:24:06 +05306796void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6797 {
6798 hdd_mon_ctx_t *pMonCtx = NULL;
6799 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6800
6801 pMonCtx->state = 0;
6802 pMonCtx->ChannelNo = 1;
6803 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306804 pMonCtx->crcCheckEnabled = 1;
6805 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6806 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306807 pMonCtx->numOfMacFilters = 0;
6808 }
6809
Jeff Johnson295189b2012-06-20 16:38:30 -07006810
6811hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006812 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 tANI_U8 rtnl_held )
6814{
6815 hdd_adapter_t *pAdapter = NULL;
6816 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6817 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6818 VOS_STATUS exitbmpsStatus;
6819
Arif Hussain6d2a3322013-11-17 19:50:10 -08006820 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006821
Nirav Shah436658f2014-02-28 17:05:45 +05306822 if(macAddr == NULL)
6823 {
6824 /* Not received valid macAddr */
6825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6826 "%s:Unable to add virtual intf: Not able to get"
6827 "valid mac address",__func__);
6828 return NULL;
6829 }
6830
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 //Disable BMPS incase of Concurrency
6832 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6833
6834 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6835 {
6836 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306837 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 VOS_ASSERT(0);
6839 return NULL;
6840 }
6841
6842 switch(session_type)
6843 {
6844 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006846 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 {
6848 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6849
6850 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306851 {
6852 hddLog(VOS_TRACE_LEVEL_FATAL,
6853 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306855 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006856
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306857#ifdef FEATURE_WLAN_TDLS
6858 /* A Mutex Lock is introduced while changing/initializing the mode to
6859 * protect the concurrent access for the Adapters by TDLS module.
6860 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306861 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306862#endif
6863
Jeff Johnsone7245742012-09-05 17:12:55 -07006864 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6865 NL80211_IFTYPE_P2P_CLIENT:
6866 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006867
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306869#ifdef FEATURE_WLAN_TDLS
6870 mutex_unlock(&pHddCtx->tdls_lock);
6871#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306872
6873 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 if( VOS_STATUS_SUCCESS != status )
6875 goto err_free_netdev;
6876
6877 status = hdd_register_interface( pAdapter, rtnl_held );
6878 if( VOS_STATUS_SUCCESS != status )
6879 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306880#ifdef FEATURE_WLAN_TDLS
6881 mutex_lock(&pHddCtx->tdls_lock);
6882#endif
c_hpothu002231a2015-02-05 14:58:51 +05306883 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306884#ifdef FEATURE_WLAN_TDLS
6885 mutex_unlock(&pHddCtx->tdls_lock);
6886#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006887 goto err_free_netdev;
6888 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306889
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306890 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306891 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306892
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306893#ifdef WLAN_NS_OFFLOAD
6894 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306895 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306896#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 netif_tx_disable(pAdapter->dev);
6900 //netif_tx_disable(pWlanDev);
6901 netif_carrier_off(pAdapter->dev);
6902
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306903 if (WLAN_HDD_P2P_CLIENT == session_type ||
6904 WLAN_HDD_P2P_DEVICE == session_type)
6905 {
6906 /* Initialize the work queue to defer the
6907 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306908 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306909 hdd_p2p_roc_work_queue);
6910 }
6911
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 break;
6913 }
6914
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 case WLAN_HDD_SOFTAP:
6917 {
6918 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6919 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306920 {
6921 hddLog(VOS_TRACE_LEVEL_FATAL,
6922 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006925
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6927 NL80211_IFTYPE_AP:
6928 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 pAdapter->device_mode = session_type;
6930
6931 status = hdd_init_ap_mode(pAdapter);
6932 if( VOS_STATUS_SUCCESS != status )
6933 goto err_free_netdev;
6934
Nirav Shah7e3c8132015-06-22 23:51:42 +05306935 status = hdd_sta_id_hash_attach(pAdapter);
6936 if (VOS_STATUS_SUCCESS != status)
6937 {
6938 hddLog(VOS_TRACE_LEVEL_FATAL,
6939 FL("failed to attach hash for session %d"), session_type);
6940 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6941 goto err_free_netdev;
6942 }
6943
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 status = hdd_register_hostapd( pAdapter, rtnl_held );
6945 if( VOS_STATUS_SUCCESS != status )
6946 {
c_hpothu002231a2015-02-05 14:58:51 +05306947 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 goto err_free_netdev;
6949 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306950 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 netif_tx_disable(pAdapter->dev);
6952 netif_carrier_off(pAdapter->dev);
6953
6954 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306955
6956 if (WLAN_HDD_P2P_GO == session_type)
6957 {
6958 /* Initialize the work queue to
6959 * defer the back to back RoC request */
6960 INIT_DELAYED_WORK(&pAdapter->roc_work,
6961 hdd_p2p_roc_work_queue);
6962 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 break;
6964 }
6965 case WLAN_HDD_MONITOR:
6966 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6968 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306969 {
6970 hddLog(VOS_TRACE_LEVEL_FATAL,
6971 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006974
Katya Nigame7b69a82015-04-28 15:24:06 +05306975 // Register wireless extensions
6976 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6977 {
6978 hddLog(VOS_TRACE_LEVEL_FATAL,
6979 "hdd_register_wext() failed with status code %08d [x%08x]",
6980 status, status );
6981 status = VOS_STATUS_E_FAILURE;
6982 }
6983
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6985 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006986#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6987 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6988#else
6989 pAdapter->dev->open = hdd_mon_open;
6990 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306991 pAdapter->dev->stop = hdd_mon_stop;
6992 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006993#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05306994 status = hdd_register_interface( pAdapter, rtnl_held );
6995 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006996 hdd_init_tx_rx( pAdapter );
6997 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05306998 //Stop the Interface TX queue.
6999 netif_tx_disable(pAdapter->dev);
7000 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 }
7002 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 case WLAN_HDD_FTM:
7004 {
7005 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7006
7007 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307008 {
7009 hddLog(VOS_TRACE_LEVEL_FATAL,
7010 FL("failed to allocate adapter for session %d"), session_type);
7011 return NULL;
7012 }
7013
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7015 * message while loading driver in FTM mode. */
7016 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7017 pAdapter->device_mode = session_type;
7018 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307019
7020 hdd_init_tx_rx( pAdapter );
7021
7022 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307023 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307024 netif_tx_disable(pAdapter->dev);
7025 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 }
7027 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 default:
7029 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307030 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7031 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 VOS_ASSERT(0);
7033 return NULL;
7034 }
7035 }
7036
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 if( VOS_STATUS_SUCCESS == status )
7038 {
7039 //Add it to the hdd's session list.
7040 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7041 if( NULL == pHddAdapterNode )
7042 {
7043 status = VOS_STATUS_E_NOMEM;
7044 }
7045 else
7046 {
7047 pHddAdapterNode->pAdapter = pAdapter;
7048 status = hdd_add_adapter_back ( pHddCtx,
7049 pHddAdapterNode );
7050 }
7051 }
7052
7053 if( VOS_STATUS_SUCCESS != status )
7054 {
7055 if( NULL != pAdapter )
7056 {
7057 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7058 pAdapter = NULL;
7059 }
7060 if( NULL != pHddAdapterNode )
7061 {
7062 vos_mem_free( pHddAdapterNode );
7063 }
7064
7065 goto resume_bmps;
7066 }
7067
7068 if(VOS_STATUS_SUCCESS == status)
7069 {
7070 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7071
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007072 //Initialize the WoWL service
7073 if(!hdd_init_wowl(pAdapter))
7074 {
7075 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7076 goto err_free_netdev;
7077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 return pAdapter;
7080
7081err_free_netdev:
7082 free_netdev(pAdapter->dev);
7083 wlan_hdd_release_intf_addr( pHddCtx,
7084 pAdapter->macAddressCurrent.bytes );
7085
7086resume_bmps:
7087 //If bmps disabled enable it
7088 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7089 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307090 if (pHddCtx->hdd_wlan_suspended)
7091 {
7092 hdd_set_pwrparams(pHddCtx);
7093 }
7094 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 }
7096 return NULL;
7097}
7098
7099VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7100 tANI_U8 rtnl_held )
7101{
7102 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7103 VOS_STATUS status;
7104
7105 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7106 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307107 {
7108 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7109 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307111 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007112
7113 while ( pCurrent->pAdapter != pAdapter )
7114 {
7115 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7116 if( VOS_STATUS_SUCCESS != status )
7117 break;
7118
7119 pCurrent = pNext;
7120 }
7121 pAdapterNode = pCurrent;
7122 if( VOS_STATUS_SUCCESS == status )
7123 {
7124 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7125 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307126
7127#ifdef FEATURE_WLAN_TDLS
7128
7129 /* A Mutex Lock is introduced while changing/initializing the mode to
7130 * protect the concurrent access for the Adapters by TDLS module.
7131 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307132 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307133#endif
7134
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 hdd_remove_adapter( pHddCtx, pAdapterNode );
7136 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007137 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007138
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307139#ifdef FEATURE_WLAN_TDLS
7140 mutex_unlock(&pHddCtx->tdls_lock);
7141#endif
7142
Jeff Johnson295189b2012-06-20 16:38:30 -07007143
7144 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307145 if ((!vos_concurrent_open_sessions_running()) &&
7146 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7147 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307149 if (pHddCtx->hdd_wlan_suspended)
7150 {
7151 hdd_set_pwrparams(pHddCtx);
7152 }
7153 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 }
7155
7156 return VOS_STATUS_SUCCESS;
7157 }
7158
7159 return VOS_STATUS_E_FAILURE;
7160}
7161
7162VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7163{
7164 hdd_adapter_list_node_t *pHddAdapterNode;
7165 VOS_STATUS status;
7166
7167 ENTER();
7168
7169 do
7170 {
7171 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7172 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7173 {
7174 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7175 vos_mem_free( pHddAdapterNode );
7176 }
7177 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7178
7179 EXIT();
7180
7181 return VOS_STATUS_SUCCESS;
7182}
7183
7184void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7185{
7186 v_U8_t addIE[1] = {0};
7187
7188 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7189 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7190 eANI_BOOLEAN_FALSE) )
7191 {
7192 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007193 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007194 }
7195
7196 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7197 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7198 eANI_BOOLEAN_FALSE) )
7199 {
7200 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007201 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007202 }
7203
7204 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7205 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7206 eANI_BOOLEAN_FALSE) )
7207 {
7208 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007209 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 }
7211}
7212
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307213VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7214 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007215{
7216 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7217 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307218 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307220 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307221 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307222 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007223
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307224 if (pHddCtx->isLogpInProgress) {
7225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7226 "%s:LOGP in Progress. Ignore!!!",__func__);
7227 return VOS_STATUS_E_FAILURE;
7228 }
7229
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307231
Nirav Shah7e3c8132015-06-22 23:51:42 +05307232 status = hdd_sta_id_hash_detach(pAdapter);
7233 if (status != VOS_STATUS_SUCCESS)
7234 hddLog(VOS_TRACE_LEVEL_ERROR,
7235 FL("sta id hash detach failed"));
7236
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307237 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 switch(pAdapter->device_mode)
7239 {
7240 case WLAN_HDD_INFRA_STATION:
7241 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007242 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307243 {
7244 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7245 if( hdd_connIsConnected(pstation) ||
7246 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007247 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307248#ifdef FEATURE_WLAN_TDLS
7249 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307250 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307251 mutex_unlock(&pHddCtx->tdls_lock);
7252#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7254 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7255 pAdapter->sessionId,
7256 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7257 else
7258 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7259 pAdapter->sessionId,
7260 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7261 //success implies disconnect command got queued up successfully
7262 if(halStatus == eHAL_STATUS_SUCCESS)
7263 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307264 ret = wait_for_completion_interruptible_timeout(
7265 &pAdapter->disconnect_comp_var,
7266 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7267 if (ret <= 0)
7268 {
7269 hddLog(VOS_TRACE_LEVEL_ERROR,
7270 "%s: wait on disconnect_comp_var failed %ld",
7271 __func__, ret);
7272 }
7273 }
7274 else
7275 {
7276 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7277 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 }
7279 memset(&wrqu, '\0', sizeof(wrqu));
7280 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7281 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7282 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7283 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307284 else if(pstation->conn_info.connState ==
7285 eConnectionState_Disconnecting)
7286 {
7287 ret = wait_for_completion_interruptible_timeout(
7288 &pAdapter->disconnect_comp_var,
7289 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7290 if (ret <= 0)
7291 {
7292 hddLog(VOS_TRACE_LEVEL_ERROR,
7293 FL("wait on disconnect_comp_var failed %ld"), ret);
7294 }
7295 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307296 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307298 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307299 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307301 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7302 {
7303 while (pAdapter->is_roc_inprogress)
7304 {
7305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7306 "%s: ROC in progress for session %d!!!",
7307 __func__, pAdapter->sessionId);
7308 // waiting for ROC to expire
7309 msleep(500);
7310 /* In GO present case , if retry exceeds 3,
7311 it means something went wrong. */
7312 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7313 {
7314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7315 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307316 if (eHAL_STATUS_SUCCESS !=
7317 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7318 pAdapter->sessionId ))
7319 {
7320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7321 FL("Failed to Cancel Remain on Channel"));
7322 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307323 wait_for_completion_interruptible_timeout(
7324 &pAdapter->cancel_rem_on_chan_var,
7325 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7326 break;
7327 }
7328 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307329 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307330 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307331#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307332 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307333#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307334
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307335 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307336
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307337 /* It is possible that the caller of this function does not
7338 * wish to close the session
7339 */
7340 if (VOS_TRUE == bCloseSession &&
7341 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 {
7343 INIT_COMPLETION(pAdapter->session_close_comp_var);
7344 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307345 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307346 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307348 unsigned long ret;
7349
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307351 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307352 &pAdapter->session_close_comp_var,
7353 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307354 if ( 0 >= ret)
7355 {
7356 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307357 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 }
7360 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 break;
7363
7364 case WLAN_HDD_SOFTAP:
7365 case WLAN_HDD_P2P_GO:
7366 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307367 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7368 while (pAdapter->is_roc_inprogress) {
7369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7370 "%s: ROC in progress for session %d!!!",
7371 __func__, pAdapter->sessionId);
7372 msleep(500);
7373 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7375 "%s: ROC completion is not received.!!!", __func__);
7376 WLANSAP_CancelRemainOnChannel(
7377 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7378 wait_for_completion_interruptible_timeout(
7379 &pAdapter->cancel_rem_on_chan_var,
7380 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7381 break;
7382 }
7383 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307384
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307385 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307386 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 mutex_lock(&pHddCtx->sap_lock);
7388 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7389 {
7390 VOS_STATUS status;
7391 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7392
7393 //Stop Bss.
7394 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7395 if (VOS_IS_STATUS_SUCCESS(status))
7396 {
7397 hdd_hostapd_state_t *pHostapdState =
7398 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7399
7400 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7401
7402 if (!VOS_IS_STATUS_SUCCESS(status))
7403 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307404 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7405 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 }
7407 }
7408 else
7409 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007410 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 }
7412 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307413 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007414
7415 if (eHAL_STATUS_FAILURE ==
7416 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7417 0, NULL, eANI_BOOLEAN_FALSE))
7418 {
7419 hddLog(LOGE,
7420 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007421 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 }
7423
7424 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7425 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7426 eANI_BOOLEAN_FALSE) )
7427 {
7428 hddLog(LOGE,
7429 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7430 }
7431
7432 // Reset WNI_CFG_PROBE_RSP Flags
7433 wlan_hdd_reset_prob_rspies(pAdapter);
7434 kfree(pAdapter->sessionCtx.ap.beacon);
7435 pAdapter->sessionCtx.ap.beacon = NULL;
7436 }
7437 mutex_unlock(&pHddCtx->sap_lock);
7438 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007439
Jeff Johnson295189b2012-06-20 16:38:30 -07007440 case WLAN_HDD_MONITOR:
7441 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007442
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 default:
7444 break;
7445 }
7446
7447 EXIT();
7448 return VOS_STATUS_SUCCESS;
7449}
7450
7451VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7452{
7453 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7454 VOS_STATUS status;
7455 hdd_adapter_t *pAdapter;
7456
7457 ENTER();
7458
7459 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7460
7461 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7462 {
7463 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007464
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307465 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007466
7467 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7468 pAdapterNode = pNext;
7469 }
7470
7471 EXIT();
7472
7473 return VOS_STATUS_SUCCESS;
7474}
7475
Rajeev Kumarf999e582014-01-09 17:33:29 -08007476
7477#ifdef FEATURE_WLAN_BATCH_SCAN
7478/**---------------------------------------------------------------------------
7479
7480 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7481 structures
7482
7483 \param - pAdapter Pointer to HDD adapter
7484
7485 \return - None
7486
7487 --------------------------------------------------------------------------*/
7488void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7489{
7490 tHddBatchScanRsp *pNode;
7491 tHddBatchScanRsp *pPrev;
7492
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307493 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007494 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307495 hddLog(VOS_TRACE_LEVEL_ERROR,
7496 "%s: Adapter context is Null", __func__);
7497 return;
7498 }
7499
7500 pNode = pAdapter->pBatchScanRsp;
7501 while (pNode)
7502 {
7503 pPrev = pNode;
7504 pNode = pNode->pNext;
7505 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007506 }
7507
7508 pAdapter->pBatchScanRsp = NULL;
7509 pAdapter->numScanList = 0;
7510 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7511 pAdapter->prev_batch_id = 0;
7512
7513 return;
7514}
7515#endif
7516
7517
Jeff Johnson295189b2012-06-20 16:38:30 -07007518VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7519{
7520 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7521 VOS_STATUS status;
7522 hdd_adapter_t *pAdapter;
7523
7524 ENTER();
7525
7526 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7527
7528 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7529 {
7530 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307531 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 netif_tx_disable(pAdapter->dev);
7533 netif_carrier_off(pAdapter->dev);
7534
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007535 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7536
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307538
Katya Nigam1fd24402015-02-16 14:52:19 +05307539 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7540 hdd_ibss_deinit_tx_rx(pAdapter);
7541
Nirav Shah7e3c8132015-06-22 23:51:42 +05307542 status = hdd_sta_id_hash_detach(pAdapter);
7543 if (status != VOS_STATUS_SUCCESS)
7544 hddLog(VOS_TRACE_LEVEL_ERROR,
7545 FL("sta id hash detach failed for session id %d"),
7546 pAdapter->sessionId);
7547
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307548 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7549
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307550 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7551 {
7552 hdd_wmm_adapter_close( pAdapter );
7553 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007555
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307556 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7557 {
7558 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7559 }
7560
Rajeev Kumarf999e582014-01-09 17:33:29 -08007561#ifdef FEATURE_WLAN_BATCH_SCAN
7562 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7563 {
7564 hdd_deinit_batch_scan(pAdapter);
7565 }
7566#endif
7567
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307568#ifdef FEATURE_WLAN_TDLS
7569 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307570 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307571 mutex_unlock(&pHddCtx->tdls_lock);
7572#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007573 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7574 pAdapterNode = pNext;
7575 }
7576
7577 EXIT();
7578
7579 return VOS_STATUS_SUCCESS;
7580}
7581
7582VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7583{
7584 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7585 VOS_STATUS status;
7586 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307587 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007588
7589 ENTER();
7590
7591 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7592
7593 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7594 {
7595 pAdapter = pAdapterNode->pAdapter;
7596
Kumar Anand82c009f2014-05-29 00:29:42 -07007597 hdd_wmm_init( pAdapter );
7598
Jeff Johnson295189b2012-06-20 16:38:30 -07007599 switch(pAdapter->device_mode)
7600 {
7601 case WLAN_HDD_INFRA_STATION:
7602 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007603 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307604
7605 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7606
Jeff Johnson295189b2012-06-20 16:38:30 -07007607 hdd_init_station_mode(pAdapter);
7608 /* Open the gates for HDD to receive Wext commands */
7609 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007610 pHddCtx->scan_info.mScanPending = FALSE;
7611 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007612
7613 //Trigger the initial scan
7614 hdd_wlan_initial_scan(pAdapter);
7615
7616 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307617 if (eConnectionState_Associated == connState ||
7618 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 {
7620 union iwreq_data wrqu;
7621 memset(&wrqu, '\0', sizeof(wrqu));
7622 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7623 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7624 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007625 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007626
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 /* indicate disconnected event to nl80211 */
7628 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7629 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307631 else if (eConnectionState_Connecting == connState)
7632 {
7633 /*
7634 * Indicate connect failure to supplicant if we were in the
7635 * process of connecting
7636 */
7637 cfg80211_connect_result(pAdapter->dev, NULL,
7638 NULL, 0, NULL, 0,
7639 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7640 GFP_KERNEL);
7641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 break;
7643
7644 case WLAN_HDD_SOFTAP:
7645 /* softAP can handle SSR */
7646 break;
7647
7648 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007651 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 break;
7653
7654 case WLAN_HDD_MONITOR:
7655 /* monitor interface start */
7656 break;
7657 default:
7658 break;
7659 }
7660
7661 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7662 pAdapterNode = pNext;
7663 }
7664
7665 EXIT();
7666
7667 return VOS_STATUS_SUCCESS;
7668}
7669
7670VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7671{
7672 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7673 hdd_adapter_t *pAdapter;
7674 VOS_STATUS status;
7675 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307676 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007677
7678 ENTER();
7679
7680 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7681
7682 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7683 {
7684 pAdapter = pAdapterNode->pAdapter;
7685
7686 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7687 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7688 {
7689 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7690 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7691
Abhishek Singhf4669da2014-05-26 15:07:49 +05307692 hddLog(VOS_TRACE_LEVEL_INFO,
7693 "%s: Set HDD connState to eConnectionState_NotConnected",
7694 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7696 init_completion(&pAdapter->disconnect_comp_var);
7697 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7698 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7699
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307700 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 &pAdapter->disconnect_comp_var,
7702 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307703 if (0 >= ret)
7704 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7705 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007706
7707 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7708 pHddCtx->isAmpAllowed = VOS_FALSE;
7709 sme_RoamConnect(pHddCtx->hHal,
7710 pAdapter->sessionId, &(pWextState->roamProfile),
7711 &roamId);
7712 }
7713
7714 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7715 pAdapterNode = pNext;
7716 }
7717
7718 EXIT();
7719
7720 return VOS_STATUS_SUCCESS;
7721}
7722
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007723void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7724{
7725 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7726 VOS_STATUS status;
7727 hdd_adapter_t *pAdapter;
7728 hdd_station_ctx_t *pHddStaCtx;
7729 hdd_ap_ctx_t *pHddApCtx;
7730 hdd_hostapd_state_t * pHostapdState;
7731 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7732 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7733 const char *p2pMode = "DEV";
7734 const char *ccMode = "Standalone";
7735 int n;
7736
7737 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7738 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7739 {
7740 pAdapter = pAdapterNode->pAdapter;
7741 switch (pAdapter->device_mode) {
7742 case WLAN_HDD_INFRA_STATION:
7743 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7744 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7745 staChannel = pHddStaCtx->conn_info.operationChannel;
7746 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7747 }
7748 break;
7749 case WLAN_HDD_P2P_CLIENT:
7750 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7751 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7752 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7753 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7754 p2pMode = "CLI";
7755 }
7756 break;
7757 case WLAN_HDD_P2P_GO:
7758 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7759 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7760 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7761 p2pChannel = pHddApCtx->operatingChannel;
7762 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7763 }
7764 p2pMode = "GO";
7765 break;
7766 case WLAN_HDD_SOFTAP:
7767 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7768 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7769 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7770 apChannel = pHddApCtx->operatingChannel;
7771 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7772 }
7773 break;
7774 default:
7775 break;
7776 }
7777 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7778 pAdapterNode = pNext;
7779 }
7780 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7781 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7782 }
7783 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7784 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7785 if (p2pChannel > 0) {
7786 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7787 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7788 }
7789 if (apChannel > 0) {
7790 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7791 apChannel, MAC_ADDR_ARRAY(apBssid));
7792 }
7793
7794 if (p2pChannel > 0 && apChannel > 0) {
7795 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7796 }
7797}
7798
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007799bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007800{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007801 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007802}
7803
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007804/* Once SSR is disabled then it cannot be set. */
7805void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007806{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007807 if (HDD_SSR_DISABLED == isSsrRequired)
7808 return;
7809
Jeff Johnson295189b2012-06-20 16:38:30 -07007810 isSsrRequired = value;
7811}
7812
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307813void hdd_set_pre_close( hdd_context_t *pHddCtx)
7814{
7815 sme_PreClose(pHddCtx->hHal);
7816}
7817
Jeff Johnson295189b2012-06-20 16:38:30 -07007818VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7819 hdd_adapter_list_node_t** ppAdapterNode)
7820{
7821 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307822 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7824 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307825 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007826 return status;
7827}
7828
7829VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7830 hdd_adapter_list_node_t* pAdapterNode,
7831 hdd_adapter_list_node_t** pNextAdapterNode)
7832{
7833 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307834 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7836 (hdd_list_node_t*) pAdapterNode,
7837 (hdd_list_node_t**)pNextAdapterNode );
7838
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307839 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 return status;
7841}
7842
7843VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7844 hdd_adapter_list_node_t* pAdapterNode)
7845{
7846 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307847 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7849 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307850 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007851 return status;
7852}
7853
7854VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7855 hdd_adapter_list_node_t** ppAdapterNode)
7856{
7857 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307858 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007859 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7860 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307861 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007862 return status;
7863}
7864
7865VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7866 hdd_adapter_list_node_t* pAdapterNode)
7867{
7868 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307869 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007870 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7871 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307872 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007873 return status;
7874}
7875
7876VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7877 hdd_adapter_list_node_t* pAdapterNode)
7878{
7879 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307880 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7882 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307883 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007884 return status;
7885}
7886
7887hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7888 tSirMacAddr macAddr )
7889{
7890 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7891 hdd_adapter_t *pAdapter;
7892 VOS_STATUS status;
7893
7894 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7895
7896 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7897 {
7898 pAdapter = pAdapterNode->pAdapter;
7899
7900 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7901 macAddr, sizeof(tSirMacAddr) ) )
7902 {
7903 return pAdapter;
7904 }
7905 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7906 pAdapterNode = pNext;
7907 }
7908
7909 return NULL;
7910
7911}
7912
7913hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7914{
7915 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7916 hdd_adapter_t *pAdapter;
7917 VOS_STATUS status;
7918
7919 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7920
7921 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7922 {
7923 pAdapter = pAdapterNode->pAdapter;
7924
7925 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7926 IFNAMSIZ ) )
7927 {
7928 return pAdapter;
7929 }
7930 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7931 pAdapterNode = pNext;
7932 }
7933
7934 return NULL;
7935
7936}
7937
7938hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7939{
7940 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7941 hdd_adapter_t *pAdapter;
7942 VOS_STATUS status;
7943
7944 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7945
7946 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7947 {
7948 pAdapter = pAdapterNode->pAdapter;
7949
7950 if( pAdapter && (mode == pAdapter->device_mode) )
7951 {
7952 return pAdapter;
7953 }
7954 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7955 pAdapterNode = pNext;
7956 }
7957
7958 return NULL;
7959
7960}
7961
7962//Remove this function later
7963hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7964{
7965 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7966 hdd_adapter_t *pAdapter;
7967 VOS_STATUS status;
7968
7969 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7970
7971 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7972 {
7973 pAdapter = pAdapterNode->pAdapter;
7974
7975 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7976 {
7977 return pAdapter;
7978 }
7979
7980 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7981 pAdapterNode = pNext;
7982 }
7983
7984 return NULL;
7985
7986}
7987
Jeff Johnson295189b2012-06-20 16:38:30 -07007988/**---------------------------------------------------------------------------
7989
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307990 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007991
7992 This API returns the operating channel of the requested device mode
7993
7994 \param - pHddCtx - Pointer to the HDD context.
7995 - mode - Device mode for which operating channel is required
7996 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7997 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7998 \return - channel number. "0" id the requested device is not found OR it is not connected.
7999 --------------------------------------------------------------------------*/
8000v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8001{
8002 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8003 VOS_STATUS status;
8004 hdd_adapter_t *pAdapter;
8005 v_U8_t operatingChannel = 0;
8006
8007 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8008
8009 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8010 {
8011 pAdapter = pAdapterNode->pAdapter;
8012
8013 if( mode == pAdapter->device_mode )
8014 {
8015 switch(pAdapter->device_mode)
8016 {
8017 case WLAN_HDD_INFRA_STATION:
8018 case WLAN_HDD_P2P_CLIENT:
8019 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8020 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8021 break;
8022 case WLAN_HDD_SOFTAP:
8023 case WLAN_HDD_P2P_GO:
8024 /*softap connection info */
8025 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8026 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8027 break;
8028 default:
8029 break;
8030 }
8031
8032 break; //Found the device of interest. break the loop
8033 }
8034
8035 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8036 pAdapterNode = pNext;
8037 }
8038 return operatingChannel;
8039}
8040
8041#ifdef WLAN_FEATURE_PACKET_FILTERING
8042/**---------------------------------------------------------------------------
8043
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308044 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008045
8046 This used to set the multicast address list.
8047
8048 \param - dev - Pointer to the WLAN device.
8049 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308050 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008051
8052 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308053static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008054{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308055 hdd_adapter_t *pAdapter;
8056 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008057 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308058 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008059 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308060
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308061 ENTER();
8062
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308063 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308064 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 {
8066 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308067 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 return;
8069 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308070 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8071 ret = wlan_hdd_validate_context(pHddCtx);
8072 if (0 != ret)
8073 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308074 return;
8075 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 if (dev->flags & IFF_ALLMULTI)
8077 {
8078 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008079 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308080 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308082 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 {
8084 mc_count = netdev_mc_count(dev);
8085 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008086 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8088 {
8089 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008090 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308091 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 return;
8093 }
8094
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308095 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008096
8097 netdev_for_each_mc_addr(ha, dev) {
8098 if (i == mc_count)
8099 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308100 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8101 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008102 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308103 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308104 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008105 i++;
8106 }
8107 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308108
8109 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008110 return;
8111}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308112
8113static void hdd_set_multicast_list(struct net_device *dev)
8114{
8115 vos_ssr_protect(__func__);
8116 __hdd_set_multicast_list(dev);
8117 vos_ssr_unprotect(__func__);
8118}
Jeff Johnson295189b2012-06-20 16:38:30 -07008119#endif
8120
8121/**---------------------------------------------------------------------------
8122
8123 \brief hdd_select_queue() -
8124
8125 This function is registered with the Linux OS for network
8126 core to decide which queue to use first.
8127
8128 \param - dev - Pointer to the WLAN device.
8129 - skb - Pointer to OS packet (sk_buff).
8130 \return - ac, Queue Index/access category corresponding to UP in IP header
8131
8132 --------------------------------------------------------------------------*/
8133v_U16_t hdd_select_queue(struct net_device *dev,
8134 struct sk_buff *skb)
8135{
8136 return hdd_wmm_select_queue(dev, skb);
8137}
8138
8139
8140/**---------------------------------------------------------------------------
8141
8142 \brief hdd_wlan_initial_scan() -
8143
8144 This function triggers the initial scan
8145
8146 \param - pAdapter - Pointer to the HDD adapter.
8147
8148 --------------------------------------------------------------------------*/
8149void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8150{
8151 tCsrScanRequest scanReq;
8152 tCsrChannelInfo channelInfo;
8153 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008154 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8156
8157 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8158 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8159 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8160
8161 if(sme_Is11dSupported(pHddCtx->hHal))
8162 {
8163 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8164 if ( HAL_STATUS_SUCCESS( halStatus ) )
8165 {
8166 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8167 if( !scanReq.ChannelInfo.ChannelList )
8168 {
8169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8170 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008171 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 return;
8173 }
8174 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8175 channelInfo.numOfChannels);
8176 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8177 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008178 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008179 }
8180
8181 scanReq.scanType = eSIR_PASSIVE_SCAN;
8182 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8183 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8184 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8185 }
8186 else
8187 {
8188 scanReq.scanType = eSIR_ACTIVE_SCAN;
8189 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8190 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8191 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8192 }
8193
8194 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8195 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8196 {
8197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8198 __func__, halStatus );
8199 }
8200
8201 if(sme_Is11dSupported(pHddCtx->hHal))
8202 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8203}
8204
mukul sharmabab477d2015-06-11 17:14:55 +05308205void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8206{
8207 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8208 VOS_STATUS status;
8209 hdd_adapter_t *pAdapter;
8210
8211 ENTER();
8212
8213 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8214
8215 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8216 {
8217 pAdapter = pAdapterNode->pAdapter;
8218
8219 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8220 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8221 pAdapterNode = pNext;
8222 }
8223
8224 EXIT();
8225}
Jeff Johnson295189b2012-06-20 16:38:30 -07008226/**---------------------------------------------------------------------------
8227
8228 \brief hdd_full_power_callback() - HDD full power callback function
8229
8230 This is the function invoked by SME to inform the result of a full power
8231 request issued by HDD
8232
8233 \param - callbackcontext - Pointer to cookie
8234 \param - status - result of request
8235
8236 \return - None
8237
8238 --------------------------------------------------------------------------*/
8239static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8240{
Jeff Johnson72a40512013-12-19 10:14:15 -08008241 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008242
8243 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308244 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008245
8246 if (NULL == callbackContext)
8247 {
8248 hddLog(VOS_TRACE_LEVEL_ERROR,
8249 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008250 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 return;
8252 }
8253
Jeff Johnson72a40512013-12-19 10:14:15 -08008254 /* there is a race condition that exists between this callback
8255 function and the caller since the caller could time out either
8256 before or while this code is executing. we use a spinlock to
8257 serialize these actions */
8258 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008259
8260 if (POWER_CONTEXT_MAGIC != pContext->magic)
8261 {
8262 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008263 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 hddLog(VOS_TRACE_LEVEL_WARN,
8265 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008266 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 return;
8268 }
8269
Jeff Johnson72a40512013-12-19 10:14:15 -08008270 /* context is valid so caller is still waiting */
8271
8272 /* paranoia: invalidate the magic */
8273 pContext->magic = 0;
8274
8275 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008277
8278 /* serialization is complete */
8279 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008280}
8281
Katya Nigamf0511f62015-05-05 16:40:57 +05308282void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8283{
8284 pMonCtx->typeSubtypeBitmap = 0;
8285 if( type%10 ) /* Management Packets */
8286 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8287 type/=10;
8288 if( type%10 ) /* Control Packets */
8289 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8290 type/=10;
8291 if( type%10 ) /* Data Packets */
8292 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8293}
8294
8295VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8296{
8297 vos_msg_t monMsg;
8298
8299 monMsg.type = WDA_MON_START_REQ;
8300 monMsg.reserved = 0;
8301 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8302 monMsg.bodyval = 0;
8303
8304 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8305 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8306 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8307 return VOS_STATUS_E_FAILURE;
8308 }
8309
8310 return VOS_STATUS_SUCCESS;
8311}
8312
8313void wlan_hdd_mon_poststopmsg(void)
8314{
8315 vos_msg_t monMsg;
8316
8317 monMsg.type = WDA_MON_STOP_REQ;
8318 monMsg.reserved = 0;
8319 monMsg.bodyptr = NULL;
8320 monMsg.bodyval = 0;
8321
8322 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8323 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8324 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8325 }
8326}
8327
Katya Nigame7b69a82015-04-28 15:24:06 +05308328void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8329{
8330 VOS_STATUS vosStatus;
8331 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8332 struct wiphy *wiphy = pHddCtx->wiphy;
8333
8334 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8335 if(pAdapter == NULL || pVosContext == NULL)
8336 {
8337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8338 return ;
8339 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308340
8341 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308342 hdd_UnregisterWext(pAdapter->dev);
8343
8344 vos_mon_stop( pVosContext );
8345
8346 vosStatus = vos_sched_close( pVosContext );
8347 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8348 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8349 "%s: Failed to close VOSS Scheduler",__func__);
8350 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8351 }
8352
8353 vosStatus = vos_nv_close();
8354 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8355 {
8356 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8357 "%s: Failed to close NV", __func__);
8358 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8359 }
8360
8361 vos_close(pVosContext);
8362
8363 #ifdef WLAN_KD_READY_NOTIFIER
8364 nl_srv_exit(pHddCtx->ptt_pid);
8365 #else
8366 nl_srv_exit();
8367 #endif
8368
8369 if (pHddCtx->cfg_ini)
8370 {
8371 kfree(pHddCtx->cfg_ini);
8372 pHddCtx->cfg_ini= NULL;
8373 }
8374 hdd_close_all_adapters( pHddCtx );
8375
8376 wiphy_free(wiphy) ;
8377
8378}
Jeff Johnson295189b2012-06-20 16:38:30 -07008379/**---------------------------------------------------------------------------
8380
8381 \brief hdd_wlan_exit() - HDD WLAN exit function
8382
8383 This is the driver exit point (invoked during rmmod)
8384
8385 \param - pHddCtx - Pointer to the HDD Context
8386
8387 \return - None
8388
8389 --------------------------------------------------------------------------*/
8390void hdd_wlan_exit(hdd_context_t *pHddCtx)
8391{
8392 eHalStatus halStatus;
8393 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8394 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308395 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008396 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008397 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308399 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008400
8401 ENTER();
8402
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308403
Katya Nigame7b69a82015-04-28 15:24:06 +05308404 if (VOS_MONITOR_MODE == hdd_get_conparam())
8405 {
8406 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8407 wlan_hdd_mon_close(pHddCtx);
8408 return;
8409 }
8410 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008411 {
8412 // Unloading, restart logic is no more required.
8413 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008414
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308415#ifdef FEATURE_WLAN_TDLS
8416 /* At the time of driver unloading; if tdls connection is present;
8417 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8418 * wlan_hdd_tdls_find_peer always checks for valid context;
8419 * as load/unload in progress there can be a race condition.
8420 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8421 * when tdls state is enabled.
8422 * As soon as driver set load/unload flag; tdls flag also needs
8423 * to be disabled so that hdd_rx_packet_cbk won't call
8424 * wlan_hdd_tdls_find_peer.
8425 */
8426 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8427#endif
8428
c_hpothu5ab05e92014-06-13 17:34:05 +05308429 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8430 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308432 pAdapter = pAdapterNode->pAdapter;
8433 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308435 /* Disable TX on the interface, after this hard_start_xmit() will
8436 * not be called on that interface
8437 */
8438 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8439 netif_tx_disable(pAdapter->dev);
8440
8441 /* Mark the interface status as "down" for outside world */
8442 netif_carrier_off(pAdapter->dev);
8443
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308444 /* DeInit the adapter. This ensures that all data packets
8445 * are freed.
8446 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308447#ifdef FEATURE_WLAN_TDLS
8448 mutex_lock(&pHddCtx->tdls_lock);
8449#endif
c_hpothu002231a2015-02-05 14:58:51 +05308450 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308451#ifdef FEATURE_WLAN_TDLS
8452 mutex_unlock(&pHddCtx->tdls_lock);
8453#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308454
c_hpothu5ab05e92014-06-13 17:34:05 +05308455 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8456 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8457 {
8458 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8459 hdd_UnregisterWext(pAdapter->dev);
8460 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308461
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308463 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8464 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 }
mukul sharmabab477d2015-06-11 17:14:55 +05308466
8467 //Purge all sme cmd's for all interface
8468 hdd_purge_cmd_list_all_adapters(pHddCtx);
8469
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308470 // Cancel any outstanding scan requests. We are about to close all
8471 // of our adapters, but an adapter structure is what SME passes back
8472 // to our callback function. Hence if there are any outstanding scan
8473 // requests then there is a race condition between when the adapter
8474 // is closed and when the callback is invoked.We try to resolve that
8475 // race condition here by canceling any outstanding scans before we
8476 // close the adapters.
8477 // Note that the scans may be cancelled in an asynchronous manner,
8478 // so ideally there needs to be some kind of synchronization. Rather
8479 // than introduce a new synchronization here, we will utilize the
8480 // fact that we are about to Request Full Power, and since that is
8481 // synchronized, the expectation is that by the time Request Full
8482 // Power has completed all scans will be cancelled.
8483 if (pHddCtx->scan_info.mScanPending)
8484 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308485 if(NULL != pAdapter)
8486 {
8487 hddLog(VOS_TRACE_LEVEL_INFO,
8488 FL("abort scan mode: %d sessionId: %d"),
8489 pAdapter->device_mode,
8490 pAdapter->sessionId);
8491 }
8492 hdd_abort_mac_scan(pHddCtx,
8493 pHddCtx->scan_info.sessionId,
8494 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308497 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008498 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308499 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308500 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8501 {
8502 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8504 "%s: in middle of FTM START", __func__);
8505 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8506 msecs_to_jiffies(20000));
8507 if(!lrc)
8508 {
8509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8510 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8511 }
8512 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008513 wlan_hdd_ftm_close(pHddCtx);
8514 goto free_hdd_ctx;
8515 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308516
Jeff Johnson295189b2012-06-20 16:38:30 -07008517 /* DeRegister with platform driver as client for Suspend/Resume */
8518 vosStatus = hddDeregisterPmOps(pHddCtx);
8519 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8520 {
8521 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8522 VOS_ASSERT(0);
8523 }
8524
8525 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8526 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8527 {
8528 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008530
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008531 //Stop the traffic monitor timer
8532 if ( VOS_TIMER_STATE_RUNNING ==
8533 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8534 {
8535 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8536 }
8537
8538 // Destroy the traffic monitor timer
8539 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8540 &pHddCtx->tx_rx_trafficTmr)))
8541 {
8542 hddLog(VOS_TRACE_LEVEL_ERROR,
8543 "%s: Cannot deallocate Traffic monitor timer", __func__);
8544 }
8545
Jeff Johnson295189b2012-06-20 16:38:30 -07008546 //Disable IMPS/BMPS as we do not want the device to enter any power
8547 //save mode during shutdown
8548 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8549 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8550 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8551
8552 //Ensure that device is in full power as we will touch H/W during vos_Stop
8553 init_completion(&powerContext.completion);
8554 powerContext.magic = POWER_CONTEXT_MAGIC;
8555
8556 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8557 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8558
8559 if (eHAL_STATUS_SUCCESS != halStatus)
8560 {
8561 if (eHAL_STATUS_PMC_PENDING == halStatus)
8562 {
8563 /* request was sent -- wait for the response */
8564 lrc = wait_for_completion_interruptible_timeout(
8565 &powerContext.completion,
8566 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008567 if (lrc <= 0)
8568 {
8569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008570 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 }
8572 }
8573 else
8574 {
8575 hddLog(VOS_TRACE_LEVEL_ERROR,
8576 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008577 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008578 /* continue -- need to clean up as much as possible */
8579 }
8580 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308581 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8582 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8583 {
8584 /* This will issue a dump command which will clean up
8585 BTQM queues and unblock MC thread */
8586 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8587 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008588
Jeff Johnson72a40512013-12-19 10:14:15 -08008589 /* either we never sent a request, we sent a request and received a
8590 response or we sent a request and timed out. if we never sent a
8591 request or if we sent a request and got a response, we want to
8592 clear the magic out of paranoia. if we timed out there is a
8593 race condition such that the callback function could be
8594 executing at the same time we are. of primary concern is if the
8595 callback function had already verified the "magic" but had not
8596 yet set the completion variable when a timeout occurred. we
8597 serialize these activities by invalidating the magic while
8598 holding a shared spinlock which will cause us to block if the
8599 callback is currently executing */
8600 spin_lock(&hdd_context_lock);
8601 powerContext.magic = 0;
8602 spin_unlock(&hdd_context_lock);
8603
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308604 /* If Device is shutdown, no point for SME to wait for responses
8605 from device. Pre Close SME */
8606 if(wcnss_device_is_shutdown())
8607 {
8608 sme_PreClose(pHddCtx->hHal);
8609 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008610 hdd_debugfs_exit(pHddCtx);
8611
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308612#ifdef WLAN_NS_OFFLOAD
8613 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8614 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8615#endif
8616 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8617 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8618
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 // Unregister the Net Device Notifier
8620 unregister_netdevice_notifier(&hdd_netdev_notifier);
8621
Jeff Johnson295189b2012-06-20 16:38:30 -07008622 hdd_stop_all_adapters( pHddCtx );
8623
Jeff Johnson295189b2012-06-20 16:38:30 -07008624#ifdef WLAN_BTAMP_FEATURE
8625 vosStatus = WLANBAP_Stop(pVosContext);
8626 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8627 {
8628 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8629 "%s: Failed to stop BAP",__func__);
8630 }
8631#endif //WLAN_BTAMP_FEATURE
8632
8633 //Stop all the modules
8634 vosStatus = vos_stop( pVosContext );
8635 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8636 {
8637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8638 "%s: Failed to stop VOSS",__func__);
8639 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8640 }
8641
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008643 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008644
8645 //Close the scheduler before calling vos_close to make sure no thread is
8646 // scheduled after the each module close is called i.e after all the data
8647 // structures are freed.
8648 vosStatus = vos_sched_close( pVosContext );
8649 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8650 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8651 "%s: Failed to close VOSS Scheduler",__func__);
8652 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8653 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008654#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8655 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308656 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008657#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008658 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308659 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008660
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308661#ifdef CONFIG_ENABLE_LINUX_REG
8662 vosStatus = vos_nv_close();
8663 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8664 {
8665 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8666 "%s: Failed to close NV", __func__);
8667 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8668 }
8669#endif
8670
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 //Close VOSS
8672 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8673 vos_close(pVosContext);
8674
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 //Close Watchdog
8676 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8677 vos_watchdog_close(pVosContext);
8678
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308679 //Clean up HDD Nlink Service
8680 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308681
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308682#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308683 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308684 {
8685 wlan_logging_sock_deactivate_svc();
8686 }
8687#endif
8688
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308689#ifdef WLAN_KD_READY_NOTIFIER
8690 nl_srv_exit(pHddCtx->ptt_pid);
8691#else
8692 nl_srv_exit();
8693#endif /* WLAN_KD_READY_NOTIFIER */
8694
8695
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 hdd_close_all_adapters( pHddCtx );
8697
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 /* free the power on lock from platform driver */
8699 if (free_riva_power_on_lock("wlan"))
8700 {
8701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8702 __func__);
8703 }
8704
Jeff Johnson88ba7742013-02-27 14:36:02 -08008705free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308706
8707 //Free up dynamically allocated members inside HDD Adapter
8708 if (pHddCtx->cfg_ini)
8709 {
8710 kfree(pHddCtx->cfg_ini);
8711 pHddCtx->cfg_ini= NULL;
8712 }
8713
Leo Changf04ddad2013-09-18 13:46:38 -07008714 /* FTM mode, WIPHY did not registered
8715 If un-register here, system crash will happen */
8716 if (VOS_FTM_MODE != hdd_get_conparam())
8717 {
8718 wiphy_unregister(wiphy) ;
8719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008720 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 if (hdd_is_ssr_required())
8722 {
8723 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008724 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 msleep(5000);
8726 }
8727 hdd_set_ssr_required (VOS_FALSE);
8728}
8729
8730
8731/**---------------------------------------------------------------------------
8732
8733 \brief hdd_update_config_from_nv() - Function to update the contents of
8734 the running configuration with parameters taken from NV storage
8735
8736 \param - pHddCtx - Pointer to the HDD global context
8737
8738 \return - VOS_STATUS_SUCCESS if successful
8739
8740 --------------------------------------------------------------------------*/
8741static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8742{
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 v_BOOL_t itemIsValid = VOS_FALSE;
8744 VOS_STATUS status;
8745 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8746 v_U8_t macLoop;
8747
8748 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8749 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8750 if(status != VOS_STATUS_SUCCESS)
8751 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008752 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 return VOS_STATUS_E_FAILURE;
8754 }
8755
8756 if (itemIsValid == VOS_TRUE)
8757 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008758 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8760 VOS_MAX_CONCURRENCY_PERSONA);
8761 if(status != VOS_STATUS_SUCCESS)
8762 {
8763 /* Get MAC from NV fail, not update CFG info
8764 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008765 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 return VOS_STATUS_E_FAILURE;
8767 }
8768
8769 /* If first MAC is not valid, treat all others are not valid
8770 * Then all MACs will be got from ini file */
8771 if(vos_is_macaddr_zero(&macFromNV[0]))
8772 {
8773 /* MAC address in NV file is not configured yet */
8774 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8775 return VOS_STATUS_E_INVAL;
8776 }
8777
8778 /* Get MAC address from NV, update CFG info */
8779 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8780 {
8781 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8782 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308783 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 /* This MAC is not valid, skip it
8785 * This MAC will be got from ini file */
8786 }
8787 else
8788 {
8789 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8790 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8791 VOS_MAC_ADDR_SIZE);
8792 }
8793 }
8794 }
8795 else
8796 {
8797 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8798 return VOS_STATUS_E_FAILURE;
8799 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008800
Jeff Johnson295189b2012-06-20 16:38:30 -07008801
8802 return VOS_STATUS_SUCCESS;
8803}
8804
8805/**---------------------------------------------------------------------------
8806
8807 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8808
8809 \param - pAdapter - Pointer to the HDD
8810
8811 \return - None
8812
8813 --------------------------------------------------------------------------*/
8814VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8815{
8816 eHalStatus halStatus;
8817 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308818 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008819
Jeff Johnson295189b2012-06-20 16:38:30 -07008820
8821 // Send ready indication to the HDD. This will kick off the MAC
8822 // into a 'running' state and should kick off an initial scan.
8823 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8824 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8825 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308826 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 "code %08d [x%08x]",__func__, halStatus, halStatus );
8828 return VOS_STATUS_E_FAILURE;
8829 }
8830
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308831 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8833 // And RIVA will crash
8834 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8835 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308836 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8837 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8838
8839
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 return VOS_STATUS_SUCCESS;
8841}
8842
Jeff Johnson295189b2012-06-20 16:38:30 -07008843/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308844void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008845{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308846
8847 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8848
Jeff Johnson295189b2012-06-20 16:38:30 -07008849}
8850
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308851void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008852{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308853
8854 vos_wake_lock_release(&wlan_wake_lock, reason);
8855
Jeff Johnson295189b2012-06-20 16:38:30 -07008856}
8857
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308858void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008859{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308860
8861 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8862 reason);
8863
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008864}
8865
Jeff Johnson295189b2012-06-20 16:38:30 -07008866/**---------------------------------------------------------------------------
8867
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008868 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8869 information between Host and Riva
8870
8871 This function gets reported version of FW
8872 It also finds the version of Riva headers used to compile the host
8873 It compares the above two and prints a warning if they are different
8874 It gets the SW and HW version string
8875 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8876 indicating the features they support through a bitmap
8877
8878 \param - pHddCtx - Pointer to HDD context
8879
8880 \return - void
8881
8882 --------------------------------------------------------------------------*/
8883
8884void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8885{
8886
8887 tSirVersionType versionCompiled;
8888 tSirVersionType versionReported;
8889 tSirVersionString versionString;
8890 tANI_U8 fwFeatCapsMsgSupported = 0;
8891 VOS_STATUS vstatus;
8892
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008893 memset(&versionCompiled, 0, sizeof(versionCompiled));
8894 memset(&versionReported, 0, sizeof(versionReported));
8895
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008896 /* retrieve and display WCNSS version information */
8897 do {
8898
8899 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8900 &versionCompiled);
8901 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8902 {
8903 hddLog(VOS_TRACE_LEVEL_FATAL,
8904 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008905 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008906 break;
8907 }
8908
8909 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8910 &versionReported);
8911 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8912 {
8913 hddLog(VOS_TRACE_LEVEL_FATAL,
8914 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008915 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008916 break;
8917 }
8918
8919 if ((versionCompiled.major != versionReported.major) ||
8920 (versionCompiled.minor != versionReported.minor) ||
8921 (versionCompiled.version != versionReported.version) ||
8922 (versionCompiled.revision != versionReported.revision))
8923 {
8924 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8925 "Host expected %u.%u.%u.%u\n",
8926 WLAN_MODULE_NAME,
8927 (int)versionReported.major,
8928 (int)versionReported.minor,
8929 (int)versionReported.version,
8930 (int)versionReported.revision,
8931 (int)versionCompiled.major,
8932 (int)versionCompiled.minor,
8933 (int)versionCompiled.version,
8934 (int)versionCompiled.revision);
8935 }
8936 else
8937 {
8938 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8939 WLAN_MODULE_NAME,
8940 (int)versionReported.major,
8941 (int)versionReported.minor,
8942 (int)versionReported.version,
8943 (int)versionReported.revision);
8944 }
8945
8946 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8947 versionString,
8948 sizeof(versionString));
8949 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8950 {
8951 hddLog(VOS_TRACE_LEVEL_FATAL,
8952 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008953 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008954 break;
8955 }
8956
8957 pr_info("%s: WCNSS software version %s\n",
8958 WLAN_MODULE_NAME, versionString);
8959
8960 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8961 versionString,
8962 sizeof(versionString));
8963 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8964 {
8965 hddLog(VOS_TRACE_LEVEL_FATAL,
8966 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008967 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008968 break;
8969 }
8970
8971 pr_info("%s: WCNSS hardware version %s\n",
8972 WLAN_MODULE_NAME, versionString);
8973
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008974 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8975 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008976 send the message only if it the riva is 1.1
8977 minor numbers for different riva branches:
8978 0 -> (1.0)Mainline Build
8979 1 -> (1.1)Mainline Build
8980 2->(1.04) Stability Build
8981 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008982 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008983 ((versionReported.minor>=1) && (versionReported.version>=1)))
8984 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8985 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008986
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008987 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008988 {
8989#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8990 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8991 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8992#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008993 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8994 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8995 {
8996 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8997 }
8998
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008999 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009000 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009001
9002 } while (0);
9003
9004}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309005void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9006{
9007 struct sk_buff *skb;
9008 struct nlmsghdr *nlh;
9009 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309010 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309011
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309012 if (in_interrupt() || irqs_disabled() || in_atomic())
9013 flags = GFP_ATOMIC;
9014
9015 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309016
9017 if(skb == NULL) {
9018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9019 "%s: alloc_skb failed", __func__);
9020 return;
9021 }
9022
9023 nlh = (struct nlmsghdr *)skb->data;
9024 nlh->nlmsg_pid = 0; /* from kernel */
9025 nlh->nlmsg_flags = 0;
9026 nlh->nlmsg_seq = 0;
9027 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9028
9029 ani_hdr = NLMSG_DATA(nlh);
9030 ani_hdr->type = type;
9031
9032 switch(type) {
9033 case WLAN_SVC_SAP_RESTART_IND:
9034 ani_hdr->length = 0;
9035 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9036 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9037 break;
9038 default:
9039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9040 "Attempt to send unknown nlink message %d", type);
9041 kfree_skb(skb);
9042 return;
9043 }
9044
9045 nl_srv_bcast(skb);
9046
9047 return;
9048}
9049
9050
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009051
9052/**---------------------------------------------------------------------------
9053
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309054 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9055
9056 \param - pHddCtx - Pointer to the hdd context
9057
9058 \return - true if hardware supports 5GHz
9059
9060 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309061boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309062{
9063 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9064 * then hardware support 5Ghz.
9065 */
9066 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9067 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309069 return true;
9070 }
9071 else
9072 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309074 __func__);
9075 return false;
9076 }
9077}
9078
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309079/**---------------------------------------------------------------------------
9080
9081 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9082 generate function
9083
9084 This is generate the random mac address for WLAN interface
9085
9086 \param - pHddCtx - Pointer to HDD context
9087 idx - Start interface index to get auto
9088 generated mac addr.
9089 mac_addr - Mac address
9090
9091 \return - 0 for success, < 0 for failure
9092
9093 --------------------------------------------------------------------------*/
9094
9095static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9096 int idx, v_MACADDR_t mac_addr)
9097{
9098 int i;
9099 unsigned int serialno;
9100 serialno = wcnss_get_serial_number();
9101
9102 if (0 != serialno)
9103 {
9104 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9105 bytes of the serial number that can be used to generate
9106 the other 3 bytes of the MAC address. Mask off all but
9107 the lower 3 bytes (this will also make sure we don't
9108 overflow in the next step) */
9109 serialno &= 0x00FFFFFF;
9110
9111 /* we need a unique address for each session */
9112 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9113
9114 /* autogen other Mac addresses */
9115 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9116 {
9117 /* start with the entire default address */
9118 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9119 /* then replace the lower 3 bytes */
9120 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9121 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9122 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9123
9124 serialno++;
9125 hddLog(VOS_TRACE_LEVEL_ERROR,
9126 "%s: Derived Mac Addr: "
9127 MAC_ADDRESS_STR, __func__,
9128 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9129 }
9130
9131 }
9132 else
9133 {
9134 hddLog(LOGE, FL("Failed to Get Serial NO"));
9135 return -1;
9136 }
9137 return 0;
9138}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309139
Katya Nigame7b69a82015-04-28 15:24:06 +05309140int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9141{
9142 VOS_STATUS status;
9143 v_CONTEXT_t pVosContext= NULL;
9144 hdd_adapter_t *pAdapter= NULL;
9145
9146 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9147
9148 if (NULL == pVosContext)
9149 {
9150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9151 "%s: Trying to open VOSS without a PreOpen", __func__);
9152 VOS_ASSERT(0);
9153 return VOS_STATUS_E_FAILURE;
9154 }
9155
9156 status = vos_nv_open();
9157 if (!VOS_IS_STATUS_SUCCESS(status))
9158 {
9159 /* NV module cannot be initialized */
9160 hddLog( VOS_TRACE_LEVEL_FATAL,
9161 "%s: vos_nv_open failed", __func__);
9162 return VOS_STATUS_E_FAILURE;
9163 }
9164
9165 status = vos_init_wiphy_from_nv_bin();
9166 if (!VOS_IS_STATUS_SUCCESS(status))
9167 {
9168 /* NV module cannot be initialized */
9169 hddLog( VOS_TRACE_LEVEL_FATAL,
9170 "%s: vos_init_wiphy failed", __func__);
9171 goto err_vos_nv_close;
9172 }
9173
9174 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9175 if ( !VOS_IS_STATUS_SUCCESS( status ))
9176 {
9177 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9178 goto err_vos_nv_close;
9179 }
9180
9181 status = vos_mon_start( pVosContext );
9182 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9183 {
9184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9185 goto err_vosclose;
9186 }
9187
9188 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9189 WDA_featureCapsExchange(pVosContext);
9190 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9191
9192 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9193 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9194 if( pAdapter == NULL )
9195 {
9196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9197 goto err_close_adapter;
9198 }
9199
9200 //Initialize the nlink service
9201 if(nl_srv_init() != 0)
9202 {
9203 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9204 goto err_close_adapter;
9205 }
9206 return VOS_STATUS_SUCCESS;
9207
9208err_close_adapter:
9209 hdd_close_all_adapters( pHddCtx );
9210 vos_mon_stop( pVosContext );
9211err_vosclose:
9212 status = vos_sched_close( pVosContext );
9213 if (!VOS_IS_STATUS_SUCCESS(status)) {
9214 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9215 "%s: Failed to close VOSS Scheduler", __func__);
9216 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9217 }
9218 vos_close(pVosContext );
9219
9220err_vos_nv_close:
9221 vos_nv_close();
9222
9223return status;
9224}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309225/**---------------------------------------------------------------------------
9226
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309227 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9228 completed to flush out the scan results
9229
9230 11d scan is done during driver load and is a passive scan on all
9231 channels supported by the device, 11d scans may find some APs on
9232 frequencies which are forbidden to be used in the regulatory domain
9233 the device is operating in. If these APs are notified to the supplicant
9234 it may try to connect to these APs, thus flush out all the scan results
9235 which are present in SME after 11d scan is done.
9236
9237 \return - eHalStatus
9238
9239 --------------------------------------------------------------------------*/
9240static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9241 tANI_U32 scanId, eCsrScanStatus status)
9242{
9243 ENTER();
9244
9245 sme_ScanFlushResult(halHandle, 0);
9246
9247 EXIT();
9248
9249 return eHAL_STATUS_SUCCESS;
9250}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309251/**---------------------------------------------------------------------------
9252
9253 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9254 logging is completed successfully.
9255
9256 \return - None
9257
9258 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309259void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309260{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309261 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309262
9263 if (NULL == pHddCtx)
9264 {
9265 hddLog(VOS_TRACE_LEVEL_ERROR,
9266 "%s: HDD context is NULL",__func__);
9267 return;
9268 }
9269
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309270 if ((VOS_STATUS_SUCCESS == status) &&
9271 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309272 {
9273 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9274 pHddCtx->mgmt_frame_logging = TRUE;
9275 }
9276 else
9277 {
9278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9279 pHddCtx->mgmt_frame_logging = FALSE;
9280 }
9281
9282 return;
9283}
9284/**---------------------------------------------------------------------------
9285
9286 \brief hdd_init_frame_logging - function to initialize frame logging.
9287 Currently only Mgmt Frames are logged in both TX
9288 and Rx direction and are sent to userspace
9289 application using logger thread when queried.
9290
9291 \return - None
9292
9293 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309294void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309295{
9296 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309297 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309298
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309299 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9300 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309301 {
9302 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9303 return;
9304 }
9305
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309306 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9307 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309308 {
9309 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9310 return;
9311 }
9312
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309313 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309314
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309315 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9316 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9317 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9318 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309319
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309320 if (pHddCtx->cfg_ini->enableFWLogging ||
9321 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309322 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309323 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309324 }
9325
9326 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9327 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309328 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309329 }
9330
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309331 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9332 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9333 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9334 wlanFWLoggingInitParam->continuousFrameLogging =
9335 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309336
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309337 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309338
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309339 wlanFWLoggingInitParam->minLogBufferSize =
9340 pHddCtx->cfg_ini->minLoggingBufferSize;
9341 wlanFWLoggingInitParam->maxLogBufferSize =
9342 pHddCtx->cfg_ini->maxLoggingBufferSize;
9343 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9344 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309345
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309346 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309347
9348 if (eHAL_STATUS_SUCCESS != halStatus)
9349 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309350 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309351 }
9352
9353 return;
9354}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309355
9356/**---------------------------------------------------------------------------
9357
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 \brief hdd_wlan_startup() - HDD init function
9359
9360 This is the driver startup code executed once a WLAN device has been detected
9361
9362 \param - dev - Pointer to the underlying device
9363
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009364 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009365
9366 --------------------------------------------------------------------------*/
9367
9368int hdd_wlan_startup(struct device *dev )
9369{
9370 VOS_STATUS status;
9371 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009372 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 hdd_context_t *pHddCtx = NULL;
9374 v_CONTEXT_t pVosContext= NULL;
9375#ifdef WLAN_BTAMP_FEATURE
9376 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9377 WLANBAP_ConfigType btAmpConfig;
9378 hdd_config_t *pConfig;
9379#endif
9380 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309382 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009383
9384 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 /*
9386 * cfg80211: wiphy allocation
9387 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309388 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009389
9390 if(wiphy == NULL)
9391 {
9392 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009393 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 pHddCtx = wiphy_priv(wiphy);
9396
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 //Initialize the adapter context to zeros.
9398 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9399
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309401 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309402 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009403
9404 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9405
9406 /*Get vos context here bcoz vos_open requires it*/
9407 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9408
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009409 if(pVosContext == NULL)
9410 {
9411 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9412 goto err_free_hdd_context;
9413 }
9414
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 //Save the Global VOSS context in adapter context for future.
9416 pHddCtx->pvosContext = pVosContext;
9417
9418 //Save the adapter context in global context for future.
9419 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9420
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 pHddCtx->parent_dev = dev;
9422
9423 init_completion(&pHddCtx->full_pwr_comp_var);
9424 init_completion(&pHddCtx->standby_comp_var);
9425 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009426 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009427 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309428 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309429 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009430
9431#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009432 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009433#else
9434 init_completion(&pHddCtx->driver_crda_req);
9435#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009436
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309437 spin_lock_init(&pHddCtx->schedScan_lock);
9438
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9440
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309441#ifdef FEATURE_WLAN_TDLS
9442 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9443 * invoked by other instances also) to protect the concurrent
9444 * access for the Adapters by TDLS module.
9445 */
9446 mutex_init(&pHddCtx->tdls_lock);
9447#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309448 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309449 mutex_init(&pHddCtx->wmmLock);
9450
Agarwal Ashish1f422872014-07-22 00:11:55 +05309451 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309452
Agarwal Ashish1f422872014-07-22 00:11:55 +05309453 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 // Load all config first as TL config is needed during vos_open
9455 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9456 if(pHddCtx->cfg_ini == NULL)
9457 {
9458 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9459 goto err_free_hdd_context;
9460 }
9461
9462 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9463
9464 // Read and parse the qcom_cfg.ini file
9465 status = hdd_parse_config_ini( pHddCtx );
9466 if ( VOS_STATUS_SUCCESS != status )
9467 {
9468 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9469 __func__, WLAN_INI_FILE);
9470 goto err_config;
9471 }
Arif Hussaind5218912013-12-05 01:10:55 -08009472#ifdef MEMORY_DEBUG
9473 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9474 vos_mem_init();
9475
9476 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9477 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9478#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009479
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309480 /* INI has been read, initialise the configuredMcastBcastFilter with
9481 * INI value as this will serve as the default value
9482 */
9483 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9484 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9485 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309486
9487 if (false == hdd_is_5g_supported(pHddCtx))
9488 {
9489 //5Ghz is not supported.
9490 if (1 != pHddCtx->cfg_ini->nBandCapability)
9491 {
9492 hddLog(VOS_TRACE_LEVEL_INFO,
9493 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9494 pHddCtx->cfg_ini->nBandCapability = 1;
9495 }
9496 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309497
9498 /* If SNR Monitoring is enabled, FW has to parse all beacons
9499 * for calcaluting and storing the average SNR, so set Nth beacon
9500 * filter to 1 to enable FW to parse all the beaocons
9501 */
9502 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9503 {
9504 /* The log level is deliberately set to WARN as overriding
9505 * nthBeaconFilter to 1 will increase power cosumption and this
9506 * might just prove helpful to detect the power issue.
9507 */
9508 hddLog(VOS_TRACE_LEVEL_WARN,
9509 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9510 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9511 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309513 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009515 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009517 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9518 {
9519 hddLog(VOS_TRACE_LEVEL_FATAL,
9520 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9521 goto err_config;
9522 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009524
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009525 // Update VOS trace levels based upon the cfg.ini
9526 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9527 pHddCtx->cfg_ini->vosTraceEnableBAP);
9528 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9529 pHddCtx->cfg_ini->vosTraceEnableTL);
9530 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9531 pHddCtx->cfg_ini->vosTraceEnableWDI);
9532 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9533 pHddCtx->cfg_ini->vosTraceEnableHDD);
9534 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9535 pHddCtx->cfg_ini->vosTraceEnableSME);
9536 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9537 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309538 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9539 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009540 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9541 pHddCtx->cfg_ini->vosTraceEnableWDA);
9542 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9543 pHddCtx->cfg_ini->vosTraceEnableSYS);
9544 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9545 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009546 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9547 pHddCtx->cfg_ini->vosTraceEnableSAP);
9548 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9549 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009550
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 // Update WDI trace levels based upon the cfg.ini
9552 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9553 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9554 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9555 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9556 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9557 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9558 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9559 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009560
Jeff Johnson88ba7742013-02-27 14:36:02 -08009561 if (VOS_FTM_MODE == hdd_get_conparam())
9562 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9564 {
9565 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9566 goto err_free_hdd_context;
9567 }
9568 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309569 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309570 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009573
Katya Nigame7b69a82015-04-28 15:24:06 +05309574 if( VOS_MONITOR_MODE == hdd_get_conparam())
9575 {
9576 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9577 {
9578 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9579 goto err_free_hdd_context;
9580 }
9581 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9582 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9583 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9584 return VOS_STATUS_SUCCESS;
9585 }
9586
Jeff Johnson88ba7742013-02-27 14:36:02 -08009587 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9589 {
9590 status = vos_watchdog_open(pVosContext,
9591 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9592
9593 if(!VOS_IS_STATUS_SUCCESS( status ))
9594 {
9595 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309596 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 }
9598 }
9599
9600 pHddCtx->isLogpInProgress = FALSE;
9601 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9602
Amar Singhala49cbc52013-10-08 18:37:44 -07009603#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009604 /* initialize the NV module. This is required so that
9605 we can initialize the channel information in wiphy
9606 from the NV.bin data. The channel information in
9607 wiphy needs to be initialized before wiphy registration */
9608
9609 status = vos_nv_open();
9610 if (!VOS_IS_STATUS_SUCCESS(status))
9611 {
9612 /* NV module cannot be initialized */
9613 hddLog( VOS_TRACE_LEVEL_FATAL,
9614 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309615 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009616 }
9617
9618 status = vos_init_wiphy_from_nv_bin();
9619 if (!VOS_IS_STATUS_SUCCESS(status))
9620 {
9621 /* NV module cannot be initialized */
9622 hddLog( VOS_TRACE_LEVEL_FATAL,
9623 "%s: vos_init_wiphy failed", __func__);
9624 goto err_vos_nv_close;
9625 }
9626
Amar Singhala49cbc52013-10-08 18:37:44 -07009627#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309628 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309629 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 if ( !VOS_IS_STATUS_SUCCESS( status ))
9631 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009632 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309633 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009634 }
9635
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9637
9638 if ( NULL == pHddCtx->hHal )
9639 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009640 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 goto err_vosclose;
9642 }
9643
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009644 status = vos_preStart( pHddCtx->pvosContext );
9645 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9646 {
9647 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309648 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009649 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009650
Arif Hussaineaf68602013-12-30 23:10:44 -08009651 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9652 {
9653 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9654 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9655 __func__, enable_dfs_chan_scan);
9656 }
9657 if (0 == enable_11d || 1 == enable_11d)
9658 {
9659 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9660 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9661 __func__, enable_11d);
9662 }
9663
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009664 /* Note that the vos_preStart() sequence triggers the cfg download.
9665 The cfg download must occur before we update the SME config
9666 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 status = hdd_set_sme_config( pHddCtx );
9668
9669 if ( VOS_STATUS_SUCCESS != status )
9670 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009671 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309672 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009674
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 /* In the integrated architecture we update the configuration from
9676 the INI file and from NV before vOSS has been started so that
9677 the final contents are available to send down to the cCPU */
9678
9679 // Apply the cfg.ini to cfg.dat
9680 if (FALSE == hdd_update_config_dat(pHddCtx))
9681 {
9682 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309683 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 }
9685
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309686 // Get mac addr from platform driver
9687 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9688
9689 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309691 /* Store the mac addr for first interface */
9692 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9693
9694 hddLog(VOS_TRACE_LEVEL_ERROR,
9695 "%s: WLAN Mac Addr: "
9696 MAC_ADDRESS_STR, __func__,
9697 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9698
9699 /* Here, passing Arg2 as 1 because we do not want to change the
9700 last 3 bytes (means non OUI bytes) of first interface mac
9701 addr.
9702 */
9703 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9704 {
9705 hddLog(VOS_TRACE_LEVEL_ERROR,
9706 "%s: Failed to generate wlan interface mac addr "
9707 "using MAC from ini file ", __func__);
9708 }
9709 }
9710 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9711 {
9712 // Apply the NV to cfg.dat
9713 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009714#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9715 /* There was not a valid set of MAC Addresses in NV. See if the
9716 default addresses were modified by the cfg.ini settings. If so,
9717 we'll use them, but if not, we'll autogenerate a set of MAC
9718 addresses based upon the device serial number */
9719
9720 static const v_MACADDR_t default_address =
9721 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009722
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309723 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9724 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009725 {
9726 /* cfg.ini has the default address, invoke autogen logic */
9727
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309728 /* Here, passing Arg2 as 0 because we want to change the
9729 last 3 bytes (means non OUI bytes) of all the interfaces
9730 mac addr.
9731 */
9732 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9733 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309735 hddLog(VOS_TRACE_LEVEL_ERROR,
9736 "%s: Failed to generate wlan interface mac addr "
9737 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9738 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 }
9741 else
9742#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9743 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009744 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 "%s: Invalid MAC address in NV, using MAC from ini file "
9746 MAC_ADDRESS_STR, __func__,
9747 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9748 }
9749 }
9750 {
9751 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309752
9753 /* Set the MAC Address Currently this is used by HAL to
9754 * add self sta. Remove this once self sta is added as
9755 * part of session open.
9756 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9758 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9759 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309760
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 if (!HAL_STATUS_SUCCESS( halStatus ))
9762 {
9763 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9764 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309765 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 }
9767 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009768
9769 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9770 Note: Firmware image will be read and downloaded inside vos_start API */
9771 status = vos_start( pHddCtx->pvosContext );
9772 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9773 {
9774 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309775 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 }
9777
Leo Chang6cec3e22014-01-21 15:33:49 -08009778#ifdef FEATURE_WLAN_CH_AVOID
9779 /* Plug in avoid channel notification callback
9780 * This should happen before ADD_SELF_STA
9781 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309782
9783 /* check the Channel Avoidance is enabled */
9784 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9785 {
9786 sme_AddChAvoidCallback(pHddCtx->hHal,
9787 hdd_hostapd_ch_avoid_cb);
9788 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009789#endif /* FEATURE_WLAN_CH_AVOID */
9790
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009791 /* Exchange capability info between Host and FW and also get versioning info from FW */
9792 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009793
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309794#ifdef CONFIG_ENABLE_LINUX_REG
9795 status = wlan_hdd_init_channels(pHddCtx);
9796 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9797 {
9798 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9799 __func__);
9800 goto err_vosstop;
9801 }
9802#endif
9803
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 status = hdd_post_voss_start_config( pHddCtx );
9805 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9806 {
9807 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9808 __func__);
9809 goto err_vosstop;
9810 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009811
9812#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309813 wlan_hdd_cfg80211_update_reg_info( wiphy );
9814
9815 /* registration of wiphy dev with cfg80211 */
9816 if (0 > wlan_hdd_cfg80211_register(wiphy))
9817 {
9818 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9819 goto err_vosstop;
9820 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009822
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309823#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309824 /* registration of wiphy dev with cfg80211 */
9825 if (0 > wlan_hdd_cfg80211_register(wiphy))
9826 {
9827 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9828 goto err_vosstop;
9829 }
9830
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309831 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309832 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9833 {
9834 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9835 __func__);
9836 goto err_unregister_wiphy;
9837 }
9838#endif
9839
c_hpothu4a298be2014-12-22 21:12:51 +05309840 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9841
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9843 {
9844 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9845 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9846 }
9847 else
9848 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9850 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9851 if (pAdapter != NULL)
9852 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309853 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309855 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9856 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9857 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009858
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309859 /* Generate the P2P Device Address. This consists of the device's
9860 * primary MAC address with the locally administered bit set.
9861 */
9862 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009863 }
9864 else
9865 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309866 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9867 if (p2p_dev_addr != NULL)
9868 {
9869 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9870 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9871 }
9872 else
9873 {
9874 hddLog(VOS_TRACE_LEVEL_FATAL,
9875 "%s: Failed to allocate mac_address for p2p_device",
9876 __func__);
9877 goto err_close_adapter;
9878 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009880
9881 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9882 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9883 if ( NULL == pP2pAdapter )
9884 {
9885 hddLog(VOS_TRACE_LEVEL_FATAL,
9886 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009887 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009888 goto err_close_adapter;
9889 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009890 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009892
9893 if( pAdapter == NULL )
9894 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009895 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9896 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009898
Arif Hussain66559122013-11-21 10:11:40 -08009899 if (country_code)
9900 {
9901 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009902 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009903 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9904#ifndef CONFIG_ENABLE_LINUX_REG
9905 hdd_checkandupdate_phymode(pAdapter, country_code);
9906#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009907 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9908 (void *)(tSmeChangeCountryCallback)
9909 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009910 country_code,
9911 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309912 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009913 if (eHAL_STATUS_SUCCESS == ret)
9914 {
Arif Hussaincb607082013-12-20 11:57:42 -08009915 ret = wait_for_completion_interruptible_timeout(
9916 &pAdapter->change_country_code,
9917 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9918
9919 if (0 >= ret)
9920 {
9921 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9922 "%s: SME while setting country code timed out", __func__);
9923 }
Arif Hussain66559122013-11-21 10:11:40 -08009924 }
9925 else
9926 {
Arif Hussaincb607082013-12-20 11:57:42 -08009927 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9928 "%s: SME Change Country code from module param fail ret=%d",
9929 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009930 }
9931 }
9932
Jeff Johnson295189b2012-06-20 16:38:30 -07009933#ifdef WLAN_BTAMP_FEATURE
9934 vStatus = WLANBAP_Open(pVosContext);
9935 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9936 {
9937 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9938 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009939 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 }
9941
9942 vStatus = BSL_Init(pVosContext);
9943 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9944 {
9945 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9946 "%s: Failed to Init BSL",__func__);
9947 goto err_bap_close;
9948 }
9949 vStatus = WLANBAP_Start(pVosContext);
9950 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9951 {
9952 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9953 "%s: Failed to start TL",__func__);
9954 goto err_bap_close;
9955 }
9956
9957 pConfig = pHddCtx->cfg_ini;
9958 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9959 status = WLANBAP_SetConfig(&btAmpConfig);
9960
9961#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009962
Mihir Shete9c238772014-10-15 14:35:16 +05309963 /*
9964 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9965 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9966 * which is greater than 0xf. So the below check is safe to make
9967 * sure that there is no entry for UapsdMask in the ini
9968 */
9969 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9970 {
9971 if(IS_DYNAMIC_WMM_PS_ENABLED)
9972 {
9973 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9974 __func__);
9975 pHddCtx->cfg_ini->UapsdMask =
9976 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9977 }
9978 else
9979 {
9980 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9981 __func__);
9982 pHddCtx->cfg_ini->UapsdMask =
9983 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9984 }
9985 }
9986
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009987#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9988 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9989 {
9990 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9991 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9992 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9993 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9994 }
9995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009996
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309997 wlan_hdd_tdls_init(pHddCtx);
9998
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309999 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10000
Jeff Johnson295189b2012-06-20 16:38:30 -070010001 /* Register with platform driver as client for Suspend/Resume */
10002 status = hddRegisterPmOps(pHddCtx);
10003 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10004 {
10005 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10006#ifdef WLAN_BTAMP_FEATURE
10007 goto err_bap_stop;
10008#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010009 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010010#endif //WLAN_BTAMP_FEATURE
10011 }
10012
Yue Ma0d4891e2013-08-06 17:01:45 -070010013 /* Open debugfs interface */
10014 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10015 {
10016 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10017 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010018 }
10019
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 /* Register TM level change handler function to the platform */
10021 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10022 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10023 {
10024 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10025 goto err_unregister_pmops;
10026 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010027
10028 /* register for riva power on lock to platform driver */
10029 if (req_riva_power_on_lock("wlan"))
10030 {
10031 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
10032 __func__);
10033 goto err_unregister_pmops;
10034 }
10035
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 // register net device notifier for device change notification
10037 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10038
10039 if(ret < 0)
10040 {
10041 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
10042 goto err_free_power_on_lock;
10043 }
10044
10045 //Initialize the nlink service
10046 if(nl_srv_init() != 0)
10047 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010048 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 goto err_reg_netdev;
10050 }
10051
Leo Chang4ce1cc52013-10-21 18:27:15 -070010052#ifdef WLAN_KD_READY_NOTIFIER
10053 pHddCtx->kd_nl_init = 1;
10054#endif /* WLAN_KD_READY_NOTIFIER */
10055
Jeff Johnson295189b2012-06-20 16:38:30 -070010056 //Initialize the BTC service
10057 if(btc_activate_service(pHddCtx) != 0)
10058 {
10059 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10060 goto err_nl_srv;
10061 }
10062
10063#ifdef PTT_SOCK_SVC_ENABLE
10064 //Initialize the PTT service
10065 if(ptt_sock_activate_svc(pHddCtx) != 0)
10066 {
10067 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10068 goto err_nl_srv;
10069 }
10070#endif
10071
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010072#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10073 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10074 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010075 if(wlan_logging_sock_activate_svc(
10076 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10077 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10078 {
10079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10080 " failed", __func__);
10081 goto err_nl_srv;
10082 }
10083 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10084 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010085 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10086 pHddCtx->cfg_ini->gEnableDebugLog =
10087 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010088 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010089
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010090 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10091 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010092 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010093 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010094 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010095 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010096 }
10097 else
10098 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010099 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010100 }
10101
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010102#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010103
10104
Sushant Kaushik215778f2015-05-21 14:05:36 +053010105 if (vos_is_multicast_logging())
10106 wlan_logging_set_log_level();
10107
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010110 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010111 /* Action frame registered in one adapter which will
10112 * applicable to all interfaces
10113 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010114 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010116
10117 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010118 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010119
Jeff Johnsone7245742012-09-05 17:12:55 -070010120#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10121 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010122 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010123 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010124
Jeff Johnsone7245742012-09-05 17:12:55 -070010125#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010126 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010127 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010128 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010129
Jeff Johnsone7245742012-09-05 17:12:55 -070010130
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010131 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10132 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
Katya Nigam5c306ea2014-06-19 15:39:54 +053010134 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010135 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010136 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010137
10138#ifdef FEATURE_WLAN_SCAN_PNO
10139 /*SME must send channel update configuration to RIVA*/
10140 sme_UpdateChannelConfig(pHddCtx->hHal);
10141#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010142 /* Send the update default channel list to the FW*/
10143 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010144
10145 /* Fwr capabilities received, Set the Dot11 mode */
10146 sme_SetDefDot11Mode(pHddCtx->hHal);
10147
Abhishek Singha306a442013-11-07 18:39:01 +053010148#ifndef CONFIG_ENABLE_LINUX_REG
10149 /*updating wiphy so that regulatory user hints can be processed*/
10150 if (wiphy)
10151 {
10152 regulatory_hint(wiphy, "00");
10153 }
10154#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010155 // Initialize the restart logic
10156 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010157
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010158 //Register the traffic monitor timer now
10159 if ( pHddCtx->cfg_ini->dynSplitscan)
10160 {
10161 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10162 VOS_TIMER_TYPE_SW,
10163 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10164 (void *)pHddCtx);
10165 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010166 wlan_hdd_cfg80211_nan_init(pHddCtx);
10167
Dino Mycle6fb96c12014-06-10 11:52:40 +053010168#ifdef WLAN_FEATURE_EXTSCAN
10169 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10170 wlan_hdd_cfg80211_extscan_callback,
10171 pHddCtx);
10172#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010173
10174#ifdef WLAN_NS_OFFLOAD
10175 // Register IPv6 notifier to notify if any change in IP
10176 // So that we can reconfigure the offload parameters
10177 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10178 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10179 if (ret)
10180 {
10181 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10182 }
10183 else
10184 {
10185 hddLog(LOGE, FL("Registered IPv6 notifier"));
10186 }
10187#endif
10188
10189 // Register IPv4 notifier to notify if any change in IP
10190 // So that we can reconfigure the offload parameters
10191 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10192 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10193 if (ret)
10194 {
10195 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10196 }
10197 else
10198 {
10199 hddLog(LOGE, FL("Registered IPv4 notifier"));
10200 }
10201
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 goto success;
10203
10204err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010205#ifdef WLAN_KD_READY_NOTIFIER
10206 nl_srv_exit(pHddCtx->ptt_pid);
10207#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010208 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010209#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010210err_reg_netdev:
10211 unregister_netdevice_notifier(&hdd_netdev_notifier);
10212
10213err_free_power_on_lock:
10214 free_riva_power_on_lock("wlan");
10215
10216err_unregister_pmops:
10217 hddDevTmUnregisterNotifyCallback(pHddCtx);
10218 hddDeregisterPmOps(pHddCtx);
10219
Yue Ma0d4891e2013-08-06 17:01:45 -070010220 hdd_debugfs_exit(pHddCtx);
10221
Jeff Johnson295189b2012-06-20 16:38:30 -070010222#ifdef WLAN_BTAMP_FEATURE
10223err_bap_stop:
10224 WLANBAP_Stop(pVosContext);
10225#endif
10226
10227#ifdef WLAN_BTAMP_FEATURE
10228err_bap_close:
10229 WLANBAP_Close(pVosContext);
10230#endif
10231
Jeff Johnson295189b2012-06-20 16:38:30 -070010232err_close_adapter:
10233 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010234#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010235err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010236#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010237 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010238err_vosstop:
10239 vos_stop(pVosContext);
10240
Amar Singhala49cbc52013-10-08 18:37:44 -070010241err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 status = vos_sched_close( pVosContext );
10243 if (!VOS_IS_STATUS_SUCCESS(status)) {
10244 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10245 "%s: Failed to close VOSS Scheduler", __func__);
10246 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10247 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010248 vos_close(pVosContext );
10249
Amar Singhal0a402232013-10-11 20:57:16 -070010250err_vos_nv_close:
10251
c_hpothue6a36282014-03-19 12:27:38 +053010252#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010253 vos_nv_close();
10254
c_hpothu70f8d812014-03-22 22:59:23 +053010255#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010256
10257err_wdclose:
10258 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10259 vos_watchdog_close(pVosContext);
10260
Jeff Johnson295189b2012-06-20 16:38:30 -070010261err_config:
10262 kfree(pHddCtx->cfg_ini);
10263 pHddCtx->cfg_ini= NULL;
10264
10265err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010266 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 wiphy_free(wiphy) ;
10268 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 VOS_BUG(1);
10270
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010271 if (hdd_is_ssr_required())
10272 {
10273 /* WDI timeout had happened during load, so SSR is needed here */
10274 subsystem_restart("wcnss");
10275 msleep(5000);
10276 }
10277 hdd_set_ssr_required (VOS_FALSE);
10278
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010279 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010280
10281success:
10282 EXIT();
10283 return 0;
10284}
10285
10286/**---------------------------------------------------------------------------
10287
Jeff Johnson32d95a32012-09-10 13:15:23 -070010288 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010289
Jeff Johnson32d95a32012-09-10 13:15:23 -070010290 This is the driver entry point - called in different timeline depending
10291 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010292
10293 \param - None
10294
10295 \return - 0 for success, non zero for failure
10296
10297 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010298static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010299{
10300 VOS_STATUS status;
10301 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 struct device *dev = NULL;
10303 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010304#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10305 int max_retries = 0;
10306#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010307#ifdef HAVE_CBC_DONE
10308 int max_cbc_retries = 0;
10309#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010310
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010311#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10312 wlan_logging_sock_init_svc();
10313#endif
10314
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 ENTER();
10316
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010317 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010318
10319 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10320 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10321
Jeff Johnson295189b2012-06-20 16:38:30 -070010322#ifdef ANI_BUS_TYPE_PCI
10323
10324 dev = wcnss_wlan_get_device();
10325
10326#endif // ANI_BUS_TYPE_PCI
10327
10328#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010329
10330#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10331 /* wait until WCNSS driver downloads NV */
10332 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10333 msleep(1000);
10334 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010335
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010336 if (max_retries >= 5) {
10337 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010338 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010339#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10340 wlan_logging_sock_deinit_svc();
10341#endif
10342
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010343 return -ENODEV;
10344 }
10345#endif
10346
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010347#ifdef HAVE_CBC_DONE
10348 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10349 msleep(1000);
10350 }
10351 if (max_cbc_retries >= 10) {
10352 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10353 }
10354#endif
10355
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 dev = wcnss_wlan_get_device();
10357#endif // ANI_BUS_TYPE_PLATFORM
10358
10359
10360 do {
10361 if (NULL == dev) {
10362 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10363 ret_status = -1;
10364 break;
10365 }
10366
Jeff Johnson295189b2012-06-20 16:38:30 -070010367#ifdef TIMER_MANAGER
10368 vos_timer_manager_init();
10369#endif
10370
10371 /* Preopen VOSS so that it is ready to start at least SAL */
10372 status = vos_preOpen(&pVosContext);
10373
10374 if (!VOS_IS_STATUS_SUCCESS(status))
10375 {
10376 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10377 ret_status = -1;
10378 break;
10379 }
10380
Sushant Kaushik02beb352015-06-04 15:15:01 +053010381 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010382#ifndef MODULE
10383 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10384 */
10385 hdd_set_conparam((v_UINT_t)con_mode);
10386#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010387
10388 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010389 if (hdd_wlan_startup(dev))
10390 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010391 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010392 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010393 vos_preClose( &pVosContext );
10394 ret_status = -1;
10395 break;
10396 }
10397
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 } while (0);
10399
10400 if (0 != ret_status)
10401 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010402#ifdef TIMER_MANAGER
10403 vos_timer_exit();
10404#endif
10405#ifdef MEMORY_DEBUG
10406 vos_mem_exit();
10407#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010408 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010409#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10410 wlan_logging_sock_deinit_svc();
10411#endif
10412
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10414 }
10415 else
10416 {
10417 //Send WLAN UP indication to Nlink Service
10418 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10419
10420 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 }
10422
10423 EXIT();
10424
10425 return ret_status;
10426}
10427
Jeff Johnson32d95a32012-09-10 13:15:23 -070010428/**---------------------------------------------------------------------------
10429
10430 \brief hdd_module_init() - Init Function
10431
10432 This is the driver entry point (invoked when module is loaded using insmod)
10433
10434 \param - None
10435
10436 \return - 0 for success, non zero for failure
10437
10438 --------------------------------------------------------------------------*/
10439#ifdef MODULE
10440static int __init hdd_module_init ( void)
10441{
10442 return hdd_driver_init();
10443}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010444#else /* #ifdef MODULE */
10445static int __init hdd_module_init ( void)
10446{
10447 /* Driver initialization is delayed to fwpath_changed_handler */
10448 return 0;
10449}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010450#endif /* #ifdef MODULE */
10451
Jeff Johnson295189b2012-06-20 16:38:30 -070010452
10453/**---------------------------------------------------------------------------
10454
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010455 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010456
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010457 This is the driver exit point (invoked when module is unloaded using rmmod
10458 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010459
10460 \param - None
10461
10462 \return - None
10463
10464 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010465static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010466{
10467 hdd_context_t *pHddCtx = NULL;
10468 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010469 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010470 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010471
10472 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10473
10474 //Get the global vos context
10475 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10476
10477 if(!pVosContext)
10478 {
10479 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10480 goto done;
10481 }
10482
10483 //Get the HDD context.
10484 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10485
10486 if(!pHddCtx)
10487 {
10488 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10489 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010490 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10491 {
10492 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10493 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10494 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10495 hdd_wlan_exit(pHddCtx);
10496 vos_preClose( &pVosContext );
10497 goto done;
10498 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 else
10500 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010501 /* We wait for active entry threads to exit from driver
10502 * by waiting until rtnl_lock is available.
10503 */
10504 rtnl_lock();
10505 rtnl_unlock();
10506
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010507 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10508 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10509 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10510 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010512 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010513 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10514 msecs_to_jiffies(30000));
10515 if(!rc)
10516 {
10517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10518 "%s:SSR timedout, fatal error", __func__);
10519 VOS_BUG(0);
10520 }
10521 }
10522
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010523 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10524 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010525
c_hpothu8adb97b2014-12-08 19:38:20 +053010526 /* Driver Need to send country code 00 in below condition
10527 * 1) If gCountryCodePriority is set to 1; and last country
10528 * code set is through 11d. This needs to be done in case
10529 * when NV country code is 00.
10530 * This Needs to be done as when kernel store last country
10531 * code and if stored country code is not through 11d,
10532 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10533 * in next load/unload as soon as we get any country through
10534 * 11d. In sme_HandleChangeCountryCodeByUser
10535 * pMsg->countryCode will be last countryCode and
10536 * pMac->scan.countryCode11d will be country through 11d so
10537 * due to mismatch driver will disable 11d.
10538 *
10539 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010540
c_hpothu8adb97b2014-12-08 19:38:20 +053010541 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010542 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010543 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010544 {
10545 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010546 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010547 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10548 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010549
c_hpothu8adb97b2014-12-08 19:38:20 +053010550 //Do all the cleanup before deregistering the driver
10551 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 }
10553
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 vos_preClose( &pVosContext );
10555
10556#ifdef TIMER_MANAGER
10557 vos_timer_exit();
10558#endif
10559#ifdef MEMORY_DEBUG
10560 vos_mem_exit();
10561#endif
10562
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010563#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10564 wlan_logging_sock_deinit_svc();
10565#endif
10566
Jeff Johnson295189b2012-06-20 16:38:30 -070010567done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010568 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010569
Jeff Johnson295189b2012-06-20 16:38:30 -070010570 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10571}
10572
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010573/**---------------------------------------------------------------------------
10574
10575 \brief hdd_module_exit() - Exit function
10576
10577 This is the driver exit point (invoked when module is unloaded using rmmod)
10578
10579 \param - None
10580
10581 \return - None
10582
10583 --------------------------------------------------------------------------*/
10584static void __exit hdd_module_exit(void)
10585{
10586 hdd_driver_exit();
10587}
10588
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010589#ifdef MODULE
10590static int fwpath_changed_handler(const char *kmessage,
10591 struct kernel_param *kp)
10592{
Jeff Johnson76052702013-04-16 13:55:05 -070010593 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010594}
10595
10596static int con_mode_handler(const char *kmessage,
10597 struct kernel_param *kp)
10598{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010599 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010600}
10601#else /* #ifdef MODULE */
10602/**---------------------------------------------------------------------------
10603
Jeff Johnson76052702013-04-16 13:55:05 -070010604 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010605
Jeff Johnson76052702013-04-16 13:55:05 -070010606 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010607 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010608 - invoked when module parameter fwpath is modified from userspace to signal
10609 initializing the WLAN driver or when con_mode is modified from userspace
10610 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010611
10612 \return - 0 for success, non zero for failure
10613
10614 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010615static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010616{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010617 int ret_status;
10618
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010619 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010620 ret_status = hdd_driver_init();
10621 wlan_hdd_inited = ret_status ? 0 : 1;
10622 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010623 }
10624
10625 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010626
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010627 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010628
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010629 ret_status = hdd_driver_init();
10630 wlan_hdd_inited = ret_status ? 0 : 1;
10631 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010632}
10633
Jeff Johnson295189b2012-06-20 16:38:30 -070010634/**---------------------------------------------------------------------------
10635
Jeff Johnson76052702013-04-16 13:55:05 -070010636 \brief fwpath_changed_handler() - Handler Function
10637
10638 Handle changes to the fwpath parameter
10639
10640 \return - 0 for success, non zero for failure
10641
10642 --------------------------------------------------------------------------*/
10643static int fwpath_changed_handler(const char *kmessage,
10644 struct kernel_param *kp)
10645{
10646 int ret;
10647
10648 ret = param_set_copystring(kmessage, kp);
10649 if (0 == ret)
10650 ret = kickstart_driver();
10651 return ret;
10652}
10653
10654/**---------------------------------------------------------------------------
10655
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010656 \brief con_mode_handler() -
10657
10658 Handler function for module param con_mode when it is changed by userspace
10659 Dynamically linked - do nothing
10660 Statically linked - exit and init driver, as in rmmod and insmod
10661
Jeff Johnson76052702013-04-16 13:55:05 -070010662 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010663
Jeff Johnson76052702013-04-16 13:55:05 -070010664 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010665
10666 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010667static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010668{
Jeff Johnson76052702013-04-16 13:55:05 -070010669 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010670
Jeff Johnson76052702013-04-16 13:55:05 -070010671 ret = param_set_int(kmessage, kp);
10672 if (0 == ret)
10673 ret = kickstart_driver();
10674 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010675}
10676#endif /* #ifdef MODULE */
10677
10678/**---------------------------------------------------------------------------
10679
Jeff Johnson295189b2012-06-20 16:38:30 -070010680 \brief hdd_get_conparam() -
10681
10682 This is the driver exit point (invoked when module is unloaded using rmmod)
10683
10684 \param - None
10685
10686 \return - tVOS_CON_MODE
10687
10688 --------------------------------------------------------------------------*/
10689tVOS_CON_MODE hdd_get_conparam ( void )
10690{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010691#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010692 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010693#else
10694 return (tVOS_CON_MODE)curr_con_mode;
10695#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010696}
10697void hdd_set_conparam ( v_UINT_t newParam )
10698{
10699 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010700#ifndef MODULE
10701 curr_con_mode = con_mode;
10702#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010703}
10704/**---------------------------------------------------------------------------
10705
10706 \brief hdd_softap_sta_deauth() - function
10707
10708 This to take counter measure to handle deauth req from HDD
10709
10710 \param - pAdapter - Pointer to the HDD
10711
10712 \param - enable - boolean value
10713
10714 \return - None
10715
10716 --------------------------------------------------------------------------*/
10717
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010718VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10719 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010720{
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010722 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010723
10724 ENTER();
10725
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010726 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10727 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010728
10729 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010730 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010731 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010732
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010733 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010734
10735 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010736 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010737}
10738
10739/**---------------------------------------------------------------------------
10740
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010741 \brief hdd_del_all_sta() - function
10742
10743 This function removes all the stations associated on stopping AP/P2P GO.
10744
10745 \param - pAdapter - Pointer to the HDD
10746
10747 \return - None
10748
10749 --------------------------------------------------------------------------*/
10750
10751int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10752{
10753 v_U16_t i;
10754 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010755 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10756 ptSapContext pSapCtx = NULL;
10757 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10758 if(pSapCtx == NULL){
10759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10760 FL("psapCtx is NULL"));
10761 return 1;
10762 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010763 ENTER();
10764
10765 hddLog(VOS_TRACE_LEVEL_INFO,
10766 "%s: Delete all STAs associated.",__func__);
10767 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10768 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10769 )
10770 {
10771 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10772 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010773 if ((pSapCtx->aStaInfo[i].isUsed) &&
10774 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010775 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010776 struct tagCsrDelStaParams delStaParams;
10777
10778 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010779 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010780 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10781 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010782 &delStaParams);
10783 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010784 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010785 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010786 }
10787 }
10788 }
10789
10790 EXIT();
10791 return 0;
10792}
10793
10794/**---------------------------------------------------------------------------
10795
Jeff Johnson295189b2012-06-20 16:38:30 -070010796 \brief hdd_softap_sta_disassoc() - function
10797
10798 This to take counter measure to handle deauth req from HDD
10799
10800 \param - pAdapter - Pointer to the HDD
10801
10802 \param - enable - boolean value
10803
10804 \return - None
10805
10806 --------------------------------------------------------------------------*/
10807
10808void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10809{
10810 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10811
10812 ENTER();
10813
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010814 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010815
10816 //Ignore request to disassoc bcmc station
10817 if( pDestMacAddress[0] & 0x1 )
10818 return;
10819
10820 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10821}
10822
10823void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10824{
10825 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10826
10827 ENTER();
10828
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010829 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010830
10831 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10832}
10833
Jeff Johnson295189b2012-06-20 16:38:30 -070010834/**---------------------------------------------------------------------------
10835 *
10836 * \brief hdd_get__concurrency_mode() -
10837 *
10838 *
10839 * \param - None
10840 *
10841 * \return - CONCURRENCY MODE
10842 *
10843 * --------------------------------------------------------------------------*/
10844tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10845{
10846 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10847 hdd_context_t *pHddCtx;
10848
10849 if (NULL != pVosContext)
10850 {
10851 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10852 if (NULL != pHddCtx)
10853 {
10854 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10855 }
10856 }
10857
10858 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010859 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 return VOS_STA;
10861}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010862v_BOOL_t
10863wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10864{
10865 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010866
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010867 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10868 if (pAdapter == NULL)
10869 {
10870 hddLog(VOS_TRACE_LEVEL_INFO,
10871 FL("GO doesn't exist"));
10872 return TRUE;
10873 }
10874 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10875 {
10876 hddLog(VOS_TRACE_LEVEL_INFO,
10877 FL("GO started"));
10878 return TRUE;
10879 }
10880 else
10881 /* wait till GO changes its interface to p2p device */
10882 hddLog(VOS_TRACE_LEVEL_INFO,
10883 FL("Del_bss called, avoid apps suspend"));
10884 return FALSE;
10885
10886}
Jeff Johnson295189b2012-06-20 16:38:30 -070010887/* Decide whether to allow/not the apps power collapse.
10888 * Allow apps power collapse if we are in connected state.
10889 * if not, allow only if we are in IMPS */
10890v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10891{
10892 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010893 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010894 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010895 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10896 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10897 hdd_adapter_t *pAdapter = NULL;
10898 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010899 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010900
Jeff Johnson295189b2012-06-20 16:38:30 -070010901 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10902 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010903
Yathish9f22e662012-12-10 14:21:35 -080010904 concurrent_state = hdd_get_concurrency_mode();
10905
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010906 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10907 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10908 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010909#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010910
Yathish9f22e662012-12-10 14:21:35 -080010911 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010912 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010913 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10914 return TRUE;
10915#endif
10916
Jeff Johnson295189b2012-06-20 16:38:30 -070010917 /*loop through all adapters. TBD fix for Concurrency */
10918 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10919 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10920 {
10921 pAdapter = pAdapterNode->pAdapter;
10922 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10923 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10924 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010925 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010926 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010927 && pmcState != STOPPED && pmcState != STANDBY &&
10928 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010929 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10930 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010931 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010932 if(pmcState == FULL_POWER &&
10933 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10934 {
10935 /*
10936 * When SCO indication comes from Coex module , host will
10937 * enter in to full power mode, but this should not prevent
10938 * apps processor power collapse.
10939 */
10940 hddLog(LOG1,
10941 FL("Allow apps power collapse"
10942 "even when sco indication is set"));
10943 return TRUE;
10944 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010945 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010946 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10947 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010948 return FALSE;
10949 }
10950 }
10951 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10952 pAdapterNode = pNext;
10953 }
10954 return TRUE;
10955}
10956
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010957/* Decides whether to send suspend notification to Riva
10958 * if any adapter is in BMPS; then it is required */
10959v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10960{
10961 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10962 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10963
10964 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10965 {
10966 return TRUE;
10967 }
10968 return FALSE;
10969}
10970
Jeff Johnson295189b2012-06-20 16:38:30 -070010971void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10972{
10973 switch(mode)
10974 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010975 case VOS_STA_MODE:
10976 case VOS_P2P_CLIENT_MODE:
10977 case VOS_P2P_GO_MODE:
10978 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010979 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010980 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 break;
10982 default:
10983 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010985 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10986 "Number of open sessions for mode %d = %d"),
10987 pHddCtx->concurrency_mode, mode,
10988 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010989}
10990
10991
10992void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10993{
10994 switch(mode)
10995 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010996 case VOS_STA_MODE:
10997 case VOS_P2P_CLIENT_MODE:
10998 case VOS_P2P_GO_MODE:
10999 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011000 pHddCtx->no_of_open_sessions[mode]--;
11001 if (!(pHddCtx->no_of_open_sessions[mode]))
11002 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011003 break;
11004 default:
11005 break;
11006 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011007 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11008 "Number of open sessions for mode %d = %d"),
11009 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11010
11011}
11012/**---------------------------------------------------------------------------
11013 *
11014 * \brief wlan_hdd_incr_active_session()
11015 *
11016 * This function increments the number of active sessions
11017 * maintained per device mode
11018 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11019 * Incase of SAP/P2P GO upon bss start it is incremented
11020 *
11021 * \param pHddCtx - HDD Context
11022 * \param mode - device mode
11023 *
11024 * \return - None
11025 *
11026 * --------------------------------------------------------------------------*/
11027void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11028{
11029 switch (mode) {
11030 case VOS_STA_MODE:
11031 case VOS_P2P_CLIENT_MODE:
11032 case VOS_P2P_GO_MODE:
11033 case VOS_STA_SAP_MODE:
11034 pHddCtx->no_of_active_sessions[mode]++;
11035 break;
11036 default:
11037 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11038 break;
11039 }
11040 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11041 mode,
11042 pHddCtx->no_of_active_sessions[mode]);
11043}
11044
11045/**---------------------------------------------------------------------------
11046 *
11047 * \brief wlan_hdd_decr_active_session()
11048 *
11049 * This function decrements the number of active sessions
11050 * maintained per device mode
11051 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11052 * Incase of SAP/P2P GO upon bss stop it is decremented
11053 *
11054 * \param pHddCtx - HDD Context
11055 * \param mode - device mode
11056 *
11057 * \return - None
11058 *
11059 * --------------------------------------------------------------------------*/
11060void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11061{
11062 switch (mode) {
11063 case VOS_STA_MODE:
11064 case VOS_P2P_CLIENT_MODE:
11065 case VOS_P2P_GO_MODE:
11066 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011067 if (pHddCtx->no_of_active_sessions[mode] > 0)
11068 pHddCtx->no_of_active_sessions[mode]--;
11069 else
11070 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11071 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011072 break;
11073 default:
11074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11075 break;
11076 }
11077 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11078 mode,
11079 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011080}
11081
Jeff Johnsone7245742012-09-05 17:12:55 -070011082/**---------------------------------------------------------------------------
11083 *
11084 * \brief wlan_hdd_restart_init
11085 *
11086 * This function initalizes restart timer/flag. An internal function.
11087 *
11088 * \param - pHddCtx
11089 *
11090 * \return - None
11091 *
11092 * --------------------------------------------------------------------------*/
11093
11094static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11095{
11096 /* Initialize */
11097 pHddCtx->hdd_restart_retries = 0;
11098 atomic_set(&pHddCtx->isRestartInProgress, 0);
11099 vos_timer_init(&pHddCtx->hdd_restart_timer,
11100 VOS_TIMER_TYPE_SW,
11101 wlan_hdd_restart_timer_cb,
11102 pHddCtx);
11103}
11104/**---------------------------------------------------------------------------
11105 *
11106 * \brief wlan_hdd_restart_deinit
11107 *
11108 * This function cleans up the resources used. An internal function.
11109 *
11110 * \param - pHddCtx
11111 *
11112 * \return - None
11113 *
11114 * --------------------------------------------------------------------------*/
11115
11116static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11117{
11118
11119 VOS_STATUS vos_status;
11120 /* Block any further calls */
11121 atomic_set(&pHddCtx->isRestartInProgress, 1);
11122 /* Cleanup */
11123 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11124 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011125 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011126 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11127 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011128 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011129
11130}
11131
11132/**---------------------------------------------------------------------------
11133 *
11134 * \brief wlan_hdd_framework_restart
11135 *
11136 * This function uses a cfg80211 API to start a framework initiated WLAN
11137 * driver module unload/load.
11138 *
11139 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11140 *
11141 *
11142 * \param - pHddCtx
11143 *
11144 * \return - VOS_STATUS_SUCCESS: Success
11145 * VOS_STATUS_E_EMPTY: Adapter is Empty
11146 * VOS_STATUS_E_NOMEM: No memory
11147
11148 * --------------------------------------------------------------------------*/
11149
11150static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11151{
11152 VOS_STATUS status = VOS_STATUS_SUCCESS;
11153 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011154 int len = (sizeof (struct ieee80211_mgmt));
11155 struct ieee80211_mgmt *mgmt = NULL;
11156
11157 /* Prepare the DEAUTH managment frame with reason code */
11158 mgmt = kzalloc(len, GFP_KERNEL);
11159 if(mgmt == NULL)
11160 {
11161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11162 "%s: memory allocation failed (%d bytes)", __func__, len);
11163 return VOS_STATUS_E_NOMEM;
11164 }
11165 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011166
11167 /* Iterate over all adapters/devices */
11168 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011169 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11170 {
11171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11172 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11173 goto end;
11174 }
11175
Jeff Johnsone7245742012-09-05 17:12:55 -070011176 do
11177 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011178 if(pAdapterNode->pAdapter &&
11179 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011180 {
11181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11182 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11183 pAdapterNode->pAdapter->dev->name,
11184 pAdapterNode->pAdapter->device_mode,
11185 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011186 /*
11187 * CFG80211 event to restart the driver
11188 *
11189 * 'cfg80211_send_unprot_deauth' sends a
11190 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11191 * of SME(Linux Kernel) state machine.
11192 *
11193 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11194 * the driver.
11195 *
11196 */
11197
11198 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011199 }
11200 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11201 pAdapterNode = pNext;
11202 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11203
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011204 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011205 /* Free the allocated management frame */
11206 kfree(mgmt);
11207
Jeff Johnsone7245742012-09-05 17:12:55 -070011208 /* Retry until we unload or reach max count */
11209 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11210 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11211
11212 return status;
11213
11214}
11215/**---------------------------------------------------------------------------
11216 *
11217 * \brief wlan_hdd_restart_timer_cb
11218 *
11219 * Restart timer callback. An internal function.
11220 *
11221 * \param - User data:
11222 *
11223 * \return - None
11224 *
11225 * --------------------------------------------------------------------------*/
11226
11227void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11228{
11229 hdd_context_t *pHddCtx = usrDataForCallback;
11230 wlan_hdd_framework_restart(pHddCtx);
11231 return;
11232
11233}
11234
11235
11236/**---------------------------------------------------------------------------
11237 *
11238 * \brief wlan_hdd_restart_driver
11239 *
11240 * This function sends an event to supplicant to restart the WLAN driver.
11241 *
11242 * This function is called from vos_wlanRestart.
11243 *
11244 * \param - pHddCtx
11245 *
11246 * \return - VOS_STATUS_SUCCESS: Success
11247 * VOS_STATUS_E_EMPTY: Adapter is Empty
11248 * VOS_STATUS_E_ALREADY: Request already in progress
11249
11250 * --------------------------------------------------------------------------*/
11251VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11252{
11253 VOS_STATUS status = VOS_STATUS_SUCCESS;
11254
11255 /* A tight check to make sure reentrancy */
11256 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11257 {
Mihir Shetefd528652014-06-23 19:07:50 +053011258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011259 "%s: WLAN restart is already in progress", __func__);
11260
11261 return VOS_STATUS_E_ALREADY;
11262 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011263 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011264#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011265 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011266#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011267
Jeff Johnsone7245742012-09-05 17:12:55 -070011268 return status;
11269}
11270
Mihir Shetee1093ba2014-01-21 20:13:32 +053011271/**---------------------------------------------------------------------------
11272 *
11273 * \brief wlan_hdd_init_channels
11274 *
11275 * This function is used to initialize the channel list in CSR
11276 *
11277 * This function is called from hdd_wlan_startup
11278 *
11279 * \param - pHddCtx: HDD context
11280 *
11281 * \return - VOS_STATUS_SUCCESS: Success
11282 * VOS_STATUS_E_FAULT: Failure reported by SME
11283
11284 * --------------------------------------------------------------------------*/
11285static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11286{
11287 eHalStatus status;
11288
11289 status = sme_InitChannels(pHddCtx->hHal);
11290 if (HAL_STATUS_SUCCESS(status))
11291 {
11292 return VOS_STATUS_SUCCESS;
11293 }
11294 else
11295 {
11296 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11297 __func__, status);
11298 return VOS_STATUS_E_FAULT;
11299 }
11300}
11301
Mihir Shete04206452014-11-20 17:50:58 +053011302#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011303VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011304{
11305 eHalStatus status;
11306
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011307 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011308 if (HAL_STATUS_SUCCESS(status))
11309 {
11310 return VOS_STATUS_SUCCESS;
11311 }
11312 else
11313 {
11314 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11315 __func__, status);
11316 return VOS_STATUS_E_FAULT;
11317 }
11318}
Mihir Shete04206452014-11-20 17:50:58 +053011319#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011320/*
11321 * API to find if there is any STA or P2P-Client is connected
11322 */
11323VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11324{
11325 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11326}
Jeff Johnsone7245742012-09-05 17:12:55 -070011327
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011328
11329/*
11330 * API to find if the firmware will send logs using DXE channel
11331 */
11332v_U8_t hdd_is_fw_logging_enabled(void)
11333{
11334 hdd_context_t *pHddCtx;
11335
11336 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11337 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11338
Sachin Ahuja084313e2015-05-21 17:57:10 +053011339 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011340}
11341
Agarwal Ashish57e84372014-12-05 18:26:53 +053011342/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011343 * API to find if the firmware will send trace logs using DXE channel
11344 */
11345v_U8_t hdd_is_fw_ev_logging_enabled(void)
11346{
11347 hdd_context_t *pHddCtx;
11348
11349 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11350 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11351
11352 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11353}
11354/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011355 * API to find if there is any session connected
11356 */
11357VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11358{
11359 return sme_is_any_session_connected(pHddCtx->hHal);
11360}
11361
11362
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011363int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11364{
11365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11366 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011367 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011368 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011369
11370 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011371 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011372 if (pScanInfo->mScanPending)
11373 {
c_hpothua3d45d52015-01-05 14:11:17 +053011374 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11375 eCSR_SCAN_ABORT_DEFAULT);
11376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11377 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011378
c_hpothua3d45d52015-01-05 14:11:17 +053011379 /* If there is active scan command lets wait for the completion else
11380 * there is no need to wait as scan command might be in the SME pending
11381 * command list.
11382 */
11383 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11384 {
c_hpothua3d45d52015-01-05 14:11:17 +053011385 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011386 &pScanInfo->abortscan_event_var,
11387 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011388 if (0 >= status)
11389 {
11390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011391 "%s: Timeout or Interrupt occurred while waiting for abort"
11392 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011393 return -ETIMEDOUT;
11394 }
11395 }
11396 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11397 {
11398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11399 FL("hdd_abort_mac_scan failed"));
11400 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011401 }
11402 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011403 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011404}
11405
c_hpothu225aa7c2014-10-22 17:45:13 +053011406VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11407{
11408 hdd_adapter_t *pAdapter;
11409 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11410 VOS_STATUS vosStatus;
11411
11412 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11413 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11414 {
11415 pAdapter = pAdapterNode->pAdapter;
11416 if (NULL != pAdapter)
11417 {
11418 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11419 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11420 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11421 {
11422 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11423 pAdapter->device_mode);
11424 if (VOS_STATUS_SUCCESS !=
11425 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11426 {
11427 hddLog(LOGE, FL("failed to abort ROC"));
11428 return VOS_STATUS_E_FAILURE;
11429 }
11430 }
11431 }
11432 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11433 pAdapterNode = pNext;
11434 }
11435 return VOS_STATUS_SUCCESS;
11436}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011437
Mihir Shete0be28772015-02-17 18:42:14 +053011438hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11439{
11440 hdd_adapter_t *pAdapter;
11441 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11442 hdd_cfg80211_state_t *cfgState;
11443 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11444 VOS_STATUS vosStatus;
11445
11446 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11447 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11448 {
11449 pAdapter = pAdapterNode->pAdapter;
11450 if (NULL != pAdapter)
11451 {
11452 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11453 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11454 if (pRemainChanCtx)
11455 break;
11456 }
11457 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11458 pAdapterNode = pNext;
11459 }
11460 return pRemainChanCtx;
11461}
11462
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011463/**
11464 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11465 *
11466 * @pHddCtx: HDD context within host driver
11467 * @dfsScanMode: dfsScanMode passed from ioctl
11468 *
11469 */
11470
11471VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11472 tANI_U8 dfsScanMode)
11473{
11474 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11475 hdd_adapter_t *pAdapter;
11476 VOS_STATUS vosStatus;
11477 hdd_station_ctx_t *pHddStaCtx;
11478 eHalStatus status = eHAL_STATUS_SUCCESS;
11479
11480 if(!pHddCtx)
11481 {
11482 hddLog(LOGE, FL("HDD context is Null"));
11483 return eHAL_STATUS_FAILURE;
11484 }
11485
11486 if (pHddCtx->scan_info.mScanPending)
11487 {
11488 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11489 pHddCtx->scan_info.sessionId);
11490 hdd_abort_mac_scan(pHddCtx,
11491 pHddCtx->scan_info.sessionId,
11492 eCSR_SCAN_ABORT_DEFAULT);
11493 }
11494
11495 if (!dfsScanMode)
11496 {
11497 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11498 while ((NULL != pAdapterNode) &&
11499 (VOS_STATUS_SUCCESS == vosStatus))
11500 {
11501 pAdapter = pAdapterNode->pAdapter;
11502
11503 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11504 {
11505 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11506
11507 if(!pHddStaCtx)
11508 {
11509 hddLog(LOGE, FL("HDD STA context is Null"));
11510 return eHAL_STATUS_FAILURE;
11511 }
11512
11513 /* if STA is already connected on DFS channel,
11514 disconnect immediately*/
11515 if (hdd_connIsConnected(pHddStaCtx) &&
11516 (NV_CHANNEL_DFS ==
11517 vos_nv_getChannelEnabledState(
11518 pHddStaCtx->conn_info.operationChannel)))
11519 {
11520 status = sme_RoamDisconnect(pHddCtx->hHal,
11521 pAdapter->sessionId,
11522 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11523 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11524 "sme_RoamDisconnect returned with status: %d"
11525 "for sessionid: %d"), pHddStaCtx->conn_info.
11526 operationChannel, status, pAdapter->sessionId);
11527 }
11528 }
11529
11530 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11531 &pNext);
11532 pAdapterNode = pNext;
11533 }
11534 }
11535
11536 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11537 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11538 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11539
11540 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11541 if (!HAL_STATUS_SUCCESS(status))
11542 {
11543 hddLog(LOGE,
11544 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11545 return status;
11546 }
11547
11548 return status;
11549}
11550
Nirav Shah7e3c8132015-06-22 23:51:42 +053011551static int hdd_log2_ceil(unsigned value)
11552{
11553 /* need to switch to unsigned math so that negative values
11554 * will right-shift towards 0 instead of -1
11555 */
11556 unsigned tmp = value;
11557 int log2 = -1;
11558
11559 if (value == 0)
11560 return 0;
11561
11562 while (tmp) {
11563 log2++;
11564 tmp >>= 1;
11565 }
11566 if (1U << log2 != value)
11567 log2++;
11568
11569 return log2;
11570}
11571
11572/**
11573 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11574 * @pAdapter: adapter handle
11575 *
11576 * Return: vos status
11577 */
11578VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11579{
11580 int hash_elem, log2, i;
11581
11582 spin_lock_bh( &pAdapter->sta_hash_lock);
11583 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11584 spin_unlock_bh( &pAdapter->sta_hash_lock);
11585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11586 "%s: hash already attached for session id %d",
11587 __func__, pAdapter->sessionId);
11588 return VOS_STATUS_SUCCESS;
11589 }
11590 spin_unlock_bh( &pAdapter->sta_hash_lock);
11591
11592 hash_elem = WLAN_MAX_STA_COUNT;
11593 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11594 log2 = hdd_log2_ceil(hash_elem);
11595 hash_elem = 1 << log2;
11596
11597 pAdapter->sta_id_hash.mask = hash_elem - 1;
11598 pAdapter->sta_id_hash.idx_bits = log2;
11599 pAdapter->sta_id_hash.bins =
11600 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11601 if (!pAdapter->sta_id_hash.bins) {
11602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11603 "%s: malloc failed for session %d",
11604 __func__, pAdapter->sessionId);
11605 return VOS_STATUS_E_NOMEM;
11606 }
11607
11608 for (i = 0; i < hash_elem; i++)
11609 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11610
11611 spin_lock_bh( &pAdapter->sta_hash_lock);
11612 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11613 spin_unlock_bh( &pAdapter->sta_hash_lock);
11614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11615 "%s: Station ID Hash attached for session id %d",
11616 __func__, pAdapter->sessionId);
11617
11618 return VOS_STATUS_SUCCESS;
11619}
11620
11621/**
11622 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11623 * @pAdapter: adapter handle
11624 *
11625 * Return: vos status
11626 */
11627VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11628{
11629 int hash_elem, i;
11630 v_SIZE_t size;
11631
11632 spin_lock_bh( &pAdapter->sta_hash_lock);
11633 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11634 spin_unlock_bh( &pAdapter->sta_hash_lock);
11635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11636 "%s: hash not initialized for session id %d",
11637 __func__, pAdapter->sessionId);
11638 return VOS_STATUS_SUCCESS;
11639 }
11640
11641 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11642 spin_unlock_bh( &pAdapter->sta_hash_lock);
11643
11644 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11645
11646 /* free all station info*/
11647 for (i = 0; i < hash_elem; i++) {
11648 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11649 if (size != 0) {
11650 VOS_STATUS status;
11651 hdd_staid_hash_node_t *sta_info_node = NULL;
11652 hdd_staid_hash_node_t *next_node = NULL;
11653 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11654 (hdd_list_node_t**) &sta_info_node );
11655
11656 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11657 {
11658 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11659 &sta_info_node->node);
11660 vos_mem_free(sta_info_node);
11661
11662 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11663 (hdd_list_node_t*)sta_info_node,
11664 (hdd_list_node_t**)&next_node);
11665 sta_info_node = next_node;
11666 }
11667 }
11668 }
11669
11670 vos_mem_free(pAdapter->sta_id_hash.bins);
11671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11672 "%s: Station ID Hash detached for session id %d",
11673 __func__, pAdapter->sessionId);
11674 return VOS_STATUS_SUCCESS;
11675}
11676
11677/**
11678 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11679 * @pAdapter: adapter handle
11680 * @mac_addr_in: input mac address
11681 *
11682 * Return: index derived from mac address
11683 */
11684int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11685 v_MACADDR_t *mac_addr_in)
11686{
11687 uint16 index;
11688 struct hdd_align_mac_addr_t * mac_addr =
11689 (struct hdd_align_mac_addr_t *)mac_addr_in;
11690
11691 index = mac_addr->bytes_ab ^
11692 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11693 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11694 index &= pAdapter->sta_id_hash.mask;
11695 return index;
11696}
11697
11698/**
11699 * hdd_sta_id_hash_add_entry() - add entry in hash
11700 * @pAdapter: adapter handle
11701 * @sta_id: station id
11702 * @mac_addr: mac address
11703 *
11704 * Return: vos status
11705 */
11706VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11707 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11708{
11709 uint16 index;
11710 hdd_staid_hash_node_t *sta_info_node = NULL;
11711
11712 spin_lock_bh( &pAdapter->sta_hash_lock);
11713 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11714 spin_unlock_bh( &pAdapter->sta_hash_lock);
11715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11716 "%s: hash is not initialized for session id %d",
11717 __func__, pAdapter->sessionId);
11718 return VOS_STATUS_E_FAILURE;
11719 }
11720
11721 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11722 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11723 if (!sta_info_node) {
11724 spin_unlock_bh( &pAdapter->sta_hash_lock);
11725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11726 "%s: malloc failed", __func__);
11727 return VOS_STATUS_E_NOMEM;
11728 }
11729
11730 sta_info_node->sta_id = sta_id;
11731 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11732
11733 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11734 (hdd_list_node_t*) sta_info_node );
11735 spin_unlock_bh( &pAdapter->sta_hash_lock);
11736 return VOS_STATUS_SUCCESS;
11737}
11738
11739/**
11740 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11741 * @pAdapter: adapter handle
11742 * @sta_id: station id
11743 * @mac_addr: mac address
11744 *
11745 * Return: vos status
11746 */
11747VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11748 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11749{
11750 uint16 index;
11751 VOS_STATUS status;
11752 hdd_staid_hash_node_t *sta_info_node = NULL;
11753 hdd_staid_hash_node_t *next_node = NULL;
11754
11755 spin_lock_bh( &pAdapter->sta_hash_lock);
11756 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11757 spin_unlock_bh( &pAdapter->sta_hash_lock);
11758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11759 "%s: hash is not initialized for session id %d",
11760 __func__, pAdapter->sessionId);
11761 return VOS_STATUS_E_FAILURE;
11762 }
11763
11764 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11765 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11766 (hdd_list_node_t**) &sta_info_node );
11767
11768 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11769 {
11770 if (sta_info_node->sta_id == sta_id) {
11771 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11772 &sta_info_node->node);
11773 vos_mem_free(sta_info_node);
11774 break;
11775 }
11776 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11777 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11778 sta_info_node = next_node;
11779 }
11780 spin_unlock_bh( &pAdapter->sta_hash_lock);
11781 return status;
11782}
11783
11784/**
11785 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11786 * @pAdapter: adapter handle
11787 * @mac_addr_in: mac address
11788 *
11789 * Return: station id
11790 */
11791int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11792 v_MACADDR_t *mac_addr_in)
11793{
11794 uint8 is_found = 0;
11795 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11796 uint16 index;
11797 VOS_STATUS status;
11798 hdd_staid_hash_node_t *sta_info_node = NULL;
11799 hdd_staid_hash_node_t *next_node = NULL;
11800
11801 spin_lock_bh( &pAdapter->sta_hash_lock);
11802 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11803 spin_unlock_bh( &pAdapter->sta_hash_lock);
11804 hddLog(VOS_TRACE_LEVEL_ERROR,
11805 FL("hash is not initialized for session id %d"),
11806 pAdapter->sessionId);
11807 return HDD_WLAN_INVALID_STA_ID;
11808 }
11809
11810 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11811 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11812 (hdd_list_node_t**) &sta_info_node );
11813
11814 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11815 {
11816 if (vos_mem_compare(&sta_info_node->mac_addr,
11817 mac_addr_in, sizeof(v_MACADDR_t))) {
11818 is_found = 1;
11819 sta_id = sta_info_node->sta_id;
11820 break;
11821 }
11822 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11823 (hdd_list_node_t*)sta_info_node,
11824 (hdd_list_node_t**)&next_node);
11825 sta_info_node = next_node;
11826 }
11827 spin_unlock_bh( &pAdapter->sta_hash_lock);
11828 return sta_id;
11829}
11830
Jeff Johnson295189b2012-06-20 16:38:30 -070011831//Register the module init/exit functions
11832module_init(hdd_module_init);
11833module_exit(hdd_module_exit);
11834
11835MODULE_LICENSE("Dual BSD/GPL");
11836MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11837MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11838
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011839module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11840 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011841
Jeff Johnson76052702013-04-16 13:55:05 -070011842module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011843 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011844
11845module_param(enable_dfs_chan_scan, int,
11846 S_IRUSR | S_IRGRP | S_IROTH);
11847
11848module_param(enable_11d, int,
11849 S_IRUSR | S_IRGRP | S_IROTH);
11850
11851module_param(country_code, charp,
11852 S_IRUSR | S_IRGRP | S_IROTH);