blob: a6fa05b436aeeb6093a4f1742c48a8a07e978bb9 [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);
Anand N Sunkad27354cf2015-07-13 14:39:11 +05302313 if(VOS_FTM_MODE != hdd_get_conparam())
2314 {
2315 /* Change band request received */
2316 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2317 if(ret < 0)
2318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2319 "%s: failed to set band ret=%d", __func__, ret);
2320 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002321 }
Kiet Lamf040f472013-11-20 21:15:23 +05302322 else if(strncmp(command, "SETWMMPS", 8) == 0)
2323 {
2324 tANI_U8 *ptr = command;
2325 ret = hdd_wmmps_helper(pAdapter, ptr);
2326 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302327
2328 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2329 {
2330 tANI_U8 *ptr = command;
2331 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2332 }
2333
Jeff Johnson32d95a32012-09-10 13:15:23 -07002334 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2335 {
2336 char *country_code;
2337
2338 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002339
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002340 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002341 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002342#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302343 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002344#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002345 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2346 (void *)(tSmeChangeCountryCallback)
2347 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302348 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002349 if (eHAL_STATUS_SUCCESS == ret)
2350 {
2351 ret = wait_for_completion_interruptible_timeout(
2352 &pAdapter->change_country_code,
2353 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2354 if (0 >= ret)
2355 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302357 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002358 }
2359 }
2360 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002361 {
2362 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002363 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002364 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002365 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002366
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002367 }
2368 /*
2369 command should be a string having format
2370 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2371 */
Amar Singhal0974e402013-02-12 14:27:46 -08002372 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002373 {
Amar Singhal0974e402013-02-12 14:27:46 -08002374 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002375
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002377 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002378
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002379 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002380 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002381 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2382 {
2383 int suspend = 0;
2384 tANI_U8 *ptr = (tANI_U8*)command + 15;
2385
2386 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2388 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2389 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002390 hdd_set_wlan_suspend_mode(suspend);
2391 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002392#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2393 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2394 {
2395 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002396 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002397 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2398 eHalStatus status = eHAL_STATUS_SUCCESS;
2399
2400 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2401 value = value + 15;
2402
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002403 /* Convert the value from ascii to integer */
2404 ret = kstrtos8(value, 10, &rssi);
2405 if (ret < 0)
2406 {
2407 /* If the input value is greater than max value of datatype, then also
2408 kstrtou8 fails */
2409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002411 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002412 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2413 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2414 ret = -EINVAL;
2415 goto exit;
2416 }
2417
Srinivas Girigowdade697412013-02-14 16:31:48 -08002418 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002419
Srinivas Girigowdade697412013-02-14 16:31:48 -08002420 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2421 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2422 {
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2424 "Neighbor lookup threshold value %d is out of range"
2425 " (Min: %d Max: %d)", lookUpThreshold,
2426 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2427 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2428 ret = -EINVAL;
2429 goto exit;
2430 }
2431
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302432 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2433 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2434 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2436 "%s: Received Command to Set Roam trigger"
2437 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2438
2439 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2440 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2441 if (eHAL_STATUS_SUCCESS != status)
2442 {
2443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2444 "%s: Failed to set roam trigger, try again", __func__);
2445 ret = -EPERM;
2446 goto exit;
2447 }
2448
2449 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302450 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002451 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2452 }
2453 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2454 {
2455 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2456 int rssi = (-1) * lookUpThreshold;
2457 char extra[32];
2458 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2461 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002462 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302463 len = VOS_MIN(priv_data.total_len, len + 1);
2464 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002465 {
2466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2467 "%s: failed to copy data to user buffer", __func__);
2468 ret = -EFAULT;
2469 goto exit;
2470 }
2471 }
2472 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2473 {
2474 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002475 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002476 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478 /* input refresh period is in terms of seconds */
2479 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2480 value = value + 18;
2481 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002482 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002483 if (ret < 0)
2484 {
2485 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002486 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002488 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002489 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002490 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2491 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002492 ret = -EINVAL;
2493 goto exit;
2494 }
2495
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2497 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500 "Roam scan period value %d is out of range"
2501 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002502 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2503 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002504 ret = -EINVAL;
2505 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302506 }
2507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2508 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2509 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002511
2512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2513 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002514 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002516 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2517 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002518 }
2519 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2520 {
2521 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2522 char extra[32];
2523 tANI_U8 len = 0;
2524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2526 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2527 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002528 len = scnprintf(extra, sizeof(extra), "%s %d",
2529 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002530 /* Returned value is in units of seconds */
2531 if (copy_to_user(priv_data.buf, &extra, len + 1))
2532 {
2533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2534 "%s: failed to copy data to user buffer", __func__);
2535 ret = -EFAULT;
2536 goto exit;
2537 }
2538 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002539 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2540 {
2541 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 /* input refresh period is in terms of seconds */
2546 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2547 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002548
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002549 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002550 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002551 if (ret < 0)
2552 {
2553 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002554 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002556 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002557 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002558 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2559 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2560 ret = -EINVAL;
2561 goto exit;
2562 }
2563
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002564 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2565 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2566 {
2567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2568 "Neighbor scan results refresh period value %d is out of range"
2569 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2570 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2571 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2572 ret = -EINVAL;
2573 goto exit;
2574 }
2575 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2576
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2578 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002579 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002580
2581 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2582 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2583 }
2584 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2585 {
2586 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2587 char extra[32];
2588 tANI_U8 len = 0;
2589
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002590 len = scnprintf(extra, sizeof(extra), "%s %d",
2591 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002592 /* Returned value is in units of seconds */
2593 if (copy_to_user(priv_data.buf, &extra, len + 1))
2594 {
2595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2596 "%s: failed to copy data to user buffer", __func__);
2597 ret = -EFAULT;
2598 goto exit;
2599 }
2600 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002601#ifdef FEATURE_WLAN_LFR
2602 /* SETROAMMODE */
2603 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2604 {
2605 tANI_U8 *value = command;
2606 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2607
2608 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2609 value = value + SIZE_OF_SETROAMMODE + 1;
2610
2611 /* Convert the value from ascii to integer */
2612 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2613 if (ret < 0)
2614 {
2615 /* If the input value is greater than max value of datatype, then also
2616 kstrtou8 fails */
2617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2618 "%s: kstrtou8 failed range [%d - %d]", __func__,
2619 CFG_LFR_FEATURE_ENABLED_MIN,
2620 CFG_LFR_FEATURE_ENABLED_MAX);
2621 ret = -EINVAL;
2622 goto exit;
2623 }
2624 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2625 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2626 {
2627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2628 "Roam Mode value %d is out of range"
2629 " (Min: %d Max: %d)", roamMode,
2630 CFG_LFR_FEATURE_ENABLED_MIN,
2631 CFG_LFR_FEATURE_ENABLED_MAX);
2632 ret = -EINVAL;
2633 goto exit;
2634 }
2635
2636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2637 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2638 /*
2639 * Note that
2640 * SETROAMMODE 0 is to enable LFR while
2641 * SETROAMMODE 1 is to disable LFR, but
2642 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2643 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2644 */
2645 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2646 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2647 else
2648 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2649
2650 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2651 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2652 }
2653 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302654 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002655 {
2656 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2657 char extra[32];
2658 tANI_U8 len = 0;
2659
2660 /*
2661 * roamMode value shall be inverted because the sementics is different.
2662 */
2663 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2664 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2665 else
2666 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2667
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002668 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002669 if (copy_to_user(priv_data.buf, &extra, len + 1))
2670 {
2671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2672 "%s: failed to copy data to user buffer", __func__);
2673 ret = -EFAULT;
2674 goto exit;
2675 }
2676 }
2677#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002678#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002679#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2681 {
2682 tANI_U8 *value = command;
2683 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2684
2685 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2686 value = value + 13;
2687 /* Convert the value from ascii to integer */
2688 ret = kstrtou8(value, 10, &roamRssiDiff);
2689 if (ret < 0)
2690 {
2691 /* If the input value is greater than max value of datatype, then also
2692 kstrtou8 fails */
2693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2694 "%s: kstrtou8 failed range [%d - %d]", __func__,
2695 CFG_ROAM_RSSI_DIFF_MIN,
2696 CFG_ROAM_RSSI_DIFF_MAX);
2697 ret = -EINVAL;
2698 goto exit;
2699 }
2700
2701 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2702 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2703 {
2704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2705 "Roam rssi diff value %d is out of range"
2706 " (Min: %d Max: %d)", roamRssiDiff,
2707 CFG_ROAM_RSSI_DIFF_MIN,
2708 CFG_ROAM_RSSI_DIFF_MAX);
2709 ret = -EINVAL;
2710 goto exit;
2711 }
2712
2713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2714 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2715
2716 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2717 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2718 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302719 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002720 {
2721 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2722 char extra[32];
2723 tANI_U8 len = 0;
2724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2726 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2727 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002728 len = scnprintf(extra, sizeof(extra), "%s %d",
2729 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 if (copy_to_user(priv_data.buf, &extra, len + 1))
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: failed to copy data to user buffer", __func__);
2734 ret = -EFAULT;
2735 goto exit;
2736 }
2737 }
2738#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002739#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002740 else if (strncmp(command, "GETBAND", 7) == 0)
2741 {
2742 int band = -1;
2743 char extra[32];
2744 tANI_U8 len = 0;
2745 hdd_getBand_helper(pHddCtx, &band);
2746
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2748 TRACE_CODE_HDD_GETBAND_IOCTL,
2749 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002750 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002751 if (copy_to_user(priv_data.buf, &extra, len + 1))
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: failed to copy data to user buffer", __func__);
2755 ret = -EFAULT;
2756 goto exit;
2757 }
2758 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002759 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 *value = command;
2762 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2763 tANI_U8 numChannels = 0;
2764 eHalStatus status = eHAL_STATUS_SUCCESS;
2765
2766 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2767 if (eHAL_STATUS_SUCCESS != status)
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: Failed to parse channel list information", __func__);
2771 ret = -EINVAL;
2772 goto exit;
2773 }
2774
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2782 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2783 ret = -EINVAL;
2784 goto exit;
2785 }
2786 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2787 numChannels);
2788 if (eHAL_STATUS_SUCCESS != status)
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: Failed to update channel list information", __func__);
2792 ret = -EINVAL;
2793 goto exit;
2794 }
2795 }
2796 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2797 {
2798 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2799 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002800 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002801 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002802 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002803
2804 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2805 ChannelList, &numChannels ))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2808 "%s: failed to get roam scan channel list", __func__);
2809 ret = -EFAULT;
2810 goto exit;
2811 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2813 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2814 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 /* output channel list is of the format
2816 [Number of roam scan channels][Channel1][Channel2]... */
2817 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002818 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002819 for (j = 0; (j < numChannels); j++)
2820 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002821 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2822 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002823 }
2824
2825 if (copy_to_user(priv_data.buf, &extra, len + 1))
2826 {
2827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: failed to copy data to user buffer", __func__);
2829 ret = -EFAULT;
2830 goto exit;
2831 }
2832 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002833 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2834 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002835 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002836 char extra[32];
2837 tANI_U8 len = 0;
2838
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002839 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002840 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002841 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002842 hdd_is_okc_mode_enabled(pHddCtx) &&
2843 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2844 {
2845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002846 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002847 " hence this operation is not permitted!", __func__);
2848 ret = -EPERM;
2849 goto exit;
2850 }
2851
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002852 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002853 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002854 if (copy_to_user(priv_data.buf, &extra, len + 1))
2855 {
2856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2857 "%s: failed to copy data to user buffer", __func__);
2858 ret = -EFAULT;
2859 goto exit;
2860 }
2861 }
2862 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2863 {
2864 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2865 char extra[32];
2866 tANI_U8 len = 0;
2867
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002868 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002869 then this operation is not permitted (return FAILURE) */
2870 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002871 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002872 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2873 {
2874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002875 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002876 " hence this operation is not permitted!", __func__);
2877 ret = -EPERM;
2878 goto exit;
2879 }
2880
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002881 len = scnprintf(extra, sizeof(extra), "%s %d",
2882 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002883 if (copy_to_user(priv_data.buf, &extra, len + 1))
2884 {
2885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2886 "%s: failed to copy data to user buffer", __func__);
2887 ret = -EFAULT;
2888 goto exit;
2889 }
2890 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002891 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002892 {
2893 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2894 char extra[32];
2895 tANI_U8 len = 0;
2896
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002897 len = scnprintf(extra, sizeof(extra), "%s %d",
2898 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002899 if (copy_to_user(priv_data.buf, &extra, len + 1))
2900 {
2901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2902 "%s: failed to copy data to user buffer", __func__);
2903 ret = -EFAULT;
2904 goto exit;
2905 }
2906 }
2907 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2908 {
2909 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2910 char extra[32];
2911 tANI_U8 len = 0;
2912
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002913 len = scnprintf(extra, sizeof(extra), "%s %d",
2914 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302915 len = VOS_MIN(priv_data.total_len, len + 1);
2916 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002917 {
2918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2919 "%s: failed to copy data to user buffer", __func__);
2920 ret = -EFAULT;
2921 goto exit;
2922 }
2923 }
2924 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2925 {
2926 tANI_U8 *value = command;
2927 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2928
2929 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2930 value = value + 26;
2931 /* Convert the value from ascii to integer */
2932 ret = kstrtou8(value, 10, &minTime);
2933 if (ret < 0)
2934 {
2935 /* If the input value is greater than max value of datatype, then also
2936 kstrtou8 fails */
2937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2938 "%s: kstrtou8 failed range [%d - %d]", __func__,
2939 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2940 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2941 ret = -EINVAL;
2942 goto exit;
2943 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002944 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2945 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2946 {
2947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2948 "scan min channel time value %d is out of range"
2949 " (Min: %d Max: %d)", minTime,
2950 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2951 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2952 ret = -EINVAL;
2953 goto exit;
2954 }
2955
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2957 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2958 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2960 "%s: Received Command to change channel min time = %d", __func__, minTime);
2961
2962 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2963 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2964 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002965 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2966 {
2967 tANI_U8 *value = command;
2968 tANI_U8 channel = 0;
2969 tANI_U8 dwellTime = 0;
2970 tANI_U8 bufLen = 0;
2971 tANI_U8 *buf = NULL;
2972 tSirMacAddr targetApBssid;
2973 eHalStatus status = eHAL_STATUS_SUCCESS;
2974 struct ieee80211_channel chan;
2975 tANI_U8 finalLen = 0;
2976 tANI_U8 *finalBuf = NULL;
2977 tANI_U8 temp = 0;
2978 u64 cookie;
2979 hdd_station_ctx_t *pHddStaCtx = NULL;
2980 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2981
2982 /* if not associated, no need to send action frame */
2983 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2984 {
2985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2986 ret = -EINVAL;
2987 goto exit;
2988 }
2989
2990 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2991 &dwellTime, &buf, &bufLen);
2992 if (eHAL_STATUS_SUCCESS != status)
2993 {
2994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2995 "%s: Failed to parse send action frame data", __func__);
2996 ret = -EINVAL;
2997 goto exit;
2998 }
2999
3000 /* if the target bssid is different from currently associated AP,
3001 then no need to send action frame */
3002 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3003 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3004 {
3005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3006 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003007 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003008 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003009 goto exit;
3010 }
3011
3012 /* if the channel number is different from operating channel then
3013 no need to send action frame */
3014 if (channel != pHddStaCtx->conn_info.operationChannel)
3015 {
3016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3017 "%s: channel(%d) is different from operating channel(%d)",
3018 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3019 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003020 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003021 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003022 goto exit;
3023 }
3024 chan.center_freq = sme_ChnToFreq(channel);
3025
3026 finalLen = bufLen + 24;
3027 finalBuf = vos_mem_malloc(finalLen);
3028 if (NULL == finalBuf)
3029 {
3030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3031 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003032 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003033 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003034 goto exit;
3035 }
3036 vos_mem_zero(finalBuf, finalLen);
3037
3038 /* Fill subtype */
3039 temp = SIR_MAC_MGMT_ACTION << 4;
3040 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3041
3042 /* Fill type */
3043 temp = SIR_MAC_MGMT_FRAME;
3044 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3045
3046 /* Fill destination address (bssid of the AP) */
3047 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3048
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003049 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003050 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3051
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003052 /* Fill BSSID (AP mac address) */
3053 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003054
3055 /* Fill received buffer from 24th address */
3056 vos_mem_copy(finalBuf + 24, buf, bufLen);
3057
Jeff Johnson11c33152013-04-16 17:52:40 -07003058 /* done with the parsed buffer */
3059 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003060 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003061
DARAM SUDHA39eede62014-02-12 11:16:40 +05303062 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003063#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3064 &(pAdapter->wdev),
3065#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003066 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003067#endif
3068 &chan, 0,
3069#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3070 NL80211_CHAN_HT20, 1,
3071#endif
3072 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003073 1, &cookie );
3074 vos_mem_free(finalBuf);
3075 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003076 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3077 {
3078 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3079 char extra[32];
3080 tANI_U8 len = 0;
3081
3082 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003083 len = scnprintf(extra, sizeof(extra), "%s %d",
3084 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303085 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3086 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3087 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003088 if (copy_to_user(priv_data.buf, &extra, len + 1))
3089 {
3090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3091 "%s: failed to copy data to user buffer", __func__);
3092 ret = -EFAULT;
3093 goto exit;
3094 }
3095 }
3096 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3097 {
3098 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003099 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003100
3101 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3102 value = value + 19;
3103 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003104 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003105 if (ret < 0)
3106 {
3107 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003108 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003110 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003111 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3112 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3113 ret = -EINVAL;
3114 goto exit;
3115 }
3116
3117 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3118 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3119 {
3120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3121 "lfr mode value %d is out of range"
3122 " (Min: %d Max: %d)", maxTime,
3123 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3124 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3125 ret = -EINVAL;
3126 goto exit;
3127 }
3128
3129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3130 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3131
3132 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3133 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3134 }
3135 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3136 {
3137 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3138 char extra[32];
3139 tANI_U8 len = 0;
3140
3141 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003142 len = scnprintf(extra, sizeof(extra), "%s %d",
3143 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003144 if (copy_to_user(priv_data.buf, &extra, len + 1))
3145 {
3146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3147 "%s: failed to copy data to user buffer", __func__);
3148 ret = -EFAULT;
3149 goto exit;
3150 }
3151 }
3152 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3153 {
3154 tANI_U8 *value = command;
3155 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3156
3157 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3158 value = value + 16;
3159 /* Convert the value from ascii to integer */
3160 ret = kstrtou16(value, 10, &val);
3161 if (ret < 0)
3162 {
3163 /* If the input value is greater than max value of datatype, then also
3164 kstrtou16 fails */
3165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3166 "%s: kstrtou16 failed range [%d - %d]", __func__,
3167 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3168 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3169 ret = -EINVAL;
3170 goto exit;
3171 }
3172
3173 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3174 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3175 {
3176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3177 "scan home time value %d is out of range"
3178 " (Min: %d Max: %d)", val,
3179 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3180 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3181 ret = -EINVAL;
3182 goto exit;
3183 }
3184
3185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3186 "%s: Received Command to change scan home time = %d", __func__, val);
3187
3188 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3189 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3190 }
3191 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3192 {
3193 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3194 char extra[32];
3195 tANI_U8 len = 0;
3196
3197 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003198 len = scnprintf(extra, sizeof(extra), "%s %d",
3199 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003200 if (copy_to_user(priv_data.buf, &extra, len + 1))
3201 {
3202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3203 "%s: failed to copy data to user buffer", __func__);
3204 ret = -EFAULT;
3205 goto exit;
3206 }
3207 }
3208 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3209 {
3210 tANI_U8 *value = command;
3211 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3212
3213 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3214 value = value + 17;
3215 /* Convert the value from ascii to integer */
3216 ret = kstrtou8(value, 10, &val);
3217 if (ret < 0)
3218 {
3219 /* If the input value is greater than max value of datatype, then also
3220 kstrtou8 fails */
3221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3222 "%s: kstrtou8 failed range [%d - %d]", __func__,
3223 CFG_ROAM_INTRA_BAND_MIN,
3224 CFG_ROAM_INTRA_BAND_MAX);
3225 ret = -EINVAL;
3226 goto exit;
3227 }
3228
3229 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3230 (val > CFG_ROAM_INTRA_BAND_MAX))
3231 {
3232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3233 "intra band mode value %d is out of range"
3234 " (Min: %d Max: %d)", val,
3235 CFG_ROAM_INTRA_BAND_MIN,
3236 CFG_ROAM_INTRA_BAND_MAX);
3237 ret = -EINVAL;
3238 goto exit;
3239 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3241 "%s: Received Command to change intra band = %d", __func__, val);
3242
3243 pHddCtx->cfg_ini->nRoamIntraBand = val;
3244 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3245 }
3246 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3247 {
3248 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3249 char extra[32];
3250 tANI_U8 len = 0;
3251
3252 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003253 len = scnprintf(extra, sizeof(extra), "%s %d",
3254 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003255 if (copy_to_user(priv_data.buf, &extra, len + 1))
3256 {
3257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3258 "%s: failed to copy data to user buffer", __func__);
3259 ret = -EFAULT;
3260 goto exit;
3261 }
3262 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003263 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3264 {
3265 tANI_U8 *value = command;
3266 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3267
3268 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3269 value = value + 15;
3270 /* Convert the value from ascii to integer */
3271 ret = kstrtou8(value, 10, &nProbes);
3272 if (ret < 0)
3273 {
3274 /* If the input value is greater than max value of datatype, then also
3275 kstrtou8 fails */
3276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3277 "%s: kstrtou8 failed range [%d - %d]", __func__,
3278 CFG_ROAM_SCAN_N_PROBES_MIN,
3279 CFG_ROAM_SCAN_N_PROBES_MAX);
3280 ret = -EINVAL;
3281 goto exit;
3282 }
3283
3284 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3285 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3286 {
3287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3288 "NProbes value %d is out of range"
3289 " (Min: %d Max: %d)", nProbes,
3290 CFG_ROAM_SCAN_N_PROBES_MIN,
3291 CFG_ROAM_SCAN_N_PROBES_MAX);
3292 ret = -EINVAL;
3293 goto exit;
3294 }
3295
3296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3297 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3298
3299 pHddCtx->cfg_ini->nProbes = nProbes;
3300 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3301 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303302 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003303 {
3304 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3305 char extra[32];
3306 tANI_U8 len = 0;
3307
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003308 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003309 if (copy_to_user(priv_data.buf, &extra, len + 1))
3310 {
3311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3312 "%s: failed to copy data to user buffer", __func__);
3313 ret = -EFAULT;
3314 goto exit;
3315 }
3316 }
3317 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3318 {
3319 tANI_U8 *value = command;
3320 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3321
3322 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3323 /* input value is in units of msec */
3324 value = value + 20;
3325 /* Convert the value from ascii to integer */
3326 ret = kstrtou16(value, 10, &homeAwayTime);
3327 if (ret < 0)
3328 {
3329 /* If the input value is greater than max value of datatype, then also
3330 kstrtou8 fails */
3331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3332 "%s: kstrtou8 failed range [%d - %d]", __func__,
3333 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3334 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3335 ret = -EINVAL;
3336 goto exit;
3337 }
3338
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003339 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3340 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3341 {
3342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3343 "homeAwayTime value %d is out of range"
3344 " (Min: %d Max: %d)", homeAwayTime,
3345 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3346 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3347 ret = -EINVAL;
3348 goto exit;
3349 }
3350
3351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3352 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003353 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3354 {
3355 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3356 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3357 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003358 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303359 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003360 {
3361 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3362 char extra[32];
3363 tANI_U8 len = 0;
3364
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003365 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003366 if (copy_to_user(priv_data.buf, &extra, len + 1))
3367 {
3368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3369 "%s: failed to copy data to user buffer", __func__);
3370 ret = -EFAULT;
3371 goto exit;
3372 }
3373 }
3374 else if (strncmp(command, "REASSOC", 7) == 0)
3375 {
3376 tANI_U8 *value = command;
3377 tANI_U8 channel = 0;
3378 tSirMacAddr targetApBssid;
3379 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003380#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3381 tCsrHandoffRequest handoffInfo;
3382#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003383 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003384 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3385
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003386 /* if not associated, no need to proceed with reassoc */
3387 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3388 {
3389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3390 ret = -EINVAL;
3391 goto exit;
3392 }
3393
3394 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3395 if (eHAL_STATUS_SUCCESS != status)
3396 {
3397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3398 "%s: Failed to parse reassoc command data", __func__);
3399 ret = -EINVAL;
3400 goto exit;
3401 }
3402
3403 /* if the target bssid is same as currently associated AP,
3404 then no need to proceed with reassoc */
3405 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3406 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3407 {
3408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3409 ret = -EINVAL;
3410 goto exit;
3411 }
3412
3413 /* Check channel number is a valid channel number */
3414 if(VOS_STATUS_SUCCESS !=
3415 wlan_hdd_validate_operation_channel(pAdapter, channel))
3416 {
3417 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003418 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003419 return -EINVAL;
3420 }
3421
3422 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003423#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3424 handoffInfo.channel = channel;
3425 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3426 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3427#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003428 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003429 else if (strncmp(command, "SETWESMODE", 10) == 0)
3430 {
3431 tANI_U8 *value = command;
3432 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3433
3434 /* Move pointer to ahead of SETWESMODE<delimiter> */
3435 value = value + 11;
3436 /* Convert the value from ascii to integer */
3437 ret = kstrtou8(value, 10, &wesMode);
3438 if (ret < 0)
3439 {
3440 /* If the input value is greater than max value of datatype, then also
3441 kstrtou8 fails */
3442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3443 "%s: kstrtou8 failed range [%d - %d]", __func__,
3444 CFG_ENABLE_WES_MODE_NAME_MIN,
3445 CFG_ENABLE_WES_MODE_NAME_MAX);
3446 ret = -EINVAL;
3447 goto exit;
3448 }
3449
3450 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3451 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3452 {
3453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3454 "WES Mode value %d is out of range"
3455 " (Min: %d Max: %d)", wesMode,
3456 CFG_ENABLE_WES_MODE_NAME_MIN,
3457 CFG_ENABLE_WES_MODE_NAME_MAX);
3458 ret = -EINVAL;
3459 goto exit;
3460 }
3461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3462 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3463
3464 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3465 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3466 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303467 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003468 {
3469 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3470 char extra[32];
3471 tANI_U8 len = 0;
3472
Arif Hussain826d9412013-11-12 16:44:54 -08003473 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003474 if (copy_to_user(priv_data.buf, &extra, len + 1))
3475 {
3476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3477 "%s: failed to copy data to user buffer", __func__);
3478 ret = -EFAULT;
3479 goto exit;
3480 }
3481 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003482#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003483#ifdef FEATURE_WLAN_LFR
3484 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3485 {
3486 tANI_U8 *value = command;
3487 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3488
3489 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3490 value = value + 12;
3491 /* Convert the value from ascii to integer */
3492 ret = kstrtou8(value, 10, &lfrMode);
3493 if (ret < 0)
3494 {
3495 /* If the input value is greater than max value of datatype, then also
3496 kstrtou8 fails */
3497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3498 "%s: kstrtou8 failed range [%d - %d]", __func__,
3499 CFG_LFR_FEATURE_ENABLED_MIN,
3500 CFG_LFR_FEATURE_ENABLED_MAX);
3501 ret = -EINVAL;
3502 goto exit;
3503 }
3504
3505 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3506 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3507 {
3508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3509 "lfr mode value %d is out of range"
3510 " (Min: %d Max: %d)", lfrMode,
3511 CFG_LFR_FEATURE_ENABLED_MIN,
3512 CFG_LFR_FEATURE_ENABLED_MAX);
3513 ret = -EINVAL;
3514 goto exit;
3515 }
3516
3517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3518 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3519
3520 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3521 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3522 }
3523#endif
3524#ifdef WLAN_FEATURE_VOWIFI_11R
3525 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3526 {
3527 tANI_U8 *value = command;
3528 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3529
3530 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3531 value = value + 18;
3532 /* Convert the value from ascii to integer */
3533 ret = kstrtou8(value, 10, &ft);
3534 if (ret < 0)
3535 {
3536 /* If the input value is greater than max value of datatype, then also
3537 kstrtou8 fails */
3538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3539 "%s: kstrtou8 failed range [%d - %d]", __func__,
3540 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3541 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3542 ret = -EINVAL;
3543 goto exit;
3544 }
3545
3546 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3547 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3548 {
3549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3550 "ft mode value %d is out of range"
3551 " (Min: %d Max: %d)", ft,
3552 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3553 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3554 ret = -EINVAL;
3555 goto exit;
3556 }
3557
3558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3559 "%s: Received Command to change ft mode = %d", __func__, ft);
3560
3561 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3562 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3563 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303564 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3565 {
3566 tANI_U8 *value = command;
3567 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303568
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303569 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3570 value = value + 15;
3571 /* Convert the value from ascii to integer */
3572 ret = kstrtou8(value, 10, &dfsScanMode);
3573 if (ret < 0)
3574 {
3575 /* If the input value is greater than max value of
3576 datatype, then also kstrtou8 fails
3577 */
3578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "%s: kstrtou8 failed range [%d - %d]", __func__,
3580 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3581 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3582 ret = -EINVAL;
3583 goto exit;
3584 }
3585
3586 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3587 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3588 {
3589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3590 "dfsScanMode value %d is out of range"
3591 " (Min: %d Max: %d)", dfsScanMode,
3592 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3593 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3594 ret = -EINVAL;
3595 goto exit;
3596 }
3597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3598 "%s: Received Command to Set DFS Scan Mode = %d",
3599 __func__, dfsScanMode);
3600
3601 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3602 }
3603 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3604 {
3605 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3606 char extra[32];
3607 tANI_U8 len = 0;
3608
3609 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3610 if (copy_to_user(priv_data.buf, &extra, len + 1))
3611 {
3612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3613 "%s: failed to copy data to user buffer", __func__);
3614 ret = -EFAULT;
3615 goto exit;
3616 }
3617 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303618 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3619 {
3620 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303621 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303622 tSirMacAddr targetApBssid;
3623 tANI_U8 trigger = 0;
3624 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303625 tHalHandle hHal;
3626 v_U32_t roamId = 0;
3627 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303628 hdd_station_ctx_t *pHddStaCtx = NULL;
3629 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303630 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303631
3632 /* if not associated, no need to proceed with reassoc */
3633 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3634 {
3635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3636 ret = -EINVAL;
3637 goto exit;
3638 }
3639
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303640 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303641 if (eHAL_STATUS_SUCCESS != status)
3642 {
3643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3644 "%s: Failed to parse reassoc command data", __func__);
3645 ret = -EINVAL;
3646 goto exit;
3647 }
3648
3649 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303650 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303651 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3652 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3653 {
3654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3655 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3656 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303657 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3658 &modProfileFields);
3659 sme_RoamReassoc(hHal, pAdapter->sessionId,
3660 NULL, modProfileFields, &roamId, 1);
3661 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303662 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303663
3664 /* Check channel number is a valid channel number */
3665 if(VOS_STATUS_SUCCESS !=
3666 wlan_hdd_validate_operation_channel(pAdapter, channel))
3667 {
3668 hddLog(VOS_TRACE_LEVEL_ERROR,
3669 "%s: Invalid Channel [%d]", __func__, channel);
3670 return -EINVAL;
3671 }
3672
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303673 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303674
3675 /* Proceed with scan/roam */
3676 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3677 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303678 (tSmeFastRoamTrigger)(trigger),
3679 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303680 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003681#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003682#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003683 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3684 {
3685 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003686 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003687
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003688 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003689 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003690 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003691 hdd_is_okc_mode_enabled(pHddCtx) &&
3692 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3693 {
3694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003695 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003696 " hence this operation is not permitted!", __func__);
3697 ret = -EPERM;
3698 goto exit;
3699 }
3700
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003701 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3702 value = value + 11;
3703 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003704 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003705 if (ret < 0)
3706 {
3707 /* If the input value is greater than max value of datatype, then also
3708 kstrtou8 fails */
3709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3710 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003711 CFG_ESE_FEATURE_ENABLED_MIN,
3712 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003713 ret = -EINVAL;
3714 goto exit;
3715 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003716 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3717 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003718 {
3719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003720 "Ese mode value %d is out of range"
3721 " (Min: %d Max: %d)", eseMode,
3722 CFG_ESE_FEATURE_ENABLED_MIN,
3723 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003724 ret = -EINVAL;
3725 goto exit;
3726 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003728 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003729
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003730 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3731 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003732 }
3733#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003734 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3735 {
3736 tANI_U8 *value = command;
3737 tANI_BOOLEAN roamScanControl = 0;
3738
3739 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3740 value = value + 19;
3741 /* Convert the value from ascii to integer */
3742 ret = kstrtou8(value, 10, &roamScanControl);
3743 if (ret < 0)
3744 {
3745 /* If the input value is greater than max value of datatype, then also
3746 kstrtou8 fails */
3747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3748 "%s: kstrtou8 failed ", __func__);
3749 ret = -EINVAL;
3750 goto exit;
3751 }
3752
3753 if (0 != roamScanControl)
3754 {
3755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3756 "roam scan control invalid value = %d",
3757 roamScanControl);
3758 ret = -EINVAL;
3759 goto exit;
3760 }
3761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3762 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3763
3764 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3765 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003766#ifdef FEATURE_WLAN_OKC
3767 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3768 {
3769 tANI_U8 *value = command;
3770 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3771
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003772 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003773 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003774 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003775 hdd_is_okc_mode_enabled(pHddCtx) &&
3776 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3777 {
3778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003779 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003780 " hence this operation is not permitted!", __func__);
3781 ret = -EPERM;
3782 goto exit;
3783 }
3784
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003785 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3786 value = value + 11;
3787 /* Convert the value from ascii to integer */
3788 ret = kstrtou8(value, 10, &okcMode);
3789 if (ret < 0)
3790 {
3791 /* If the input value is greater than max value of datatype, then also
3792 kstrtou8 fails */
3793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3794 "%s: kstrtou8 failed range [%d - %d]", __func__,
3795 CFG_OKC_FEATURE_ENABLED_MIN,
3796 CFG_OKC_FEATURE_ENABLED_MAX);
3797 ret = -EINVAL;
3798 goto exit;
3799 }
3800
3801 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3802 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3803 {
3804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3805 "Okc mode value %d is out of range"
3806 " (Min: %d Max: %d)", okcMode,
3807 CFG_OKC_FEATURE_ENABLED_MIN,
3808 CFG_OKC_FEATURE_ENABLED_MAX);
3809 ret = -EINVAL;
3810 goto exit;
3811 }
3812
3813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3814 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3815
3816 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3817 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003818#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303819 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003820 {
3821 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3822 char extra[32];
3823 tANI_U8 len = 0;
3824
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003825 len = scnprintf(extra, sizeof(extra), "%s %d",
3826 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003827 if (copy_to_user(priv_data.buf, &extra, len + 1))
3828 {
3829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3830 "%s: failed to copy data to user buffer", __func__);
3831 ret = -EFAULT;
3832 goto exit;
3833 }
3834 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303835#ifdef WLAN_FEATURE_PACKET_FILTERING
3836 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3837 {
3838 tANI_U8 filterType = 0;
3839 tANI_U8 *value = command;
3840
3841 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3842 value = value + 22;
3843
3844 /* Convert the value from ascii to integer */
3845 ret = kstrtou8(value, 10, &filterType);
3846 if (ret < 0)
3847 {
3848 /* If the input value is greater than max value of datatype,
3849 * then also kstrtou8 fails
3850 */
3851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3852 "%s: kstrtou8 failed range ", __func__);
3853 ret = -EINVAL;
3854 goto exit;
3855 }
3856
3857 if (filterType != 0 && filterType != 1)
3858 {
3859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3860 "%s: Accepted Values are 0 and 1 ", __func__);
3861 ret = -EINVAL;
3862 goto exit;
3863 }
3864 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3865 pAdapter->sessionId);
3866 }
3867#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303868 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3869 {
Kiet Lamad161252014-07-22 11:23:32 -07003870 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303871 int ret;
3872
Kiet Lamad161252014-07-22 11:23:32 -07003873 dhcpPhase = command + 11;
3874 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303875 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003877 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303878
3879 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003880
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303881 ret = wlan_hdd_scan_abort(pAdapter);
3882 if (ret < 0)
3883 {
3884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3885 FL("failed to abort existing scan %d"), ret);
3886 }
3887
Kiet Lamad161252014-07-22 11:23:32 -07003888 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3889 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303890 }
Kiet Lamad161252014-07-22 11:23:32 -07003891 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303892 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003894 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303895
3896 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003897
3898 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3899 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303900 }
3901 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003902 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3903 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3905 FL("making default scan to ACTIVE"));
3906 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003907 }
3908 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3909 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3911 FL("making default scan to PASSIVE"));
3912 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003913 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303914 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3915 {
3916 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3917 char extra[32];
3918 tANI_U8 len = 0;
3919
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303920 memset(extra, 0, sizeof(extra));
3921 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3922 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303923 {
3924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3925 "%s: failed to copy data to user buffer", __func__);
3926 ret = -EFAULT;
3927 goto exit;
3928 }
3929 ret = len;
3930 }
3931 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3932 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303933 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303934 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003935 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3936 {
3937 tANI_U8 filterType = 0;
3938 tANI_U8 *value;
3939 value = command + 9;
3940
3941 /* Convert the value from ascii to integer */
3942 ret = kstrtou8(value, 10, &filterType);
3943 if (ret < 0)
3944 {
3945 /* If the input value is greater than max value of datatype,
3946 * then also kstrtou8 fails
3947 */
3948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3949 "%s: kstrtou8 failed range ", __func__);
3950 ret = -EINVAL;
3951 goto exit;
3952 }
3953 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3954 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3955 {
3956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3957 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3958 " 2-Sink ", __func__);
3959 ret = -EINVAL;
3960 goto exit;
3961 }
3962 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3963 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303964 pScanInfo = &pHddCtx->scan_info;
3965 if (filterType && pScanInfo != NULL &&
3966 pHddCtx->scan_info.mScanPending)
3967 {
3968 /*Miracast Session started. Abort Scan */
3969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3970 "%s, Aborting Scan For Miracast",__func__);
3971 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3972 eCSR_SCAN_ABORT_DEFAULT);
3973 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003974 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303975 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003976 }
Leo Chang614d2072013-08-22 14:59:44 -07003977 else if (strncmp(command, "SETMCRATE", 9) == 0)
3978 {
Leo Chang614d2072013-08-22 14:59:44 -07003979 tANI_U8 *value = command;
3980 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003981 tSirRateUpdateInd *rateUpdate;
3982 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003983
3984 /* Only valid for SAP mode */
3985 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3986 {
3987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3988 "%s: SAP mode is not running", __func__);
3989 ret = -EFAULT;
3990 goto exit;
3991 }
3992
3993 /* Move pointer to ahead of SETMCRATE<delimiter> */
3994 /* input value is in units of hundred kbps */
3995 value = value + 10;
3996 /* Convert the value from ascii to integer, decimal base */
3997 ret = kstrtouint(value, 10, &targetRate);
3998
Leo Chang1f98cbd2013-10-17 15:03:52 -07003999 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4000 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004001 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004002 hddLog(VOS_TRACE_LEVEL_ERROR,
4003 "%s: SETMCRATE indication alloc fail", __func__);
4004 ret = -EFAULT;
4005 goto exit;
4006 }
4007 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4008
4009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4010 "MC Target rate %d", targetRate);
4011 /* Ignore unicast */
4012 rateUpdate->ucastDataRate = -1;
4013 rateUpdate->mcastDataRate24GHz = targetRate;
4014 rateUpdate->mcastDataRate5GHz = targetRate;
4015 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4016 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4017 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4018 if (eHAL_STATUS_SUCCESS != status)
4019 {
4020 hddLog(VOS_TRACE_LEVEL_ERROR,
4021 "%s: SET_MC_RATE failed", __func__);
4022 vos_mem_free(rateUpdate);
4023 ret = -EFAULT;
4024 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004025 }
4026 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304027#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004028 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304029 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004030 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304031 }
4032#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004033#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004034 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4035 {
4036 tANI_U8 *value = command;
4037 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4038 tANI_U8 numChannels = 0;
4039 eHalStatus status = eHAL_STATUS_SUCCESS;
4040
4041 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4042 if (eHAL_STATUS_SUCCESS != status)
4043 {
4044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4045 "%s: Failed to parse channel list information", __func__);
4046 ret = -EINVAL;
4047 goto exit;
4048 }
4049
4050 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4051 {
4052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4053 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4054 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4055 ret = -EINVAL;
4056 goto exit;
4057 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004058 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004059 ChannelList,
4060 numChannels);
4061 if (eHAL_STATUS_SUCCESS != status)
4062 {
4063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4064 "%s: Failed to update channel list information", __func__);
4065 ret = -EINVAL;
4066 goto exit;
4067 }
4068 }
4069 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4070 {
4071 tANI_U8 *value = command;
4072 char extra[128] = {0};
4073 int len = 0;
4074 tANI_U8 tid = 0;
4075 hdd_station_ctx_t *pHddStaCtx = NULL;
4076 tAniTrafStrmMetrics tsmMetrics;
4077 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4078
4079 /* if not associated, return error */
4080 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4081 {
4082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4083 ret = -EINVAL;
4084 goto exit;
4085 }
4086
4087 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4088 value = value + 12;
4089 /* Convert the value from ascii to integer */
4090 ret = kstrtou8(value, 10, &tid);
4091 if (ret < 0)
4092 {
4093 /* If the input value is greater than max value of datatype, then also
4094 kstrtou8 fails */
4095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4096 "%s: kstrtou8 failed range [%d - %d]", __func__,
4097 TID_MIN_VALUE,
4098 TID_MAX_VALUE);
4099 ret = -EINVAL;
4100 goto exit;
4101 }
4102
4103 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4104 {
4105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4106 "tid value %d is out of range"
4107 " (Min: %d Max: %d)", tid,
4108 TID_MIN_VALUE,
4109 TID_MAX_VALUE);
4110 ret = -EINVAL;
4111 goto exit;
4112 }
4113
4114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4115 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4116
4117 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4118 {
4119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4120 "%s: failed to get tsm stats", __func__);
4121 ret = -EFAULT;
4122 goto exit;
4123 }
4124
4125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4126 "UplinkPktQueueDly(%d)\n"
4127 "UplinkPktQueueDlyHist[0](%d)\n"
4128 "UplinkPktQueueDlyHist[1](%d)\n"
4129 "UplinkPktQueueDlyHist[2](%d)\n"
4130 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304131 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004132 "UplinkPktLoss(%d)\n"
4133 "UplinkPktCount(%d)\n"
4134 "RoamingCount(%d)\n"
4135 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4136 tsmMetrics.UplinkPktQueueDlyHist[0],
4137 tsmMetrics.UplinkPktQueueDlyHist[1],
4138 tsmMetrics.UplinkPktQueueDlyHist[2],
4139 tsmMetrics.UplinkPktQueueDlyHist[3],
4140 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4141 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4142
4143 /* Output TSM stats is of the format
4144 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4145 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004146 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004147 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4148 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4149 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4150 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4151 tsmMetrics.RoamingDly);
4152
4153 if (copy_to_user(priv_data.buf, &extra, len + 1))
4154 {
4155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4156 "%s: failed to copy data to user buffer", __func__);
4157 ret = -EFAULT;
4158 goto exit;
4159 }
4160 }
4161 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4162 {
4163 tANI_U8 *value = command;
4164 tANI_U8 *cckmIe = NULL;
4165 tANI_U8 cckmIeLen = 0;
4166 eHalStatus status = eHAL_STATUS_SUCCESS;
4167
4168 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4169 if (eHAL_STATUS_SUCCESS != status)
4170 {
4171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4172 "%s: Failed to parse cckm ie data", __func__);
4173 ret = -EINVAL;
4174 goto exit;
4175 }
4176
4177 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4178 {
4179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4180 "%s: CCKM Ie input length is more than max[%d]", __func__,
4181 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004182 vos_mem_free(cckmIe);
4183 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004184 ret = -EINVAL;
4185 goto exit;
4186 }
4187 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004188 vos_mem_free(cckmIe);
4189 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004190 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004191 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4192 {
4193 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004194 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004195 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004196
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004197 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004198 if (eHAL_STATUS_SUCCESS != status)
4199 {
4200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004201 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004202 ret = -EINVAL;
4203 goto exit;
4204 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004205 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4206 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4207 hdd_indicateEseBcnReportNoResults (pAdapter,
4208 eseBcnReq.bcnReq[0].measurementToken,
4209 0x02, //BIT(1) set for measurement done
4210 0); // no BSS
4211 goto exit;
4212 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004213
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004214 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4215 if (eHAL_STATUS_SUCCESS != status)
4216 {
4217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4218 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4219 ret = -EINVAL;
4220 goto exit;
4221 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004222 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004223#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304224 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4225 {
4226 eHalStatus status;
4227 char buf[32], len;
4228 long waitRet;
4229 bcnMissRateContext_t getBcnMissRateCtx;
4230
4231 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4232
4233 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4234 {
4235 hddLog(VOS_TRACE_LEVEL_WARN,
4236 FL("GETBCNMISSRATE: STA is not in connected state"));
4237 ret = -1;
4238 goto exit;
4239 }
4240
4241 init_completion(&(getBcnMissRateCtx.completion));
4242 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4243
4244 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4245 pAdapter->sessionId,
4246 (void *)getBcnMissRateCB,
4247 (void *)(&getBcnMissRateCtx));
4248 if( eHAL_STATUS_SUCCESS != status)
4249 {
4250 hddLog(VOS_TRACE_LEVEL_INFO,
4251 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4252 ret = -EINVAL;
4253 goto exit;
4254 }
4255
4256 waitRet = wait_for_completion_interruptible_timeout
4257 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4258 if(waitRet <= 0)
4259 {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,
4261 FL("failed to wait on bcnMissRateComp %d"), ret);
4262
4263 //Make magic number to zero so that callback is not called.
4264 spin_lock(&hdd_context_lock);
4265 getBcnMissRateCtx.magic = 0x0;
4266 spin_unlock(&hdd_context_lock);
4267 ret = -EINVAL;
4268 goto exit;
4269 }
4270
4271 hddLog(VOS_TRACE_LEVEL_INFO,
4272 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4273
4274 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4275 if (copy_to_user(priv_data.buf, &buf, len + 1))
4276 {
4277 hddLog(VOS_TRACE_LEVEL_ERROR,
4278 "%s: failed to copy data to user buffer", __func__);
4279 ret = -EFAULT;
4280 goto exit;
4281 }
4282 ret = len;
4283 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304284#ifdef FEATURE_WLAN_TDLS
4285 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4286 tANI_U8 *value = command;
4287 int set_value;
4288 /* Move pointer to ahead of TDLSOFFCH*/
4289 value += 26;
4290 sscanf(value, "%d", &set_value);
4291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4292 "%s: Tdls offchannel offset:%d",
4293 __func__, set_value);
4294 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4295 if (ret < 0)
4296 {
4297 ret = -EINVAL;
4298 goto exit;
4299 }
4300
4301 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4302 tANI_U8 *value = command;
4303 int set_value;
4304 /* Move pointer to ahead of tdlsoffchnmode*/
4305 value += 18;
4306 sscanf(value, "%d", &set_value);
4307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4308 "%s: Tdls offchannel mode:%d",
4309 __func__, set_value);
4310 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4311 if (ret < 0)
4312 {
4313 ret = -EINVAL;
4314 goto exit;
4315 }
4316 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4317 tANI_U8 *value = command;
4318 int set_value;
4319 /* Move pointer to ahead of TDLSOFFCH*/
4320 value += 14;
4321 sscanf(value, "%d", &set_value);
4322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4323 "%s: Tdls offchannel num: %d",
4324 __func__, set_value);
4325 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4326 if (ret < 0)
4327 {
4328 ret = -EINVAL;
4329 goto exit;
4330 }
4331 }
4332#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304333 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4334 {
4335 eHalStatus status;
4336 char *buf = NULL;
4337 char len;
4338 long waitRet;
4339 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304340 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304341 tANI_U8 *ptr = command;
4342 int stats = *(ptr + 11) - '0';
4343
4344 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4345 if (!IS_FEATURE_FW_STATS_ENABLE)
4346 {
4347 hddLog(VOS_TRACE_LEVEL_INFO,
4348 FL("Get Firmware stats feature not supported"));
4349 ret = -EINVAL;
4350 goto exit;
4351 }
4352
4353 if (FW_STATS_MAX <= stats || 0 >= stats)
4354 {
4355 hddLog(VOS_TRACE_LEVEL_INFO,
4356 FL(" stats %d not supported"),stats);
4357 ret = -EINVAL;
4358 goto exit;
4359 }
4360
4361 init_completion(&(fwStatsCtx.completion));
4362 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4363 fwStatsCtx.pAdapter = pAdapter;
4364 fwStatsRsp->type = 0;
4365 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304366 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304367 if (eHAL_STATUS_SUCCESS != status)
4368 {
4369 hddLog(VOS_TRACE_LEVEL_ERROR,
4370 FL(" fail to post WDA cmd status = %d"), status);
4371 ret = -EINVAL;
4372 goto exit;
4373 }
4374 waitRet = wait_for_completion_timeout
4375 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4376 if (waitRet <= 0)
4377 {
4378 hddLog(VOS_TRACE_LEVEL_ERROR,
4379 FL("failed to wait on GwtFwstats"));
4380 //Make magic number to zero so that callback is not executed.
4381 spin_lock(&hdd_context_lock);
4382 fwStatsCtx.magic = 0x0;
4383 spin_unlock(&hdd_context_lock);
4384 ret = -EINVAL;
4385 goto exit;
4386 }
4387 if (fwStatsRsp->type)
4388 {
4389 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4390 if (!buf)
4391 {
4392 hddLog(VOS_TRACE_LEVEL_ERROR,
4393 FL(" failed to allocate memory"));
4394 ret = -ENOMEM;
4395 goto exit;
4396 }
4397 switch( fwStatsRsp->type )
4398 {
4399 case FW_UBSP_STATS:
4400 {
4401 len = snprintf(buf, FW_STATE_RSP_LEN,
4402 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304403 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4404 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304405 }
4406 break;
4407 default:
4408 {
4409 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4410 ret = -EFAULT;
4411 kfree(buf);
4412 goto exit;
4413 }
4414 }
4415 if (copy_to_user(priv_data.buf, buf, len + 1))
4416 {
4417 hddLog(VOS_TRACE_LEVEL_ERROR,
4418 FL(" failed to copy data to user buffer"));
4419 ret = -EFAULT;
4420 kfree(buf);
4421 goto exit;
4422 }
4423 ret = len;
4424 kfree(buf);
4425 }
4426 else
4427 {
4428 hddLog(VOS_TRACE_LEVEL_ERROR,
4429 FL("failed to fetch the stats"));
4430 ret = -EFAULT;
4431 goto exit;
4432 }
4433
4434 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304435 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4436 {
4437 /*
4438 * this command wld be called by user-space when it detects WLAN
4439 * ON after airplane mode is set. When APM is set, WLAN turns off.
4440 * But it can be turned back on. Otherwise; when APM is turned back
4441 * off, WLAN wld turn back on. So at that point the command is
4442 * expected to come down. 0 means disable, 1 means enable. The
4443 * constraint is removed when parameter 1 is set or different
4444 * country code is set
4445 */
4446 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4447 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004448 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304449 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4450 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4451 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304452 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4453 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004454 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 }
4456exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304457 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004458 if (command)
4459 {
4460 kfree(command);
4461 }
4462 return ret;
4463}
4464
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004465#ifdef CONFIG_COMPAT
4466static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4467{
4468 struct {
4469 compat_uptr_t buf;
4470 int used_len;
4471 int total_len;
4472 } compat_priv_data;
4473 hdd_priv_data_t priv_data;
4474 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004475
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004476 /*
4477 * Note that pAdapter and ifr have already been verified by caller,
4478 * and HDD context has also been validated
4479 */
4480 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4481 sizeof(compat_priv_data))) {
4482 ret = -EFAULT;
4483 goto exit;
4484 }
4485 priv_data.buf = compat_ptr(compat_priv_data.buf);
4486 priv_data.used_len = compat_priv_data.used_len;
4487 priv_data.total_len = compat_priv_data.total_len;
4488 ret = hdd_driver_command(pAdapter, &priv_data);
4489 exit:
4490 return ret;
4491}
4492#else /* CONFIG_COMPAT */
4493static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4494{
4495 /* will never be invoked */
4496 return 0;
4497}
4498#endif /* CONFIG_COMPAT */
4499
4500static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4501{
4502 hdd_priv_data_t priv_data;
4503 int ret = 0;
4504
4505 /*
4506 * Note that pAdapter and ifr have already been verified by caller,
4507 * and HDD context has also been validated
4508 */
4509 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4510 ret = -EFAULT;
4511 } else {
4512 ret = hdd_driver_command(pAdapter, &priv_data);
4513 }
4514 return ret;
4515}
4516
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304517int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004518{
4519 hdd_adapter_t *pAdapter;
4520 hdd_context_t *pHddCtx;
4521 int ret;
4522
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304523 ENTER();
4524
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004525 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4526 if (NULL == pAdapter) {
4527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4528 "%s: HDD adapter context is Null", __func__);
4529 ret = -ENODEV;
4530 goto exit;
4531 }
4532 if (dev != pAdapter->dev) {
4533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4534 "%s: HDD adapter/dev inconsistency", __func__);
4535 ret = -ENODEV;
4536 goto exit;
4537 }
4538
4539 if ((!ifr) || (!ifr->ifr_data)) {
4540 ret = -EINVAL;
4541 goto exit;
4542 }
4543
4544 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4545 ret = wlan_hdd_validate_context(pHddCtx);
4546 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004547 ret = -EBUSY;
4548 goto exit;
4549 }
4550
4551 switch (cmd) {
4552 case (SIOCDEVPRIVATE + 1):
4553 if (is_compat_task())
4554 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4555 else
4556 ret = hdd_driver_ioctl(pAdapter, ifr);
4557 break;
4558 default:
4559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4560 __func__, cmd);
4561 ret = -EINVAL;
4562 break;
4563 }
4564 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304565 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004566 return ret;
4567}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004568
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304569int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4570{
4571 int ret;
4572
4573 vos_ssr_protect(__func__);
4574 ret = __hdd_ioctl(dev, ifr, cmd);
4575 vos_ssr_unprotect(__func__);
4576
4577 return ret;
4578}
4579
Katya Nigame7b69a82015-04-28 15:24:06 +05304580int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4581{
4582 return 0;
4583}
4584
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004585#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004586/**---------------------------------------------------------------------------
4587
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004588 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004589
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004590 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004591 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4592 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4593 <space>Scan Mode N<space>Meas Duration N
4594 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4595 then take N.
4596 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4597 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4598 This function does not take care of removing duplicate channels from the list
4599
4600 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004601 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004602
4603 \return - 0 for success non-zero for failure
4604
4605 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004606static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4607 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004608{
4609 tANI_U8 *inPtr = pValue;
4610 int tempInt = 0;
4611 int j = 0, i = 0, v = 0;
4612 char buf[32];
4613
4614 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4615 /*no argument after the command*/
4616 if (NULL == inPtr)
4617 {
4618 return -EINVAL;
4619 }
4620 /*no space after the command*/
4621 else if (SPACE_ASCII_VALUE != *inPtr)
4622 {
4623 return -EINVAL;
4624 }
4625
4626 /*removing empty spaces*/
4627 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4628
4629 /*no argument followed by spaces*/
4630 if ('\0' == *inPtr) return -EINVAL;
4631
4632 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004633 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004634 if (1 != v) return -EINVAL;
4635
4636 v = kstrtos32(buf, 10, &tempInt);
4637 if ( v < 0) return -EINVAL;
4638
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004639 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004640
4641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004642 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004643
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004644 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004645 {
4646 for (i = 0; i < 4; i++)
4647 {
4648 /*inPtr pointing to the beginning of first space after number of ie fields*/
4649 inPtr = strpbrk( inPtr, " " );
4650 /*no ie data after the number of ie fields argument*/
4651 if (NULL == inPtr) return -EINVAL;
4652
4653 /*removing empty space*/
4654 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4655
4656 /*no ie data after the number of ie fields argument and spaces*/
4657 if ( '\0' == *inPtr ) return -EINVAL;
4658
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004659 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004660 if (1 != v) return -EINVAL;
4661
4662 v = kstrtos32(buf, 10, &tempInt);
4663 if (v < 0) return -EINVAL;
4664
4665 switch (i)
4666 {
4667 case 0: /* Measurement token */
4668 if (tempInt <= 0)
4669 {
4670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4671 "Invalid Measurement Token(%d)", tempInt);
4672 return -EINVAL;
4673 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004674 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004675 break;
4676
4677 case 1: /* Channel number */
4678 if ((tempInt <= 0) ||
4679 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4680 {
4681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4682 "Invalid Channel Number(%d)", tempInt);
4683 return -EINVAL;
4684 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004685 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004686 break;
4687
4688 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004689 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004690 {
4691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4692 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4693 return -EINVAL;
4694 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004695 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004696 break;
4697
4698 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004699 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4700 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004701 {
4702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4703 "Invalid Measurement Duration(%d)", tempInt);
4704 return -EINVAL;
4705 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004706 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004707 break;
4708 }
4709 }
4710 }
4711
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004712 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004713 {
4714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304715 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004716 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004717 pEseBcnReq->bcnReq[j].measurementToken,
4718 pEseBcnReq->bcnReq[j].channel,
4719 pEseBcnReq->bcnReq[j].scanMode,
4720 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004721 }
4722
4723 return VOS_STATUS_SUCCESS;
4724}
4725
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004726static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4727{
4728 struct statsContext *pStatsContext = NULL;
4729 hdd_adapter_t *pAdapter = NULL;
4730
4731 if (NULL == pContext)
4732 {
4733 hddLog(VOS_TRACE_LEVEL_ERROR,
4734 "%s: Bad param, pContext [%p]",
4735 __func__, pContext);
4736 return;
4737 }
4738
Jeff Johnson72a40512013-12-19 10:14:15 -08004739 /* there is a race condition that exists between this callback
4740 function and the caller since the caller could time out either
4741 before or while this code is executing. we use a spinlock to
4742 serialize these actions */
4743 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004744
4745 pStatsContext = pContext;
4746 pAdapter = pStatsContext->pAdapter;
4747 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4748 {
4749 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004750 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004751 hddLog(VOS_TRACE_LEVEL_WARN,
4752 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4753 __func__, pAdapter, pStatsContext->magic);
4754 return;
4755 }
4756
Jeff Johnson72a40512013-12-19 10:14:15 -08004757 /* context is valid so caller is still waiting */
4758
4759 /* paranoia: invalidate the magic */
4760 pStatsContext->magic = 0;
4761
4762 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004763 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4764 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4765 tsmMetrics.UplinkPktQueueDlyHist,
4766 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4767 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4768 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4769 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4770 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4771 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4772 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4773
Jeff Johnson72a40512013-12-19 10:14:15 -08004774 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004775 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004776
4777 /* serialization is complete */
4778 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004779}
4780
4781
4782
4783static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4784 tAniTrafStrmMetrics* pTsmMetrics)
4785{
4786 hdd_station_ctx_t *pHddStaCtx = NULL;
4787 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004788 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004789 long lrc;
4790 struct statsContext context;
4791 hdd_context_t *pHddCtx = NULL;
4792
4793 if (NULL == pAdapter)
4794 {
4795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4796 return VOS_STATUS_E_FAULT;
4797 }
4798
4799 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4800 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4801
4802 /* we are connected prepare our callback context */
4803 init_completion(&context.completion);
4804 context.pAdapter = pAdapter;
4805 context.magic = STATS_CONTEXT_MAGIC;
4806
4807 /* query tsm stats */
4808 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4809 pHddStaCtx->conn_info.staId[ 0 ],
4810 pHddStaCtx->conn_info.bssId,
4811 &context, pHddCtx->pvosContext, tid);
4812
4813 if (eHAL_STATUS_SUCCESS != hstatus)
4814 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4816 __func__);
4817 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004818 }
4819 else
4820 {
4821 /* request was sent -- wait for the response */
4822 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4823 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004824 if (lrc <= 0)
4825 {
4826 hddLog(VOS_TRACE_LEVEL_ERROR,
4827 "%s: SME %s while retrieving statistics",
4828 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004829 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004830 }
4831 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004832
Jeff Johnson72a40512013-12-19 10:14:15 -08004833 /* either we never sent a request, we sent a request and received a
4834 response or we sent a request and timed out. if we never sent a
4835 request or if we sent a request and got a response, we want to
4836 clear the magic out of paranoia. if we timed out there is a
4837 race condition such that the callback function could be
4838 executing at the same time we are. of primary concern is if the
4839 callback function had already verified the "magic" but had not
4840 yet set the completion variable when a timeout occurred. we
4841 serialize these activities by invalidating the magic while
4842 holding a shared spinlock which will cause us to block if the
4843 callback is currently executing */
4844 spin_lock(&hdd_context_lock);
4845 context.magic = 0;
4846 spin_unlock(&hdd_context_lock);
4847
4848 if (VOS_STATUS_SUCCESS == vstatus)
4849 {
4850 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4851 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4852 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4853 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4854 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4855 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4856 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4857 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4858 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4859 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4860 }
4861 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004862}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004863#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004864
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004865#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004866void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4867{
4868 eCsrBand band = -1;
4869 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4870 switch (band)
4871 {
4872 case eCSR_BAND_ALL:
4873 *pBand = WLAN_HDD_UI_BAND_AUTO;
4874 break;
4875
4876 case eCSR_BAND_24:
4877 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4878 break;
4879
4880 case eCSR_BAND_5G:
4881 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4882 break;
4883
4884 default:
4885 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4886 *pBand = -1;
4887 break;
4888 }
4889}
4890
4891/**---------------------------------------------------------------------------
4892
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004893 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4894
4895 This function parses the send action frame data passed in the format
4896 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4897
Srinivas Girigowda56076852013-08-20 14:00:50 -07004898 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004899 \param - pTargetApBssid Pointer to target Ap bssid
4900 \param - pChannel Pointer to the Target AP channel
4901 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4902 \param - pBuf Pointer to data
4903 \param - pBufLen Pointer to data length
4904
4905 \return - 0 for success non-zero for failure
4906
4907 --------------------------------------------------------------------------*/
4908VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4909 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4910{
4911 tANI_U8 *inPtr = pValue;
4912 tANI_U8 *dataEnd;
4913 int tempInt;
4914 int j = 0;
4915 int i = 0;
4916 int v = 0;
4917 tANI_U8 tempBuf[32];
4918 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004919 /* 12 hexa decimal digits, 5 ':' and '\0' */
4920 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004921
4922 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4923 /*no argument after the command*/
4924 if (NULL == inPtr)
4925 {
4926 return -EINVAL;
4927 }
4928
4929 /*no space after the command*/
4930 else if (SPACE_ASCII_VALUE != *inPtr)
4931 {
4932 return -EINVAL;
4933 }
4934
4935 /*removing empty spaces*/
4936 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4937
4938 /*no argument followed by spaces*/
4939 if ('\0' == *inPtr)
4940 {
4941 return -EINVAL;
4942 }
4943
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004944 v = sscanf(inPtr, "%17s", macAddress);
4945 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004946 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4948 "Invalid MAC address or All hex inputs are not read (%d)", v);
4949 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004950 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004951
4952 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4953 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4954 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4955 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4956 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4957 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004958
4959 /* point to the next argument */
4960 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4961 /*no argument after the command*/
4962 if (NULL == inPtr) return -EINVAL;
4963
4964 /*removing empty spaces*/
4965 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4966
4967 /*no argument followed by spaces*/
4968 if ('\0' == *inPtr)
4969 {
4970 return -EINVAL;
4971 }
4972
4973 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004974 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004975 if (1 != v) return -EINVAL;
4976
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004977 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304978 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304979 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004980
4981 *pChannel = tempInt;
4982
4983 /* point to the next argument */
4984 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4985 /*no argument after the command*/
4986 if (NULL == inPtr) return -EINVAL;
4987 /*removing empty spaces*/
4988 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4989
4990 /*no argument followed by spaces*/
4991 if ('\0' == *inPtr)
4992 {
4993 return -EINVAL;
4994 }
4995
4996 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004997 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004998 if (1 != v) return -EINVAL;
4999
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005000 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005001 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005002
5003 *pDwellTime = tempInt;
5004
5005 /* point to the next argument */
5006 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5007 /*no argument after the command*/
5008 if (NULL == inPtr) return -EINVAL;
5009 /*removing empty spaces*/
5010 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5011
5012 /*no argument followed by spaces*/
5013 if ('\0' == *inPtr)
5014 {
5015 return -EINVAL;
5016 }
5017
5018 /* find the length of data */
5019 dataEnd = inPtr;
5020 while(('\0' != *dataEnd) )
5021 {
5022 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005023 }
Kiet Lambe150c22013-11-21 16:30:32 +05305024 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005025 if ( *pBufLen <= 0) return -EINVAL;
5026
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005027 /* Allocate the number of bytes based on the number of input characters
5028 whether it is even or odd.
5029 if the number of input characters are even, then we need N/2 byte.
5030 if the number of input characters are odd, then we need do (N+1)/2 to
5031 compensate rounding off.
5032 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5033 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5034 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005035 if (NULL == *pBuf)
5036 {
5037 hddLog(VOS_TRACE_LEVEL_FATAL,
5038 "%s: vos_mem_alloc failed ", __func__);
5039 return -EINVAL;
5040 }
5041
5042 /* the buffer received from the upper layer is character buffer,
5043 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5044 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5045 and f0 in 3rd location */
5046 for (i = 0, j = 0; j < *pBufLen; j += 2)
5047 {
Kiet Lambe150c22013-11-21 16:30:32 +05305048 if( j+1 == *pBufLen)
5049 {
5050 tempByte = hdd_parse_hex(inPtr[j]);
5051 }
5052 else
5053 {
5054 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5055 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005056 (*pBuf)[i++] = tempByte;
5057 }
5058 *pBufLen = i;
5059 return VOS_STATUS_SUCCESS;
5060}
5061
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005062/**---------------------------------------------------------------------------
5063
Srinivas Girigowdade697412013-02-14 16:31:48 -08005064 \brief hdd_parse_channellist() - HDD Parse channel list
5065
5066 This function parses the channel list passed in the format
5067 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005068 if the Number of channels (N) does not match with the actual number of channels passed
5069 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5070 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5071 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5072 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005073
5074 \param - pValue Pointer to input channel list
5075 \param - ChannelList Pointer to local output array to record channel list
5076 \param - pNumChannels Pointer to number of roam scan channels
5077
5078 \return - 0 for success non-zero for failure
5079
5080 --------------------------------------------------------------------------*/
5081VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5082{
5083 tANI_U8 *inPtr = pValue;
5084 int tempInt;
5085 int j = 0;
5086 int v = 0;
5087 char buf[32];
5088
5089 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5090 /*no argument after the command*/
5091 if (NULL == inPtr)
5092 {
5093 return -EINVAL;
5094 }
5095
5096 /*no space after the command*/
5097 else if (SPACE_ASCII_VALUE != *inPtr)
5098 {
5099 return -EINVAL;
5100 }
5101
5102 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005103 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005104
5105 /*no argument followed by spaces*/
5106 if ('\0' == *inPtr)
5107 {
5108 return -EINVAL;
5109 }
5110
5111 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005112 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005113 if (1 != v) return -EINVAL;
5114
Srinivas Girigowdade697412013-02-14 16:31:48 -08005115 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005116 if ((v < 0) ||
5117 (tempInt <= 0) ||
5118 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5119 {
5120 return -EINVAL;
5121 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005122
5123 *pNumChannels = tempInt;
5124
5125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5126 "Number of channels are: %d", *pNumChannels);
5127
5128 for (j = 0; j < (*pNumChannels); j++)
5129 {
5130 /*inPtr pointing to the beginning of first space after number of channels*/
5131 inPtr = strpbrk( inPtr, " " );
5132 /*no channel list after the number of channels argument*/
5133 if (NULL == inPtr)
5134 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005135 if (0 != j)
5136 {
5137 *pNumChannels = j;
5138 return VOS_STATUS_SUCCESS;
5139 }
5140 else
5141 {
5142 return -EINVAL;
5143 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005144 }
5145
5146 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005147 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005148
5149 /*no channel list after the number of channels argument and spaces*/
5150 if ( '\0' == *inPtr )
5151 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005152 if (0 != j)
5153 {
5154 *pNumChannels = j;
5155 return VOS_STATUS_SUCCESS;
5156 }
5157 else
5158 {
5159 return -EINVAL;
5160 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005161 }
5162
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005163 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005164 if (1 != v) return -EINVAL;
5165
Srinivas Girigowdade697412013-02-14 16:31:48 -08005166 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005167 if ((v < 0) ||
5168 (tempInt <= 0) ||
5169 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5170 {
5171 return -EINVAL;
5172 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005173 pChannelList[j] = tempInt;
5174
5175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5176 "Channel %d added to preferred channel list",
5177 pChannelList[j] );
5178 }
5179
Srinivas Girigowdade697412013-02-14 16:31:48 -08005180 return VOS_STATUS_SUCCESS;
5181}
5182
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005183
5184/**---------------------------------------------------------------------------
5185
5186 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5187
5188 This function parses the reasoc command data passed in the format
5189 REASSOC<space><bssid><space><channel>
5190
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005191 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005192 \param - pTargetApBssid Pointer to target Ap bssid
5193 \param - pChannel Pointer to the Target AP channel
5194
5195 \return - 0 for success non-zero for failure
5196
5197 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005198VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5199 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005200{
5201 tANI_U8 *inPtr = pValue;
5202 int tempInt;
5203 int v = 0;
5204 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005205 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005206 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005207
5208 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5209 /*no argument after the command*/
5210 if (NULL == inPtr)
5211 {
5212 return -EINVAL;
5213 }
5214
5215 /*no space after the command*/
5216 else if (SPACE_ASCII_VALUE != *inPtr)
5217 {
5218 return -EINVAL;
5219 }
5220
5221 /*removing empty spaces*/
5222 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5223
5224 /*no argument followed by spaces*/
5225 if ('\0' == *inPtr)
5226 {
5227 return -EINVAL;
5228 }
5229
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005230 v = sscanf(inPtr, "%17s", macAddress);
5231 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005232 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5234 "Invalid MAC address or All hex inputs are not read (%d)", v);
5235 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005236 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005237
5238 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5239 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5240 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5241 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5242 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5243 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005244
5245 /* point to the next argument */
5246 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5247 /*no argument after the command*/
5248 if (NULL == inPtr) return -EINVAL;
5249
5250 /*removing empty spaces*/
5251 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5252
5253 /*no argument followed by spaces*/
5254 if ('\0' == *inPtr)
5255 {
5256 return -EINVAL;
5257 }
5258
5259 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005260 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005261 if (1 != v) return -EINVAL;
5262
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005263 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005264 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305265 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005266 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5267 {
5268 return -EINVAL;
5269 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005270
5271 *pChannel = tempInt;
5272 return VOS_STATUS_SUCCESS;
5273}
5274
5275#endif
5276
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005277#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005278/**---------------------------------------------------------------------------
5279
5280 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5281
5282 This function parses the SETCCKM IE command
5283 SETCCKMIE<space><ie data>
5284
5285 \param - pValue Pointer to input data
5286 \param - pCckmIe Pointer to output cckm Ie
5287 \param - pCckmIeLen Pointer to output cckm ie length
5288
5289 \return - 0 for success non-zero for failure
5290
5291 --------------------------------------------------------------------------*/
5292VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5293 tANI_U8 *pCckmIeLen)
5294{
5295 tANI_U8 *inPtr = pValue;
5296 tANI_U8 *dataEnd;
5297 int j = 0;
5298 int i = 0;
5299 tANI_U8 tempByte = 0;
5300
5301 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5302 /*no argument after the command*/
5303 if (NULL == inPtr)
5304 {
5305 return -EINVAL;
5306 }
5307
5308 /*no space after the command*/
5309 else if (SPACE_ASCII_VALUE != *inPtr)
5310 {
5311 return -EINVAL;
5312 }
5313
5314 /*removing empty spaces*/
5315 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5316
5317 /*no argument followed by spaces*/
5318 if ('\0' == *inPtr)
5319 {
5320 return -EINVAL;
5321 }
5322
5323 /* find the length of data */
5324 dataEnd = inPtr;
5325 while(('\0' != *dataEnd) )
5326 {
5327 dataEnd++;
5328 ++(*pCckmIeLen);
5329 }
5330 if ( *pCckmIeLen <= 0) return -EINVAL;
5331
5332 /* Allocate the number of bytes based on the number of input characters
5333 whether it is even or odd.
5334 if the number of input characters are even, then we need N/2 byte.
5335 if the number of input characters are odd, then we need do (N+1)/2 to
5336 compensate rounding off.
5337 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5338 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5339 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5340 if (NULL == *pCckmIe)
5341 {
5342 hddLog(VOS_TRACE_LEVEL_FATAL,
5343 "%s: vos_mem_alloc failed ", __func__);
5344 return -EINVAL;
5345 }
5346 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5347 /* the buffer received from the upper layer is character buffer,
5348 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5349 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5350 and f0 in 3rd location */
5351 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5352 {
5353 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5354 (*pCckmIe)[i++] = tempByte;
5355 }
5356 *pCckmIeLen = i;
5357
5358 return VOS_STATUS_SUCCESS;
5359}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005360#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005361
Jeff Johnson295189b2012-06-20 16:38:30 -07005362/**---------------------------------------------------------------------------
5363
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005364 \brief hdd_is_valid_mac_address() - Validate MAC address
5365
5366 This function validates whether the given MAC address is valid or not
5367 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5368 where X is the hexa decimal digit character and separated by ':'
5369 This algorithm works even if MAC address is not separated by ':'
5370
5371 This code checks given input string mac contains exactly 12 hexadecimal digits.
5372 and a separator colon : appears in the input string only after
5373 an even number of hex digits.
5374
5375 \param - pMacAddr pointer to the input MAC address
5376 \return - 1 for valid and 0 for invalid
5377
5378 --------------------------------------------------------------------------*/
5379
5380v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5381{
5382 int xdigit = 0;
5383 int separator = 0;
5384 while (*pMacAddr)
5385 {
5386 if (isxdigit(*pMacAddr))
5387 {
5388 xdigit++;
5389 }
5390 else if (':' == *pMacAddr)
5391 {
5392 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5393 break;
5394
5395 ++separator;
5396 }
5397 else
5398 {
5399 separator = -1;
5400 /* Invalid MAC found */
5401 return 0;
5402 }
5403 ++pMacAddr;
5404 }
5405 return (xdigit == 12 && (separator == 5 || separator == 0));
5406}
5407
5408/**---------------------------------------------------------------------------
5409
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305410 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005411
5412 \param - dev Pointer to net_device structure
5413
5414 \return - 0 for success non-zero for failure
5415
5416 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305417int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005418{
5419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5420 hdd_context_t *pHddCtx;
5421 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5422 VOS_STATUS status;
5423 v_BOOL_t in_standby = TRUE;
5424
5425 if (NULL == pAdapter)
5426 {
5427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305428 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 return -ENODEV;
5430 }
5431
5432 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305433 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5434 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 if (NULL == pHddCtx)
5436 {
5437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005438 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 return -ENODEV;
5440 }
5441
5442 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5443 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5444 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005445 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5446 {
5447 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305448 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005449 in_standby = FALSE;
5450 break;
5451 }
5452 else
5453 {
5454 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5455 pAdapterNode = pNext;
5456 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005457 }
5458
5459 if (TRUE == in_standby)
5460 {
5461 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5462 {
5463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5464 "wlan out of power save", __func__);
5465 return -EINVAL;
5466 }
5467 }
5468
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005469 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5471 {
5472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005473 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305475 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 netif_tx_start_all_queues(dev);
5477 }
5478
5479 return 0;
5480}
5481
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305482/**---------------------------------------------------------------------------
5483
5484 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5485
5486 This is called in response to ifconfig up
5487
5488 \param - dev Pointer to net_device structure
5489
5490 \return - 0 for success non-zero for failure
5491
5492 --------------------------------------------------------------------------*/
5493int hdd_open(struct net_device *dev)
5494{
5495 int ret;
5496
5497 vos_ssr_protect(__func__);
5498 ret = __hdd_open(dev);
5499 vos_ssr_unprotect(__func__);
5500
5501 return ret;
5502}
5503
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305504int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005505{
5506 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5507
5508 if(pAdapter == NULL) {
5509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005510 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005511 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005512 }
5513
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 return 0;
5515}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305516
5517int hdd_mon_open (struct net_device *dev)
5518{
5519 int ret;
5520
5521 vos_ssr_protect(__func__);
5522 ret = __hdd_mon_open(dev);
5523 vos_ssr_unprotect(__func__);
5524
5525 return ret;
5526}
5527
Katya Nigame7b69a82015-04-28 15:24:06 +05305528int hdd_mon_stop(struct net_device *dev)
5529{
5530 return 0;
5531}
5532
Jeff Johnson295189b2012-06-20 16:38:30 -07005533/**---------------------------------------------------------------------------
5534
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305535 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005536
5537 \param - dev Pointer to net_device structure
5538
5539 \return - 0 for success non-zero for failure
5540
5541 --------------------------------------------------------------------------*/
5542
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305543int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005544{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305545 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5547 hdd_context_t *pHddCtx;
5548 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5549 VOS_STATUS status;
5550 v_BOOL_t enter_standby = TRUE;
5551
5552 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 if (NULL == pAdapter)
5554 {
5555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305556 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 return -ENODEV;
5558 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305559 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305560 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305561
5562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5563 ret = wlan_hdd_validate_context(pHddCtx);
5564 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305566 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 }
5568
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305569 /* Nothing to be done if the interface is not opened */
5570 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5571 {
5572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5573 "%s: NETDEV Interface is not OPENED", __func__);
5574 return -ENODEV;
5575 }
5576
5577 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005578 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305580
5581 /* Disable TX on the interface, after this hard_start_xmit() will not
5582 * be called on that interface
5583 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305584 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005585 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305586
5587 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 netif_carrier_off(pAdapter->dev);
5589
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305590 /* The interface is marked as down for outside world (aka kernel)
5591 * But the driver is pretty much alive inside. The driver needs to
5592 * tear down the existing connection on the netdev (session)
5593 * cleanup the data pipes and wait until the control plane is stabilized
5594 * for this interface. The call also needs to wait until the above
5595 * mentioned actions are completed before returning to the caller.
5596 * Notice that the hdd_stop_adapter is requested not to close the session
5597 * That is intentional to be able to scan if it is a STA/P2P interface
5598 */
5599 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305600#ifdef FEATURE_WLAN_TDLS
5601 mutex_lock(&pHddCtx->tdls_lock);
5602#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305603 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305604 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305605#ifdef FEATURE_WLAN_TDLS
5606 mutex_unlock(&pHddCtx->tdls_lock);
5607#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 /* SoftAP ifaces should never go in power save mode
5609 making sure same here. */
5610 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5611 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005613 )
5614 {
5615 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5617 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 EXIT();
5619 return 0;
5620 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305621 /* Find if any iface is up. If any iface is up then can't put device to
5622 * sleep/power save mode
5623 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5625 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5626 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005627 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5628 {
5629 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305630 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005631 enter_standby = FALSE;
5632 break;
5633 }
5634 else
5635 {
5636 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5637 pAdapterNode = pNext;
5638 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 }
5640
5641 if (TRUE == enter_standby)
5642 {
5643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5644 "entering standby", __func__);
5645 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5646 {
5647 /*log and return success*/
5648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5649 "wlan in power save", __func__);
5650 }
5651 }
5652
5653 EXIT();
5654 return 0;
5655}
5656
5657/**---------------------------------------------------------------------------
5658
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305659 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005660
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305661 This is called in response to ifconfig down
5662
5663 \param - dev Pointer to net_device structure
5664
5665 \return - 0 for success non-zero for failure
5666-----------------------------------------------------------------------------*/
5667int hdd_stop (struct net_device *dev)
5668{
5669 int ret;
5670
5671 vos_ssr_protect(__func__);
5672 ret = __hdd_stop(dev);
5673 vos_ssr_unprotect(__func__);
5674
5675 return ret;
5676}
5677
5678/**---------------------------------------------------------------------------
5679
5680 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005681
5682 \param - dev Pointer to net_device structure
5683
5684 \return - void
5685
5686 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305687static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005688{
5689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305690 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005691 ENTER();
5692
5693 do
5694 {
5695 if (NULL == pAdapter)
5696 {
5697 hddLog(VOS_TRACE_LEVEL_FATAL,
5698 "%s: NULL pAdapter", __func__);
5699 break;
5700 }
5701
5702 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5703 {
5704 hddLog(VOS_TRACE_LEVEL_FATAL,
5705 "%s: Invalid magic", __func__);
5706 break;
5707 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305708 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5709 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 {
5711 hddLog(VOS_TRACE_LEVEL_FATAL,
5712 "%s: NULL pHddCtx", __func__);
5713 break;
5714 }
5715
5716 if (dev != pAdapter->dev)
5717 {
5718 hddLog(VOS_TRACE_LEVEL_FATAL,
5719 "%s: Invalid device reference", __func__);
5720 /* we haven't validated all cases so let this go for now */
5721 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305722#ifdef FEATURE_WLAN_TDLS
5723 mutex_lock(&pHddCtx->tdls_lock);
5724#endif
c_hpothu002231a2015-02-05 14:58:51 +05305725 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305726#ifdef FEATURE_WLAN_TDLS
5727 mutex_unlock(&pHddCtx->tdls_lock);
5728#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005729
5730 /* after uninit our adapter structure will no longer be valid */
5731 pAdapter->dev = NULL;
5732 pAdapter->magic = 0;
5733 } while (0);
5734
5735 EXIT();
5736}
5737
5738/**---------------------------------------------------------------------------
5739
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305740 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5741
5742 This is called during the netdev unregister to uninitialize all data
5743associated with the device
5744
5745 \param - dev Pointer to net_device structure
5746
5747 \return - void
5748
5749 --------------------------------------------------------------------------*/
5750static void hdd_uninit (struct net_device *dev)
5751{
5752 vos_ssr_protect(__func__);
5753 __hdd_uninit(dev);
5754 vos_ssr_unprotect(__func__);
5755}
5756
5757/**---------------------------------------------------------------------------
5758
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 \brief hdd_release_firmware() -
5760
5761 This function calls the release firmware API to free the firmware buffer.
5762
5763 \param - pFileName Pointer to the File Name.
5764 pCtx - Pointer to the adapter .
5765
5766
5767 \return - 0 for success, non zero for failure
5768
5769 --------------------------------------------------------------------------*/
5770
5771VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5772{
5773 VOS_STATUS status = VOS_STATUS_SUCCESS;
5774 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5775 ENTER();
5776
5777
5778 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5779
5780 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5781
5782 if(pHddCtx->fw) {
5783 release_firmware(pHddCtx->fw);
5784 pHddCtx->fw = NULL;
5785 }
5786 else
5787 status = VOS_STATUS_E_FAILURE;
5788 }
5789 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5790 if(pHddCtx->nv) {
5791 release_firmware(pHddCtx->nv);
5792 pHddCtx->nv = NULL;
5793 }
5794 else
5795 status = VOS_STATUS_E_FAILURE;
5796
5797 }
5798
5799 EXIT();
5800 return status;
5801}
5802
5803/**---------------------------------------------------------------------------
5804
5805 \brief hdd_request_firmware() -
5806
5807 This function reads the firmware file using the request firmware
5808 API and returns the the firmware data and the firmware file size.
5809
5810 \param - pfileName - Pointer to the file name.
5811 - pCtx - Pointer to the adapter .
5812 - ppfw_data - Pointer to the pointer of the firmware data.
5813 - pSize - Pointer to the file size.
5814
5815 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5816
5817 --------------------------------------------------------------------------*/
5818
5819
5820VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5821{
5822 int status;
5823 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5824 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5825 ENTER();
5826
5827 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5828
5829 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5830
5831 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5832 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5833 __func__, pfileName);
5834 retval = VOS_STATUS_E_FAILURE;
5835 }
5836
5837 else {
5838 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5839 *pSize = pHddCtx->fw->size;
5840 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5841 __func__, *pSize);
5842 }
5843 }
5844 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5845
5846 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5847
5848 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5849 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5850 __func__, pfileName);
5851 retval = VOS_STATUS_E_FAILURE;
5852 }
5853
5854 else {
5855 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5856 *pSize = pHddCtx->nv->size;
5857 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5858 __func__, *pSize);
5859 }
5860 }
5861
5862 EXIT();
5863 return retval;
5864}
5865/**---------------------------------------------------------------------------
5866 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5867
5868 This is the function invoked by SME to inform the result of a full power
5869 request issued by HDD
5870
5871 \param - callbackcontext - Pointer to cookie
5872 status - result of request
5873
5874 \return - None
5875
5876--------------------------------------------------------------------------*/
5877void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5878{
5879 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5880
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005881 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 if(&pHddCtx->full_pwr_comp_var)
5883 {
5884 complete(&pHddCtx->full_pwr_comp_var);
5885 }
5886}
5887
5888/**---------------------------------------------------------------------------
5889
5890 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5891
5892 This is the function invoked by SME to inform the result of BMPS
5893 request issued by HDD
5894
5895 \param - callbackcontext - Pointer to cookie
5896 status - result of request
5897
5898 \return - None
5899
5900--------------------------------------------------------------------------*/
5901void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5902{
5903
5904 struct completion *completion_var = (struct completion*) callbackContext;
5905
Arif Hussain6d2a3322013-11-17 19:50:10 -08005906 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 if(completion_var != NULL)
5908 {
5909 complete(completion_var);
5910 }
5911}
5912
5913/**---------------------------------------------------------------------------
5914
5915 \brief hdd_get_cfg_file_size() -
5916
5917 This function reads the configuration file using the request firmware
5918 API and returns the configuration file size.
5919
5920 \param - pCtx - Pointer to the adapter .
5921 - pFileName - Pointer to the file name.
5922 - pBufSize - Pointer to the buffer size.
5923
5924 \return - 0 for success, non zero for failure
5925
5926 --------------------------------------------------------------------------*/
5927
5928VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5929{
5930 int status;
5931 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5932
5933 ENTER();
5934
5935 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5936
5937 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5938 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5939 status = VOS_STATUS_E_FAILURE;
5940 }
5941 else {
5942 *pBufSize = pHddCtx->fw->size;
5943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5944 release_firmware(pHddCtx->fw);
5945 pHddCtx->fw = NULL;
5946 }
5947
5948 EXIT();
5949 return VOS_STATUS_SUCCESS;
5950}
5951
5952/**---------------------------------------------------------------------------
5953
5954 \brief hdd_read_cfg_file() -
5955
5956 This function reads the configuration file using the request firmware
5957 API and returns the cfg data and the buffer size of the configuration file.
5958
5959 \param - pCtx - Pointer to the adapter .
5960 - pFileName - Pointer to the file name.
5961 - pBuffer - Pointer to the data buffer.
5962 - pBufSize - Pointer to the buffer size.
5963
5964 \return - 0 for success, non zero for failure
5965
5966 --------------------------------------------------------------------------*/
5967
5968VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5969 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5970{
5971 int status;
5972 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5973
5974 ENTER();
5975
5976 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5977
5978 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5979 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5980 return VOS_STATUS_E_FAILURE;
5981 }
5982 else {
5983 if(*pBufSize != pHddCtx->fw->size) {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5985 "file size", __func__);
5986 release_firmware(pHddCtx->fw);
5987 pHddCtx->fw = NULL;
5988 return VOS_STATUS_E_FAILURE;
5989 }
5990 else {
5991 if(pBuffer) {
5992 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5993 }
5994 release_firmware(pHddCtx->fw);
5995 pHddCtx->fw = NULL;
5996 }
5997 }
5998
5999 EXIT();
6000
6001 return VOS_STATUS_SUCCESS;
6002}
6003
6004/**---------------------------------------------------------------------------
6005
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306006 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006007
6008 This function sets the user specified mac address using
6009 the command ifconfig wlanX hw ether <mac adress>.
6010
6011 \param - dev - Pointer to the net device.
6012 - addr - Pointer to the sockaddr.
6013 \return - 0 for success, non zero for failure
6014
6015 --------------------------------------------------------------------------*/
6016
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306017static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006018{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306019 hdd_adapter_t *pAdapter;
6020 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 struct sockaddr *psta_mac_addr = addr;
6022 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306023 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006024
6025 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306026 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6027 if (NULL == pAdapter)
6028 {
6029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6030 "%s: Adapter is NULL",__func__);
6031 return -EINVAL;
6032 }
6033 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6034 ret = wlan_hdd_validate_context(pHddCtx);
6035 if (0 != ret)
6036 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306037 return ret;
6038 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006039
6040 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006041 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6042
6043 EXIT();
6044 return halStatus;
6045}
6046
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306047/**---------------------------------------------------------------------------
6048
6049 \brief hdd_set_mac_address() -
6050
6051 Wrapper function to protect __hdd_set_mac_address() function from ssr
6052
6053 \param - dev - Pointer to the net device.
6054 - addr - Pointer to the sockaddr.
6055 \return - 0 for success, non zero for failure
6056
6057 --------------------------------------------------------------------------*/
6058static int hdd_set_mac_address(struct net_device *dev, void *addr)
6059{
6060 int ret;
6061
6062 vos_ssr_protect(__func__);
6063 ret = __hdd_set_mac_address(dev, addr);
6064 vos_ssr_unprotect(__func__);
6065
6066 return ret;
6067}
6068
Jeff Johnson295189b2012-06-20 16:38:30 -07006069tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6070{
6071 int i;
6072 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6073 {
Abhishek Singheb183782014-02-06 13:37:21 +05306074 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 break;
6076 }
6077
6078 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6079 return NULL;
6080
6081 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6082 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6083}
6084
6085void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6086{
6087 int i;
6088 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6089 {
6090 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6091 {
6092 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6093 break;
6094 }
6095 }
6096 return;
6097}
6098
6099#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6100 static struct net_device_ops wlan_drv_ops = {
6101 .ndo_open = hdd_open,
6102 .ndo_stop = hdd_stop,
6103 .ndo_uninit = hdd_uninit,
6104 .ndo_start_xmit = hdd_hard_start_xmit,
6105 .ndo_tx_timeout = hdd_tx_timeout,
6106 .ndo_get_stats = hdd_stats,
6107 .ndo_do_ioctl = hdd_ioctl,
6108 .ndo_set_mac_address = hdd_set_mac_address,
6109 .ndo_select_queue = hdd_select_queue,
6110#ifdef WLAN_FEATURE_PACKET_FILTERING
6111#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6112 .ndo_set_rx_mode = hdd_set_multicast_list,
6113#else
6114 .ndo_set_multicast_list = hdd_set_multicast_list,
6115#endif //LINUX_VERSION_CODE
6116#endif
6117 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006118 static struct net_device_ops wlan_mon_drv_ops = {
6119 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306120 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006121 .ndo_uninit = hdd_uninit,
6122 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6123 .ndo_tx_timeout = hdd_tx_timeout,
6124 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306125 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 .ndo_set_mac_address = hdd_set_mac_address,
6127 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306128
Jeff Johnson295189b2012-06-20 16:38:30 -07006129#endif
6130
6131void hdd_set_station_ops( struct net_device *pWlanDev )
6132{
6133#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 pWlanDev->netdev_ops = &wlan_drv_ops;
6135#else
6136 pWlanDev->open = hdd_open;
6137 pWlanDev->stop = hdd_stop;
6138 pWlanDev->uninit = hdd_uninit;
6139 pWlanDev->hard_start_xmit = NULL;
6140 pWlanDev->tx_timeout = hdd_tx_timeout;
6141 pWlanDev->get_stats = hdd_stats;
6142 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006143 pWlanDev->set_mac_address = hdd_set_mac_address;
6144#endif
6145}
6146
Katya Nigam1fd24402015-02-16 14:52:19 +05306147void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6148{
6149 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6150 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6151 #else
6152 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6153 #endif
6154}
6155
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006156static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006157{
6158 struct net_device *pWlanDev = NULL;
6159 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 /*
6161 * cfg80211 initialization and registration....
6162 */
6163 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6164
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 if(pWlanDev != NULL)
6166 {
6167
6168 //Save the pointer to the net_device in the HDD adapter
6169 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6170
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6172
6173 pAdapter->dev = pWlanDev;
6174 pAdapter->pHddCtx = pHddCtx;
6175 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306176 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006177
6178 init_completion(&pAdapter->session_open_comp_var);
6179 init_completion(&pAdapter->session_close_comp_var);
6180 init_completion(&pAdapter->disconnect_comp_var);
6181 init_completion(&pAdapter->linkup_event_var);
6182 init_completion(&pAdapter->cancel_rem_on_chan_var);
6183 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306184 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6186 init_completion(&pAdapter->offchannel_tx_event);
6187#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006188 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006189#ifdef FEATURE_WLAN_TDLS
6190 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006191 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006192 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306193 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006194#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 init_completion(&pHddCtx->mc_sus_event_var);
6196 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306197 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006198 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006199 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006200
Rajeev79dbe4c2013-10-05 11:03:42 +05306201#ifdef FEATURE_WLAN_BATCH_SCAN
6202 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6203 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6204 pAdapter->pBatchScanRsp = NULL;
6205 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006206 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006207 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306208 mutex_init(&pAdapter->hdd_batch_scan_lock);
6209#endif
6210
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 pAdapter->isLinkUpSvcNeeded = FALSE;
6212 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6213 //Init the net_device structure
6214 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6215
6216 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6217 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6218 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6219 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6220
6221 hdd_set_station_ops( pAdapter->dev );
6222
6223 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006224 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6225 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6226 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 /* set pWlanDev's parent to underlying device */
6228 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006229
6230 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 }
6232
6233 return pAdapter;
6234}
6235
6236VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6237{
6238 struct net_device *pWlanDev = pAdapter->dev;
6239 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6240 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6241 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6242
6243 if( rtnl_lock_held )
6244 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006245 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6247 {
6248 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6249 return VOS_STATUS_E_FAILURE;
6250 }
6251 }
6252 if (register_netdevice(pWlanDev))
6253 {
6254 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6255 return VOS_STATUS_E_FAILURE;
6256 }
6257 }
6258 else
6259 {
6260 if(register_netdev(pWlanDev))
6261 {
6262 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6263 return VOS_STATUS_E_FAILURE;
6264 }
6265 }
6266 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6267
6268 return VOS_STATUS_SUCCESS;
6269}
6270
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006271static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006272{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006273 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006274
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006275 if (NULL == pAdapter)
6276 {
6277 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6278 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006280
6281 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6282 {
6283 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6284 return eHAL_STATUS_NOT_INITIALIZED;
6285 }
6286
6287 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6288
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006289#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006290 /* need to make sure all of our scheduled work has completed.
6291 * This callback is called from MC thread context, so it is safe to
6292 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006293 *
6294 * Even though this is called from MC thread context, if there is a faulty
6295 * work item in the system, that can hang this call forever. So flushing
6296 * this global work queue is not safe; and now we make sure that
6297 * individual work queues are stopped correctly. But the cancel work queue
6298 * is a GPL only API, so the proprietary version of the driver would still
6299 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006300 */
6301 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006302#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006303
6304 /* We can be blocked while waiting for scheduled work to be
6305 * flushed, and the adapter structure can potentially be freed, in
6306 * which case the magic will have been reset. So make sure the
6307 * magic is still good, and hence the adapter structure is still
6308 * valid, before signaling completion */
6309 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6310 {
6311 complete(&pAdapter->session_close_comp_var);
6312 }
6313
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 return eHAL_STATUS_SUCCESS;
6315}
6316
6317VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6318{
6319 struct net_device *pWlanDev = pAdapter->dev;
6320 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6321 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6322 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6323 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306324 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006325
Nirav Shah7e3c8132015-06-22 23:51:42 +05306326 spin_lock_init( &pAdapter->sta_hash_lock);
6327 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6328
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006330 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 //Open a SME session for future operation
6332 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006333 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6335 {
6336 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006337 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 halStatus, halStatus );
6339 status = VOS_STATUS_E_FAILURE;
6340 goto error_sme_open;
6341 }
6342
6343 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306344 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 &pAdapter->session_open_comp_var,
6346 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306347 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 {
6349 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306350 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 status = VOS_STATUS_E_FAILURE;
6352 goto error_sme_open;
6353 }
6354
6355 // Register wireless extensions
6356 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6357 {
6358 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006359 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 halStatus, halStatus );
6361 status = VOS_STATUS_E_FAILURE;
6362 goto error_register_wext;
6363 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306364
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306366 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6367 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6368 #else
6369 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6370 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006371
6372 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306373 hddLog(VOS_TRACE_LEVEL_INFO,
6374 "%s: Set HDD connState to eConnectionState_NotConnected",
6375 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006376 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6377
6378 //Set the default operation channel
6379 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6380
6381 /* Make the default Auth Type as OPEN*/
6382 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6383
6384 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6385 {
6386 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006387 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 status, status );
6389 goto error_init_txrx;
6390 }
6391
6392 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6393
6394 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6395 {
6396 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006397 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006398 status, status );
6399 goto error_wmm_init;
6400 }
6401
6402 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6403
6404 return VOS_STATUS_SUCCESS;
6405
6406error_wmm_init:
6407 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6408 hdd_deinit_tx_rx(pAdapter);
6409error_init_txrx:
6410 hdd_UnregisterWext(pWlanDev);
6411error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006412 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 {
6414 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006415 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306416 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006417 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306419 unsigned long rc;
6420
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306422 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006424 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306425 if (rc <= 0)
6426 hddLog(VOS_TRACE_LEVEL_ERROR,
6427 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 }
6429}
6430error_sme_open:
6431 return status;
6432}
6433
Jeff Johnson295189b2012-06-20 16:38:30 -07006434void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6435{
6436 hdd_cfg80211_state_t *cfgState;
6437
6438 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6439
6440 if( NULL != cfgState->buf )
6441 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306442 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6444 rc = wait_for_completion_interruptible_timeout(
6445 &pAdapter->tx_action_cnf_event,
6446 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306447 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306450 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6451 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 }
6453 }
6454 return;
6455}
Jeff Johnson295189b2012-06-20 16:38:30 -07006456
c_hpothu002231a2015-02-05 14:58:51 +05306457void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006458{
6459 ENTER();
6460 switch ( pAdapter->device_mode )
6461 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306462 case WLAN_HDD_IBSS:
6463 {
6464 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6465 {
6466 hdd_ibss_deinit_tx_rx( pAdapter );
6467 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6468 }
6469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 case WLAN_HDD_INFRA_STATION:
6471 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006472 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 {
6474 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6475 {
6476 hdd_deinit_tx_rx( pAdapter );
6477 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6478 }
6479
6480 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6481 {
6482 hdd_wmm_adapter_close( pAdapter );
6483 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6484 }
6485
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 break;
6488 }
6489
6490 case WLAN_HDD_SOFTAP:
6491 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306493
6494 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6495 {
6496 hdd_wmm_adapter_close( pAdapter );
6497 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6498 }
6499
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006501
c_hpothu002231a2015-02-05 14:58:51 +05306502 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 break;
6505 }
6506
6507 case WLAN_HDD_MONITOR:
6508 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6510 {
6511 hdd_deinit_tx_rx( pAdapter );
6512 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 break;
6515 }
6516
6517
6518 default:
6519 break;
6520 }
6521
6522 EXIT();
6523}
6524
6525void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6526{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006527 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306528
6529 ENTER();
6530 if (NULL == pAdapter)
6531 {
6532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6533 "%s: HDD adapter is Null", __func__);
6534 return;
6535 }
6536
6537 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006538
Rajeev79dbe4c2013-10-05 11:03:42 +05306539#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306540 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6541 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006542 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306543 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6544 )
6545 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006546 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306547 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006548 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6549 {
6550 hdd_deinit_batch_scan(pAdapter);
6551 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306552 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006553 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306554#endif
6555
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6557 if( rtnl_held )
6558 {
6559 unregister_netdevice(pWlanDev);
6560 }
6561 else
6562 {
6563 unregister_netdev(pWlanDev);
6564 }
6565 // note that the pAdapter is no longer valid at this point
6566 // since the memory has been reclaimed
6567 }
6568
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306569 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006570}
6571
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006572void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6573{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306574 VOS_STATUS status;
6575 hdd_adapter_t *pAdapter = NULL;
6576 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006577
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306578 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006579
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306580 /*loop through all adapters.*/
6581 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006582 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306583 pAdapter = pAdapterNode->pAdapter;
6584 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6585 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006586
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306587 { // we skip this registration for modes other than STA and P2P client modes.
6588 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6589 pAdapterNode = pNext;
6590 continue;
6591 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006592
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306593 //Apply Dynamic DTIM For P2P
6594 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6595 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6596 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6597 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6598 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6599 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6600 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6601 (eConnectionState_Associated ==
6602 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6603 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6604 {
6605 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006606
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306607 powerRequest.uIgnoreDTIM = 1;
6608 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6609
6610 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6611 {
6612 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6613 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6614 }
6615 else
6616 {
6617 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6618 }
6619
6620 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6621 * specified during Enter/Exit BMPS when LCD off*/
6622 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6623 NULL, eANI_BOOLEAN_FALSE);
6624 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6625 NULL, eANI_BOOLEAN_FALSE);
6626
6627 /* switch to the DTIM specified in cfg.ini */
6628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6629 "Switch to DTIM %d", powerRequest.uListenInterval);
6630 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6631 break;
6632
6633 }
6634
6635 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6636 pAdapterNode = pNext;
6637 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006638}
6639
6640void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6641{
6642 /*Switch back to DTIM 1*/
6643 tSirSetPowerParamsReq powerRequest = { 0 };
6644
6645 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6646 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006647 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006648
6649 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6650 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6651 NULL, eANI_BOOLEAN_FALSE);
6652 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6653 NULL, eANI_BOOLEAN_FALSE);
6654
6655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6656 "Switch to DTIM%d",powerRequest.uListenInterval);
6657 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6658
6659}
6660
Jeff Johnson295189b2012-06-20 16:38:30 -07006661VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6662{
6663 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306664 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6665 {
6666 hddLog( LOGE, FL("Wlan Unload in progress"));
6667 return VOS_STATUS_E_PERM;
6668 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006669 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6670 {
6671 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6672 }
6673
6674 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6675 {
6676 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6677 }
6678
6679 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6680 {
6681 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6682 }
6683
6684 return status;
6685}
6686
6687VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6688{
6689 hdd_adapter_t *pAdapter = NULL;
6690 eHalStatus halStatus;
6691 VOS_STATUS status = VOS_STATUS_E_INVAL;
6692 v_BOOL_t disableBmps = FALSE;
6693 v_BOOL_t disableImps = FALSE;
6694
6695 switch(session_type)
6696 {
6697 case WLAN_HDD_INFRA_STATION:
6698 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 case WLAN_HDD_P2P_CLIENT:
6700 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 //Exit BMPS -> Is Sta/P2P Client is already connected
6702 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6703 if((NULL != pAdapter)&&
6704 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6705 {
6706 disableBmps = TRUE;
6707 }
6708
6709 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6710 if((NULL != pAdapter)&&
6711 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6712 {
6713 disableBmps = TRUE;
6714 }
6715
6716 //Exit both Bmps and Imps incase of Go/SAP Mode
6717 if((WLAN_HDD_SOFTAP == session_type) ||
6718 (WLAN_HDD_P2P_GO == session_type))
6719 {
6720 disableBmps = TRUE;
6721 disableImps = TRUE;
6722 }
6723
6724 if(TRUE == disableImps)
6725 {
6726 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6727 {
6728 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6729 }
6730 }
6731
6732 if(TRUE == disableBmps)
6733 {
6734 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6735 {
6736 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6737
6738 if(eHAL_STATUS_SUCCESS != halStatus)
6739 {
6740 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006741 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006742 VOS_ASSERT(0);
6743 return status;
6744 }
6745 }
6746
6747 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6748 {
6749 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6750
6751 if(eHAL_STATUS_SUCCESS != halStatus)
6752 {
6753 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006754 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 VOS_ASSERT(0);
6756 return status;
6757 }
6758 }
6759 }
6760
6761 if((TRUE == disableBmps) ||
6762 (TRUE == disableImps))
6763 {
6764 /* Now, get the chip into Full Power now */
6765 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6766 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6767 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6768
6769 if(halStatus != eHAL_STATUS_SUCCESS)
6770 {
6771 if(halStatus == eHAL_STATUS_PMC_PENDING)
6772 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306773 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306775 ret = wait_for_completion_interruptible_timeout(
6776 &pHddCtx->full_pwr_comp_var,
6777 msecs_to_jiffies(1000));
6778 if (ret <= 0)
6779 {
6780 hddLog(VOS_TRACE_LEVEL_ERROR,
6781 "%s: wait on full_pwr_comp_var failed %ld",
6782 __func__, ret);
6783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 }
6785 else
6786 {
6787 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006788 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 VOS_ASSERT(0);
6790 return status;
6791 }
6792 }
6793
6794 status = VOS_STATUS_SUCCESS;
6795 }
6796
6797 break;
6798 }
6799 return status;
6800}
Katya Nigame7b69a82015-04-28 15:24:06 +05306801void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6802 {
6803 hdd_mon_ctx_t *pMonCtx = NULL;
6804 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6805
6806 pMonCtx->state = 0;
6807 pMonCtx->ChannelNo = 1;
6808 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306809 pMonCtx->crcCheckEnabled = 1;
6810 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6811 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306812 pMonCtx->numOfMacFilters = 0;
6813 }
6814
Jeff Johnson295189b2012-06-20 16:38:30 -07006815
6816hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006817 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 tANI_U8 rtnl_held )
6819{
6820 hdd_adapter_t *pAdapter = NULL;
6821 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6822 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6823 VOS_STATUS exitbmpsStatus;
6824
Arif Hussain6d2a3322013-11-17 19:50:10 -08006825 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006826
Nirav Shah436658f2014-02-28 17:05:45 +05306827 if(macAddr == NULL)
6828 {
6829 /* Not received valid macAddr */
6830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6831 "%s:Unable to add virtual intf: Not able to get"
6832 "valid mac address",__func__);
6833 return NULL;
6834 }
6835
Jeff Johnson295189b2012-06-20 16:38:30 -07006836 //Disable BMPS incase of Concurrency
6837 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6838
6839 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6840 {
6841 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306842 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 VOS_ASSERT(0);
6844 return NULL;
6845 }
6846
6847 switch(session_type)
6848 {
6849 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006851 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006852 {
6853 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6854
6855 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306856 {
6857 hddLog(VOS_TRACE_LEVEL_FATAL,
6858 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306860 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006861
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306862#ifdef FEATURE_WLAN_TDLS
6863 /* A Mutex Lock is introduced while changing/initializing the mode to
6864 * protect the concurrent access for the Adapters by TDLS module.
6865 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306866 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306867#endif
6868
Jeff Johnsone7245742012-09-05 17:12:55 -07006869 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6870 NL80211_IFTYPE_P2P_CLIENT:
6871 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006872
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306874#ifdef FEATURE_WLAN_TDLS
6875 mutex_unlock(&pHddCtx->tdls_lock);
6876#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306877
6878 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 if( VOS_STATUS_SUCCESS != status )
6880 goto err_free_netdev;
6881
6882 status = hdd_register_interface( pAdapter, rtnl_held );
6883 if( VOS_STATUS_SUCCESS != status )
6884 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306885#ifdef FEATURE_WLAN_TDLS
6886 mutex_lock(&pHddCtx->tdls_lock);
6887#endif
c_hpothu002231a2015-02-05 14:58:51 +05306888 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306889#ifdef FEATURE_WLAN_TDLS
6890 mutex_unlock(&pHddCtx->tdls_lock);
6891#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 goto err_free_netdev;
6893 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306894
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306895 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306896 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306897
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306898#ifdef WLAN_NS_OFFLOAD
6899 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306900 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306901#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306903 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 netif_tx_disable(pAdapter->dev);
6905 //netif_tx_disable(pWlanDev);
6906 netif_carrier_off(pAdapter->dev);
6907
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306908 if (WLAN_HDD_P2P_CLIENT == session_type ||
6909 WLAN_HDD_P2P_DEVICE == session_type)
6910 {
6911 /* Initialize the work queue to defer the
6912 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306913 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306914 hdd_p2p_roc_work_queue);
6915 }
6916
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 break;
6918 }
6919
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 case WLAN_HDD_SOFTAP:
6922 {
6923 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6924 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306925 {
6926 hddLog(VOS_TRACE_LEVEL_FATAL,
6927 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006928 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006930
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6932 NL80211_IFTYPE_AP:
6933 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 pAdapter->device_mode = session_type;
6935
6936 status = hdd_init_ap_mode(pAdapter);
6937 if( VOS_STATUS_SUCCESS != status )
6938 goto err_free_netdev;
6939
Nirav Shah7e3c8132015-06-22 23:51:42 +05306940 status = hdd_sta_id_hash_attach(pAdapter);
6941 if (VOS_STATUS_SUCCESS != status)
6942 {
6943 hddLog(VOS_TRACE_LEVEL_FATAL,
6944 FL("failed to attach hash for session %d"), session_type);
6945 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6946 goto err_free_netdev;
6947 }
6948
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 status = hdd_register_hostapd( pAdapter, rtnl_held );
6950 if( VOS_STATUS_SUCCESS != status )
6951 {
c_hpothu002231a2015-02-05 14:58:51 +05306952 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 goto err_free_netdev;
6954 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306955 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 netif_tx_disable(pAdapter->dev);
6957 netif_carrier_off(pAdapter->dev);
6958
6959 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306960
6961 if (WLAN_HDD_P2P_GO == session_type)
6962 {
6963 /* Initialize the work queue to
6964 * defer the back to back RoC request */
6965 INIT_DELAYED_WORK(&pAdapter->roc_work,
6966 hdd_p2p_roc_work_queue);
6967 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 break;
6969 }
6970 case WLAN_HDD_MONITOR:
6971 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6973 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306974 {
6975 hddLog(VOS_TRACE_LEVEL_FATAL,
6976 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306978 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006979
Katya Nigame7b69a82015-04-28 15:24:06 +05306980 // Register wireless extensions
6981 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6982 {
6983 hddLog(VOS_TRACE_LEVEL_FATAL,
6984 "hdd_register_wext() failed with status code %08d [x%08x]",
6985 status, status );
6986 status = VOS_STATUS_E_FAILURE;
6987 }
6988
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6990 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006991#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6992 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6993#else
6994 pAdapter->dev->open = hdd_mon_open;
6995 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306996 pAdapter->dev->stop = hdd_mon_stop;
6997 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006998#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05306999 status = hdd_register_interface( pAdapter, rtnl_held );
7000 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 hdd_init_tx_rx( pAdapter );
7002 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307003 //Stop the Interface TX queue.
7004 netif_tx_disable(pAdapter->dev);
7005 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 }
7007 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 case WLAN_HDD_FTM:
7009 {
7010 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7011
7012 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307013 {
7014 hddLog(VOS_TRACE_LEVEL_FATAL,
7015 FL("failed to allocate adapter for session %d"), session_type);
7016 return NULL;
7017 }
7018
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7020 * message while loading driver in FTM mode. */
7021 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7022 pAdapter->device_mode = session_type;
7023 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307024
7025 hdd_init_tx_rx( pAdapter );
7026
7027 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307028 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307029 netif_tx_disable(pAdapter->dev);
7030 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 }
7032 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 default:
7034 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307035 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7036 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 VOS_ASSERT(0);
7038 return NULL;
7039 }
7040 }
7041
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 if( VOS_STATUS_SUCCESS == status )
7043 {
7044 //Add it to the hdd's session list.
7045 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7046 if( NULL == pHddAdapterNode )
7047 {
7048 status = VOS_STATUS_E_NOMEM;
7049 }
7050 else
7051 {
7052 pHddAdapterNode->pAdapter = pAdapter;
7053 status = hdd_add_adapter_back ( pHddCtx,
7054 pHddAdapterNode );
7055 }
7056 }
7057
7058 if( VOS_STATUS_SUCCESS != status )
7059 {
7060 if( NULL != pAdapter )
7061 {
7062 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7063 pAdapter = NULL;
7064 }
7065 if( NULL != pHddAdapterNode )
7066 {
7067 vos_mem_free( pHddAdapterNode );
7068 }
7069
7070 goto resume_bmps;
7071 }
7072
7073 if(VOS_STATUS_SUCCESS == status)
7074 {
7075 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7076
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007077 //Initialize the WoWL service
7078 if(!hdd_init_wowl(pAdapter))
7079 {
7080 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7081 goto err_free_netdev;
7082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 return pAdapter;
7085
7086err_free_netdev:
7087 free_netdev(pAdapter->dev);
7088 wlan_hdd_release_intf_addr( pHddCtx,
7089 pAdapter->macAddressCurrent.bytes );
7090
7091resume_bmps:
7092 //If bmps disabled enable it
7093 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7094 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307095 if (pHddCtx->hdd_wlan_suspended)
7096 {
7097 hdd_set_pwrparams(pHddCtx);
7098 }
7099 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007100 }
7101 return NULL;
7102}
7103
7104VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7105 tANI_U8 rtnl_held )
7106{
7107 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7108 VOS_STATUS status;
7109
7110 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7111 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307112 {
7113 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7114 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007117
7118 while ( pCurrent->pAdapter != pAdapter )
7119 {
7120 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7121 if( VOS_STATUS_SUCCESS != status )
7122 break;
7123
7124 pCurrent = pNext;
7125 }
7126 pAdapterNode = pCurrent;
7127 if( VOS_STATUS_SUCCESS == status )
7128 {
7129 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7130 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307131
7132#ifdef FEATURE_WLAN_TDLS
7133
7134 /* A Mutex Lock is introduced while changing/initializing the mode to
7135 * protect the concurrent access for the Adapters by TDLS module.
7136 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307137 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307138#endif
7139
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 hdd_remove_adapter( pHddCtx, pAdapterNode );
7141 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007142 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007143
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307144#ifdef FEATURE_WLAN_TDLS
7145 mutex_unlock(&pHddCtx->tdls_lock);
7146#endif
7147
Jeff Johnson295189b2012-06-20 16:38:30 -07007148
7149 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307150 if ((!vos_concurrent_open_sessions_running()) &&
7151 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7152 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007153 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307154 if (pHddCtx->hdd_wlan_suspended)
7155 {
7156 hdd_set_pwrparams(pHddCtx);
7157 }
7158 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007159 }
7160
7161 return VOS_STATUS_SUCCESS;
7162 }
7163
7164 return VOS_STATUS_E_FAILURE;
7165}
7166
7167VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7168{
7169 hdd_adapter_list_node_t *pHddAdapterNode;
7170 VOS_STATUS status;
7171
7172 ENTER();
7173
7174 do
7175 {
7176 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7177 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7178 {
7179 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7180 vos_mem_free( pHddAdapterNode );
7181 }
7182 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7183
7184 EXIT();
7185
7186 return VOS_STATUS_SUCCESS;
7187}
7188
7189void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7190{
7191 v_U8_t addIE[1] = {0};
7192
7193 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7194 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7195 eANI_BOOLEAN_FALSE) )
7196 {
7197 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007198 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 }
7200
7201 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7202 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7203 eANI_BOOLEAN_FALSE) )
7204 {
7205 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007206 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 }
7208
7209 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7210 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7211 eANI_BOOLEAN_FALSE) )
7212 {
7213 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007214 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007215 }
7216}
7217
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307218VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7219 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007220{
7221 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7222 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307223 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307225 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307226 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307227 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007228
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307229 if (pHddCtx->isLogpInProgress) {
7230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7231 "%s:LOGP in Progress. Ignore!!!",__func__);
7232 return VOS_STATUS_E_FAILURE;
7233 }
7234
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307236
Nirav Shah7e3c8132015-06-22 23:51:42 +05307237 status = hdd_sta_id_hash_detach(pAdapter);
7238 if (status != VOS_STATUS_SUCCESS)
7239 hddLog(VOS_TRACE_LEVEL_ERROR,
7240 FL("sta id hash detach failed"));
7241
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307242 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 switch(pAdapter->device_mode)
7244 {
7245 case WLAN_HDD_INFRA_STATION:
7246 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007247 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307248 {
7249 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307250#ifdef FEATURE_WLAN_TDLS
7251 mutex_lock(&pHddCtx->tdls_lock);
7252 wlan_hdd_tdls_exit(pAdapter, TRUE);
7253 mutex_unlock(&pHddCtx->tdls_lock);
7254#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307255 if( hdd_connIsConnected(pstation) ||
7256 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 {
7258 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7259 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7260 pAdapter->sessionId,
7261 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7262 else
7263 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7264 pAdapter->sessionId,
7265 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7266 //success implies disconnect command got queued up successfully
7267 if(halStatus == eHAL_STATUS_SUCCESS)
7268 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307269 ret = wait_for_completion_interruptible_timeout(
7270 &pAdapter->disconnect_comp_var,
7271 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7272 if (ret <= 0)
7273 {
7274 hddLog(VOS_TRACE_LEVEL_ERROR,
7275 "%s: wait on disconnect_comp_var failed %ld",
7276 __func__, ret);
7277 }
7278 }
7279 else
7280 {
7281 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7282 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 }
7284 memset(&wrqu, '\0', sizeof(wrqu));
7285 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7286 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7287 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7288 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307289 else if(pstation->conn_info.connState ==
7290 eConnectionState_Disconnecting)
7291 {
7292 ret = wait_for_completion_interruptible_timeout(
7293 &pAdapter->disconnect_comp_var,
7294 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7295 if (ret <= 0)
7296 {
7297 hddLog(VOS_TRACE_LEVEL_ERROR,
7298 FL("wait on disconnect_comp_var failed %ld"), ret);
7299 }
7300 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307301 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307303 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307304 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307306 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7307 {
7308 while (pAdapter->is_roc_inprogress)
7309 {
7310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7311 "%s: ROC in progress for session %d!!!",
7312 __func__, pAdapter->sessionId);
7313 // waiting for ROC to expire
7314 msleep(500);
7315 /* In GO present case , if retry exceeds 3,
7316 it means something went wrong. */
7317 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7318 {
7319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7320 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307321 if (eHAL_STATUS_SUCCESS !=
7322 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7323 pAdapter->sessionId ))
7324 {
7325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7326 FL("Failed to Cancel Remain on Channel"));
7327 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307328 wait_for_completion_interruptible_timeout(
7329 &pAdapter->cancel_rem_on_chan_var,
7330 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7331 break;
7332 }
7333 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307334 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307335 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307336#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307337 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307338#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307339
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307340 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307341
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307342 /* It is possible that the caller of this function does not
7343 * wish to close the session
7344 */
7345 if (VOS_TRUE == bCloseSession &&
7346 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 {
7348 INIT_COMPLETION(pAdapter->session_close_comp_var);
7349 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307350 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307351 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307353 unsigned long ret;
7354
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307356 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307357 &pAdapter->session_close_comp_var,
7358 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307359 if ( 0 >= ret)
7360 {
7361 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307362 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007364 }
7365 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007367 break;
7368
7369 case WLAN_HDD_SOFTAP:
7370 case WLAN_HDD_P2P_GO:
7371 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307372 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7373 while (pAdapter->is_roc_inprogress) {
7374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7375 "%s: ROC in progress for session %d!!!",
7376 __func__, pAdapter->sessionId);
7377 msleep(500);
7378 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7380 "%s: ROC completion is not received.!!!", __func__);
7381 WLANSAP_CancelRemainOnChannel(
7382 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7383 wait_for_completion_interruptible_timeout(
7384 &pAdapter->cancel_rem_on_chan_var,
7385 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7386 break;
7387 }
7388 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307389
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307390 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 mutex_lock(&pHddCtx->sap_lock);
7393 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7394 {
7395 VOS_STATUS status;
7396 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7397
7398 //Stop Bss.
7399 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7400 if (VOS_IS_STATUS_SUCCESS(status))
7401 {
7402 hdd_hostapd_state_t *pHostapdState =
7403 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7404
7405 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7406
7407 if (!VOS_IS_STATUS_SUCCESS(status))
7408 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307409 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7410 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 }
7412 }
7413 else
7414 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007415 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007416 }
7417 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307418 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007419
7420 if (eHAL_STATUS_FAILURE ==
7421 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7422 0, NULL, eANI_BOOLEAN_FALSE))
7423 {
7424 hddLog(LOGE,
7425 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007426 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 }
7428
7429 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7430 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7431 eANI_BOOLEAN_FALSE) )
7432 {
7433 hddLog(LOGE,
7434 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7435 }
7436
7437 // Reset WNI_CFG_PROBE_RSP Flags
7438 wlan_hdd_reset_prob_rspies(pAdapter);
7439 kfree(pAdapter->sessionCtx.ap.beacon);
7440 pAdapter->sessionCtx.ap.beacon = NULL;
7441 }
7442 mutex_unlock(&pHddCtx->sap_lock);
7443 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007444
Jeff Johnson295189b2012-06-20 16:38:30 -07007445 case WLAN_HDD_MONITOR:
7446 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007447
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 default:
7449 break;
7450 }
7451
7452 EXIT();
7453 return VOS_STATUS_SUCCESS;
7454}
7455
7456VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7457{
7458 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7459 VOS_STATUS status;
7460 hdd_adapter_t *pAdapter;
7461
7462 ENTER();
7463
7464 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7465
7466 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7467 {
7468 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007469
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307470 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007471
7472 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7473 pAdapterNode = pNext;
7474 }
7475
7476 EXIT();
7477
7478 return VOS_STATUS_SUCCESS;
7479}
7480
Rajeev Kumarf999e582014-01-09 17:33:29 -08007481
7482#ifdef FEATURE_WLAN_BATCH_SCAN
7483/**---------------------------------------------------------------------------
7484
7485 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7486 structures
7487
7488 \param - pAdapter Pointer to HDD adapter
7489
7490 \return - None
7491
7492 --------------------------------------------------------------------------*/
7493void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7494{
7495 tHddBatchScanRsp *pNode;
7496 tHddBatchScanRsp *pPrev;
7497
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307498 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007499 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307500 hddLog(VOS_TRACE_LEVEL_ERROR,
7501 "%s: Adapter context is Null", __func__);
7502 return;
7503 }
7504
7505 pNode = pAdapter->pBatchScanRsp;
7506 while (pNode)
7507 {
7508 pPrev = pNode;
7509 pNode = pNode->pNext;
7510 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007511 }
7512
7513 pAdapter->pBatchScanRsp = NULL;
7514 pAdapter->numScanList = 0;
7515 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7516 pAdapter->prev_batch_id = 0;
7517
7518 return;
7519}
7520#endif
7521
7522
Jeff Johnson295189b2012-06-20 16:38:30 -07007523VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7524{
7525 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7526 VOS_STATUS status;
7527 hdd_adapter_t *pAdapter;
7528
7529 ENTER();
7530
7531 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7532
7533 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7534 {
7535 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307536 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 netif_tx_disable(pAdapter->dev);
7538 netif_carrier_off(pAdapter->dev);
7539
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007540 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7541
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307543
Katya Nigam1fd24402015-02-16 14:52:19 +05307544 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7545 hdd_ibss_deinit_tx_rx(pAdapter);
7546
Nirav Shah7e3c8132015-06-22 23:51:42 +05307547 status = hdd_sta_id_hash_detach(pAdapter);
7548 if (status != VOS_STATUS_SUCCESS)
7549 hddLog(VOS_TRACE_LEVEL_ERROR,
7550 FL("sta id hash detach failed for session id %d"),
7551 pAdapter->sessionId);
7552
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307553 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7554
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307555 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7556 {
7557 hdd_wmm_adapter_close( pAdapter );
7558 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7559 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007560
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307561 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7562 {
7563 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7564 }
7565
Rajeev Kumarf999e582014-01-09 17:33:29 -08007566#ifdef FEATURE_WLAN_BATCH_SCAN
7567 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7568 {
7569 hdd_deinit_batch_scan(pAdapter);
7570 }
7571#endif
7572
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307573#ifdef FEATURE_WLAN_TDLS
7574 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307575 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307576 mutex_unlock(&pHddCtx->tdls_lock);
7577#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007578 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7579 pAdapterNode = pNext;
7580 }
7581
7582 EXIT();
7583
7584 return VOS_STATUS_SUCCESS;
7585}
7586
7587VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7588{
7589 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7590 VOS_STATUS status;
7591 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307592 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007593
7594 ENTER();
7595
7596 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7597
7598 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7599 {
7600 pAdapter = pAdapterNode->pAdapter;
7601
Kumar Anand82c009f2014-05-29 00:29:42 -07007602 hdd_wmm_init( pAdapter );
7603
Jeff Johnson295189b2012-06-20 16:38:30 -07007604 switch(pAdapter->device_mode)
7605 {
7606 case WLAN_HDD_INFRA_STATION:
7607 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007608 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307609
7610 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7611
Jeff Johnson295189b2012-06-20 16:38:30 -07007612 hdd_init_station_mode(pAdapter);
7613 /* Open the gates for HDD to receive Wext commands */
7614 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007615 pHddCtx->scan_info.mScanPending = FALSE;
7616 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007617
7618 //Trigger the initial scan
7619 hdd_wlan_initial_scan(pAdapter);
7620
7621 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307622 if (eConnectionState_Associated == connState ||
7623 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 {
7625 union iwreq_data wrqu;
7626 memset(&wrqu, '\0', sizeof(wrqu));
7627 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7628 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7629 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007630 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007631
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 /* indicate disconnected event to nl80211 */
7633 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7634 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307636 else if (eConnectionState_Connecting == connState)
7637 {
7638 /*
7639 * Indicate connect failure to supplicant if we were in the
7640 * process of connecting
7641 */
7642 cfg80211_connect_result(pAdapter->dev, NULL,
7643 NULL, 0, NULL, 0,
7644 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7645 GFP_KERNEL);
7646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 break;
7648
7649 case WLAN_HDD_SOFTAP:
7650 /* softAP can handle SSR */
7651 break;
7652
7653 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007656 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 break;
7658
7659 case WLAN_HDD_MONITOR:
7660 /* monitor interface start */
7661 break;
7662 default:
7663 break;
7664 }
7665
7666 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7667 pAdapterNode = pNext;
7668 }
7669
7670 EXIT();
7671
7672 return VOS_STATUS_SUCCESS;
7673}
7674
7675VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7676{
7677 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7678 hdd_adapter_t *pAdapter;
7679 VOS_STATUS status;
7680 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307681 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007682
7683 ENTER();
7684
7685 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7686
7687 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7688 {
7689 pAdapter = pAdapterNode->pAdapter;
7690
7691 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7692 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7693 {
7694 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7695 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7696
Abhishek Singhf4669da2014-05-26 15:07:49 +05307697 hddLog(VOS_TRACE_LEVEL_INFO,
7698 "%s: Set HDD connState to eConnectionState_NotConnected",
7699 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7701 init_completion(&pAdapter->disconnect_comp_var);
7702 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7703 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7704
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307705 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 &pAdapter->disconnect_comp_var,
7707 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307708 if (0 >= ret)
7709 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7710 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007711
7712 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7713 pHddCtx->isAmpAllowed = VOS_FALSE;
7714 sme_RoamConnect(pHddCtx->hHal,
7715 pAdapter->sessionId, &(pWextState->roamProfile),
7716 &roamId);
7717 }
7718
7719 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7720 pAdapterNode = pNext;
7721 }
7722
7723 EXIT();
7724
7725 return VOS_STATUS_SUCCESS;
7726}
7727
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007728void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7729{
7730 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7731 VOS_STATUS status;
7732 hdd_adapter_t *pAdapter;
7733 hdd_station_ctx_t *pHddStaCtx;
7734 hdd_ap_ctx_t *pHddApCtx;
7735 hdd_hostapd_state_t * pHostapdState;
7736 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7737 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7738 const char *p2pMode = "DEV";
7739 const char *ccMode = "Standalone";
7740 int n;
7741
7742 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7743 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7744 {
7745 pAdapter = pAdapterNode->pAdapter;
7746 switch (pAdapter->device_mode) {
7747 case WLAN_HDD_INFRA_STATION:
7748 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7749 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7750 staChannel = pHddStaCtx->conn_info.operationChannel;
7751 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7752 }
7753 break;
7754 case WLAN_HDD_P2P_CLIENT:
7755 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7756 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7757 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7758 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7759 p2pMode = "CLI";
7760 }
7761 break;
7762 case WLAN_HDD_P2P_GO:
7763 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7764 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7765 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7766 p2pChannel = pHddApCtx->operatingChannel;
7767 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7768 }
7769 p2pMode = "GO";
7770 break;
7771 case WLAN_HDD_SOFTAP:
7772 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7773 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7774 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7775 apChannel = pHddApCtx->operatingChannel;
7776 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7777 }
7778 break;
7779 default:
7780 break;
7781 }
7782 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7783 pAdapterNode = pNext;
7784 }
7785 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7786 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7787 }
7788 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7789 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7790 if (p2pChannel > 0) {
7791 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7792 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7793 }
7794 if (apChannel > 0) {
7795 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7796 apChannel, MAC_ADDR_ARRAY(apBssid));
7797 }
7798
7799 if (p2pChannel > 0 && apChannel > 0) {
7800 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7801 }
7802}
7803
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007804bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007805{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007806 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007807}
7808
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007809/* Once SSR is disabled then it cannot be set. */
7810void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007811{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007812 if (HDD_SSR_DISABLED == isSsrRequired)
7813 return;
7814
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 isSsrRequired = value;
7816}
7817
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307818void hdd_set_pre_close( hdd_context_t *pHddCtx)
7819{
7820 sme_PreClose(pHddCtx->hHal);
7821}
7822
Jeff Johnson295189b2012-06-20 16:38:30 -07007823VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7824 hdd_adapter_list_node_t** ppAdapterNode)
7825{
7826 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307827 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007828 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7829 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307830 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007831 return status;
7832}
7833
7834VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7835 hdd_adapter_list_node_t* pAdapterNode,
7836 hdd_adapter_list_node_t** pNextAdapterNode)
7837{
7838 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307839 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7841 (hdd_list_node_t*) pAdapterNode,
7842 (hdd_list_node_t**)pNextAdapterNode );
7843
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307844 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 return status;
7846}
7847
7848VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7849 hdd_adapter_list_node_t* pAdapterNode)
7850{
7851 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307852 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7854 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307855 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007856 return status;
7857}
7858
7859VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7860 hdd_adapter_list_node_t** ppAdapterNode)
7861{
7862 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307863 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7865 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307866 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007867 return status;
7868}
7869
7870VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7871 hdd_adapter_list_node_t* pAdapterNode)
7872{
7873 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307874 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007875 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7876 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307877 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 return status;
7879}
7880
7881VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7882 hdd_adapter_list_node_t* pAdapterNode)
7883{
7884 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307885 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007886 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7887 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307888 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 return status;
7890}
7891
7892hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7893 tSirMacAddr macAddr )
7894{
7895 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7896 hdd_adapter_t *pAdapter;
7897 VOS_STATUS status;
7898
7899 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7900
7901 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7902 {
7903 pAdapter = pAdapterNode->pAdapter;
7904
7905 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7906 macAddr, sizeof(tSirMacAddr) ) )
7907 {
7908 return pAdapter;
7909 }
7910 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7911 pAdapterNode = pNext;
7912 }
7913
7914 return NULL;
7915
7916}
7917
7918hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7919{
7920 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7921 hdd_adapter_t *pAdapter;
7922 VOS_STATUS status;
7923
7924 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7925
7926 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7927 {
7928 pAdapter = pAdapterNode->pAdapter;
7929
7930 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7931 IFNAMSIZ ) )
7932 {
7933 return pAdapter;
7934 }
7935 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7936 pAdapterNode = pNext;
7937 }
7938
7939 return NULL;
7940
7941}
7942
7943hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7944{
7945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7946 hdd_adapter_t *pAdapter;
7947 VOS_STATUS status;
7948
7949 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7950
7951 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7952 {
7953 pAdapter = pAdapterNode->pAdapter;
7954
7955 if( pAdapter && (mode == pAdapter->device_mode) )
7956 {
7957 return pAdapter;
7958 }
7959 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7960 pAdapterNode = pNext;
7961 }
7962
7963 return NULL;
7964
7965}
7966
7967//Remove this function later
7968hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7969{
7970 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7971 hdd_adapter_t *pAdapter;
7972 VOS_STATUS status;
7973
7974 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7975
7976 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7977 {
7978 pAdapter = pAdapterNode->pAdapter;
7979
7980 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7981 {
7982 return pAdapter;
7983 }
7984
7985 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7986 pAdapterNode = pNext;
7987 }
7988
7989 return NULL;
7990
7991}
7992
Jeff Johnson295189b2012-06-20 16:38:30 -07007993/**---------------------------------------------------------------------------
7994
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307995 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007996
7997 This API returns the operating channel of the requested device mode
7998
7999 \param - pHddCtx - Pointer to the HDD context.
8000 - mode - Device mode for which operating channel is required
8001 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8002 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8003 \return - channel number. "0" id the requested device is not found OR it is not connected.
8004 --------------------------------------------------------------------------*/
8005v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8006{
8007 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8008 VOS_STATUS status;
8009 hdd_adapter_t *pAdapter;
8010 v_U8_t operatingChannel = 0;
8011
8012 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8013
8014 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8015 {
8016 pAdapter = pAdapterNode->pAdapter;
8017
8018 if( mode == pAdapter->device_mode )
8019 {
8020 switch(pAdapter->device_mode)
8021 {
8022 case WLAN_HDD_INFRA_STATION:
8023 case WLAN_HDD_P2P_CLIENT:
8024 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8025 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8026 break;
8027 case WLAN_HDD_SOFTAP:
8028 case WLAN_HDD_P2P_GO:
8029 /*softap connection info */
8030 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8031 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8032 break;
8033 default:
8034 break;
8035 }
8036
8037 break; //Found the device of interest. break the loop
8038 }
8039
8040 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8041 pAdapterNode = pNext;
8042 }
8043 return operatingChannel;
8044}
8045
8046#ifdef WLAN_FEATURE_PACKET_FILTERING
8047/**---------------------------------------------------------------------------
8048
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308049 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008050
8051 This used to set the multicast address list.
8052
8053 \param - dev - Pointer to the WLAN device.
8054 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308055 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008056
8057 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308058static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008059{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308060 hdd_adapter_t *pAdapter;
8061 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008062 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308063 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308066 ENTER();
8067
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308068 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308069 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008070 {
8071 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308072 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 return;
8074 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308075 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8076 ret = wlan_hdd_validate_context(pHddCtx);
8077 if (0 != ret)
8078 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308079 return;
8080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 if (dev->flags & IFF_ALLMULTI)
8082 {
8083 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008084 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308085 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308087 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 {
8089 mc_count = netdev_mc_count(dev);
8090 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008091 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8093 {
8094 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008095 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308096 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 return;
8098 }
8099
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308100 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008101
8102 netdev_for_each_mc_addr(ha, dev) {
8103 if (i == mc_count)
8104 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308105 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8106 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308108 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308109 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008110 i++;
8111 }
8112 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308113
8114 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 return;
8116}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308117
8118static void hdd_set_multicast_list(struct net_device *dev)
8119{
8120 vos_ssr_protect(__func__);
8121 __hdd_set_multicast_list(dev);
8122 vos_ssr_unprotect(__func__);
8123}
Jeff Johnson295189b2012-06-20 16:38:30 -07008124#endif
8125
8126/**---------------------------------------------------------------------------
8127
8128 \brief hdd_select_queue() -
8129
8130 This function is registered with the Linux OS for network
8131 core to decide which queue to use first.
8132
8133 \param - dev - Pointer to the WLAN device.
8134 - skb - Pointer to OS packet (sk_buff).
8135 \return - ac, Queue Index/access category corresponding to UP in IP header
8136
8137 --------------------------------------------------------------------------*/
8138v_U16_t hdd_select_queue(struct net_device *dev,
8139 struct sk_buff *skb)
8140{
8141 return hdd_wmm_select_queue(dev, skb);
8142}
8143
8144
8145/**---------------------------------------------------------------------------
8146
8147 \brief hdd_wlan_initial_scan() -
8148
8149 This function triggers the initial scan
8150
8151 \param - pAdapter - Pointer to the HDD adapter.
8152
8153 --------------------------------------------------------------------------*/
8154void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8155{
8156 tCsrScanRequest scanReq;
8157 tCsrChannelInfo channelInfo;
8158 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008159 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008160 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8161
8162 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8163 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8164 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8165
8166 if(sme_Is11dSupported(pHddCtx->hHal))
8167 {
8168 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8169 if ( HAL_STATUS_SUCCESS( halStatus ) )
8170 {
8171 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8172 if( !scanReq.ChannelInfo.ChannelList )
8173 {
8174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8175 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008176 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008177 return;
8178 }
8179 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8180 channelInfo.numOfChannels);
8181 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8182 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008183 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 }
8185
8186 scanReq.scanType = eSIR_PASSIVE_SCAN;
8187 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8188 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8189 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8190 }
8191 else
8192 {
8193 scanReq.scanType = eSIR_ACTIVE_SCAN;
8194 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8195 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8196 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8197 }
8198
8199 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8200 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8201 {
8202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8203 __func__, halStatus );
8204 }
8205
8206 if(sme_Is11dSupported(pHddCtx->hHal))
8207 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8208}
8209
mukul sharmabab477d2015-06-11 17:14:55 +05308210void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8211{
8212 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8213 VOS_STATUS status;
8214 hdd_adapter_t *pAdapter;
8215
8216 ENTER();
8217
8218 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8219
8220 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8221 {
8222 pAdapter = pAdapterNode->pAdapter;
8223
8224 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8225 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8226 pAdapterNode = pNext;
8227 }
8228
8229 EXIT();
8230}
Jeff Johnson295189b2012-06-20 16:38:30 -07008231/**---------------------------------------------------------------------------
8232
8233 \brief hdd_full_power_callback() - HDD full power callback function
8234
8235 This is the function invoked by SME to inform the result of a full power
8236 request issued by HDD
8237
8238 \param - callbackcontext - Pointer to cookie
8239 \param - status - result of request
8240
8241 \return - None
8242
8243 --------------------------------------------------------------------------*/
8244static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8245{
Jeff Johnson72a40512013-12-19 10:14:15 -08008246 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008247
8248 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308249 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008250
8251 if (NULL == callbackContext)
8252 {
8253 hddLog(VOS_TRACE_LEVEL_ERROR,
8254 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008255 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 return;
8257 }
8258
Jeff Johnson72a40512013-12-19 10:14:15 -08008259 /* there is a race condition that exists between this callback
8260 function and the caller since the caller could time out either
8261 before or while this code is executing. we use a spinlock to
8262 serialize these actions */
8263 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008264
8265 if (POWER_CONTEXT_MAGIC != pContext->magic)
8266 {
8267 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008268 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008269 hddLog(VOS_TRACE_LEVEL_WARN,
8270 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008271 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008272 return;
8273 }
8274
Jeff Johnson72a40512013-12-19 10:14:15 -08008275 /* context is valid so caller is still waiting */
8276
8277 /* paranoia: invalidate the magic */
8278 pContext->magic = 0;
8279
8280 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008281 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008282
8283 /* serialization is complete */
8284 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008285}
8286
Katya Nigamf0511f62015-05-05 16:40:57 +05308287void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8288{
8289 pMonCtx->typeSubtypeBitmap = 0;
8290 if( type%10 ) /* Management Packets */
8291 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8292 type/=10;
8293 if( type%10 ) /* Control Packets */
8294 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8295 type/=10;
8296 if( type%10 ) /* Data Packets */
8297 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8298}
8299
8300VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8301{
8302 vos_msg_t monMsg;
8303
8304 monMsg.type = WDA_MON_START_REQ;
8305 monMsg.reserved = 0;
8306 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8307 monMsg.bodyval = 0;
8308
8309 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8310 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8311 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8312 return VOS_STATUS_E_FAILURE;
8313 }
8314
8315 return VOS_STATUS_SUCCESS;
8316}
8317
8318void wlan_hdd_mon_poststopmsg(void)
8319{
8320 vos_msg_t monMsg;
8321
8322 monMsg.type = WDA_MON_STOP_REQ;
8323 monMsg.reserved = 0;
8324 monMsg.bodyptr = NULL;
8325 monMsg.bodyval = 0;
8326
8327 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8328 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8329 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8330 }
8331}
8332
Katya Nigame7b69a82015-04-28 15:24:06 +05308333void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8334{
8335 VOS_STATUS vosStatus;
8336 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8337 struct wiphy *wiphy = pHddCtx->wiphy;
8338
8339 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8340 if(pAdapter == NULL || pVosContext == NULL)
8341 {
8342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8343 return ;
8344 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308345
8346 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308347 hdd_UnregisterWext(pAdapter->dev);
8348
8349 vos_mon_stop( pVosContext );
8350
8351 vosStatus = vos_sched_close( pVosContext );
8352 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8353 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8354 "%s: Failed to close VOSS Scheduler",__func__);
8355 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8356 }
8357
8358 vosStatus = vos_nv_close();
8359 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8360 {
8361 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8362 "%s: Failed to close NV", __func__);
8363 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8364 }
8365
8366 vos_close(pVosContext);
8367
8368 #ifdef WLAN_KD_READY_NOTIFIER
8369 nl_srv_exit(pHddCtx->ptt_pid);
8370 #else
8371 nl_srv_exit();
8372 #endif
8373
8374 if (pHddCtx->cfg_ini)
8375 {
8376 kfree(pHddCtx->cfg_ini);
8377 pHddCtx->cfg_ini= NULL;
8378 }
8379 hdd_close_all_adapters( pHddCtx );
8380
8381 wiphy_free(wiphy) ;
8382
8383}
Jeff Johnson295189b2012-06-20 16:38:30 -07008384/**---------------------------------------------------------------------------
8385
8386 \brief hdd_wlan_exit() - HDD WLAN exit function
8387
8388 This is the driver exit point (invoked during rmmod)
8389
8390 \param - pHddCtx - Pointer to the HDD Context
8391
8392 \return - None
8393
8394 --------------------------------------------------------------------------*/
8395void hdd_wlan_exit(hdd_context_t *pHddCtx)
8396{
8397 eHalStatus halStatus;
8398 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8399 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308400 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008401 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008402 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308404 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008405
8406 ENTER();
8407
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308408
Katya Nigame7b69a82015-04-28 15:24:06 +05308409 if (VOS_MONITOR_MODE == hdd_get_conparam())
8410 {
8411 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8412 wlan_hdd_mon_close(pHddCtx);
8413 return;
8414 }
8415 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008416 {
8417 // Unloading, restart logic is no more required.
8418 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008419
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308420#ifdef FEATURE_WLAN_TDLS
8421 /* At the time of driver unloading; if tdls connection is present;
8422 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8423 * wlan_hdd_tdls_find_peer always checks for valid context;
8424 * as load/unload in progress there can be a race condition.
8425 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8426 * when tdls state is enabled.
8427 * As soon as driver set load/unload flag; tdls flag also needs
8428 * to be disabled so that hdd_rx_packet_cbk won't call
8429 * wlan_hdd_tdls_find_peer.
8430 */
8431 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8432#endif
8433
c_hpothu5ab05e92014-06-13 17:34:05 +05308434 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8435 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308437 pAdapter = pAdapterNode->pAdapter;
8438 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308440 /* Disable TX on the interface, after this hard_start_xmit() will
8441 * not be called on that interface
8442 */
8443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8444 netif_tx_disable(pAdapter->dev);
8445
8446 /* Mark the interface status as "down" for outside world */
8447 netif_carrier_off(pAdapter->dev);
8448
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308449 /* DeInit the adapter. This ensures that all data packets
8450 * are freed.
8451 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308452#ifdef FEATURE_WLAN_TDLS
8453 mutex_lock(&pHddCtx->tdls_lock);
8454#endif
c_hpothu002231a2015-02-05 14:58:51 +05308455 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308456#ifdef FEATURE_WLAN_TDLS
8457 mutex_unlock(&pHddCtx->tdls_lock);
8458#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308459
c_hpothu5ab05e92014-06-13 17:34:05 +05308460 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8461 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8462 {
8463 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8464 hdd_UnregisterWext(pAdapter->dev);
8465 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308466
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308468 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8469 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 }
mukul sharmabab477d2015-06-11 17:14:55 +05308471
8472 //Purge all sme cmd's for all interface
8473 hdd_purge_cmd_list_all_adapters(pHddCtx);
8474
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308475 // Cancel any outstanding scan requests. We are about to close all
8476 // of our adapters, but an adapter structure is what SME passes back
8477 // to our callback function. Hence if there are any outstanding scan
8478 // requests then there is a race condition between when the adapter
8479 // is closed and when the callback is invoked.We try to resolve that
8480 // race condition here by canceling any outstanding scans before we
8481 // close the adapters.
8482 // Note that the scans may be cancelled in an asynchronous manner,
8483 // so ideally there needs to be some kind of synchronization. Rather
8484 // than introduce a new synchronization here, we will utilize the
8485 // fact that we are about to Request Full Power, and since that is
8486 // synchronized, the expectation is that by the time Request Full
8487 // Power has completed all scans will be cancelled.
8488 if (pHddCtx->scan_info.mScanPending)
8489 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308490 if(NULL != pAdapter)
8491 {
8492 hddLog(VOS_TRACE_LEVEL_INFO,
8493 FL("abort scan mode: %d sessionId: %d"),
8494 pAdapter->device_mode,
8495 pAdapter->sessionId);
8496 }
8497 hdd_abort_mac_scan(pHddCtx,
8498 pHddCtx->scan_info.sessionId,
8499 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308502 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008503 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308504 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308505 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8506 {
8507 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8509 "%s: in middle of FTM START", __func__);
8510 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8511 msecs_to_jiffies(20000));
8512 if(!lrc)
8513 {
8514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8515 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8516 }
8517 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008518 wlan_hdd_ftm_close(pHddCtx);
8519 goto free_hdd_ctx;
8520 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308521
Jeff Johnson295189b2012-06-20 16:38:30 -07008522 /* DeRegister with platform driver as client for Suspend/Resume */
8523 vosStatus = hddDeregisterPmOps(pHddCtx);
8524 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8525 {
8526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8527 VOS_ASSERT(0);
8528 }
8529
8530 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8531 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8532 {
8533 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008535
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008536 //Stop the traffic monitor timer
8537 if ( VOS_TIMER_STATE_RUNNING ==
8538 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8539 {
8540 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8541 }
8542
8543 // Destroy the traffic monitor timer
8544 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8545 &pHddCtx->tx_rx_trafficTmr)))
8546 {
8547 hddLog(VOS_TRACE_LEVEL_ERROR,
8548 "%s: Cannot deallocate Traffic monitor timer", __func__);
8549 }
8550
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 //Disable IMPS/BMPS as we do not want the device to enter any power
8552 //save mode during shutdown
8553 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8554 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8555 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8556
8557 //Ensure that device is in full power as we will touch H/W during vos_Stop
8558 init_completion(&powerContext.completion);
8559 powerContext.magic = POWER_CONTEXT_MAGIC;
8560
8561 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8562 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8563
8564 if (eHAL_STATUS_SUCCESS != halStatus)
8565 {
8566 if (eHAL_STATUS_PMC_PENDING == halStatus)
8567 {
8568 /* request was sent -- wait for the response */
8569 lrc = wait_for_completion_interruptible_timeout(
8570 &powerContext.completion,
8571 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 if (lrc <= 0)
8573 {
8574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008575 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 }
8577 }
8578 else
8579 {
8580 hddLog(VOS_TRACE_LEVEL_ERROR,
8581 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008582 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008583 /* continue -- need to clean up as much as possible */
8584 }
8585 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308586 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8587 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8588 {
8589 /* This will issue a dump command which will clean up
8590 BTQM queues and unblock MC thread */
8591 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008593
Jeff Johnson72a40512013-12-19 10:14:15 -08008594 /* either we never sent a request, we sent a request and received a
8595 response or we sent a request and timed out. if we never sent a
8596 request or if we sent a request and got a response, we want to
8597 clear the magic out of paranoia. if we timed out there is a
8598 race condition such that the callback function could be
8599 executing at the same time we are. of primary concern is if the
8600 callback function had already verified the "magic" but had not
8601 yet set the completion variable when a timeout occurred. we
8602 serialize these activities by invalidating the magic while
8603 holding a shared spinlock which will cause us to block if the
8604 callback is currently executing */
8605 spin_lock(&hdd_context_lock);
8606 powerContext.magic = 0;
8607 spin_unlock(&hdd_context_lock);
8608
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308609 /* If Device is shutdown, no point for SME to wait for responses
8610 from device. Pre Close SME */
8611 if(wcnss_device_is_shutdown())
8612 {
8613 sme_PreClose(pHddCtx->hHal);
8614 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008615 hdd_debugfs_exit(pHddCtx);
8616
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308617#ifdef WLAN_NS_OFFLOAD
8618 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8619 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8620#endif
8621 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8622 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8623
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 // Unregister the Net Device Notifier
8625 unregister_netdevice_notifier(&hdd_netdev_notifier);
8626
Jeff Johnson295189b2012-06-20 16:38:30 -07008627 hdd_stop_all_adapters( pHddCtx );
8628
Jeff Johnson295189b2012-06-20 16:38:30 -07008629#ifdef WLAN_BTAMP_FEATURE
8630 vosStatus = WLANBAP_Stop(pVosContext);
8631 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8632 {
8633 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8634 "%s: Failed to stop BAP",__func__);
8635 }
8636#endif //WLAN_BTAMP_FEATURE
8637
8638 //Stop all the modules
8639 vosStatus = vos_stop( pVosContext );
8640 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8641 {
8642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8643 "%s: Failed to stop VOSS",__func__);
8644 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8645 }
8646
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008649
8650 //Close the scheduler before calling vos_close to make sure no thread is
8651 // scheduled after the each module close is called i.e after all the data
8652 // structures are freed.
8653 vosStatus = vos_sched_close( pVosContext );
8654 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8655 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8656 "%s: Failed to close VOSS Scheduler",__func__);
8657 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8658 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008659#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8660 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308661 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008662#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008663 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308664 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008665
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308666#ifdef CONFIG_ENABLE_LINUX_REG
8667 vosStatus = vos_nv_close();
8668 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8669 {
8670 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8671 "%s: Failed to close NV", __func__);
8672 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8673 }
8674#endif
8675
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 //Close VOSS
8677 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8678 vos_close(pVosContext);
8679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 //Close Watchdog
8681 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8682 vos_watchdog_close(pVosContext);
8683
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308684 //Clean up HDD Nlink Service
8685 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308686
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308687#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308688 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308689 {
8690 wlan_logging_sock_deactivate_svc();
8691 }
8692#endif
8693
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308694#ifdef WLAN_KD_READY_NOTIFIER
8695 nl_srv_exit(pHddCtx->ptt_pid);
8696#else
8697 nl_srv_exit();
8698#endif /* WLAN_KD_READY_NOTIFIER */
8699
8700
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 hdd_close_all_adapters( pHddCtx );
8702
Jeff Johnson295189b2012-06-20 16:38:30 -07008703 /* free the power on lock from platform driver */
8704 if (free_riva_power_on_lock("wlan"))
8705 {
8706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8707 __func__);
8708 }
8709
Jeff Johnson88ba7742013-02-27 14:36:02 -08008710free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308711
8712 //Free up dynamically allocated members inside HDD Adapter
8713 if (pHddCtx->cfg_ini)
8714 {
8715 kfree(pHddCtx->cfg_ini);
8716 pHddCtx->cfg_ini= NULL;
8717 }
8718
Leo Changf04ddad2013-09-18 13:46:38 -07008719 /* FTM mode, WIPHY did not registered
8720 If un-register here, system crash will happen */
8721 if (VOS_FTM_MODE != hdd_get_conparam())
8722 {
8723 wiphy_unregister(wiphy) ;
8724 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008726 if (hdd_is_ssr_required())
8727 {
8728 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008729 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 msleep(5000);
8731 }
8732 hdd_set_ssr_required (VOS_FALSE);
8733}
8734
8735
8736/**---------------------------------------------------------------------------
8737
8738 \brief hdd_update_config_from_nv() - Function to update the contents of
8739 the running configuration with parameters taken from NV storage
8740
8741 \param - pHddCtx - Pointer to the HDD global context
8742
8743 \return - VOS_STATUS_SUCCESS if successful
8744
8745 --------------------------------------------------------------------------*/
8746static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8747{
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 v_BOOL_t itemIsValid = VOS_FALSE;
8749 VOS_STATUS status;
8750 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8751 v_U8_t macLoop;
8752
8753 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8754 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8755 if(status != VOS_STATUS_SUCCESS)
8756 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008757 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 return VOS_STATUS_E_FAILURE;
8759 }
8760
8761 if (itemIsValid == VOS_TRUE)
8762 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008763 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8765 VOS_MAX_CONCURRENCY_PERSONA);
8766 if(status != VOS_STATUS_SUCCESS)
8767 {
8768 /* Get MAC from NV fail, not update CFG info
8769 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008770 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 return VOS_STATUS_E_FAILURE;
8772 }
8773
8774 /* If first MAC is not valid, treat all others are not valid
8775 * Then all MACs will be got from ini file */
8776 if(vos_is_macaddr_zero(&macFromNV[0]))
8777 {
8778 /* MAC address in NV file is not configured yet */
8779 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8780 return VOS_STATUS_E_INVAL;
8781 }
8782
8783 /* Get MAC address from NV, update CFG info */
8784 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8785 {
8786 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8787 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308788 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 /* This MAC is not valid, skip it
8790 * This MAC will be got from ini file */
8791 }
8792 else
8793 {
8794 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8795 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8796 VOS_MAC_ADDR_SIZE);
8797 }
8798 }
8799 }
8800 else
8801 {
8802 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8803 return VOS_STATUS_E_FAILURE;
8804 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008805
Jeff Johnson295189b2012-06-20 16:38:30 -07008806
8807 return VOS_STATUS_SUCCESS;
8808}
8809
8810/**---------------------------------------------------------------------------
8811
8812 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8813
8814 \param - pAdapter - Pointer to the HDD
8815
8816 \return - None
8817
8818 --------------------------------------------------------------------------*/
8819VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8820{
8821 eHalStatus halStatus;
8822 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308823 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825
8826 // Send ready indication to the HDD. This will kick off the MAC
8827 // into a 'running' state and should kick off an initial scan.
8828 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8829 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8830 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308831 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 "code %08d [x%08x]",__func__, halStatus, halStatus );
8833 return VOS_STATUS_E_FAILURE;
8834 }
8835
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308836 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8838 // And RIVA will crash
8839 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8840 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308841 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8842 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8843
8844
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 return VOS_STATUS_SUCCESS;
8846}
8847
Jeff Johnson295189b2012-06-20 16:38:30 -07008848/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308849void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008850{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308851
8852 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8853
Jeff Johnson295189b2012-06-20 16:38:30 -07008854}
8855
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308856void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008857{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308858
8859 vos_wake_lock_release(&wlan_wake_lock, reason);
8860
Jeff Johnson295189b2012-06-20 16:38:30 -07008861}
8862
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308863void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008864{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308865
8866 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8867 reason);
8868
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008869}
8870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871/**---------------------------------------------------------------------------
8872
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008873 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8874 information between Host and Riva
8875
8876 This function gets reported version of FW
8877 It also finds the version of Riva headers used to compile the host
8878 It compares the above two and prints a warning if they are different
8879 It gets the SW and HW version string
8880 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8881 indicating the features they support through a bitmap
8882
8883 \param - pHddCtx - Pointer to HDD context
8884
8885 \return - void
8886
8887 --------------------------------------------------------------------------*/
8888
8889void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8890{
8891
8892 tSirVersionType versionCompiled;
8893 tSirVersionType versionReported;
8894 tSirVersionString versionString;
8895 tANI_U8 fwFeatCapsMsgSupported = 0;
8896 VOS_STATUS vstatus;
8897
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008898 memset(&versionCompiled, 0, sizeof(versionCompiled));
8899 memset(&versionReported, 0, sizeof(versionReported));
8900
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008901 /* retrieve and display WCNSS version information */
8902 do {
8903
8904 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8905 &versionCompiled);
8906 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8907 {
8908 hddLog(VOS_TRACE_LEVEL_FATAL,
8909 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008910 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008911 break;
8912 }
8913
8914 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8915 &versionReported);
8916 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8917 {
8918 hddLog(VOS_TRACE_LEVEL_FATAL,
8919 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008920 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008921 break;
8922 }
8923
8924 if ((versionCompiled.major != versionReported.major) ||
8925 (versionCompiled.minor != versionReported.minor) ||
8926 (versionCompiled.version != versionReported.version) ||
8927 (versionCompiled.revision != versionReported.revision))
8928 {
8929 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8930 "Host expected %u.%u.%u.%u\n",
8931 WLAN_MODULE_NAME,
8932 (int)versionReported.major,
8933 (int)versionReported.minor,
8934 (int)versionReported.version,
8935 (int)versionReported.revision,
8936 (int)versionCompiled.major,
8937 (int)versionCompiled.minor,
8938 (int)versionCompiled.version,
8939 (int)versionCompiled.revision);
8940 }
8941 else
8942 {
8943 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8944 WLAN_MODULE_NAME,
8945 (int)versionReported.major,
8946 (int)versionReported.minor,
8947 (int)versionReported.version,
8948 (int)versionReported.revision);
8949 }
8950
8951 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8952 versionString,
8953 sizeof(versionString));
8954 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8955 {
8956 hddLog(VOS_TRACE_LEVEL_FATAL,
8957 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008958 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008959 break;
8960 }
8961
8962 pr_info("%s: WCNSS software version %s\n",
8963 WLAN_MODULE_NAME, versionString);
8964
8965 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8966 versionString,
8967 sizeof(versionString));
8968 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8969 {
8970 hddLog(VOS_TRACE_LEVEL_FATAL,
8971 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008972 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008973 break;
8974 }
8975
8976 pr_info("%s: WCNSS hardware version %s\n",
8977 WLAN_MODULE_NAME, versionString);
8978
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008979 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8980 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008981 send the message only if it the riva is 1.1
8982 minor numbers for different riva branches:
8983 0 -> (1.0)Mainline Build
8984 1 -> (1.1)Mainline Build
8985 2->(1.04) Stability Build
8986 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008987 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008988 ((versionReported.minor>=1) && (versionReported.version>=1)))
8989 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8990 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008991
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008992 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008993 {
8994#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8995 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8996 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8997#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008998 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8999 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9000 {
9001 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9002 }
9003
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009004 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009005 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009006
9007 } while (0);
9008
9009}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309010void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9011{
9012 struct sk_buff *skb;
9013 struct nlmsghdr *nlh;
9014 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309015 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309016
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309017 if (in_interrupt() || irqs_disabled() || in_atomic())
9018 flags = GFP_ATOMIC;
9019
9020 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309021
9022 if(skb == NULL) {
9023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9024 "%s: alloc_skb failed", __func__);
9025 return;
9026 }
9027
9028 nlh = (struct nlmsghdr *)skb->data;
9029 nlh->nlmsg_pid = 0; /* from kernel */
9030 nlh->nlmsg_flags = 0;
9031 nlh->nlmsg_seq = 0;
9032 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9033
9034 ani_hdr = NLMSG_DATA(nlh);
9035 ani_hdr->type = type;
9036
9037 switch(type) {
9038 case WLAN_SVC_SAP_RESTART_IND:
9039 ani_hdr->length = 0;
9040 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9041 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9042 break;
9043 default:
9044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9045 "Attempt to send unknown nlink message %d", type);
9046 kfree_skb(skb);
9047 return;
9048 }
9049
9050 nl_srv_bcast(skb);
9051
9052 return;
9053}
9054
9055
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009056
9057/**---------------------------------------------------------------------------
9058
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309059 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9060
9061 \param - pHddCtx - Pointer to the hdd context
9062
9063 \return - true if hardware supports 5GHz
9064
9065 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309066boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309067{
9068 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9069 * then hardware support 5Ghz.
9070 */
9071 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9072 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309074 return true;
9075 }
9076 else
9077 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309079 __func__);
9080 return false;
9081 }
9082}
9083
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309084/**---------------------------------------------------------------------------
9085
9086 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9087 generate function
9088
9089 This is generate the random mac address for WLAN interface
9090
9091 \param - pHddCtx - Pointer to HDD context
9092 idx - Start interface index to get auto
9093 generated mac addr.
9094 mac_addr - Mac address
9095
9096 \return - 0 for success, < 0 for failure
9097
9098 --------------------------------------------------------------------------*/
9099
9100static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9101 int idx, v_MACADDR_t mac_addr)
9102{
9103 int i;
9104 unsigned int serialno;
9105 serialno = wcnss_get_serial_number();
9106
9107 if (0 != serialno)
9108 {
9109 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9110 bytes of the serial number that can be used to generate
9111 the other 3 bytes of the MAC address. Mask off all but
9112 the lower 3 bytes (this will also make sure we don't
9113 overflow in the next step) */
9114 serialno &= 0x00FFFFFF;
9115
9116 /* we need a unique address for each session */
9117 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9118
9119 /* autogen other Mac addresses */
9120 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9121 {
9122 /* start with the entire default address */
9123 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9124 /* then replace the lower 3 bytes */
9125 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9126 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9127 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9128
9129 serialno++;
9130 hddLog(VOS_TRACE_LEVEL_ERROR,
9131 "%s: Derived Mac Addr: "
9132 MAC_ADDRESS_STR, __func__,
9133 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9134 }
9135
9136 }
9137 else
9138 {
9139 hddLog(LOGE, FL("Failed to Get Serial NO"));
9140 return -1;
9141 }
9142 return 0;
9143}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309144
Katya Nigame7b69a82015-04-28 15:24:06 +05309145int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9146{
9147 VOS_STATUS status;
9148 v_CONTEXT_t pVosContext= NULL;
9149 hdd_adapter_t *pAdapter= NULL;
9150
9151 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9152
9153 if (NULL == pVosContext)
9154 {
9155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9156 "%s: Trying to open VOSS without a PreOpen", __func__);
9157 VOS_ASSERT(0);
9158 return VOS_STATUS_E_FAILURE;
9159 }
9160
9161 status = vos_nv_open();
9162 if (!VOS_IS_STATUS_SUCCESS(status))
9163 {
9164 /* NV module cannot be initialized */
9165 hddLog( VOS_TRACE_LEVEL_FATAL,
9166 "%s: vos_nv_open failed", __func__);
9167 return VOS_STATUS_E_FAILURE;
9168 }
9169
9170 status = vos_init_wiphy_from_nv_bin();
9171 if (!VOS_IS_STATUS_SUCCESS(status))
9172 {
9173 /* NV module cannot be initialized */
9174 hddLog( VOS_TRACE_LEVEL_FATAL,
9175 "%s: vos_init_wiphy failed", __func__);
9176 goto err_vos_nv_close;
9177 }
9178
9179 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9180 if ( !VOS_IS_STATUS_SUCCESS( status ))
9181 {
9182 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9183 goto err_vos_nv_close;
9184 }
9185
9186 status = vos_mon_start( pVosContext );
9187 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9188 {
9189 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9190 goto err_vosclose;
9191 }
9192
9193 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9194 WDA_featureCapsExchange(pVosContext);
9195 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9196
9197 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9198 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9199 if( pAdapter == NULL )
9200 {
9201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9202 goto err_close_adapter;
9203 }
9204
9205 //Initialize the nlink service
9206 if(nl_srv_init() != 0)
9207 {
9208 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9209 goto err_close_adapter;
9210 }
9211 return VOS_STATUS_SUCCESS;
9212
9213err_close_adapter:
9214 hdd_close_all_adapters( pHddCtx );
9215 vos_mon_stop( pVosContext );
9216err_vosclose:
9217 status = vos_sched_close( pVosContext );
9218 if (!VOS_IS_STATUS_SUCCESS(status)) {
9219 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9220 "%s: Failed to close VOSS Scheduler", __func__);
9221 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9222 }
9223 vos_close(pVosContext );
9224
9225err_vos_nv_close:
9226 vos_nv_close();
9227
9228return status;
9229}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309230/**---------------------------------------------------------------------------
9231
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309232 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9233 completed to flush out the scan results
9234
9235 11d scan is done during driver load and is a passive scan on all
9236 channels supported by the device, 11d scans may find some APs on
9237 frequencies which are forbidden to be used in the regulatory domain
9238 the device is operating in. If these APs are notified to the supplicant
9239 it may try to connect to these APs, thus flush out all the scan results
9240 which are present in SME after 11d scan is done.
9241
9242 \return - eHalStatus
9243
9244 --------------------------------------------------------------------------*/
9245static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9246 tANI_U32 scanId, eCsrScanStatus status)
9247{
9248 ENTER();
9249
9250 sme_ScanFlushResult(halHandle, 0);
9251
9252 EXIT();
9253
9254 return eHAL_STATUS_SUCCESS;
9255}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309256/**---------------------------------------------------------------------------
9257
9258 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9259 logging is completed successfully.
9260
9261 \return - None
9262
9263 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309264void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309265{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309266 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309267
9268 if (NULL == pHddCtx)
9269 {
9270 hddLog(VOS_TRACE_LEVEL_ERROR,
9271 "%s: HDD context is NULL",__func__);
9272 return;
9273 }
9274
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309275 if ((VOS_STATUS_SUCCESS == status) &&
9276 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309277 {
9278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9279 pHddCtx->mgmt_frame_logging = TRUE;
9280 }
9281 else
9282 {
9283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9284 pHddCtx->mgmt_frame_logging = FALSE;
9285 }
9286
9287 return;
9288}
9289/**---------------------------------------------------------------------------
9290
9291 \brief hdd_init_frame_logging - function to initialize frame logging.
9292 Currently only Mgmt Frames are logged in both TX
9293 and Rx direction and are sent to userspace
9294 application using logger thread when queried.
9295
9296 \return - None
9297
9298 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309299void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309300{
9301 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309302 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309303
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309304 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9305 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309306 {
9307 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9308 return;
9309 }
9310
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309311 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9312 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309313 {
9314 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9315 return;
9316 }
9317
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309318 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309319
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309320 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9321 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9322 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9323 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309324
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309325 if (pHddCtx->cfg_ini->enableFWLogging ||
9326 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309327 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309328 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309329 }
9330
Sushant Kaushik46804902015-07-08 14:46:03 +05309331 if (pHddCtx->cfg_ini->enableMgmtLogging)
9332 {
9333 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9334 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309335 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9336 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309337 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309338 }
9339
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309340 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9341 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9342 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9343 wlanFWLoggingInitParam->continuousFrameLogging =
9344 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309345
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309346 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309347
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309348 wlanFWLoggingInitParam->minLogBufferSize =
9349 pHddCtx->cfg_ini->minLoggingBufferSize;
9350 wlanFWLoggingInitParam->maxLogBufferSize =
9351 pHddCtx->cfg_ini->maxLoggingBufferSize;
9352 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9353 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309354
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309355 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309356
9357 if (eHAL_STATUS_SUCCESS != halStatus)
9358 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309359 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309360 }
9361
9362 return;
9363}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309364
9365/**---------------------------------------------------------------------------
9366
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 \brief hdd_wlan_startup() - HDD init function
9368
9369 This is the driver startup code executed once a WLAN device has been detected
9370
9371 \param - dev - Pointer to the underlying device
9372
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009373 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009374
9375 --------------------------------------------------------------------------*/
9376
9377int hdd_wlan_startup(struct device *dev )
9378{
9379 VOS_STATUS status;
9380 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009381 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 hdd_context_t *pHddCtx = NULL;
9383 v_CONTEXT_t pVosContext= NULL;
9384#ifdef WLAN_BTAMP_FEATURE
9385 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9386 WLANBAP_ConfigType btAmpConfig;
9387 hdd_config_t *pConfig;
9388#endif
9389 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309391 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009392
9393 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 /*
9395 * cfg80211: wiphy allocation
9396 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309397 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009398
9399 if(wiphy == NULL)
9400 {
9401 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009402 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 pHddCtx = wiphy_priv(wiphy);
9405
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 //Initialize the adapter context to zeros.
9407 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9408
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309410 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309411 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009412
9413 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9414
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309415 /* register for riva power on lock to platform driver
9416 * Locking power early to ensure FW doesn't reset by kernel while
9417 * host driver is busy initializing itself */
9418 if (req_riva_power_on_lock("wlan"))
9419 {
9420 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9421 __func__);
9422 goto err_free_hdd_context;
9423 }
9424
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 /*Get vos context here bcoz vos_open requires it*/
9426 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9427
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009428 if(pVosContext == NULL)
9429 {
9430 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9431 goto err_free_hdd_context;
9432 }
9433
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 //Save the Global VOSS context in adapter context for future.
9435 pHddCtx->pvosContext = pVosContext;
9436
9437 //Save the adapter context in global context for future.
9438 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9439
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 pHddCtx->parent_dev = dev;
9441
9442 init_completion(&pHddCtx->full_pwr_comp_var);
9443 init_completion(&pHddCtx->standby_comp_var);
9444 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009445 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009446 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309447 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309448 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009449
9450#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009451 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009452#else
9453 init_completion(&pHddCtx->driver_crda_req);
9454#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009455
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309456 spin_lock_init(&pHddCtx->schedScan_lock);
9457
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9459
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309460#ifdef FEATURE_WLAN_TDLS
9461 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9462 * invoked by other instances also) to protect the concurrent
9463 * access for the Adapters by TDLS module.
9464 */
9465 mutex_init(&pHddCtx->tdls_lock);
9466#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309467 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309468 mutex_init(&pHddCtx->wmmLock);
9469
Agarwal Ashish1f422872014-07-22 00:11:55 +05309470 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309471
Agarwal Ashish1f422872014-07-22 00:11:55 +05309472 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 // Load all config first as TL config is needed during vos_open
9474 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9475 if(pHddCtx->cfg_ini == NULL)
9476 {
9477 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9478 goto err_free_hdd_context;
9479 }
9480
9481 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9482
9483 // Read and parse the qcom_cfg.ini file
9484 status = hdd_parse_config_ini( pHddCtx );
9485 if ( VOS_STATUS_SUCCESS != status )
9486 {
9487 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9488 __func__, WLAN_INI_FILE);
9489 goto err_config;
9490 }
Arif Hussaind5218912013-12-05 01:10:55 -08009491#ifdef MEMORY_DEBUG
9492 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9493 vos_mem_init();
9494
9495 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9496 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9497#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009498
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309499 /* INI has been read, initialise the configuredMcastBcastFilter with
9500 * INI value as this will serve as the default value
9501 */
9502 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9503 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9504 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309505
9506 if (false == hdd_is_5g_supported(pHddCtx))
9507 {
9508 //5Ghz is not supported.
9509 if (1 != pHddCtx->cfg_ini->nBandCapability)
9510 {
9511 hddLog(VOS_TRACE_LEVEL_INFO,
9512 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9513 pHddCtx->cfg_ini->nBandCapability = 1;
9514 }
9515 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309516
9517 /* If SNR Monitoring is enabled, FW has to parse all beacons
9518 * for calcaluting and storing the average SNR, so set Nth beacon
9519 * filter to 1 to enable FW to parse all the beaocons
9520 */
9521 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9522 {
9523 /* The log level is deliberately set to WARN as overriding
9524 * nthBeaconFilter to 1 will increase power cosumption and this
9525 * might just prove helpful to detect the power issue.
9526 */
9527 hddLog(VOS_TRACE_LEVEL_WARN,
9528 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9529 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309532 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009534 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009536 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9537 {
9538 hddLog(VOS_TRACE_LEVEL_FATAL,
9539 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9540 goto err_config;
9541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009543
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009544 // Update VOS trace levels based upon the cfg.ini
9545 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9546 pHddCtx->cfg_ini->vosTraceEnableBAP);
9547 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9548 pHddCtx->cfg_ini->vosTraceEnableTL);
9549 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9550 pHddCtx->cfg_ini->vosTraceEnableWDI);
9551 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9552 pHddCtx->cfg_ini->vosTraceEnableHDD);
9553 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9554 pHddCtx->cfg_ini->vosTraceEnableSME);
9555 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9556 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309557 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9558 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009559 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9560 pHddCtx->cfg_ini->vosTraceEnableWDA);
9561 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9562 pHddCtx->cfg_ini->vosTraceEnableSYS);
9563 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9564 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009565 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9566 pHddCtx->cfg_ini->vosTraceEnableSAP);
9567 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9568 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009569
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 // Update WDI trace levels based upon the cfg.ini
9571 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9572 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9573 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9574 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9575 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9576 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9577 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9578 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009579
Jeff Johnson88ba7742013-02-27 14:36:02 -08009580 if (VOS_FTM_MODE == hdd_get_conparam())
9581 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9583 {
9584 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9585 goto err_free_hdd_context;
9586 }
9587 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309588 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309589 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009592
Katya Nigame7b69a82015-04-28 15:24:06 +05309593 if( VOS_MONITOR_MODE == hdd_get_conparam())
9594 {
9595 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9596 {
9597 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9598 goto err_free_hdd_context;
9599 }
9600 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9601 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9602 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9603 return VOS_STATUS_SUCCESS;
9604 }
9605
Jeff Johnson88ba7742013-02-27 14:36:02 -08009606 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9608 {
9609 status = vos_watchdog_open(pVosContext,
9610 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9611
9612 if(!VOS_IS_STATUS_SUCCESS( status ))
9613 {
9614 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309615 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 }
9617 }
9618
9619 pHddCtx->isLogpInProgress = FALSE;
9620 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9621
Amar Singhala49cbc52013-10-08 18:37:44 -07009622#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009623 /* initialize the NV module. This is required so that
9624 we can initialize the channel information in wiphy
9625 from the NV.bin data. The channel information in
9626 wiphy needs to be initialized before wiphy registration */
9627
9628 status = vos_nv_open();
9629 if (!VOS_IS_STATUS_SUCCESS(status))
9630 {
9631 /* NV module cannot be initialized */
9632 hddLog( VOS_TRACE_LEVEL_FATAL,
9633 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309634 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009635 }
9636
9637 status = vos_init_wiphy_from_nv_bin();
9638 if (!VOS_IS_STATUS_SUCCESS(status))
9639 {
9640 /* NV module cannot be initialized */
9641 hddLog( VOS_TRACE_LEVEL_FATAL,
9642 "%s: vos_init_wiphy failed", __func__);
9643 goto err_vos_nv_close;
9644 }
9645
Amar Singhala49cbc52013-10-08 18:37:44 -07009646#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309647 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309648 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 if ( !VOS_IS_STATUS_SUCCESS( status ))
9650 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009651 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309652 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 }
9654
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9656
9657 if ( NULL == pHddCtx->hHal )
9658 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009659 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 goto err_vosclose;
9661 }
9662
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009663 status = vos_preStart( pHddCtx->pvosContext );
9664 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9665 {
9666 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309667 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009668 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009669
Arif Hussaineaf68602013-12-30 23:10:44 -08009670 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9671 {
9672 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9673 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9674 __func__, enable_dfs_chan_scan);
9675 }
9676 if (0 == enable_11d || 1 == enable_11d)
9677 {
9678 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9679 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9680 __func__, enable_11d);
9681 }
9682
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009683 /* Note that the vos_preStart() sequence triggers the cfg download.
9684 The cfg download must occur before we update the SME config
9685 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 status = hdd_set_sme_config( pHddCtx );
9687
9688 if ( VOS_STATUS_SUCCESS != status )
9689 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009690 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309691 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009693
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 /* In the integrated architecture we update the configuration from
9695 the INI file and from NV before vOSS has been started so that
9696 the final contents are available to send down to the cCPU */
9697
9698 // Apply the cfg.ini to cfg.dat
9699 if (FALSE == hdd_update_config_dat(pHddCtx))
9700 {
9701 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309702 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 }
9704
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309705 // Get mac addr from platform driver
9706 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9707
9708 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309710 /* Store the mac addr for first interface */
9711 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9712
9713 hddLog(VOS_TRACE_LEVEL_ERROR,
9714 "%s: WLAN Mac Addr: "
9715 MAC_ADDRESS_STR, __func__,
9716 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9717
9718 /* Here, passing Arg2 as 1 because we do not want to change the
9719 last 3 bytes (means non OUI bytes) of first interface mac
9720 addr.
9721 */
9722 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9723 {
9724 hddLog(VOS_TRACE_LEVEL_ERROR,
9725 "%s: Failed to generate wlan interface mac addr "
9726 "using MAC from ini file ", __func__);
9727 }
9728 }
9729 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9730 {
9731 // Apply the NV to cfg.dat
9732 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009733#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9734 /* There was not a valid set of MAC Addresses in NV. See if the
9735 default addresses were modified by the cfg.ini settings. If so,
9736 we'll use them, but if not, we'll autogenerate a set of MAC
9737 addresses based upon the device serial number */
9738
9739 static const v_MACADDR_t default_address =
9740 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009741
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309742 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9743 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 {
9745 /* cfg.ini has the default address, invoke autogen logic */
9746
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309747 /* Here, passing Arg2 as 0 because we want to change the
9748 last 3 bytes (means non OUI bytes) of all the interfaces
9749 mac addr.
9750 */
9751 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9752 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309754 hddLog(VOS_TRACE_LEVEL_ERROR,
9755 "%s: Failed to generate wlan interface mac addr "
9756 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9757 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 }
9760 else
9761#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9762 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009763 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009764 "%s: Invalid MAC address in NV, using MAC from ini file "
9765 MAC_ADDRESS_STR, __func__,
9766 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9767 }
9768 }
9769 {
9770 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309771
9772 /* Set the MAC Address Currently this is used by HAL to
9773 * add self sta. Remove this once self sta is added as
9774 * part of session open.
9775 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9777 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9778 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309779
Jeff Johnson295189b2012-06-20 16:38:30 -07009780 if (!HAL_STATUS_SUCCESS( halStatus ))
9781 {
9782 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9783 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309784 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 }
9786 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009787
9788 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9789 Note: Firmware image will be read and downloaded inside vos_start API */
9790 status = vos_start( pHddCtx->pvosContext );
9791 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9792 {
9793 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309794 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 }
9796
Leo Chang6cec3e22014-01-21 15:33:49 -08009797#ifdef FEATURE_WLAN_CH_AVOID
9798 /* Plug in avoid channel notification callback
9799 * This should happen before ADD_SELF_STA
9800 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309801
9802 /* check the Channel Avoidance is enabled */
9803 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9804 {
9805 sme_AddChAvoidCallback(pHddCtx->hHal,
9806 hdd_hostapd_ch_avoid_cb);
9807 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009808#endif /* FEATURE_WLAN_CH_AVOID */
9809
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009810 /* Exchange capability info between Host and FW and also get versioning info from FW */
9811 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009812
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309813#ifdef CONFIG_ENABLE_LINUX_REG
9814 status = wlan_hdd_init_channels(pHddCtx);
9815 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9816 {
9817 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9818 __func__);
9819 goto err_vosstop;
9820 }
9821#endif
9822
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 status = hdd_post_voss_start_config( pHddCtx );
9824 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9825 {
9826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9827 __func__);
9828 goto err_vosstop;
9829 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009830
9831#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309832 wlan_hdd_cfg80211_update_reg_info( wiphy );
9833
9834 /* registration of wiphy dev with cfg80211 */
9835 if (0 > wlan_hdd_cfg80211_register(wiphy))
9836 {
9837 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9838 goto err_vosstop;
9839 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009840#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009841
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309842#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309843 /* registration of wiphy dev with cfg80211 */
9844 if (0 > wlan_hdd_cfg80211_register(wiphy))
9845 {
9846 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9847 goto err_vosstop;
9848 }
9849
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309850 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309851 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9852 {
9853 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9854 __func__);
9855 goto err_unregister_wiphy;
9856 }
9857#endif
9858
c_hpothu4a298be2014-12-22 21:12:51 +05309859 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9860
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9862 {
9863 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9864 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9865 }
9866 else
9867 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9869 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9870 if (pAdapter != NULL)
9871 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309872 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309874 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9875 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9876 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009877
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309878 /* Generate the P2P Device Address. This consists of the device's
9879 * primary MAC address with the locally administered bit set.
9880 */
9881 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009882 }
9883 else
9884 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309885 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9886 if (p2p_dev_addr != NULL)
9887 {
9888 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9889 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9890 }
9891 else
9892 {
9893 hddLog(VOS_TRACE_LEVEL_FATAL,
9894 "%s: Failed to allocate mac_address for p2p_device",
9895 __func__);
9896 goto err_close_adapter;
9897 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009898 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009899
9900 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9901 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9902 if ( NULL == pP2pAdapter )
9903 {
9904 hddLog(VOS_TRACE_LEVEL_FATAL,
9905 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009906 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009907 goto err_close_adapter;
9908 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009909 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009911
9912 if( pAdapter == NULL )
9913 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9915 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009917
Arif Hussain66559122013-11-21 10:11:40 -08009918 if (country_code)
9919 {
9920 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009921 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009922 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9923#ifndef CONFIG_ENABLE_LINUX_REG
9924 hdd_checkandupdate_phymode(pAdapter, country_code);
9925#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009926 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9927 (void *)(tSmeChangeCountryCallback)
9928 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009929 country_code,
9930 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309931 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009932 if (eHAL_STATUS_SUCCESS == ret)
9933 {
Arif Hussaincb607082013-12-20 11:57:42 -08009934 ret = wait_for_completion_interruptible_timeout(
9935 &pAdapter->change_country_code,
9936 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9937
9938 if (0 >= ret)
9939 {
9940 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9941 "%s: SME while setting country code timed out", __func__);
9942 }
Arif Hussain66559122013-11-21 10:11:40 -08009943 }
9944 else
9945 {
Arif Hussaincb607082013-12-20 11:57:42 -08009946 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9947 "%s: SME Change Country code from module param fail ret=%d",
9948 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009949 }
9950 }
9951
Jeff Johnson295189b2012-06-20 16:38:30 -07009952#ifdef WLAN_BTAMP_FEATURE
9953 vStatus = WLANBAP_Open(pVosContext);
9954 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9955 {
9956 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9957 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009958 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 }
9960
9961 vStatus = BSL_Init(pVosContext);
9962 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9963 {
9964 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9965 "%s: Failed to Init BSL",__func__);
9966 goto err_bap_close;
9967 }
9968 vStatus = WLANBAP_Start(pVosContext);
9969 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9970 {
9971 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9972 "%s: Failed to start TL",__func__);
9973 goto err_bap_close;
9974 }
9975
9976 pConfig = pHddCtx->cfg_ini;
9977 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9978 status = WLANBAP_SetConfig(&btAmpConfig);
9979
9980#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009981
Mihir Shete9c238772014-10-15 14:35:16 +05309982 /*
9983 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9984 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9985 * which is greater than 0xf. So the below check is safe to make
9986 * sure that there is no entry for UapsdMask in the ini
9987 */
9988 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9989 {
9990 if(IS_DYNAMIC_WMM_PS_ENABLED)
9991 {
9992 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9993 __func__);
9994 pHddCtx->cfg_ini->UapsdMask =
9995 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9996 }
9997 else
9998 {
9999 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10000 __func__);
10001 pHddCtx->cfg_ini->UapsdMask =
10002 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10003 }
10004 }
10005
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010006#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10007 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10008 {
10009 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10010 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10011 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10012 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10013 }
10014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010015
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010016 wlan_hdd_tdls_init(pHddCtx);
10017
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010018 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10019
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 /* Register with platform driver as client for Suspend/Resume */
10021 status = hddRegisterPmOps(pHddCtx);
10022 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10023 {
10024 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10025#ifdef WLAN_BTAMP_FEATURE
10026 goto err_bap_stop;
10027#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010028 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010029#endif //WLAN_BTAMP_FEATURE
10030 }
10031
Yue Ma0d4891e2013-08-06 17:01:45 -070010032 /* Open debugfs interface */
10033 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10034 {
10035 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10036 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010037 }
10038
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 /* Register TM level change handler function to the platform */
10040 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10041 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10042 {
10043 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10044 goto err_unregister_pmops;
10045 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010046
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 // register net device notifier for device change notification
10048 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10049
10050 if(ret < 0)
10051 {
10052 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010053 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 }
10055
10056 //Initialize the nlink service
10057 if(nl_srv_init() != 0)
10058 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010059 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010060 goto err_reg_netdev;
10061 }
10062
Leo Chang4ce1cc52013-10-21 18:27:15 -070010063#ifdef WLAN_KD_READY_NOTIFIER
10064 pHddCtx->kd_nl_init = 1;
10065#endif /* WLAN_KD_READY_NOTIFIER */
10066
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 //Initialize the BTC service
10068 if(btc_activate_service(pHddCtx) != 0)
10069 {
10070 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10071 goto err_nl_srv;
10072 }
10073
10074#ifdef PTT_SOCK_SVC_ENABLE
10075 //Initialize the PTT service
10076 if(ptt_sock_activate_svc(pHddCtx) != 0)
10077 {
10078 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10079 goto err_nl_srv;
10080 }
10081#endif
10082
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010083#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10084 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10085 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010086 if(wlan_logging_sock_activate_svc(
10087 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10088 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10089 {
10090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10091 " failed", __func__);
10092 goto err_nl_srv;
10093 }
10094 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10095 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010096 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10097 pHddCtx->cfg_ini->gEnableDebugLog =
10098 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010099 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010100
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010101 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10102 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010103 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010104 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010105 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010106 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010107 }
10108 else
10109 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010111 }
10112
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010113#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010114
10115
Sushant Kaushik215778f2015-05-21 14:05:36 +053010116 if (vos_is_multicast_logging())
10117 wlan_logging_set_log_level();
10118
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010121 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010122 /* Action frame registered in one adapter which will
10123 * applicable to all interfaces
10124 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010125 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010127
10128 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010129 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010130
Jeff Johnsone7245742012-09-05 17:12:55 -070010131#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10132 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010133 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010134 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010135
Jeff Johnsone7245742012-09-05 17:12:55 -070010136#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010137 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010138 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010139 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010140
Jeff Johnsone7245742012-09-05 17:12:55 -070010141
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010142 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10143 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010144
Katya Nigam5c306ea2014-06-19 15:39:54 +053010145 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010146 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010147 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010148
10149#ifdef FEATURE_WLAN_SCAN_PNO
10150 /*SME must send channel update configuration to RIVA*/
10151 sme_UpdateChannelConfig(pHddCtx->hHal);
10152#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010153 /* Send the update default channel list to the FW*/
10154 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010155
10156 /* Fwr capabilities received, Set the Dot11 mode */
10157 sme_SetDefDot11Mode(pHddCtx->hHal);
10158
Abhishek Singha306a442013-11-07 18:39:01 +053010159#ifndef CONFIG_ENABLE_LINUX_REG
10160 /*updating wiphy so that regulatory user hints can be processed*/
10161 if (wiphy)
10162 {
10163 regulatory_hint(wiphy, "00");
10164 }
10165#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010166 // Initialize the restart logic
10167 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010168
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010169 //Register the traffic monitor timer now
10170 if ( pHddCtx->cfg_ini->dynSplitscan)
10171 {
10172 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10173 VOS_TIMER_TYPE_SW,
10174 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10175 (void *)pHddCtx);
10176 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010177 wlan_hdd_cfg80211_nan_init(pHddCtx);
10178
Dino Mycle6fb96c12014-06-10 11:52:40 +053010179#ifdef WLAN_FEATURE_EXTSCAN
10180 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10181 wlan_hdd_cfg80211_extscan_callback,
10182 pHddCtx);
10183#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010184
10185#ifdef WLAN_NS_OFFLOAD
10186 // Register IPv6 notifier to notify if any change in IP
10187 // So that we can reconfigure the offload parameters
10188 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10189 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10190 if (ret)
10191 {
10192 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10193 }
10194 else
10195 {
10196 hddLog(LOGE, FL("Registered IPv6 notifier"));
10197 }
10198#endif
10199
10200 // Register IPv4 notifier to notify if any change in IP
10201 // So that we can reconfigure the offload parameters
10202 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10203 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10204 if (ret)
10205 {
10206 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10207 }
10208 else
10209 {
10210 hddLog(LOGE, FL("Registered IPv4 notifier"));
10211 }
10212
Jeff Johnson295189b2012-06-20 16:38:30 -070010213 goto success;
10214
10215err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010216#ifdef WLAN_KD_READY_NOTIFIER
10217 nl_srv_exit(pHddCtx->ptt_pid);
10218#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010220#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010221err_reg_netdev:
10222 unregister_netdevice_notifier(&hdd_netdev_notifier);
10223
Jeff Johnson295189b2012-06-20 16:38:30 -070010224err_unregister_pmops:
10225 hddDevTmUnregisterNotifyCallback(pHddCtx);
10226 hddDeregisterPmOps(pHddCtx);
10227
Yue Ma0d4891e2013-08-06 17:01:45 -070010228 hdd_debugfs_exit(pHddCtx);
10229
Jeff Johnson295189b2012-06-20 16:38:30 -070010230#ifdef WLAN_BTAMP_FEATURE
10231err_bap_stop:
10232 WLANBAP_Stop(pVosContext);
10233#endif
10234
10235#ifdef WLAN_BTAMP_FEATURE
10236err_bap_close:
10237 WLANBAP_Close(pVosContext);
10238#endif
10239
Jeff Johnson295189b2012-06-20 16:38:30 -070010240err_close_adapter:
10241 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010242#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010243err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010244#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010245 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010246err_vosstop:
10247 vos_stop(pVosContext);
10248
Amar Singhala49cbc52013-10-08 18:37:44 -070010249err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 status = vos_sched_close( pVosContext );
10251 if (!VOS_IS_STATUS_SUCCESS(status)) {
10252 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10253 "%s: Failed to close VOSS Scheduler", __func__);
10254 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10255 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010256 vos_close(pVosContext );
10257
Amar Singhal0a402232013-10-11 20:57:16 -070010258err_vos_nv_close:
10259
c_hpothue6a36282014-03-19 12:27:38 +053010260#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010261 vos_nv_close();
10262
c_hpothu70f8d812014-03-22 22:59:23 +053010263#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010264
10265err_wdclose:
10266 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10267 vos_watchdog_close(pVosContext);
10268
Jeff Johnson295189b2012-06-20 16:38:30 -070010269err_config:
10270 kfree(pHddCtx->cfg_ini);
10271 pHddCtx->cfg_ini= NULL;
10272
10273err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010274 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010275 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 wiphy_free(wiphy) ;
10277 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 VOS_BUG(1);
10279
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010280 if (hdd_is_ssr_required())
10281 {
10282 /* WDI timeout had happened during load, so SSR is needed here */
10283 subsystem_restart("wcnss");
10284 msleep(5000);
10285 }
10286 hdd_set_ssr_required (VOS_FALSE);
10287
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010288 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010289
10290success:
10291 EXIT();
10292 return 0;
10293}
10294
10295/**---------------------------------------------------------------------------
10296
Jeff Johnson32d95a32012-09-10 13:15:23 -070010297 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010298
Jeff Johnson32d95a32012-09-10 13:15:23 -070010299 This is the driver entry point - called in different timeline depending
10300 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010301
10302 \param - None
10303
10304 \return - 0 for success, non zero for failure
10305
10306 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010307static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010308{
10309 VOS_STATUS status;
10310 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010311 struct device *dev = NULL;
10312 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010313#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10314 int max_retries = 0;
10315#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010316#ifdef HAVE_CBC_DONE
10317 int max_cbc_retries = 0;
10318#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010319
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010320#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10321 wlan_logging_sock_init_svc();
10322#endif
10323
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 ENTER();
10325
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010326 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010327
10328 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10329 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10330
Jeff Johnson295189b2012-06-20 16:38:30 -070010331#ifdef ANI_BUS_TYPE_PCI
10332
10333 dev = wcnss_wlan_get_device();
10334
10335#endif // ANI_BUS_TYPE_PCI
10336
10337#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010338
10339#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10340 /* wait until WCNSS driver downloads NV */
10341 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10342 msleep(1000);
10343 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010344
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010345 if (max_retries >= 5) {
10346 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010347 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010348#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10349 wlan_logging_sock_deinit_svc();
10350#endif
10351
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010352 return -ENODEV;
10353 }
10354#endif
10355
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010356#ifdef HAVE_CBC_DONE
10357 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10358 msleep(1000);
10359 }
10360 if (max_cbc_retries >= 10) {
10361 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10362 }
10363#endif
10364
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 dev = wcnss_wlan_get_device();
10366#endif // ANI_BUS_TYPE_PLATFORM
10367
10368
10369 do {
10370 if (NULL == dev) {
10371 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10372 ret_status = -1;
10373 break;
10374 }
10375
Jeff Johnson295189b2012-06-20 16:38:30 -070010376#ifdef TIMER_MANAGER
10377 vos_timer_manager_init();
10378#endif
10379
10380 /* Preopen VOSS so that it is ready to start at least SAL */
10381 status = vos_preOpen(&pVosContext);
10382
10383 if (!VOS_IS_STATUS_SUCCESS(status))
10384 {
10385 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10386 ret_status = -1;
10387 break;
10388 }
10389
Sushant Kaushik02beb352015-06-04 15:15:01 +053010390 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010391#ifndef MODULE
10392 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10393 */
10394 hdd_set_conparam((v_UINT_t)con_mode);
10395#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010396
10397 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010398 if (hdd_wlan_startup(dev))
10399 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010401 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 vos_preClose( &pVosContext );
10403 ret_status = -1;
10404 break;
10405 }
10406
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 } while (0);
10408
10409 if (0 != ret_status)
10410 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010411#ifdef TIMER_MANAGER
10412 vos_timer_exit();
10413#endif
10414#ifdef MEMORY_DEBUG
10415 vos_mem_exit();
10416#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010417 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010418#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10419 wlan_logging_sock_deinit_svc();
10420#endif
10421
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10423 }
10424 else
10425 {
10426 //Send WLAN UP indication to Nlink Service
10427 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10428
10429 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 }
10431
10432 EXIT();
10433
10434 return ret_status;
10435}
10436
Jeff Johnson32d95a32012-09-10 13:15:23 -070010437/**---------------------------------------------------------------------------
10438
10439 \brief hdd_module_init() - Init Function
10440
10441 This is the driver entry point (invoked when module is loaded using insmod)
10442
10443 \param - None
10444
10445 \return - 0 for success, non zero for failure
10446
10447 --------------------------------------------------------------------------*/
10448#ifdef MODULE
10449static int __init hdd_module_init ( void)
10450{
10451 return hdd_driver_init();
10452}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010453#else /* #ifdef MODULE */
10454static int __init hdd_module_init ( void)
10455{
10456 /* Driver initialization is delayed to fwpath_changed_handler */
10457 return 0;
10458}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010459#endif /* #ifdef MODULE */
10460
Jeff Johnson295189b2012-06-20 16:38:30 -070010461
10462/**---------------------------------------------------------------------------
10463
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010464 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010465
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010466 This is the driver exit point (invoked when module is unloaded using rmmod
10467 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010468
10469 \param - None
10470
10471 \return - None
10472
10473 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010474static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010475{
10476 hdd_context_t *pHddCtx = NULL;
10477 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010478 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010479 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010480
10481 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10482
10483 //Get the global vos context
10484 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10485
10486 if(!pVosContext)
10487 {
10488 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10489 goto done;
10490 }
10491
10492 //Get the HDD context.
10493 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10494
10495 if(!pHddCtx)
10496 {
10497 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10498 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010499 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10500 {
10501 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10502 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10503 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10504 hdd_wlan_exit(pHddCtx);
10505 vos_preClose( &pVosContext );
10506 goto done;
10507 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 else
10509 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010510 /* We wait for active entry threads to exit from driver
10511 * by waiting until rtnl_lock is available.
10512 */
10513 rtnl_lock();
10514 rtnl_unlock();
10515
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010516 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10517 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10518 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10519 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010521 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010522 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10523 msecs_to_jiffies(30000));
10524 if(!rc)
10525 {
10526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10527 "%s:SSR timedout, fatal error", __func__);
10528 VOS_BUG(0);
10529 }
10530 }
10531
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010532 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10533 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534
c_hpothu8adb97b2014-12-08 19:38:20 +053010535 /* Driver Need to send country code 00 in below condition
10536 * 1) If gCountryCodePriority is set to 1; and last country
10537 * code set is through 11d. This needs to be done in case
10538 * when NV country code is 00.
10539 * This Needs to be done as when kernel store last country
10540 * code and if stored country code is not through 11d,
10541 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10542 * in next load/unload as soon as we get any country through
10543 * 11d. In sme_HandleChangeCountryCodeByUser
10544 * pMsg->countryCode will be last countryCode and
10545 * pMac->scan.countryCode11d will be country through 11d so
10546 * due to mismatch driver will disable 11d.
10547 *
10548 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010549
c_hpothu8adb97b2014-12-08 19:38:20 +053010550 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010551 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010552 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010553 {
10554 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010555 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010556 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10557 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010558
c_hpothu8adb97b2014-12-08 19:38:20 +053010559 //Do all the cleanup before deregistering the driver
10560 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 }
10562
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 vos_preClose( &pVosContext );
10564
10565#ifdef TIMER_MANAGER
10566 vos_timer_exit();
10567#endif
10568#ifdef MEMORY_DEBUG
10569 vos_mem_exit();
10570#endif
10571
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010572#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10573 wlan_logging_sock_deinit_svc();
10574#endif
10575
Jeff Johnson295189b2012-06-20 16:38:30 -070010576done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010577 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010578
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10580}
10581
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010582/**---------------------------------------------------------------------------
10583
10584 \brief hdd_module_exit() - Exit function
10585
10586 This is the driver exit point (invoked when module is unloaded using rmmod)
10587
10588 \param - None
10589
10590 \return - None
10591
10592 --------------------------------------------------------------------------*/
10593static void __exit hdd_module_exit(void)
10594{
10595 hdd_driver_exit();
10596}
10597
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010598#ifdef MODULE
10599static int fwpath_changed_handler(const char *kmessage,
10600 struct kernel_param *kp)
10601{
Jeff Johnson76052702013-04-16 13:55:05 -070010602 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010603}
10604
10605static int con_mode_handler(const char *kmessage,
10606 struct kernel_param *kp)
10607{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010608 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010609}
10610#else /* #ifdef MODULE */
10611/**---------------------------------------------------------------------------
10612
Jeff Johnson76052702013-04-16 13:55:05 -070010613 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010614
Jeff Johnson76052702013-04-16 13:55:05 -070010615 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010616 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010617 - invoked when module parameter fwpath is modified from userspace to signal
10618 initializing the WLAN driver or when con_mode is modified from userspace
10619 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010620
10621 \return - 0 for success, non zero for failure
10622
10623 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010624static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010625{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010626 int ret_status;
10627
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010628 if (!wlan_hdd_inited) {
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
10634 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010635
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010636 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010637
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010638 ret_status = hdd_driver_init();
10639 wlan_hdd_inited = ret_status ? 0 : 1;
10640 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010641}
10642
Jeff Johnson295189b2012-06-20 16:38:30 -070010643/**---------------------------------------------------------------------------
10644
Jeff Johnson76052702013-04-16 13:55:05 -070010645 \brief fwpath_changed_handler() - Handler Function
10646
10647 Handle changes to the fwpath parameter
10648
10649 \return - 0 for success, non zero for failure
10650
10651 --------------------------------------------------------------------------*/
10652static int fwpath_changed_handler(const char *kmessage,
10653 struct kernel_param *kp)
10654{
10655 int ret;
10656
10657 ret = param_set_copystring(kmessage, kp);
10658 if (0 == ret)
10659 ret = kickstart_driver();
10660 return ret;
10661}
10662
10663/**---------------------------------------------------------------------------
10664
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010665 \brief con_mode_handler() -
10666
10667 Handler function for module param con_mode when it is changed by userspace
10668 Dynamically linked - do nothing
10669 Statically linked - exit and init driver, as in rmmod and insmod
10670
Jeff Johnson76052702013-04-16 13:55:05 -070010671 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010672
Jeff Johnson76052702013-04-16 13:55:05 -070010673 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010674
10675 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010676static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010677{
Jeff Johnson76052702013-04-16 13:55:05 -070010678 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010679
Jeff Johnson76052702013-04-16 13:55:05 -070010680 ret = param_set_int(kmessage, kp);
10681 if (0 == ret)
10682 ret = kickstart_driver();
10683 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010684}
10685#endif /* #ifdef MODULE */
10686
10687/**---------------------------------------------------------------------------
10688
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 \brief hdd_get_conparam() -
10690
10691 This is the driver exit point (invoked when module is unloaded using rmmod)
10692
10693 \param - None
10694
10695 \return - tVOS_CON_MODE
10696
10697 --------------------------------------------------------------------------*/
10698tVOS_CON_MODE hdd_get_conparam ( void )
10699{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010700#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010702#else
10703 return (tVOS_CON_MODE)curr_con_mode;
10704#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010705}
10706void hdd_set_conparam ( v_UINT_t newParam )
10707{
10708 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010709#ifndef MODULE
10710 curr_con_mode = con_mode;
10711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010712}
10713/**---------------------------------------------------------------------------
10714
10715 \brief hdd_softap_sta_deauth() - function
10716
10717 This to take counter measure to handle deauth req from HDD
10718
10719 \param - pAdapter - Pointer to the HDD
10720
10721 \param - enable - boolean value
10722
10723 \return - None
10724
10725 --------------------------------------------------------------------------*/
10726
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010727VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10728 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010729{
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010731 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010732
10733 ENTER();
10734
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010735 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10736 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010737
10738 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010739 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010740 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010741
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010742 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010743
10744 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010745 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010746}
10747
10748/**---------------------------------------------------------------------------
10749
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010750 \brief hdd_del_all_sta() - function
10751
10752 This function removes all the stations associated on stopping AP/P2P GO.
10753
10754 \param - pAdapter - Pointer to the HDD
10755
10756 \return - None
10757
10758 --------------------------------------------------------------------------*/
10759
10760int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10761{
10762 v_U16_t i;
10763 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010764 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10765 ptSapContext pSapCtx = NULL;
10766 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10767 if(pSapCtx == NULL){
10768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10769 FL("psapCtx is NULL"));
10770 return 1;
10771 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010772 ENTER();
10773
10774 hddLog(VOS_TRACE_LEVEL_INFO,
10775 "%s: Delete all STAs associated.",__func__);
10776 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10777 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10778 )
10779 {
10780 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10781 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010782 if ((pSapCtx->aStaInfo[i].isUsed) &&
10783 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010784 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010785 struct tagCsrDelStaParams delStaParams;
10786
10787 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010788 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010789 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10790 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010791 &delStaParams);
10792 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010793 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010794 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010795 }
10796 }
10797 }
10798
10799 EXIT();
10800 return 0;
10801}
10802
10803/**---------------------------------------------------------------------------
10804
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 \brief hdd_softap_sta_disassoc() - function
10806
10807 This to take counter measure to handle deauth req from HDD
10808
10809 \param - pAdapter - Pointer to the HDD
10810
10811 \param - enable - boolean value
10812
10813 \return - None
10814
10815 --------------------------------------------------------------------------*/
10816
10817void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10818{
10819 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10820
10821 ENTER();
10822
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010823 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010824
10825 //Ignore request to disassoc bcmc station
10826 if( pDestMacAddress[0] & 0x1 )
10827 return;
10828
10829 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10830}
10831
10832void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10833{
10834 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10835
10836 ENTER();
10837
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010838 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010839
10840 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10841}
10842
Jeff Johnson295189b2012-06-20 16:38:30 -070010843/**---------------------------------------------------------------------------
10844 *
10845 * \brief hdd_get__concurrency_mode() -
10846 *
10847 *
10848 * \param - None
10849 *
10850 * \return - CONCURRENCY MODE
10851 *
10852 * --------------------------------------------------------------------------*/
10853tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10854{
10855 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10856 hdd_context_t *pHddCtx;
10857
10858 if (NULL != pVosContext)
10859 {
10860 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10861 if (NULL != pHddCtx)
10862 {
10863 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10864 }
10865 }
10866
10867 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010868 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 return VOS_STA;
10870}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010871v_BOOL_t
10872wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10873{
10874 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010875
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010876 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10877 if (pAdapter == NULL)
10878 {
10879 hddLog(VOS_TRACE_LEVEL_INFO,
10880 FL("GO doesn't exist"));
10881 return TRUE;
10882 }
10883 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10884 {
10885 hddLog(VOS_TRACE_LEVEL_INFO,
10886 FL("GO started"));
10887 return TRUE;
10888 }
10889 else
10890 /* wait till GO changes its interface to p2p device */
10891 hddLog(VOS_TRACE_LEVEL_INFO,
10892 FL("Del_bss called, avoid apps suspend"));
10893 return FALSE;
10894
10895}
Jeff Johnson295189b2012-06-20 16:38:30 -070010896/* Decide whether to allow/not the apps power collapse.
10897 * Allow apps power collapse if we are in connected state.
10898 * if not, allow only if we are in IMPS */
10899v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10900{
10901 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010902 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010903 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010904 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10905 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10906 hdd_adapter_t *pAdapter = NULL;
10907 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010908 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010909
Jeff Johnson295189b2012-06-20 16:38:30 -070010910 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10911 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010912
Yathish9f22e662012-12-10 14:21:35 -080010913 concurrent_state = hdd_get_concurrency_mode();
10914
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010915 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10916 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10917 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010918#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010919
Yathish9f22e662012-12-10 14:21:35 -080010920 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010921 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010922 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10923 return TRUE;
10924#endif
10925
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 /*loop through all adapters. TBD fix for Concurrency */
10927 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10928 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10929 {
10930 pAdapter = pAdapterNode->pAdapter;
10931 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10932 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10933 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010934 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010935 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010936 && pmcState != STOPPED && pmcState != STANDBY &&
10937 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010938 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10939 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010941 if(pmcState == FULL_POWER &&
10942 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10943 {
10944 /*
10945 * When SCO indication comes from Coex module , host will
10946 * enter in to full power mode, but this should not prevent
10947 * apps processor power collapse.
10948 */
10949 hddLog(LOG1,
10950 FL("Allow apps power collapse"
10951 "even when sco indication is set"));
10952 return TRUE;
10953 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010954 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010955 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10956 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010957 return FALSE;
10958 }
10959 }
10960 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10961 pAdapterNode = pNext;
10962 }
10963 return TRUE;
10964}
10965
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010966/* Decides whether to send suspend notification to Riva
10967 * if any adapter is in BMPS; then it is required */
10968v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10969{
10970 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10971 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10972
10973 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10974 {
10975 return TRUE;
10976 }
10977 return FALSE;
10978}
10979
Jeff Johnson295189b2012-06-20 16:38:30 -070010980void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10981{
10982 switch(mode)
10983 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010984 case VOS_STA_MODE:
10985 case VOS_P2P_CLIENT_MODE:
10986 case VOS_P2P_GO_MODE:
10987 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010988 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010989 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 break;
10991 default:
10992 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010994 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10995 "Number of open sessions for mode %d = %d"),
10996 pHddCtx->concurrency_mode, mode,
10997 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010998}
10999
11000
11001void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11002{
11003 switch(mode)
11004 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011005 case VOS_STA_MODE:
11006 case VOS_P2P_CLIENT_MODE:
11007 case VOS_P2P_GO_MODE:
11008 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011009 pHddCtx->no_of_open_sessions[mode]--;
11010 if (!(pHddCtx->no_of_open_sessions[mode]))
11011 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 break;
11013 default:
11014 break;
11015 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011016 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11017 "Number of open sessions for mode %d = %d"),
11018 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11019
11020}
11021/**---------------------------------------------------------------------------
11022 *
11023 * \brief wlan_hdd_incr_active_session()
11024 *
11025 * This function increments the number of active sessions
11026 * maintained per device mode
11027 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11028 * Incase of SAP/P2P GO upon bss start it is incremented
11029 *
11030 * \param pHddCtx - HDD Context
11031 * \param mode - device mode
11032 *
11033 * \return - None
11034 *
11035 * --------------------------------------------------------------------------*/
11036void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11037{
11038 switch (mode) {
11039 case VOS_STA_MODE:
11040 case VOS_P2P_CLIENT_MODE:
11041 case VOS_P2P_GO_MODE:
11042 case VOS_STA_SAP_MODE:
11043 pHddCtx->no_of_active_sessions[mode]++;
11044 break;
11045 default:
11046 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11047 break;
11048 }
11049 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11050 mode,
11051 pHddCtx->no_of_active_sessions[mode]);
11052}
11053
11054/**---------------------------------------------------------------------------
11055 *
11056 * \brief wlan_hdd_decr_active_session()
11057 *
11058 * This function decrements the number of active sessions
11059 * maintained per device mode
11060 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11061 * Incase of SAP/P2P GO upon bss stop it is decremented
11062 *
11063 * \param pHddCtx - HDD Context
11064 * \param mode - device mode
11065 *
11066 * \return - None
11067 *
11068 * --------------------------------------------------------------------------*/
11069void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11070{
11071 switch (mode) {
11072 case VOS_STA_MODE:
11073 case VOS_P2P_CLIENT_MODE:
11074 case VOS_P2P_GO_MODE:
11075 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011076 if (pHddCtx->no_of_active_sessions[mode] > 0)
11077 pHddCtx->no_of_active_sessions[mode]--;
11078 else
11079 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11080 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011081 break;
11082 default:
11083 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11084 break;
11085 }
11086 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11087 mode,
11088 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011089}
11090
Jeff Johnsone7245742012-09-05 17:12:55 -070011091/**---------------------------------------------------------------------------
11092 *
11093 * \brief wlan_hdd_restart_init
11094 *
11095 * This function initalizes restart timer/flag. An internal function.
11096 *
11097 * \param - pHddCtx
11098 *
11099 * \return - None
11100 *
11101 * --------------------------------------------------------------------------*/
11102
11103static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11104{
11105 /* Initialize */
11106 pHddCtx->hdd_restart_retries = 0;
11107 atomic_set(&pHddCtx->isRestartInProgress, 0);
11108 vos_timer_init(&pHddCtx->hdd_restart_timer,
11109 VOS_TIMER_TYPE_SW,
11110 wlan_hdd_restart_timer_cb,
11111 pHddCtx);
11112}
11113/**---------------------------------------------------------------------------
11114 *
11115 * \brief wlan_hdd_restart_deinit
11116 *
11117 * This function cleans up the resources used. An internal function.
11118 *
11119 * \param - pHddCtx
11120 *
11121 * \return - None
11122 *
11123 * --------------------------------------------------------------------------*/
11124
11125static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11126{
11127
11128 VOS_STATUS vos_status;
11129 /* Block any further calls */
11130 atomic_set(&pHddCtx->isRestartInProgress, 1);
11131 /* Cleanup */
11132 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11133 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011134 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011135 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11136 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011137 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011138
11139}
11140
11141/**---------------------------------------------------------------------------
11142 *
11143 * \brief wlan_hdd_framework_restart
11144 *
11145 * This function uses a cfg80211 API to start a framework initiated WLAN
11146 * driver module unload/load.
11147 *
11148 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11149 *
11150 *
11151 * \param - pHddCtx
11152 *
11153 * \return - VOS_STATUS_SUCCESS: Success
11154 * VOS_STATUS_E_EMPTY: Adapter is Empty
11155 * VOS_STATUS_E_NOMEM: No memory
11156
11157 * --------------------------------------------------------------------------*/
11158
11159static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11160{
11161 VOS_STATUS status = VOS_STATUS_SUCCESS;
11162 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011163 int len = (sizeof (struct ieee80211_mgmt));
11164 struct ieee80211_mgmt *mgmt = NULL;
11165
11166 /* Prepare the DEAUTH managment frame with reason code */
11167 mgmt = kzalloc(len, GFP_KERNEL);
11168 if(mgmt == NULL)
11169 {
11170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11171 "%s: memory allocation failed (%d bytes)", __func__, len);
11172 return VOS_STATUS_E_NOMEM;
11173 }
11174 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011175
11176 /* Iterate over all adapters/devices */
11177 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011178 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11179 {
11180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11181 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11182 goto end;
11183 }
11184
Jeff Johnsone7245742012-09-05 17:12:55 -070011185 do
11186 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011187 if(pAdapterNode->pAdapter &&
11188 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011189 {
11190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11191 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11192 pAdapterNode->pAdapter->dev->name,
11193 pAdapterNode->pAdapter->device_mode,
11194 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011195 /*
11196 * CFG80211 event to restart the driver
11197 *
11198 * 'cfg80211_send_unprot_deauth' sends a
11199 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11200 * of SME(Linux Kernel) state machine.
11201 *
11202 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11203 * the driver.
11204 *
11205 */
11206
11207 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011208 }
11209 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11210 pAdapterNode = pNext;
11211 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11212
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011213 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011214 /* Free the allocated management frame */
11215 kfree(mgmt);
11216
Jeff Johnsone7245742012-09-05 17:12:55 -070011217 /* Retry until we unload or reach max count */
11218 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11219 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11220
11221 return status;
11222
11223}
11224/**---------------------------------------------------------------------------
11225 *
11226 * \brief wlan_hdd_restart_timer_cb
11227 *
11228 * Restart timer callback. An internal function.
11229 *
11230 * \param - User data:
11231 *
11232 * \return - None
11233 *
11234 * --------------------------------------------------------------------------*/
11235
11236void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11237{
11238 hdd_context_t *pHddCtx = usrDataForCallback;
11239 wlan_hdd_framework_restart(pHddCtx);
11240 return;
11241
11242}
11243
11244
11245/**---------------------------------------------------------------------------
11246 *
11247 * \brief wlan_hdd_restart_driver
11248 *
11249 * This function sends an event to supplicant to restart the WLAN driver.
11250 *
11251 * This function is called from vos_wlanRestart.
11252 *
11253 * \param - pHddCtx
11254 *
11255 * \return - VOS_STATUS_SUCCESS: Success
11256 * VOS_STATUS_E_EMPTY: Adapter is Empty
11257 * VOS_STATUS_E_ALREADY: Request already in progress
11258
11259 * --------------------------------------------------------------------------*/
11260VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11261{
11262 VOS_STATUS status = VOS_STATUS_SUCCESS;
11263
11264 /* A tight check to make sure reentrancy */
11265 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11266 {
Mihir Shetefd528652014-06-23 19:07:50 +053011267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011268 "%s: WLAN restart is already in progress", __func__);
11269
11270 return VOS_STATUS_E_ALREADY;
11271 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011272 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011273#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011274 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011275#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011276
Jeff Johnsone7245742012-09-05 17:12:55 -070011277 return status;
11278}
11279
Mihir Shetee1093ba2014-01-21 20:13:32 +053011280/**---------------------------------------------------------------------------
11281 *
11282 * \brief wlan_hdd_init_channels
11283 *
11284 * This function is used to initialize the channel list in CSR
11285 *
11286 * This function is called from hdd_wlan_startup
11287 *
11288 * \param - pHddCtx: HDD context
11289 *
11290 * \return - VOS_STATUS_SUCCESS: Success
11291 * VOS_STATUS_E_FAULT: Failure reported by SME
11292
11293 * --------------------------------------------------------------------------*/
11294static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11295{
11296 eHalStatus status;
11297
11298 status = sme_InitChannels(pHddCtx->hHal);
11299 if (HAL_STATUS_SUCCESS(status))
11300 {
11301 return VOS_STATUS_SUCCESS;
11302 }
11303 else
11304 {
11305 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11306 __func__, status);
11307 return VOS_STATUS_E_FAULT;
11308 }
11309}
11310
Mihir Shete04206452014-11-20 17:50:58 +053011311#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011312VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011313{
11314 eHalStatus status;
11315
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011316 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011317 if (HAL_STATUS_SUCCESS(status))
11318 {
11319 return VOS_STATUS_SUCCESS;
11320 }
11321 else
11322 {
11323 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11324 __func__, status);
11325 return VOS_STATUS_E_FAULT;
11326 }
11327}
Mihir Shete04206452014-11-20 17:50:58 +053011328#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011329/*
11330 * API to find if there is any STA or P2P-Client is connected
11331 */
11332VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11333{
11334 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11335}
Jeff Johnsone7245742012-09-05 17:12:55 -070011336
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011337
11338/*
11339 * API to find if the firmware will send logs using DXE channel
11340 */
11341v_U8_t hdd_is_fw_logging_enabled(void)
11342{
11343 hdd_context_t *pHddCtx;
11344
11345 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11346 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11347
Sachin Ahuja084313e2015-05-21 17:57:10 +053011348 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011349}
11350
Agarwal Ashish57e84372014-12-05 18:26:53 +053011351/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011352 * API to find if the firmware will send trace logs using DXE channel
11353 */
11354v_U8_t hdd_is_fw_ev_logging_enabled(void)
11355{
11356 hdd_context_t *pHddCtx;
11357
11358 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11359 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11360
11361 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11362}
11363/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011364 * API to find if there is any session connected
11365 */
11366VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11367{
11368 return sme_is_any_session_connected(pHddCtx->hHal);
11369}
11370
11371
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011372int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11373{
11374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11375 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011376 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011377 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011378
11379 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011380 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011381 if (pScanInfo->mScanPending)
11382 {
c_hpothua3d45d52015-01-05 14:11:17 +053011383 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11384 eCSR_SCAN_ABORT_DEFAULT);
11385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11386 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011387
c_hpothua3d45d52015-01-05 14:11:17 +053011388 /* If there is active scan command lets wait for the completion else
11389 * there is no need to wait as scan command might be in the SME pending
11390 * command list.
11391 */
11392 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11393 {
c_hpothua3d45d52015-01-05 14:11:17 +053011394 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011395 &pScanInfo->abortscan_event_var,
11396 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011397 if (0 >= status)
11398 {
11399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011400 "%s: Timeout or Interrupt occurred while waiting for abort"
11401 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011402 return -ETIMEDOUT;
11403 }
11404 }
11405 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11406 {
11407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11408 FL("hdd_abort_mac_scan failed"));
11409 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011410 }
11411 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011412 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011413}
11414
c_hpothu225aa7c2014-10-22 17:45:13 +053011415VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11416{
11417 hdd_adapter_t *pAdapter;
11418 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11419 VOS_STATUS vosStatus;
11420
11421 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11422 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11423 {
11424 pAdapter = pAdapterNode->pAdapter;
11425 if (NULL != pAdapter)
11426 {
11427 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11428 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11429 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11430 {
11431 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11432 pAdapter->device_mode);
11433 if (VOS_STATUS_SUCCESS !=
11434 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11435 {
11436 hddLog(LOGE, FL("failed to abort ROC"));
11437 return VOS_STATUS_E_FAILURE;
11438 }
11439 }
11440 }
11441 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11442 pAdapterNode = pNext;
11443 }
11444 return VOS_STATUS_SUCCESS;
11445}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011446
Mihir Shete0be28772015-02-17 18:42:14 +053011447hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11448{
11449 hdd_adapter_t *pAdapter;
11450 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11451 hdd_cfg80211_state_t *cfgState;
11452 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11453 VOS_STATUS vosStatus;
11454
11455 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11456 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11457 {
11458 pAdapter = pAdapterNode->pAdapter;
11459 if (NULL != pAdapter)
11460 {
11461 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11462 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11463 if (pRemainChanCtx)
11464 break;
11465 }
11466 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11467 pAdapterNode = pNext;
11468 }
11469 return pRemainChanCtx;
11470}
11471
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011472/**
11473 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11474 *
11475 * @pHddCtx: HDD context within host driver
11476 * @dfsScanMode: dfsScanMode passed from ioctl
11477 *
11478 */
11479
11480VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11481 tANI_U8 dfsScanMode)
11482{
11483 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11484 hdd_adapter_t *pAdapter;
11485 VOS_STATUS vosStatus;
11486 hdd_station_ctx_t *pHddStaCtx;
11487 eHalStatus status = eHAL_STATUS_SUCCESS;
11488
11489 if(!pHddCtx)
11490 {
11491 hddLog(LOGE, FL("HDD context is Null"));
11492 return eHAL_STATUS_FAILURE;
11493 }
11494
11495 if (pHddCtx->scan_info.mScanPending)
11496 {
11497 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11498 pHddCtx->scan_info.sessionId);
11499 hdd_abort_mac_scan(pHddCtx,
11500 pHddCtx->scan_info.sessionId,
11501 eCSR_SCAN_ABORT_DEFAULT);
11502 }
11503
11504 if (!dfsScanMode)
11505 {
11506 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11507 while ((NULL != pAdapterNode) &&
11508 (VOS_STATUS_SUCCESS == vosStatus))
11509 {
11510 pAdapter = pAdapterNode->pAdapter;
11511
11512 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11513 {
11514 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11515
11516 if(!pHddStaCtx)
11517 {
11518 hddLog(LOGE, FL("HDD STA context is Null"));
11519 return eHAL_STATUS_FAILURE;
11520 }
11521
11522 /* if STA is already connected on DFS channel,
11523 disconnect immediately*/
11524 if (hdd_connIsConnected(pHddStaCtx) &&
11525 (NV_CHANNEL_DFS ==
11526 vos_nv_getChannelEnabledState(
11527 pHddStaCtx->conn_info.operationChannel)))
11528 {
11529 status = sme_RoamDisconnect(pHddCtx->hHal,
11530 pAdapter->sessionId,
11531 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11532 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11533 "sme_RoamDisconnect returned with status: %d"
11534 "for sessionid: %d"), pHddStaCtx->conn_info.
11535 operationChannel, status, pAdapter->sessionId);
11536 }
11537 }
11538
11539 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11540 &pNext);
11541 pAdapterNode = pNext;
11542 }
11543 }
11544
11545 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11546 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11547 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11548
11549 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11550 if (!HAL_STATUS_SUCCESS(status))
11551 {
11552 hddLog(LOGE,
11553 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11554 return status;
11555 }
11556
11557 return status;
11558}
11559
Nirav Shah7e3c8132015-06-22 23:51:42 +053011560static int hdd_log2_ceil(unsigned value)
11561{
11562 /* need to switch to unsigned math so that negative values
11563 * will right-shift towards 0 instead of -1
11564 */
11565 unsigned tmp = value;
11566 int log2 = -1;
11567
11568 if (value == 0)
11569 return 0;
11570
11571 while (tmp) {
11572 log2++;
11573 tmp >>= 1;
11574 }
11575 if (1U << log2 != value)
11576 log2++;
11577
11578 return log2;
11579}
11580
11581/**
11582 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11583 * @pAdapter: adapter handle
11584 *
11585 * Return: vos status
11586 */
11587VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11588{
11589 int hash_elem, log2, i;
11590
11591 spin_lock_bh( &pAdapter->sta_hash_lock);
11592 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11593 spin_unlock_bh( &pAdapter->sta_hash_lock);
11594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11595 "%s: hash already attached for session id %d",
11596 __func__, pAdapter->sessionId);
11597 return VOS_STATUS_SUCCESS;
11598 }
11599 spin_unlock_bh( &pAdapter->sta_hash_lock);
11600
11601 hash_elem = WLAN_MAX_STA_COUNT;
11602 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11603 log2 = hdd_log2_ceil(hash_elem);
11604 hash_elem = 1 << log2;
11605
11606 pAdapter->sta_id_hash.mask = hash_elem - 1;
11607 pAdapter->sta_id_hash.idx_bits = log2;
11608 pAdapter->sta_id_hash.bins =
11609 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11610 if (!pAdapter->sta_id_hash.bins) {
11611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11612 "%s: malloc failed for session %d",
11613 __func__, pAdapter->sessionId);
11614 return VOS_STATUS_E_NOMEM;
11615 }
11616
11617 for (i = 0; i < hash_elem; i++)
11618 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11619
11620 spin_lock_bh( &pAdapter->sta_hash_lock);
11621 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11622 spin_unlock_bh( &pAdapter->sta_hash_lock);
11623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11624 "%s: Station ID Hash attached for session id %d",
11625 __func__, pAdapter->sessionId);
11626
11627 return VOS_STATUS_SUCCESS;
11628}
11629
11630/**
11631 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11632 * @pAdapter: adapter handle
11633 *
11634 * Return: vos status
11635 */
11636VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11637{
11638 int hash_elem, i;
11639 v_SIZE_t size;
11640
11641 spin_lock_bh( &pAdapter->sta_hash_lock);
11642 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11643 spin_unlock_bh( &pAdapter->sta_hash_lock);
11644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11645 "%s: hash not initialized for session id %d",
11646 __func__, pAdapter->sessionId);
11647 return VOS_STATUS_SUCCESS;
11648 }
11649
11650 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11651 spin_unlock_bh( &pAdapter->sta_hash_lock);
11652
11653 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11654
11655 /* free all station info*/
11656 for (i = 0; i < hash_elem; i++) {
11657 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11658 if (size != 0) {
11659 VOS_STATUS status;
11660 hdd_staid_hash_node_t *sta_info_node = NULL;
11661 hdd_staid_hash_node_t *next_node = NULL;
11662 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11663 (hdd_list_node_t**) &sta_info_node );
11664
11665 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11666 {
11667 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11668 &sta_info_node->node);
11669 vos_mem_free(sta_info_node);
11670
11671 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11672 (hdd_list_node_t*)sta_info_node,
11673 (hdd_list_node_t**)&next_node);
11674 sta_info_node = next_node;
11675 }
11676 }
11677 }
11678
11679 vos_mem_free(pAdapter->sta_id_hash.bins);
11680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11681 "%s: Station ID Hash detached for session id %d",
11682 __func__, pAdapter->sessionId);
11683 return VOS_STATUS_SUCCESS;
11684}
11685
11686/**
11687 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11688 * @pAdapter: adapter handle
11689 * @mac_addr_in: input mac address
11690 *
11691 * Return: index derived from mac address
11692 */
11693int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11694 v_MACADDR_t *mac_addr_in)
11695{
11696 uint16 index;
11697 struct hdd_align_mac_addr_t * mac_addr =
11698 (struct hdd_align_mac_addr_t *)mac_addr_in;
11699
11700 index = mac_addr->bytes_ab ^
11701 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11702 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11703 index &= pAdapter->sta_id_hash.mask;
11704 return index;
11705}
11706
11707/**
11708 * hdd_sta_id_hash_add_entry() - add entry in hash
11709 * @pAdapter: adapter handle
11710 * @sta_id: station id
11711 * @mac_addr: mac address
11712 *
11713 * Return: vos status
11714 */
11715VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11716 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11717{
11718 uint16 index;
11719 hdd_staid_hash_node_t *sta_info_node = NULL;
11720
11721 spin_lock_bh( &pAdapter->sta_hash_lock);
11722 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11723 spin_unlock_bh( &pAdapter->sta_hash_lock);
11724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11725 "%s: hash is not initialized for session id %d",
11726 __func__, pAdapter->sessionId);
11727 return VOS_STATUS_E_FAILURE;
11728 }
11729
11730 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11731 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11732 if (!sta_info_node) {
11733 spin_unlock_bh( &pAdapter->sta_hash_lock);
11734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11735 "%s: malloc failed", __func__);
11736 return VOS_STATUS_E_NOMEM;
11737 }
11738
11739 sta_info_node->sta_id = sta_id;
11740 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11741
11742 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11743 (hdd_list_node_t*) sta_info_node );
11744 spin_unlock_bh( &pAdapter->sta_hash_lock);
11745 return VOS_STATUS_SUCCESS;
11746}
11747
11748/**
11749 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11750 * @pAdapter: adapter handle
11751 * @sta_id: station id
11752 * @mac_addr: mac address
11753 *
11754 * Return: vos status
11755 */
11756VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11757 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11758{
11759 uint16 index;
11760 VOS_STATUS status;
11761 hdd_staid_hash_node_t *sta_info_node = NULL;
11762 hdd_staid_hash_node_t *next_node = NULL;
11763
11764 spin_lock_bh( &pAdapter->sta_hash_lock);
11765 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11766 spin_unlock_bh( &pAdapter->sta_hash_lock);
11767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11768 "%s: hash is not initialized for session id %d",
11769 __func__, pAdapter->sessionId);
11770 return VOS_STATUS_E_FAILURE;
11771 }
11772
11773 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11774 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11775 (hdd_list_node_t**) &sta_info_node );
11776
11777 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11778 {
11779 if (sta_info_node->sta_id == sta_id) {
11780 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11781 &sta_info_node->node);
11782 vos_mem_free(sta_info_node);
11783 break;
11784 }
11785 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11786 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11787 sta_info_node = next_node;
11788 }
11789 spin_unlock_bh( &pAdapter->sta_hash_lock);
11790 return status;
11791}
11792
11793/**
11794 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11795 * @pAdapter: adapter handle
11796 * @mac_addr_in: mac address
11797 *
11798 * Return: station id
11799 */
11800int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11801 v_MACADDR_t *mac_addr_in)
11802{
11803 uint8 is_found = 0;
11804 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11805 uint16 index;
11806 VOS_STATUS status;
11807 hdd_staid_hash_node_t *sta_info_node = NULL;
11808 hdd_staid_hash_node_t *next_node = NULL;
11809
11810 spin_lock_bh( &pAdapter->sta_hash_lock);
11811 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11812 spin_unlock_bh( &pAdapter->sta_hash_lock);
11813 hddLog(VOS_TRACE_LEVEL_ERROR,
11814 FL("hash is not initialized for session id %d"),
11815 pAdapter->sessionId);
11816 return HDD_WLAN_INVALID_STA_ID;
11817 }
11818
11819 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11820 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11821 (hdd_list_node_t**) &sta_info_node );
11822
11823 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11824 {
11825 if (vos_mem_compare(&sta_info_node->mac_addr,
11826 mac_addr_in, sizeof(v_MACADDR_t))) {
11827 is_found = 1;
11828 sta_id = sta_info_node->sta_id;
11829 break;
11830 }
11831 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11832 (hdd_list_node_t*)sta_info_node,
11833 (hdd_list_node_t**)&next_node);
11834 sta_info_node = next_node;
11835 }
11836 spin_unlock_bh( &pAdapter->sta_hash_lock);
11837 return sta_id;
11838}
11839
Jeff Johnson295189b2012-06-20 16:38:30 -070011840//Register the module init/exit functions
11841module_init(hdd_module_init);
11842module_exit(hdd_module_exit);
11843
11844MODULE_LICENSE("Dual BSD/GPL");
11845MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11846MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11847
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011848module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11849 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011850
Jeff Johnson76052702013-04-16 13:55:05 -070011851module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011852 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011853
11854module_param(enable_dfs_chan_scan, int,
11855 S_IRUSR | S_IRGRP | S_IROTH);
11856
11857module_param(enable_11d, int,
11858 S_IRUSR | S_IRGRP | S_IROTH);
11859
11860module_param(country_code, charp,
11861 S_IRUSR | S_IRGRP | S_IROTH);