blob: 543862bb81fbd3462f9423cb674e77aa7e60c5a4 [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 Girigowdade697412013-02-14 16:31:48 -08002463 if (copy_to_user(priv_data.buf, &extra, len + 1))
2464 {
2465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2466 "%s: failed to copy data to user buffer", __func__);
2467 ret = -EFAULT;
2468 goto exit;
2469 }
2470 }
2471 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2472 {
2473 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002474 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002475 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002476
Srinivas Girigowdade697412013-02-14 16:31:48 -08002477 /* input refresh period is in terms of seconds */
2478 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2479 value = value + 18;
2480 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002481 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002482 if (ret < 0)
2483 {
2484 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002485 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002487 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002488 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002489 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2490 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002491 ret = -EINVAL;
2492 goto exit;
2493 }
2494
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002495 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2496 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002497 {
2498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002499 "Roam scan period value %d is out of range"
2500 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002501 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2502 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002503 ret = -EINVAL;
2504 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302505 }
2506 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2507 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2508 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002509 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002510
2511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2512 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002513 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002514
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002515 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2516 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002517 }
2518 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2519 {
2520 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2521 char extra[32];
2522 tANI_U8 len = 0;
2523
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2525 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2526 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002527 len = scnprintf(extra, sizeof(extra), "%s %d",
2528 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002529 /* Returned value is in units of seconds */
2530 if (copy_to_user(priv_data.buf, &extra, len + 1))
2531 {
2532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2533 "%s: failed to copy data to user buffer", __func__);
2534 ret = -EFAULT;
2535 goto exit;
2536 }
2537 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002538 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2539 {
2540 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002541 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002542 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002543
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002544 /* input refresh period is in terms of seconds */
2545 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2546 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002547
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002548 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002549 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002550 if (ret < 0)
2551 {
2552 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002553 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002555 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002556 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002557 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2558 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2559 ret = -EINVAL;
2560 goto exit;
2561 }
2562
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002563 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2564 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2565 {
2566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2567 "Neighbor scan results refresh period value %d is out of range"
2568 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2569 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2570 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2571 ret = -EINVAL;
2572 goto exit;
2573 }
2574 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2575
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2577 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002578 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002579
2580 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2581 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2582 }
2583 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2584 {
2585 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2586 char extra[32];
2587 tANI_U8 len = 0;
2588
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002589 len = scnprintf(extra, sizeof(extra), "%s %d",
2590 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002591 /* Returned value is in units of seconds */
2592 if (copy_to_user(priv_data.buf, &extra, len + 1))
2593 {
2594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2595 "%s: failed to copy data to user buffer", __func__);
2596 ret = -EFAULT;
2597 goto exit;
2598 }
2599 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002600#ifdef FEATURE_WLAN_LFR
2601 /* SETROAMMODE */
2602 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2603 {
2604 tANI_U8 *value = command;
2605 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2606
2607 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2608 value = value + SIZE_OF_SETROAMMODE + 1;
2609
2610 /* Convert the value from ascii to integer */
2611 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2612 if (ret < 0)
2613 {
2614 /* If the input value is greater than max value of datatype, then also
2615 kstrtou8 fails */
2616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2617 "%s: kstrtou8 failed range [%d - %d]", __func__,
2618 CFG_LFR_FEATURE_ENABLED_MIN,
2619 CFG_LFR_FEATURE_ENABLED_MAX);
2620 ret = -EINVAL;
2621 goto exit;
2622 }
2623 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2624 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2625 {
2626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2627 "Roam Mode value %d is out of range"
2628 " (Min: %d Max: %d)", roamMode,
2629 CFG_LFR_FEATURE_ENABLED_MIN,
2630 CFG_LFR_FEATURE_ENABLED_MAX);
2631 ret = -EINVAL;
2632 goto exit;
2633 }
2634
2635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2636 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2637 /*
2638 * Note that
2639 * SETROAMMODE 0 is to enable LFR while
2640 * SETROAMMODE 1 is to disable LFR, but
2641 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2642 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2643 */
2644 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2645 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2646 else
2647 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2648
2649 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2650 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2651 }
2652 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302653 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002654 {
2655 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2656 char extra[32];
2657 tANI_U8 len = 0;
2658
2659 /*
2660 * roamMode value shall be inverted because the sementics is different.
2661 */
2662 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2663 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2664 else
2665 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2666
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002667 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002668 if (copy_to_user(priv_data.buf, &extra, len + 1))
2669 {
2670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2671 "%s: failed to copy data to user buffer", __func__);
2672 ret = -EFAULT;
2673 goto exit;
2674 }
2675 }
2676#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002677#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002678#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002679 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2680 {
2681 tANI_U8 *value = command;
2682 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2683
2684 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2685 value = value + 13;
2686 /* Convert the value from ascii to integer */
2687 ret = kstrtou8(value, 10, &roamRssiDiff);
2688 if (ret < 0)
2689 {
2690 /* If the input value is greater than max value of datatype, then also
2691 kstrtou8 fails */
2692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2693 "%s: kstrtou8 failed range [%d - %d]", __func__,
2694 CFG_ROAM_RSSI_DIFF_MIN,
2695 CFG_ROAM_RSSI_DIFF_MAX);
2696 ret = -EINVAL;
2697 goto exit;
2698 }
2699
2700 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2701 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2702 {
2703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2704 "Roam rssi diff value %d is out of range"
2705 " (Min: %d Max: %d)", roamRssiDiff,
2706 CFG_ROAM_RSSI_DIFF_MIN,
2707 CFG_ROAM_RSSI_DIFF_MAX);
2708 ret = -EINVAL;
2709 goto exit;
2710 }
2711
2712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2713 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2714
2715 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2716 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2717 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302718 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002719 {
2720 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2721 char extra[32];
2722 tANI_U8 len = 0;
2723
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302724 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2725 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2726 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002727 len = scnprintf(extra, sizeof(extra), "%s %d",
2728 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002729 if (copy_to_user(priv_data.buf, &extra, len + 1))
2730 {
2731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2732 "%s: failed to copy data to user buffer", __func__);
2733 ret = -EFAULT;
2734 goto exit;
2735 }
2736 }
2737#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002738#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002739 else if (strncmp(command, "GETBAND", 7) == 0)
2740 {
2741 int band = -1;
2742 char extra[32];
2743 tANI_U8 len = 0;
2744 hdd_getBand_helper(pHddCtx, &band);
2745
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302746 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2747 TRACE_CODE_HDD_GETBAND_IOCTL,
2748 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002749 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002750 if (copy_to_user(priv_data.buf, &extra, len + 1))
2751 {
2752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2753 "%s: failed to copy data to user buffer", __func__);
2754 ret = -EFAULT;
2755 goto exit;
2756 }
2757 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002758 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2759 {
2760 tANI_U8 *value = command;
2761 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2762 tANI_U8 numChannels = 0;
2763 eHalStatus status = eHAL_STATUS_SUCCESS;
2764
2765 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2766 if (eHAL_STATUS_SUCCESS != status)
2767 {
2768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2769 "%s: Failed to parse channel list information", __func__);
2770 ret = -EINVAL;
2771 goto exit;
2772 }
2773
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302774 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2775 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2776 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002777 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2778 {
2779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2780 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2781 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2782 ret = -EINVAL;
2783 goto exit;
2784 }
2785 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2786 numChannels);
2787 if (eHAL_STATUS_SUCCESS != status)
2788 {
2789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2790 "%s: Failed to update channel list information", __func__);
2791 ret = -EINVAL;
2792 goto exit;
2793 }
2794 }
2795 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2796 {
2797 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2798 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002799 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002800 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002801 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002802
2803 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2804 ChannelList, &numChannels ))
2805 {
2806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2807 "%s: failed to get roam scan channel list", __func__);
2808 ret = -EFAULT;
2809 goto exit;
2810 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2812 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2813 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002814 /* output channel list is of the format
2815 [Number of roam scan channels][Channel1][Channel2]... */
2816 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002817 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002818 for (j = 0; (j < numChannels); j++)
2819 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002820 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2821 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002822 }
2823
2824 if (copy_to_user(priv_data.buf, &extra, len + 1))
2825 {
2826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2827 "%s: failed to copy data to user buffer", __func__);
2828 ret = -EFAULT;
2829 goto exit;
2830 }
2831 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002832 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2833 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002834 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002835 char extra[32];
2836 tANI_U8 len = 0;
2837
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002838 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002839 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002840 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002841 hdd_is_okc_mode_enabled(pHddCtx) &&
2842 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2843 {
2844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002845 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002846 " hence this operation is not permitted!", __func__);
2847 ret = -EPERM;
2848 goto exit;
2849 }
2850
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002851 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002852 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002853 if (copy_to_user(priv_data.buf, &extra, len + 1))
2854 {
2855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: failed to copy data to user buffer", __func__);
2857 ret = -EFAULT;
2858 goto exit;
2859 }
2860 }
2861 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2862 {
2863 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2864 char extra[32];
2865 tANI_U8 len = 0;
2866
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002867 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002868 then this operation is not permitted (return FAILURE) */
2869 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002870 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002871 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2872 {
2873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002874 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002875 " hence this operation is not permitted!", __func__);
2876 ret = -EPERM;
2877 goto exit;
2878 }
2879
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002880 len = scnprintf(extra, sizeof(extra), "%s %d",
2881 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002882 if (copy_to_user(priv_data.buf, &extra, len + 1))
2883 {
2884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2885 "%s: failed to copy data to user buffer", __func__);
2886 ret = -EFAULT;
2887 goto exit;
2888 }
2889 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002890 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002891 {
2892 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2893 char extra[32];
2894 tANI_U8 len = 0;
2895
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002896 len = scnprintf(extra, sizeof(extra), "%s %d",
2897 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002898 if (copy_to_user(priv_data.buf, &extra, len + 1))
2899 {
2900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2901 "%s: failed to copy data to user buffer", __func__);
2902 ret = -EFAULT;
2903 goto exit;
2904 }
2905 }
2906 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2907 {
2908 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2909 char extra[32];
2910 tANI_U8 len = 0;
2911
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002912 len = scnprintf(extra, sizeof(extra), "%s %d",
2913 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002914 if (copy_to_user(priv_data.buf, &extra, len + 1))
2915 {
2916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2917 "%s: failed to copy data to user buffer", __func__);
2918 ret = -EFAULT;
2919 goto exit;
2920 }
2921 }
2922 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2923 {
2924 tANI_U8 *value = command;
2925 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2926
2927 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2928 value = value + 26;
2929 /* Convert the value from ascii to integer */
2930 ret = kstrtou8(value, 10, &minTime);
2931 if (ret < 0)
2932 {
2933 /* If the input value is greater than max value of datatype, then also
2934 kstrtou8 fails */
2935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2936 "%s: kstrtou8 failed range [%d - %d]", __func__,
2937 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2938 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2939 ret = -EINVAL;
2940 goto exit;
2941 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002942 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2943 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2944 {
2945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2946 "scan min channel time value %d is out of range"
2947 " (Min: %d Max: %d)", minTime,
2948 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2949 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2950 ret = -EINVAL;
2951 goto exit;
2952 }
2953
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302954 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2955 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2956 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2958 "%s: Received Command to change channel min time = %d", __func__, minTime);
2959
2960 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2961 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2962 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002963 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2964 {
2965 tANI_U8 *value = command;
2966 tANI_U8 channel = 0;
2967 tANI_U8 dwellTime = 0;
2968 tANI_U8 bufLen = 0;
2969 tANI_U8 *buf = NULL;
2970 tSirMacAddr targetApBssid;
2971 eHalStatus status = eHAL_STATUS_SUCCESS;
2972 struct ieee80211_channel chan;
2973 tANI_U8 finalLen = 0;
2974 tANI_U8 *finalBuf = NULL;
2975 tANI_U8 temp = 0;
2976 u64 cookie;
2977 hdd_station_ctx_t *pHddStaCtx = NULL;
2978 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2979
2980 /* if not associated, no need to send action frame */
2981 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2982 {
2983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2984 ret = -EINVAL;
2985 goto exit;
2986 }
2987
2988 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2989 &dwellTime, &buf, &bufLen);
2990 if (eHAL_STATUS_SUCCESS != status)
2991 {
2992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2993 "%s: Failed to parse send action frame data", __func__);
2994 ret = -EINVAL;
2995 goto exit;
2996 }
2997
2998 /* if the target bssid is different from currently associated AP,
2999 then no need to send action frame */
3000 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3001 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3002 {
3003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3004 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003005 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003006 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003007 goto exit;
3008 }
3009
3010 /* if the channel number is different from operating channel then
3011 no need to send action frame */
3012 if (channel != pHddStaCtx->conn_info.operationChannel)
3013 {
3014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3015 "%s: channel(%d) is different from operating channel(%d)",
3016 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3017 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003018 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003019 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003020 goto exit;
3021 }
3022 chan.center_freq = sme_ChnToFreq(channel);
3023
3024 finalLen = bufLen + 24;
3025 finalBuf = vos_mem_malloc(finalLen);
3026 if (NULL == finalBuf)
3027 {
3028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3029 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003030 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003031 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003032 goto exit;
3033 }
3034 vos_mem_zero(finalBuf, finalLen);
3035
3036 /* Fill subtype */
3037 temp = SIR_MAC_MGMT_ACTION << 4;
3038 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3039
3040 /* Fill type */
3041 temp = SIR_MAC_MGMT_FRAME;
3042 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3043
3044 /* Fill destination address (bssid of the AP) */
3045 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3046
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003047 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003048 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3049
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003050 /* Fill BSSID (AP mac address) */
3051 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003052
3053 /* Fill received buffer from 24th address */
3054 vos_mem_copy(finalBuf + 24, buf, bufLen);
3055
Jeff Johnson11c33152013-04-16 17:52:40 -07003056 /* done with the parsed buffer */
3057 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003058 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003059
DARAM SUDHA39eede62014-02-12 11:16:40 +05303060 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3062 &(pAdapter->wdev),
3063#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003064 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003065#endif
3066 &chan, 0,
3067#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3068 NL80211_CHAN_HT20, 1,
3069#endif
3070 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003071 1, &cookie );
3072 vos_mem_free(finalBuf);
3073 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003074 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3075 {
3076 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3077 char extra[32];
3078 tANI_U8 len = 0;
3079
3080 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003081 len = scnprintf(extra, sizeof(extra), "%s %d",
3082 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3084 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3085 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003086 if (copy_to_user(priv_data.buf, &extra, len + 1))
3087 {
3088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3089 "%s: failed to copy data to user buffer", __func__);
3090 ret = -EFAULT;
3091 goto exit;
3092 }
3093 }
3094 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3095 {
3096 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003097 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003098
3099 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3100 value = value + 19;
3101 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003102 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003103 if (ret < 0)
3104 {
3105 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003106 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003108 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003109 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3110 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3111 ret = -EINVAL;
3112 goto exit;
3113 }
3114
3115 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3116 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3117 {
3118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3119 "lfr mode value %d is out of range"
3120 " (Min: %d Max: %d)", maxTime,
3121 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3122 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3123 ret = -EINVAL;
3124 goto exit;
3125 }
3126
3127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3128 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3129
3130 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3131 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3132 }
3133 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3134 {
3135 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3136 char extra[32];
3137 tANI_U8 len = 0;
3138
3139 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003140 len = scnprintf(extra, sizeof(extra), "%s %d",
3141 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003142 if (copy_to_user(priv_data.buf, &extra, len + 1))
3143 {
3144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3145 "%s: failed to copy data to user buffer", __func__);
3146 ret = -EFAULT;
3147 goto exit;
3148 }
3149 }
3150 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3151 {
3152 tANI_U8 *value = command;
3153 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3154
3155 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3156 value = value + 16;
3157 /* Convert the value from ascii to integer */
3158 ret = kstrtou16(value, 10, &val);
3159 if (ret < 0)
3160 {
3161 /* If the input value is greater than max value of datatype, then also
3162 kstrtou16 fails */
3163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3164 "%s: kstrtou16 failed range [%d - %d]", __func__,
3165 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3166 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3167 ret = -EINVAL;
3168 goto exit;
3169 }
3170
3171 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3172 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3173 {
3174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3175 "scan home time value %d is out of range"
3176 " (Min: %d Max: %d)", val,
3177 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3178 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3179 ret = -EINVAL;
3180 goto exit;
3181 }
3182
3183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3184 "%s: Received Command to change scan home time = %d", __func__, val);
3185
3186 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3187 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3188 }
3189 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3190 {
3191 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3192 char extra[32];
3193 tANI_U8 len = 0;
3194
3195 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003196 len = scnprintf(extra, sizeof(extra), "%s %d",
3197 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003198 if (copy_to_user(priv_data.buf, &extra, len + 1))
3199 {
3200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3201 "%s: failed to copy data to user buffer", __func__);
3202 ret = -EFAULT;
3203 goto exit;
3204 }
3205 }
3206 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3207 {
3208 tANI_U8 *value = command;
3209 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3210
3211 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3212 value = value + 17;
3213 /* Convert the value from ascii to integer */
3214 ret = kstrtou8(value, 10, &val);
3215 if (ret < 0)
3216 {
3217 /* If the input value is greater than max value of datatype, then also
3218 kstrtou8 fails */
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3220 "%s: kstrtou8 failed range [%d - %d]", __func__,
3221 CFG_ROAM_INTRA_BAND_MIN,
3222 CFG_ROAM_INTRA_BAND_MAX);
3223 ret = -EINVAL;
3224 goto exit;
3225 }
3226
3227 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3228 (val > CFG_ROAM_INTRA_BAND_MAX))
3229 {
3230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3231 "intra band mode value %d is out of range"
3232 " (Min: %d Max: %d)", val,
3233 CFG_ROAM_INTRA_BAND_MIN,
3234 CFG_ROAM_INTRA_BAND_MAX);
3235 ret = -EINVAL;
3236 goto exit;
3237 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3239 "%s: Received Command to change intra band = %d", __func__, val);
3240
3241 pHddCtx->cfg_ini->nRoamIntraBand = val;
3242 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3243 }
3244 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3245 {
3246 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3247 char extra[32];
3248 tANI_U8 len = 0;
3249
3250 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003251 len = scnprintf(extra, sizeof(extra), "%s %d",
3252 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003253 if (copy_to_user(priv_data.buf, &extra, len + 1))
3254 {
3255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3256 "%s: failed to copy data to user buffer", __func__);
3257 ret = -EFAULT;
3258 goto exit;
3259 }
3260 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003261 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3262 {
3263 tANI_U8 *value = command;
3264 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3265
3266 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3267 value = value + 15;
3268 /* Convert the value from ascii to integer */
3269 ret = kstrtou8(value, 10, &nProbes);
3270 if (ret < 0)
3271 {
3272 /* If the input value is greater than max value of datatype, then also
3273 kstrtou8 fails */
3274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3275 "%s: kstrtou8 failed range [%d - %d]", __func__,
3276 CFG_ROAM_SCAN_N_PROBES_MIN,
3277 CFG_ROAM_SCAN_N_PROBES_MAX);
3278 ret = -EINVAL;
3279 goto exit;
3280 }
3281
3282 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3283 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3284 {
3285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3286 "NProbes value %d is out of range"
3287 " (Min: %d Max: %d)", nProbes,
3288 CFG_ROAM_SCAN_N_PROBES_MIN,
3289 CFG_ROAM_SCAN_N_PROBES_MAX);
3290 ret = -EINVAL;
3291 goto exit;
3292 }
3293
3294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3295 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3296
3297 pHddCtx->cfg_ini->nProbes = nProbes;
3298 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3299 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303300 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003301 {
3302 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3303 char extra[32];
3304 tANI_U8 len = 0;
3305
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003306 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003307 if (copy_to_user(priv_data.buf, &extra, len + 1))
3308 {
3309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3310 "%s: failed to copy data to user buffer", __func__);
3311 ret = -EFAULT;
3312 goto exit;
3313 }
3314 }
3315 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3316 {
3317 tANI_U8 *value = command;
3318 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3319
3320 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3321 /* input value is in units of msec */
3322 value = value + 20;
3323 /* Convert the value from ascii to integer */
3324 ret = kstrtou16(value, 10, &homeAwayTime);
3325 if (ret < 0)
3326 {
3327 /* If the input value is greater than max value of datatype, then also
3328 kstrtou8 fails */
3329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3330 "%s: kstrtou8 failed range [%d - %d]", __func__,
3331 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3332 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3333 ret = -EINVAL;
3334 goto exit;
3335 }
3336
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003337 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3338 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3339 {
3340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3341 "homeAwayTime value %d is out of range"
3342 " (Min: %d Max: %d)", homeAwayTime,
3343 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3344 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3345 ret = -EINVAL;
3346 goto exit;
3347 }
3348
3349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3350 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003351 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3352 {
3353 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3354 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3355 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003356 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303357 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003358 {
3359 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3360 char extra[32];
3361 tANI_U8 len = 0;
3362
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003363 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003364 if (copy_to_user(priv_data.buf, &extra, len + 1))
3365 {
3366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3367 "%s: failed to copy data to user buffer", __func__);
3368 ret = -EFAULT;
3369 goto exit;
3370 }
3371 }
3372 else if (strncmp(command, "REASSOC", 7) == 0)
3373 {
3374 tANI_U8 *value = command;
3375 tANI_U8 channel = 0;
3376 tSirMacAddr targetApBssid;
3377 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003378#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3379 tCsrHandoffRequest handoffInfo;
3380#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003381 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003382 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3383
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003384 /* if not associated, no need to proceed with reassoc */
3385 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3386 {
3387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3388 ret = -EINVAL;
3389 goto exit;
3390 }
3391
3392 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3393 if (eHAL_STATUS_SUCCESS != status)
3394 {
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3396 "%s: Failed to parse reassoc command data", __func__);
3397 ret = -EINVAL;
3398 goto exit;
3399 }
3400
3401 /* if the target bssid is same as currently associated AP,
3402 then no need to proceed with reassoc */
3403 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3404 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3405 {
3406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3407 ret = -EINVAL;
3408 goto exit;
3409 }
3410
3411 /* Check channel number is a valid channel number */
3412 if(VOS_STATUS_SUCCESS !=
3413 wlan_hdd_validate_operation_channel(pAdapter, channel))
3414 {
3415 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003416 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003417 return -EINVAL;
3418 }
3419
3420 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003421#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3422 handoffInfo.channel = channel;
3423 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3424 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3425#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003426 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003427 else if (strncmp(command, "SETWESMODE", 10) == 0)
3428 {
3429 tANI_U8 *value = command;
3430 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3431
3432 /* Move pointer to ahead of SETWESMODE<delimiter> */
3433 value = value + 11;
3434 /* Convert the value from ascii to integer */
3435 ret = kstrtou8(value, 10, &wesMode);
3436 if (ret < 0)
3437 {
3438 /* If the input value is greater than max value of datatype, then also
3439 kstrtou8 fails */
3440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3441 "%s: kstrtou8 failed range [%d - %d]", __func__,
3442 CFG_ENABLE_WES_MODE_NAME_MIN,
3443 CFG_ENABLE_WES_MODE_NAME_MAX);
3444 ret = -EINVAL;
3445 goto exit;
3446 }
3447
3448 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3449 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3450 {
3451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3452 "WES Mode value %d is out of range"
3453 " (Min: %d Max: %d)", wesMode,
3454 CFG_ENABLE_WES_MODE_NAME_MIN,
3455 CFG_ENABLE_WES_MODE_NAME_MAX);
3456 ret = -EINVAL;
3457 goto exit;
3458 }
3459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3460 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3461
3462 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3463 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3464 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303465 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003466 {
3467 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3468 char extra[32];
3469 tANI_U8 len = 0;
3470
Arif Hussain826d9412013-11-12 16:44:54 -08003471 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003472 if (copy_to_user(priv_data.buf, &extra, len + 1))
3473 {
3474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3475 "%s: failed to copy data to user buffer", __func__);
3476 ret = -EFAULT;
3477 goto exit;
3478 }
3479 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003480#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003481#ifdef FEATURE_WLAN_LFR
3482 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3483 {
3484 tANI_U8 *value = command;
3485 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3486
3487 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3488 value = value + 12;
3489 /* Convert the value from ascii to integer */
3490 ret = kstrtou8(value, 10, &lfrMode);
3491 if (ret < 0)
3492 {
3493 /* If the input value is greater than max value of datatype, then also
3494 kstrtou8 fails */
3495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3496 "%s: kstrtou8 failed range [%d - %d]", __func__,
3497 CFG_LFR_FEATURE_ENABLED_MIN,
3498 CFG_LFR_FEATURE_ENABLED_MAX);
3499 ret = -EINVAL;
3500 goto exit;
3501 }
3502
3503 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3504 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3505 {
3506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3507 "lfr mode value %d is out of range"
3508 " (Min: %d Max: %d)", lfrMode,
3509 CFG_LFR_FEATURE_ENABLED_MIN,
3510 CFG_LFR_FEATURE_ENABLED_MAX);
3511 ret = -EINVAL;
3512 goto exit;
3513 }
3514
3515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3516 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3517
3518 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3519 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3520 }
3521#endif
3522#ifdef WLAN_FEATURE_VOWIFI_11R
3523 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3524 {
3525 tANI_U8 *value = command;
3526 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3527
3528 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3529 value = value + 18;
3530 /* Convert the value from ascii to integer */
3531 ret = kstrtou8(value, 10, &ft);
3532 if (ret < 0)
3533 {
3534 /* If the input value is greater than max value of datatype, then also
3535 kstrtou8 fails */
3536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3537 "%s: kstrtou8 failed range [%d - %d]", __func__,
3538 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3539 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3540 ret = -EINVAL;
3541 goto exit;
3542 }
3543
3544 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3545 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3546 {
3547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3548 "ft mode value %d is out of range"
3549 " (Min: %d Max: %d)", ft,
3550 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3551 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3552 ret = -EINVAL;
3553 goto exit;
3554 }
3555
3556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3557 "%s: Received Command to change ft mode = %d", __func__, ft);
3558
3559 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3560 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3561 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303562 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3563 {
3564 tANI_U8 *value = command;
3565 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303566
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303567 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3568 value = value + 15;
3569 /* Convert the value from ascii to integer */
3570 ret = kstrtou8(value, 10, &dfsScanMode);
3571 if (ret < 0)
3572 {
3573 /* If the input value is greater than max value of
3574 datatype, then also kstrtou8 fails
3575 */
3576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3577 "%s: kstrtou8 failed range [%d - %d]", __func__,
3578 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3579 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3580 ret = -EINVAL;
3581 goto exit;
3582 }
3583
3584 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3585 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3586 {
3587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3588 "dfsScanMode value %d is out of range"
3589 " (Min: %d Max: %d)", dfsScanMode,
3590 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3591 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3592 ret = -EINVAL;
3593 goto exit;
3594 }
3595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3596 "%s: Received Command to Set DFS Scan Mode = %d",
3597 __func__, dfsScanMode);
3598
3599 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3600 }
3601 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3602 {
3603 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3604 char extra[32];
3605 tANI_U8 len = 0;
3606
3607 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3608 if (copy_to_user(priv_data.buf, &extra, len + 1))
3609 {
3610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3611 "%s: failed to copy data to user buffer", __func__);
3612 ret = -EFAULT;
3613 goto exit;
3614 }
3615 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303616 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3617 {
3618 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303619 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303620 tSirMacAddr targetApBssid;
3621 tANI_U8 trigger = 0;
3622 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303623 tHalHandle hHal;
3624 v_U32_t roamId = 0;
3625 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303626 hdd_station_ctx_t *pHddStaCtx = NULL;
3627 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303628 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303629
3630 /* if not associated, no need to proceed with reassoc */
3631 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3632 {
3633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3634 ret = -EINVAL;
3635 goto exit;
3636 }
3637
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303638 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303639 if (eHAL_STATUS_SUCCESS != status)
3640 {
3641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3642 "%s: Failed to parse reassoc command data", __func__);
3643 ret = -EINVAL;
3644 goto exit;
3645 }
3646
3647 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303648 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303649 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3650 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3651 {
3652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3653 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3654 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303655 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3656 &modProfileFields);
3657 sme_RoamReassoc(hHal, pAdapter->sessionId,
3658 NULL, modProfileFields, &roamId, 1);
3659 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303660 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303661
3662 /* Check channel number is a valid channel number */
3663 if(VOS_STATUS_SUCCESS !=
3664 wlan_hdd_validate_operation_channel(pAdapter, channel))
3665 {
3666 hddLog(VOS_TRACE_LEVEL_ERROR,
3667 "%s: Invalid Channel [%d]", __func__, channel);
3668 return -EINVAL;
3669 }
3670
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303671 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303672
3673 /* Proceed with scan/roam */
3674 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3675 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303676 (tSmeFastRoamTrigger)(trigger),
3677 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303678 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003679#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003680#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003681 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3682 {
3683 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003684 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003685
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003686 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003687 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003688 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003689 hdd_is_okc_mode_enabled(pHddCtx) &&
3690 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3691 {
3692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003693 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003694 " hence this operation is not permitted!", __func__);
3695 ret = -EPERM;
3696 goto exit;
3697 }
3698
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003699 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3700 value = value + 11;
3701 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003702 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003703 if (ret < 0)
3704 {
3705 /* If the input value is greater than max value of datatype, then also
3706 kstrtou8 fails */
3707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3708 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003709 CFG_ESE_FEATURE_ENABLED_MIN,
3710 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003711 ret = -EINVAL;
3712 goto exit;
3713 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003714 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3715 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003716 {
3717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003718 "Ese mode value %d is out of range"
3719 " (Min: %d Max: %d)", eseMode,
3720 CFG_ESE_FEATURE_ENABLED_MIN,
3721 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003722 ret = -EINVAL;
3723 goto exit;
3724 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003726 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003727
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003728 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3729 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003730 }
3731#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003732 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3733 {
3734 tANI_U8 *value = command;
3735 tANI_BOOLEAN roamScanControl = 0;
3736
3737 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3738 value = value + 19;
3739 /* Convert the value from ascii to integer */
3740 ret = kstrtou8(value, 10, &roamScanControl);
3741 if (ret < 0)
3742 {
3743 /* If the input value is greater than max value of datatype, then also
3744 kstrtou8 fails */
3745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3746 "%s: kstrtou8 failed ", __func__);
3747 ret = -EINVAL;
3748 goto exit;
3749 }
3750
3751 if (0 != roamScanControl)
3752 {
3753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3754 "roam scan control invalid value = %d",
3755 roamScanControl);
3756 ret = -EINVAL;
3757 goto exit;
3758 }
3759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3760 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3761
3762 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3763 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003764#ifdef FEATURE_WLAN_OKC
3765 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3766 {
3767 tANI_U8 *value = command;
3768 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3769
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003770 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003771 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003772 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003773 hdd_is_okc_mode_enabled(pHddCtx) &&
3774 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3775 {
3776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003777 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003778 " hence this operation is not permitted!", __func__);
3779 ret = -EPERM;
3780 goto exit;
3781 }
3782
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003783 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3784 value = value + 11;
3785 /* Convert the value from ascii to integer */
3786 ret = kstrtou8(value, 10, &okcMode);
3787 if (ret < 0)
3788 {
3789 /* If the input value is greater than max value of datatype, then also
3790 kstrtou8 fails */
3791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3792 "%s: kstrtou8 failed range [%d - %d]", __func__,
3793 CFG_OKC_FEATURE_ENABLED_MIN,
3794 CFG_OKC_FEATURE_ENABLED_MAX);
3795 ret = -EINVAL;
3796 goto exit;
3797 }
3798
3799 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3800 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3801 {
3802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3803 "Okc mode value %d is out of range"
3804 " (Min: %d Max: %d)", okcMode,
3805 CFG_OKC_FEATURE_ENABLED_MIN,
3806 CFG_OKC_FEATURE_ENABLED_MAX);
3807 ret = -EINVAL;
3808 goto exit;
3809 }
3810
3811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3812 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3813
3814 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3815 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003816#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303817 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003818 {
3819 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3820 char extra[32];
3821 tANI_U8 len = 0;
3822
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003823 len = scnprintf(extra, sizeof(extra), "%s %d",
3824 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003825 if (copy_to_user(priv_data.buf, &extra, len + 1))
3826 {
3827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3828 "%s: failed to copy data to user buffer", __func__);
3829 ret = -EFAULT;
3830 goto exit;
3831 }
3832 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303833#ifdef WLAN_FEATURE_PACKET_FILTERING
3834 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3835 {
3836 tANI_U8 filterType = 0;
3837 tANI_U8 *value = command;
3838
3839 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3840 value = value + 22;
3841
3842 /* Convert the value from ascii to integer */
3843 ret = kstrtou8(value, 10, &filterType);
3844 if (ret < 0)
3845 {
3846 /* If the input value is greater than max value of datatype,
3847 * then also kstrtou8 fails
3848 */
3849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3850 "%s: kstrtou8 failed range ", __func__);
3851 ret = -EINVAL;
3852 goto exit;
3853 }
3854
3855 if (filterType != 0 && filterType != 1)
3856 {
3857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3858 "%s: Accepted Values are 0 and 1 ", __func__);
3859 ret = -EINVAL;
3860 goto exit;
3861 }
3862 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3863 pAdapter->sessionId);
3864 }
3865#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303866 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3867 {
Kiet Lamad161252014-07-22 11:23:32 -07003868 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303869 int ret;
3870
Kiet Lamad161252014-07-22 11:23:32 -07003871 dhcpPhase = command + 11;
3872 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303873 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003875 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303876
3877 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003878
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303879 ret = wlan_hdd_scan_abort(pAdapter);
3880 if (ret < 0)
3881 {
3882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3883 FL("failed to abort existing scan %d"), ret);
3884 }
3885
Kiet Lamad161252014-07-22 11:23:32 -07003886 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3887 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303888 }
Kiet Lamad161252014-07-22 11:23:32 -07003889 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303890 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003892 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303893
3894 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003895
3896 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3897 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303898 }
3899 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003900 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3901 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3903 FL("making default scan to ACTIVE"));
3904 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003905 }
3906 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3907 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3909 FL("making default scan to PASSIVE"));
3910 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003911 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303912 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3913 {
3914 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3915 char extra[32];
3916 tANI_U8 len = 0;
3917
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303918 memset(extra, 0, sizeof(extra));
3919 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3920 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303921 {
3922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3923 "%s: failed to copy data to user buffer", __func__);
3924 ret = -EFAULT;
3925 goto exit;
3926 }
3927 ret = len;
3928 }
3929 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3930 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303931 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303932 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003933 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3934 {
3935 tANI_U8 filterType = 0;
3936 tANI_U8 *value;
3937 value = command + 9;
3938
3939 /* Convert the value from ascii to integer */
3940 ret = kstrtou8(value, 10, &filterType);
3941 if (ret < 0)
3942 {
3943 /* If the input value is greater than max value of datatype,
3944 * then also kstrtou8 fails
3945 */
3946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3947 "%s: kstrtou8 failed range ", __func__);
3948 ret = -EINVAL;
3949 goto exit;
3950 }
3951 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3952 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3953 {
3954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3955 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3956 " 2-Sink ", __func__);
3957 ret = -EINVAL;
3958 goto exit;
3959 }
3960 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3961 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303962 pScanInfo = &pHddCtx->scan_info;
3963 if (filterType && pScanInfo != NULL &&
3964 pHddCtx->scan_info.mScanPending)
3965 {
3966 /*Miracast Session started. Abort Scan */
3967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3968 "%s, Aborting Scan For Miracast",__func__);
3969 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3970 eCSR_SCAN_ABORT_DEFAULT);
3971 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003972 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303973 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003974 }
Leo Chang614d2072013-08-22 14:59:44 -07003975 else if (strncmp(command, "SETMCRATE", 9) == 0)
3976 {
Leo Chang614d2072013-08-22 14:59:44 -07003977 tANI_U8 *value = command;
3978 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003979 tSirRateUpdateInd *rateUpdate;
3980 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003981
3982 /* Only valid for SAP mode */
3983 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3984 {
3985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3986 "%s: SAP mode is not running", __func__);
3987 ret = -EFAULT;
3988 goto exit;
3989 }
3990
3991 /* Move pointer to ahead of SETMCRATE<delimiter> */
3992 /* input value is in units of hundred kbps */
3993 value = value + 10;
3994 /* Convert the value from ascii to integer, decimal base */
3995 ret = kstrtouint(value, 10, &targetRate);
3996
Leo Chang1f98cbd2013-10-17 15:03:52 -07003997 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3998 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003999 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004000 hddLog(VOS_TRACE_LEVEL_ERROR,
4001 "%s: SETMCRATE indication alloc fail", __func__);
4002 ret = -EFAULT;
4003 goto exit;
4004 }
4005 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4006
4007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4008 "MC Target rate %d", targetRate);
4009 /* Ignore unicast */
4010 rateUpdate->ucastDataRate = -1;
4011 rateUpdate->mcastDataRate24GHz = targetRate;
4012 rateUpdate->mcastDataRate5GHz = targetRate;
4013 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4014 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4015 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4016 if (eHAL_STATUS_SUCCESS != status)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR,
4019 "%s: SET_MC_RATE failed", __func__);
4020 vos_mem_free(rateUpdate);
4021 ret = -EFAULT;
4022 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004023 }
4024 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304025#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004026 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304027 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004028 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304029 }
4030#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004031#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004032 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4033 {
4034 tANI_U8 *value = command;
4035 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4036 tANI_U8 numChannels = 0;
4037 eHalStatus status = eHAL_STATUS_SUCCESS;
4038
4039 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4040 if (eHAL_STATUS_SUCCESS != status)
4041 {
4042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4043 "%s: Failed to parse channel list information", __func__);
4044 ret = -EINVAL;
4045 goto exit;
4046 }
4047
4048 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4049 {
4050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4051 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4052 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4053 ret = -EINVAL;
4054 goto exit;
4055 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004056 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004057 ChannelList,
4058 numChannels);
4059 if (eHAL_STATUS_SUCCESS != status)
4060 {
4061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4062 "%s: Failed to update channel list information", __func__);
4063 ret = -EINVAL;
4064 goto exit;
4065 }
4066 }
4067 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4068 {
4069 tANI_U8 *value = command;
4070 char extra[128] = {0};
4071 int len = 0;
4072 tANI_U8 tid = 0;
4073 hdd_station_ctx_t *pHddStaCtx = NULL;
4074 tAniTrafStrmMetrics tsmMetrics;
4075 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4076
4077 /* if not associated, return error */
4078 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4079 {
4080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4081 ret = -EINVAL;
4082 goto exit;
4083 }
4084
4085 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4086 value = value + 12;
4087 /* Convert the value from ascii to integer */
4088 ret = kstrtou8(value, 10, &tid);
4089 if (ret < 0)
4090 {
4091 /* If the input value is greater than max value of datatype, then also
4092 kstrtou8 fails */
4093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4094 "%s: kstrtou8 failed range [%d - %d]", __func__,
4095 TID_MIN_VALUE,
4096 TID_MAX_VALUE);
4097 ret = -EINVAL;
4098 goto exit;
4099 }
4100
4101 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4102 {
4103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4104 "tid value %d is out of range"
4105 " (Min: %d Max: %d)", tid,
4106 TID_MIN_VALUE,
4107 TID_MAX_VALUE);
4108 ret = -EINVAL;
4109 goto exit;
4110 }
4111
4112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4113 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4114
4115 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4116 {
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4118 "%s: failed to get tsm stats", __func__);
4119 ret = -EFAULT;
4120 goto exit;
4121 }
4122
4123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4124 "UplinkPktQueueDly(%d)\n"
4125 "UplinkPktQueueDlyHist[0](%d)\n"
4126 "UplinkPktQueueDlyHist[1](%d)\n"
4127 "UplinkPktQueueDlyHist[2](%d)\n"
4128 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304129 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004130 "UplinkPktLoss(%d)\n"
4131 "UplinkPktCount(%d)\n"
4132 "RoamingCount(%d)\n"
4133 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4134 tsmMetrics.UplinkPktQueueDlyHist[0],
4135 tsmMetrics.UplinkPktQueueDlyHist[1],
4136 tsmMetrics.UplinkPktQueueDlyHist[2],
4137 tsmMetrics.UplinkPktQueueDlyHist[3],
4138 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4139 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4140
4141 /* Output TSM stats is of the format
4142 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4143 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004144 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004145 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4146 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4147 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4148 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4149 tsmMetrics.RoamingDly);
4150
4151 if (copy_to_user(priv_data.buf, &extra, len + 1))
4152 {
4153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4154 "%s: failed to copy data to user buffer", __func__);
4155 ret = -EFAULT;
4156 goto exit;
4157 }
4158 }
4159 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4160 {
4161 tANI_U8 *value = command;
4162 tANI_U8 *cckmIe = NULL;
4163 tANI_U8 cckmIeLen = 0;
4164 eHalStatus status = eHAL_STATUS_SUCCESS;
4165
4166 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4167 if (eHAL_STATUS_SUCCESS != status)
4168 {
4169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4170 "%s: Failed to parse cckm ie data", __func__);
4171 ret = -EINVAL;
4172 goto exit;
4173 }
4174
4175 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4176 {
4177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4178 "%s: CCKM Ie input length is more than max[%d]", __func__,
4179 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004180 vos_mem_free(cckmIe);
4181 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004182 ret = -EINVAL;
4183 goto exit;
4184 }
4185 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004186 vos_mem_free(cckmIe);
4187 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004188 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004189 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4190 {
4191 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004192 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004193 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004194
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004195 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004196 if (eHAL_STATUS_SUCCESS != status)
4197 {
4198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004199 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004200 ret = -EINVAL;
4201 goto exit;
4202 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004203 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4204 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4205 hdd_indicateEseBcnReportNoResults (pAdapter,
4206 eseBcnReq.bcnReq[0].measurementToken,
4207 0x02, //BIT(1) set for measurement done
4208 0); // no BSS
4209 goto exit;
4210 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004211
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004212 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4213 if (eHAL_STATUS_SUCCESS != status)
4214 {
4215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4216 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4217 ret = -EINVAL;
4218 goto exit;
4219 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004220 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004221#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304222 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4223 {
4224 eHalStatus status;
4225 char buf[32], len;
4226 long waitRet;
4227 bcnMissRateContext_t getBcnMissRateCtx;
4228
4229 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4230
4231 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4232 {
4233 hddLog(VOS_TRACE_LEVEL_WARN,
4234 FL("GETBCNMISSRATE: STA is not in connected state"));
4235 ret = -1;
4236 goto exit;
4237 }
4238
4239 init_completion(&(getBcnMissRateCtx.completion));
4240 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4241
4242 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4243 pAdapter->sessionId,
4244 (void *)getBcnMissRateCB,
4245 (void *)(&getBcnMissRateCtx));
4246 if( eHAL_STATUS_SUCCESS != status)
4247 {
4248 hddLog(VOS_TRACE_LEVEL_INFO,
4249 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4250 ret = -EINVAL;
4251 goto exit;
4252 }
4253
4254 waitRet = wait_for_completion_interruptible_timeout
4255 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4256 if(waitRet <= 0)
4257 {
4258 hddLog(VOS_TRACE_LEVEL_ERROR,
4259 FL("failed to wait on bcnMissRateComp %d"), ret);
4260
4261 //Make magic number to zero so that callback is not called.
4262 spin_lock(&hdd_context_lock);
4263 getBcnMissRateCtx.magic = 0x0;
4264 spin_unlock(&hdd_context_lock);
4265 ret = -EINVAL;
4266 goto exit;
4267 }
4268
4269 hddLog(VOS_TRACE_LEVEL_INFO,
4270 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4271
4272 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4273 if (copy_to_user(priv_data.buf, &buf, len + 1))
4274 {
4275 hddLog(VOS_TRACE_LEVEL_ERROR,
4276 "%s: failed to copy data to user buffer", __func__);
4277 ret = -EFAULT;
4278 goto exit;
4279 }
4280 ret = len;
4281 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304282#ifdef FEATURE_WLAN_TDLS
4283 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4284 tANI_U8 *value = command;
4285 int set_value;
4286 /* Move pointer to ahead of TDLSOFFCH*/
4287 value += 26;
4288 sscanf(value, "%d", &set_value);
4289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4290 "%s: Tdls offchannel offset:%d",
4291 __func__, set_value);
4292 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4293 if (ret < 0)
4294 {
4295 ret = -EINVAL;
4296 goto exit;
4297 }
4298
4299 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4300 tANI_U8 *value = command;
4301 int set_value;
4302 /* Move pointer to ahead of tdlsoffchnmode*/
4303 value += 18;
4304 sscanf(value, "%d", &set_value);
4305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4306 "%s: Tdls offchannel mode:%d",
4307 __func__, set_value);
4308 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4309 if (ret < 0)
4310 {
4311 ret = -EINVAL;
4312 goto exit;
4313 }
4314 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4315 tANI_U8 *value = command;
4316 int set_value;
4317 /* Move pointer to ahead of TDLSOFFCH*/
4318 value += 14;
4319 sscanf(value, "%d", &set_value);
4320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4321 "%s: Tdls offchannel num: %d",
4322 __func__, set_value);
4323 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4324 if (ret < 0)
4325 {
4326 ret = -EINVAL;
4327 goto exit;
4328 }
4329 }
4330#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304331 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4332 {
4333 eHalStatus status;
4334 char *buf = NULL;
4335 char len;
4336 long waitRet;
4337 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304338 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304339 tANI_U8 *ptr = command;
4340 int stats = *(ptr + 11) - '0';
4341
4342 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4343 if (!IS_FEATURE_FW_STATS_ENABLE)
4344 {
4345 hddLog(VOS_TRACE_LEVEL_INFO,
4346 FL("Get Firmware stats feature not supported"));
4347 ret = -EINVAL;
4348 goto exit;
4349 }
4350
4351 if (FW_STATS_MAX <= stats || 0 >= stats)
4352 {
4353 hddLog(VOS_TRACE_LEVEL_INFO,
4354 FL(" stats %d not supported"),stats);
4355 ret = -EINVAL;
4356 goto exit;
4357 }
4358
4359 init_completion(&(fwStatsCtx.completion));
4360 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4361 fwStatsCtx.pAdapter = pAdapter;
4362 fwStatsRsp->type = 0;
4363 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304364 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304365 if (eHAL_STATUS_SUCCESS != status)
4366 {
4367 hddLog(VOS_TRACE_LEVEL_ERROR,
4368 FL(" fail to post WDA cmd status = %d"), status);
4369 ret = -EINVAL;
4370 goto exit;
4371 }
4372 waitRet = wait_for_completion_timeout
4373 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4374 if (waitRet <= 0)
4375 {
4376 hddLog(VOS_TRACE_LEVEL_ERROR,
4377 FL("failed to wait on GwtFwstats"));
4378 //Make magic number to zero so that callback is not executed.
4379 spin_lock(&hdd_context_lock);
4380 fwStatsCtx.magic = 0x0;
4381 spin_unlock(&hdd_context_lock);
4382 ret = -EINVAL;
4383 goto exit;
4384 }
4385 if (fwStatsRsp->type)
4386 {
4387 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4388 if (!buf)
4389 {
4390 hddLog(VOS_TRACE_LEVEL_ERROR,
4391 FL(" failed to allocate memory"));
4392 ret = -ENOMEM;
4393 goto exit;
4394 }
4395 switch( fwStatsRsp->type )
4396 {
4397 case FW_UBSP_STATS:
4398 {
4399 len = snprintf(buf, FW_STATE_RSP_LEN,
4400 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304401 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4402 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304403 }
4404 break;
4405 default:
4406 {
4407 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4408 ret = -EFAULT;
4409 kfree(buf);
4410 goto exit;
4411 }
4412 }
4413 if (copy_to_user(priv_data.buf, buf, len + 1))
4414 {
4415 hddLog(VOS_TRACE_LEVEL_ERROR,
4416 FL(" failed to copy data to user buffer"));
4417 ret = -EFAULT;
4418 kfree(buf);
4419 goto exit;
4420 }
4421 ret = len;
4422 kfree(buf);
4423 }
4424 else
4425 {
4426 hddLog(VOS_TRACE_LEVEL_ERROR,
4427 FL("failed to fetch the stats"));
4428 ret = -EFAULT;
4429 goto exit;
4430 }
4431
4432 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304433 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4434 {
4435 /*
4436 * this command wld be called by user-space when it detects WLAN
4437 * ON after airplane mode is set. When APM is set, WLAN turns off.
4438 * But it can be turned back on. Otherwise; when APM is turned back
4439 * off, WLAN wld turn back on. So at that point the command is
4440 * expected to come down. 0 means disable, 1 means enable. The
4441 * constraint is removed when parameter 1 is set or different
4442 * country code is set
4443 */
4444 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4445 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004446 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304447 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4448 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4449 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304450 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4451 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 }
4454exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304455 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004456 if (command)
4457 {
4458 kfree(command);
4459 }
4460 return ret;
4461}
4462
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004463#ifdef CONFIG_COMPAT
4464static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4465{
4466 struct {
4467 compat_uptr_t buf;
4468 int used_len;
4469 int total_len;
4470 } compat_priv_data;
4471 hdd_priv_data_t priv_data;
4472 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004473
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004474 /*
4475 * Note that pAdapter and ifr have already been verified by caller,
4476 * and HDD context has also been validated
4477 */
4478 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4479 sizeof(compat_priv_data))) {
4480 ret = -EFAULT;
4481 goto exit;
4482 }
4483 priv_data.buf = compat_ptr(compat_priv_data.buf);
4484 priv_data.used_len = compat_priv_data.used_len;
4485 priv_data.total_len = compat_priv_data.total_len;
4486 ret = hdd_driver_command(pAdapter, &priv_data);
4487 exit:
4488 return ret;
4489}
4490#else /* CONFIG_COMPAT */
4491static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4492{
4493 /* will never be invoked */
4494 return 0;
4495}
4496#endif /* CONFIG_COMPAT */
4497
4498static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4499{
4500 hdd_priv_data_t priv_data;
4501 int ret = 0;
4502
4503 /*
4504 * Note that pAdapter and ifr have already been verified by caller,
4505 * and HDD context has also been validated
4506 */
4507 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4508 ret = -EFAULT;
4509 } else {
4510 ret = hdd_driver_command(pAdapter, &priv_data);
4511 }
4512 return ret;
4513}
4514
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304515int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004516{
4517 hdd_adapter_t *pAdapter;
4518 hdd_context_t *pHddCtx;
4519 int ret;
4520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304521 ENTER();
4522
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004523 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4524 if (NULL == pAdapter) {
4525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4526 "%s: HDD adapter context is Null", __func__);
4527 ret = -ENODEV;
4528 goto exit;
4529 }
4530 if (dev != pAdapter->dev) {
4531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4532 "%s: HDD adapter/dev inconsistency", __func__);
4533 ret = -ENODEV;
4534 goto exit;
4535 }
4536
4537 if ((!ifr) || (!ifr->ifr_data)) {
4538 ret = -EINVAL;
4539 goto exit;
4540 }
4541
4542 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4543 ret = wlan_hdd_validate_context(pHddCtx);
4544 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004545 ret = -EBUSY;
4546 goto exit;
4547 }
4548
4549 switch (cmd) {
4550 case (SIOCDEVPRIVATE + 1):
4551 if (is_compat_task())
4552 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4553 else
4554 ret = hdd_driver_ioctl(pAdapter, ifr);
4555 break;
4556 default:
4557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4558 __func__, cmd);
4559 ret = -EINVAL;
4560 break;
4561 }
4562 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304563 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004564 return ret;
4565}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004566
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304567int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4568{
4569 int ret;
4570
4571 vos_ssr_protect(__func__);
4572 ret = __hdd_ioctl(dev, ifr, cmd);
4573 vos_ssr_unprotect(__func__);
4574
4575 return ret;
4576}
4577
Katya Nigame7b69a82015-04-28 15:24:06 +05304578int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4579{
4580 return 0;
4581}
4582
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004583#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004584/**---------------------------------------------------------------------------
4585
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004588 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004589 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4590 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4591 <space>Scan Mode N<space>Meas Duration N
4592 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4593 then take N.
4594 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4595 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4596 This function does not take care of removing duplicate channels from the list
4597
4598 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004599 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004600
4601 \return - 0 for success non-zero for failure
4602
4603 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004604static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4605 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004606{
4607 tANI_U8 *inPtr = pValue;
4608 int tempInt = 0;
4609 int j = 0, i = 0, v = 0;
4610 char buf[32];
4611
4612 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4613 /*no argument after the command*/
4614 if (NULL == inPtr)
4615 {
4616 return -EINVAL;
4617 }
4618 /*no space after the command*/
4619 else if (SPACE_ASCII_VALUE != *inPtr)
4620 {
4621 return -EINVAL;
4622 }
4623
4624 /*removing empty spaces*/
4625 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4626
4627 /*no argument followed by spaces*/
4628 if ('\0' == *inPtr) return -EINVAL;
4629
4630 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004631 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004632 if (1 != v) return -EINVAL;
4633
4634 v = kstrtos32(buf, 10, &tempInt);
4635 if ( v < 0) return -EINVAL;
4636
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004637 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004638
4639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004640 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004641
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004642 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004643 {
4644 for (i = 0; i < 4; i++)
4645 {
4646 /*inPtr pointing to the beginning of first space after number of ie fields*/
4647 inPtr = strpbrk( inPtr, " " );
4648 /*no ie data after the number of ie fields argument*/
4649 if (NULL == inPtr) return -EINVAL;
4650
4651 /*removing empty space*/
4652 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4653
4654 /*no ie data after the number of ie fields argument and spaces*/
4655 if ( '\0' == *inPtr ) return -EINVAL;
4656
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004657 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004658 if (1 != v) return -EINVAL;
4659
4660 v = kstrtos32(buf, 10, &tempInt);
4661 if (v < 0) return -EINVAL;
4662
4663 switch (i)
4664 {
4665 case 0: /* Measurement token */
4666 if (tempInt <= 0)
4667 {
4668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4669 "Invalid Measurement Token(%d)", tempInt);
4670 return -EINVAL;
4671 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004672 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004673 break;
4674
4675 case 1: /* Channel number */
4676 if ((tempInt <= 0) ||
4677 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4678 {
4679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4680 "Invalid Channel Number(%d)", tempInt);
4681 return -EINVAL;
4682 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004683 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004684 break;
4685
4686 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004687 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004688 {
4689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4690 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4691 return -EINVAL;
4692 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004693 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004694 break;
4695
4696 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004697 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4698 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004699 {
4700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4701 "Invalid Measurement Duration(%d)", tempInt);
4702 return -EINVAL;
4703 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004704 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004705 break;
4706 }
4707 }
4708 }
4709
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004710 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004711 {
4712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304713 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004714 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004715 pEseBcnReq->bcnReq[j].measurementToken,
4716 pEseBcnReq->bcnReq[j].channel,
4717 pEseBcnReq->bcnReq[j].scanMode,
4718 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004719 }
4720
4721 return VOS_STATUS_SUCCESS;
4722}
4723
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004724static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4725{
4726 struct statsContext *pStatsContext = NULL;
4727 hdd_adapter_t *pAdapter = NULL;
4728
4729 if (NULL == pContext)
4730 {
4731 hddLog(VOS_TRACE_LEVEL_ERROR,
4732 "%s: Bad param, pContext [%p]",
4733 __func__, pContext);
4734 return;
4735 }
4736
Jeff Johnson72a40512013-12-19 10:14:15 -08004737 /* there is a race condition that exists between this callback
4738 function and the caller since the caller could time out either
4739 before or while this code is executing. we use a spinlock to
4740 serialize these actions */
4741 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004742
4743 pStatsContext = pContext;
4744 pAdapter = pStatsContext->pAdapter;
4745 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4746 {
4747 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004748 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004749 hddLog(VOS_TRACE_LEVEL_WARN,
4750 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4751 __func__, pAdapter, pStatsContext->magic);
4752 return;
4753 }
4754
Jeff Johnson72a40512013-12-19 10:14:15 -08004755 /* context is valid so caller is still waiting */
4756
4757 /* paranoia: invalidate the magic */
4758 pStatsContext->magic = 0;
4759
4760 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004761 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4762 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4763 tsmMetrics.UplinkPktQueueDlyHist,
4764 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4765 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4766 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4767 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4768 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4769 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4770 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4771
Jeff Johnson72a40512013-12-19 10:14:15 -08004772 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004773 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004774
4775 /* serialization is complete */
4776 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004777}
4778
4779
4780
4781static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4782 tAniTrafStrmMetrics* pTsmMetrics)
4783{
4784 hdd_station_ctx_t *pHddStaCtx = NULL;
4785 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004786 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004787 long lrc;
4788 struct statsContext context;
4789 hdd_context_t *pHddCtx = NULL;
4790
4791 if (NULL == pAdapter)
4792 {
4793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4794 return VOS_STATUS_E_FAULT;
4795 }
4796
4797 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4798 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4799
4800 /* we are connected prepare our callback context */
4801 init_completion(&context.completion);
4802 context.pAdapter = pAdapter;
4803 context.magic = STATS_CONTEXT_MAGIC;
4804
4805 /* query tsm stats */
4806 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4807 pHddStaCtx->conn_info.staId[ 0 ],
4808 pHddStaCtx->conn_info.bssId,
4809 &context, pHddCtx->pvosContext, tid);
4810
4811 if (eHAL_STATUS_SUCCESS != hstatus)
4812 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4814 __func__);
4815 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004816 }
4817 else
4818 {
4819 /* request was sent -- wait for the response */
4820 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4821 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004822 if (lrc <= 0)
4823 {
4824 hddLog(VOS_TRACE_LEVEL_ERROR,
4825 "%s: SME %s while retrieving statistics",
4826 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004827 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004828 }
4829 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004830
Jeff Johnson72a40512013-12-19 10:14:15 -08004831 /* either we never sent a request, we sent a request and received a
4832 response or we sent a request and timed out. if we never sent a
4833 request or if we sent a request and got a response, we want to
4834 clear the magic out of paranoia. if we timed out there is a
4835 race condition such that the callback function could be
4836 executing at the same time we are. of primary concern is if the
4837 callback function had already verified the "magic" but had not
4838 yet set the completion variable when a timeout occurred. we
4839 serialize these activities by invalidating the magic while
4840 holding a shared spinlock which will cause us to block if the
4841 callback is currently executing */
4842 spin_lock(&hdd_context_lock);
4843 context.magic = 0;
4844 spin_unlock(&hdd_context_lock);
4845
4846 if (VOS_STATUS_SUCCESS == vstatus)
4847 {
4848 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4849 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4850 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4851 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4852 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4853 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4854 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4855 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4856 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4857 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4858 }
4859 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004860}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004861#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004862
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004863#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004864void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4865{
4866 eCsrBand band = -1;
4867 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4868 switch (band)
4869 {
4870 case eCSR_BAND_ALL:
4871 *pBand = WLAN_HDD_UI_BAND_AUTO;
4872 break;
4873
4874 case eCSR_BAND_24:
4875 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4876 break;
4877
4878 case eCSR_BAND_5G:
4879 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4880 break;
4881
4882 default:
4883 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4884 *pBand = -1;
4885 break;
4886 }
4887}
4888
4889/**---------------------------------------------------------------------------
4890
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004891 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4892
4893 This function parses the send action frame data passed in the format
4894 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4895
Srinivas Girigowda56076852013-08-20 14:00:50 -07004896 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004897 \param - pTargetApBssid Pointer to target Ap bssid
4898 \param - pChannel Pointer to the Target AP channel
4899 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4900 \param - pBuf Pointer to data
4901 \param - pBufLen Pointer to data length
4902
4903 \return - 0 for success non-zero for failure
4904
4905 --------------------------------------------------------------------------*/
4906VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4907 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4908{
4909 tANI_U8 *inPtr = pValue;
4910 tANI_U8 *dataEnd;
4911 int tempInt;
4912 int j = 0;
4913 int i = 0;
4914 int v = 0;
4915 tANI_U8 tempBuf[32];
4916 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004917 /* 12 hexa decimal digits, 5 ':' and '\0' */
4918 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004919
4920 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4921 /*no argument after the command*/
4922 if (NULL == inPtr)
4923 {
4924 return -EINVAL;
4925 }
4926
4927 /*no space after the command*/
4928 else if (SPACE_ASCII_VALUE != *inPtr)
4929 {
4930 return -EINVAL;
4931 }
4932
4933 /*removing empty spaces*/
4934 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4935
4936 /*no argument followed by spaces*/
4937 if ('\0' == *inPtr)
4938 {
4939 return -EINVAL;
4940 }
4941
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004942 v = sscanf(inPtr, "%17s", macAddress);
4943 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004944 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4946 "Invalid MAC address or All hex inputs are not read (%d)", v);
4947 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004948 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004949
4950 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4951 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4952 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4953 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4954 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4955 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004956
4957 /* point to the next argument */
4958 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4959 /*no argument after the command*/
4960 if (NULL == inPtr) return -EINVAL;
4961
4962 /*removing empty spaces*/
4963 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4964
4965 /*no argument followed by spaces*/
4966 if ('\0' == *inPtr)
4967 {
4968 return -EINVAL;
4969 }
4970
4971 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004972 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004973 if (1 != v) return -EINVAL;
4974
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004975 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304976 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304977 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004978
4979 *pChannel = tempInt;
4980
4981 /* point to the next argument */
4982 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4983 /*no argument after the command*/
4984 if (NULL == inPtr) return -EINVAL;
4985 /*removing empty spaces*/
4986 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4987
4988 /*no argument followed by spaces*/
4989 if ('\0' == *inPtr)
4990 {
4991 return -EINVAL;
4992 }
4993
4994 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004995 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004996 if (1 != v) return -EINVAL;
4997
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004998 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004999 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005000
5001 *pDwellTime = tempInt;
5002
5003 /* point to the next argument */
5004 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5005 /*no argument after the command*/
5006 if (NULL == inPtr) return -EINVAL;
5007 /*removing empty spaces*/
5008 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5009
5010 /*no argument followed by spaces*/
5011 if ('\0' == *inPtr)
5012 {
5013 return -EINVAL;
5014 }
5015
5016 /* find the length of data */
5017 dataEnd = inPtr;
5018 while(('\0' != *dataEnd) )
5019 {
5020 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005021 }
Kiet Lambe150c22013-11-21 16:30:32 +05305022 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005023 if ( *pBufLen <= 0) return -EINVAL;
5024
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005025 /* Allocate the number of bytes based on the number of input characters
5026 whether it is even or odd.
5027 if the number of input characters are even, then we need N/2 byte.
5028 if the number of input characters are odd, then we need do (N+1)/2 to
5029 compensate rounding off.
5030 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5031 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5032 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005033 if (NULL == *pBuf)
5034 {
5035 hddLog(VOS_TRACE_LEVEL_FATAL,
5036 "%s: vos_mem_alloc failed ", __func__);
5037 return -EINVAL;
5038 }
5039
5040 /* the buffer received from the upper layer is character buffer,
5041 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5042 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5043 and f0 in 3rd location */
5044 for (i = 0, j = 0; j < *pBufLen; j += 2)
5045 {
Kiet Lambe150c22013-11-21 16:30:32 +05305046 if( j+1 == *pBufLen)
5047 {
5048 tempByte = hdd_parse_hex(inPtr[j]);
5049 }
5050 else
5051 {
5052 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5053 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005054 (*pBuf)[i++] = tempByte;
5055 }
5056 *pBufLen = i;
5057 return VOS_STATUS_SUCCESS;
5058}
5059
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005060/**---------------------------------------------------------------------------
5061
Srinivas Girigowdade697412013-02-14 16:31:48 -08005062 \brief hdd_parse_channellist() - HDD Parse channel list
5063
5064 This function parses the channel list passed in the format
5065 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005066 if the Number of channels (N) does not match with the actual number of channels passed
5067 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5068 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5069 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5070 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005071
5072 \param - pValue Pointer to input channel list
5073 \param - ChannelList Pointer to local output array to record channel list
5074 \param - pNumChannels Pointer to number of roam scan channels
5075
5076 \return - 0 for success non-zero for failure
5077
5078 --------------------------------------------------------------------------*/
5079VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5080{
5081 tANI_U8 *inPtr = pValue;
5082 int tempInt;
5083 int j = 0;
5084 int v = 0;
5085 char buf[32];
5086
5087 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5088 /*no argument after the command*/
5089 if (NULL == inPtr)
5090 {
5091 return -EINVAL;
5092 }
5093
5094 /*no space after the command*/
5095 else if (SPACE_ASCII_VALUE != *inPtr)
5096 {
5097 return -EINVAL;
5098 }
5099
5100 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005101 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005102
5103 /*no argument followed by spaces*/
5104 if ('\0' == *inPtr)
5105 {
5106 return -EINVAL;
5107 }
5108
5109 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005110 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005111 if (1 != v) return -EINVAL;
5112
Srinivas Girigowdade697412013-02-14 16:31:48 -08005113 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005114 if ((v < 0) ||
5115 (tempInt <= 0) ||
5116 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5117 {
5118 return -EINVAL;
5119 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005120
5121 *pNumChannels = tempInt;
5122
5123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5124 "Number of channels are: %d", *pNumChannels);
5125
5126 for (j = 0; j < (*pNumChannels); j++)
5127 {
5128 /*inPtr pointing to the beginning of first space after number of channels*/
5129 inPtr = strpbrk( inPtr, " " );
5130 /*no channel list after the number of channels argument*/
5131 if (NULL == inPtr)
5132 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005133 if (0 != j)
5134 {
5135 *pNumChannels = j;
5136 return VOS_STATUS_SUCCESS;
5137 }
5138 else
5139 {
5140 return -EINVAL;
5141 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005142 }
5143
5144 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005145 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005146
5147 /*no channel list after the number of channels argument and spaces*/
5148 if ( '\0' == *inPtr )
5149 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005150 if (0 != j)
5151 {
5152 *pNumChannels = j;
5153 return VOS_STATUS_SUCCESS;
5154 }
5155 else
5156 {
5157 return -EINVAL;
5158 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005159 }
5160
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005161 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005162 if (1 != v) return -EINVAL;
5163
Srinivas Girigowdade697412013-02-14 16:31:48 -08005164 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005165 if ((v < 0) ||
5166 (tempInt <= 0) ||
5167 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5168 {
5169 return -EINVAL;
5170 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005171 pChannelList[j] = tempInt;
5172
5173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5174 "Channel %d added to preferred channel list",
5175 pChannelList[j] );
5176 }
5177
Srinivas Girigowdade697412013-02-14 16:31:48 -08005178 return VOS_STATUS_SUCCESS;
5179}
5180
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005181
5182/**---------------------------------------------------------------------------
5183
5184 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5185
5186 This function parses the reasoc command data passed in the format
5187 REASSOC<space><bssid><space><channel>
5188
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005189 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005190 \param - pTargetApBssid Pointer to target Ap bssid
5191 \param - pChannel Pointer to the Target AP channel
5192
5193 \return - 0 for success non-zero for failure
5194
5195 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005196VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5197 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005198{
5199 tANI_U8 *inPtr = pValue;
5200 int tempInt;
5201 int v = 0;
5202 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005203 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005204 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005205
5206 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5207 /*no argument after the command*/
5208 if (NULL == inPtr)
5209 {
5210 return -EINVAL;
5211 }
5212
5213 /*no space after the command*/
5214 else if (SPACE_ASCII_VALUE != *inPtr)
5215 {
5216 return -EINVAL;
5217 }
5218
5219 /*removing empty spaces*/
5220 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5221
5222 /*no argument followed by spaces*/
5223 if ('\0' == *inPtr)
5224 {
5225 return -EINVAL;
5226 }
5227
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005228 v = sscanf(inPtr, "%17s", macAddress);
5229 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005230 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5232 "Invalid MAC address or All hex inputs are not read (%d)", v);
5233 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005234 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005235
5236 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5237 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5238 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5239 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5240 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5241 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005242
5243 /* point to the next argument */
5244 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5245 /*no argument after the command*/
5246 if (NULL == inPtr) return -EINVAL;
5247
5248 /*removing empty spaces*/
5249 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5250
5251 /*no argument followed by spaces*/
5252 if ('\0' == *inPtr)
5253 {
5254 return -EINVAL;
5255 }
5256
5257 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005258 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005259 if (1 != v) return -EINVAL;
5260
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005261 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005262 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305263 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005264 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5265 {
5266 return -EINVAL;
5267 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005268
5269 *pChannel = tempInt;
5270 return VOS_STATUS_SUCCESS;
5271}
5272
5273#endif
5274
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005275#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005276/**---------------------------------------------------------------------------
5277
5278 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5279
5280 This function parses the SETCCKM IE command
5281 SETCCKMIE<space><ie data>
5282
5283 \param - pValue Pointer to input data
5284 \param - pCckmIe Pointer to output cckm Ie
5285 \param - pCckmIeLen Pointer to output cckm ie length
5286
5287 \return - 0 for success non-zero for failure
5288
5289 --------------------------------------------------------------------------*/
5290VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5291 tANI_U8 *pCckmIeLen)
5292{
5293 tANI_U8 *inPtr = pValue;
5294 tANI_U8 *dataEnd;
5295 int j = 0;
5296 int i = 0;
5297 tANI_U8 tempByte = 0;
5298
5299 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5300 /*no argument after the command*/
5301 if (NULL == inPtr)
5302 {
5303 return -EINVAL;
5304 }
5305
5306 /*no space after the command*/
5307 else if (SPACE_ASCII_VALUE != *inPtr)
5308 {
5309 return -EINVAL;
5310 }
5311
5312 /*removing empty spaces*/
5313 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5314
5315 /*no argument followed by spaces*/
5316 if ('\0' == *inPtr)
5317 {
5318 return -EINVAL;
5319 }
5320
5321 /* find the length of data */
5322 dataEnd = inPtr;
5323 while(('\0' != *dataEnd) )
5324 {
5325 dataEnd++;
5326 ++(*pCckmIeLen);
5327 }
5328 if ( *pCckmIeLen <= 0) return -EINVAL;
5329
5330 /* Allocate the number of bytes based on the number of input characters
5331 whether it is even or odd.
5332 if the number of input characters are even, then we need N/2 byte.
5333 if the number of input characters are odd, then we need do (N+1)/2 to
5334 compensate rounding off.
5335 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5336 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5337 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5338 if (NULL == *pCckmIe)
5339 {
5340 hddLog(VOS_TRACE_LEVEL_FATAL,
5341 "%s: vos_mem_alloc failed ", __func__);
5342 return -EINVAL;
5343 }
5344 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5345 /* the buffer received from the upper layer is character buffer,
5346 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5347 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5348 and f0 in 3rd location */
5349 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5350 {
5351 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5352 (*pCckmIe)[i++] = tempByte;
5353 }
5354 *pCckmIeLen = i;
5355
5356 return VOS_STATUS_SUCCESS;
5357}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005358#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005359
Jeff Johnson295189b2012-06-20 16:38:30 -07005360/**---------------------------------------------------------------------------
5361
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005362 \brief hdd_is_valid_mac_address() - Validate MAC address
5363
5364 This function validates whether the given MAC address is valid or not
5365 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5366 where X is the hexa decimal digit character and separated by ':'
5367 This algorithm works even if MAC address is not separated by ':'
5368
5369 This code checks given input string mac contains exactly 12 hexadecimal digits.
5370 and a separator colon : appears in the input string only after
5371 an even number of hex digits.
5372
5373 \param - pMacAddr pointer to the input MAC address
5374 \return - 1 for valid and 0 for invalid
5375
5376 --------------------------------------------------------------------------*/
5377
5378v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5379{
5380 int xdigit = 0;
5381 int separator = 0;
5382 while (*pMacAddr)
5383 {
5384 if (isxdigit(*pMacAddr))
5385 {
5386 xdigit++;
5387 }
5388 else if (':' == *pMacAddr)
5389 {
5390 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5391 break;
5392
5393 ++separator;
5394 }
5395 else
5396 {
5397 separator = -1;
5398 /* Invalid MAC found */
5399 return 0;
5400 }
5401 ++pMacAddr;
5402 }
5403 return (xdigit == 12 && (separator == 5 || separator == 0));
5404}
5405
5406/**---------------------------------------------------------------------------
5407
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305408 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005409
5410 \param - dev Pointer to net_device structure
5411
5412 \return - 0 for success non-zero for failure
5413
5414 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305415int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005416{
5417 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5418 hdd_context_t *pHddCtx;
5419 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5420 VOS_STATUS status;
5421 v_BOOL_t in_standby = TRUE;
5422
5423 if (NULL == pAdapter)
5424 {
5425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305426 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 return -ENODEV;
5428 }
5429
5430 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305431 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5432 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 if (NULL == pHddCtx)
5434 {
5435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005436 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 return -ENODEV;
5438 }
5439
5440 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5441 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5442 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005443 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5444 {
5445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305446 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005447 in_standby = FALSE;
5448 break;
5449 }
5450 else
5451 {
5452 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5453 pAdapterNode = pNext;
5454 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 }
5456
5457 if (TRUE == in_standby)
5458 {
5459 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5460 {
5461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5462 "wlan out of power save", __func__);
5463 return -EINVAL;
5464 }
5465 }
5466
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005467 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5469 {
5470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005471 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 netif_tx_start_all_queues(dev);
5475 }
5476
5477 return 0;
5478}
5479
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305480/**---------------------------------------------------------------------------
5481
5482 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5483
5484 This is called in response to ifconfig up
5485
5486 \param - dev Pointer to net_device structure
5487
5488 \return - 0 for success non-zero for failure
5489
5490 --------------------------------------------------------------------------*/
5491int hdd_open(struct net_device *dev)
5492{
5493 int ret;
5494
5495 vos_ssr_protect(__func__);
5496 ret = __hdd_open(dev);
5497 vos_ssr_unprotect(__func__);
5498
5499 return ret;
5500}
5501
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305502int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005503{
5504 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5505
5506 if(pAdapter == NULL) {
5507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005508 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005509 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005510 }
5511
Jeff Johnson295189b2012-06-20 16:38:30 -07005512 return 0;
5513}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305514
5515int hdd_mon_open (struct net_device *dev)
5516{
5517 int ret;
5518
5519 vos_ssr_protect(__func__);
5520 ret = __hdd_mon_open(dev);
5521 vos_ssr_unprotect(__func__);
5522
5523 return ret;
5524}
5525
Katya Nigame7b69a82015-04-28 15:24:06 +05305526int hdd_mon_stop(struct net_device *dev)
5527{
5528 return 0;
5529}
5530
Jeff Johnson295189b2012-06-20 16:38:30 -07005531/**---------------------------------------------------------------------------
5532
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305533 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005534
5535 \param - dev Pointer to net_device structure
5536
5537 \return - 0 for success non-zero for failure
5538
5539 --------------------------------------------------------------------------*/
5540
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305541int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005542{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305543 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5545 hdd_context_t *pHddCtx;
5546 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5547 VOS_STATUS status;
5548 v_BOOL_t enter_standby = TRUE;
5549
5550 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 if (NULL == pAdapter)
5552 {
5553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305554 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005555 return -ENODEV;
5556 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305557 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305558 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305559
5560 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5561 ret = wlan_hdd_validate_context(pHddCtx);
5562 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305564 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 }
5566
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305567 /* Nothing to be done if the interface is not opened */
5568 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5569 {
5570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5571 "%s: NETDEV Interface is not OPENED", __func__);
5572 return -ENODEV;
5573 }
5574
5575 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005576 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305578
5579 /* Disable TX on the interface, after this hard_start_xmit() will not
5580 * be called on that interface
5581 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305582 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305584
5585 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 netif_carrier_off(pAdapter->dev);
5587
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305588 /* The interface is marked as down for outside world (aka kernel)
5589 * But the driver is pretty much alive inside. The driver needs to
5590 * tear down the existing connection on the netdev (session)
5591 * cleanup the data pipes and wait until the control plane is stabilized
5592 * for this interface. The call also needs to wait until the above
5593 * mentioned actions are completed before returning to the caller.
5594 * Notice that the hdd_stop_adapter is requested not to close the session
5595 * That is intentional to be able to scan if it is a STA/P2P interface
5596 */
5597 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305598#ifdef FEATURE_WLAN_TDLS
5599 mutex_lock(&pHddCtx->tdls_lock);
5600#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305601 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305602 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305603#ifdef FEATURE_WLAN_TDLS
5604 mutex_unlock(&pHddCtx->tdls_lock);
5605#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 /* SoftAP ifaces should never go in power save mode
5607 making sure same here. */
5608 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5609 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 )
5612 {
5613 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5615 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 EXIT();
5617 return 0;
5618 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305619 /* Find if any iface is up. If any iface is up then can't put device to
5620 * sleep/power save mode
5621 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5623 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5624 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005625 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5626 {
5627 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305628 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005629 enter_standby = FALSE;
5630 break;
5631 }
5632 else
5633 {
5634 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5635 pAdapterNode = pNext;
5636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 }
5638
5639 if (TRUE == enter_standby)
5640 {
5641 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5642 "entering standby", __func__);
5643 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5644 {
5645 /*log and return success*/
5646 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5647 "wlan in power save", __func__);
5648 }
5649 }
5650
5651 EXIT();
5652 return 0;
5653}
5654
5655/**---------------------------------------------------------------------------
5656
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305657 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005658
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305659 This is called in response to ifconfig down
5660
5661 \param - dev Pointer to net_device structure
5662
5663 \return - 0 for success non-zero for failure
5664-----------------------------------------------------------------------------*/
5665int hdd_stop (struct net_device *dev)
5666{
5667 int ret;
5668
5669 vos_ssr_protect(__func__);
5670 ret = __hdd_stop(dev);
5671 vos_ssr_unprotect(__func__);
5672
5673 return ret;
5674}
5675
5676/**---------------------------------------------------------------------------
5677
5678 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005679
5680 \param - dev Pointer to net_device structure
5681
5682 \return - void
5683
5684 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305685static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005686{
5687 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305688 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 ENTER();
5690
5691 do
5692 {
5693 if (NULL == pAdapter)
5694 {
5695 hddLog(VOS_TRACE_LEVEL_FATAL,
5696 "%s: NULL pAdapter", __func__);
5697 break;
5698 }
5699
5700 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5701 {
5702 hddLog(VOS_TRACE_LEVEL_FATAL,
5703 "%s: Invalid magic", __func__);
5704 break;
5705 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305706 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5707 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005708 {
5709 hddLog(VOS_TRACE_LEVEL_FATAL,
5710 "%s: NULL pHddCtx", __func__);
5711 break;
5712 }
5713
5714 if (dev != pAdapter->dev)
5715 {
5716 hddLog(VOS_TRACE_LEVEL_FATAL,
5717 "%s: Invalid device reference", __func__);
5718 /* we haven't validated all cases so let this go for now */
5719 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305720#ifdef FEATURE_WLAN_TDLS
5721 mutex_lock(&pHddCtx->tdls_lock);
5722#endif
c_hpothu002231a2015-02-05 14:58:51 +05305723 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305724#ifdef FEATURE_WLAN_TDLS
5725 mutex_unlock(&pHddCtx->tdls_lock);
5726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005727
5728 /* after uninit our adapter structure will no longer be valid */
5729 pAdapter->dev = NULL;
5730 pAdapter->magic = 0;
5731 } while (0);
5732
5733 EXIT();
5734}
5735
5736/**---------------------------------------------------------------------------
5737
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305738 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5739
5740 This is called during the netdev unregister to uninitialize all data
5741associated with the device
5742
5743 \param - dev Pointer to net_device structure
5744
5745 \return - void
5746
5747 --------------------------------------------------------------------------*/
5748static void hdd_uninit (struct net_device *dev)
5749{
5750 vos_ssr_protect(__func__);
5751 __hdd_uninit(dev);
5752 vos_ssr_unprotect(__func__);
5753}
5754
5755/**---------------------------------------------------------------------------
5756
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 \brief hdd_release_firmware() -
5758
5759 This function calls the release firmware API to free the firmware buffer.
5760
5761 \param - pFileName Pointer to the File Name.
5762 pCtx - Pointer to the adapter .
5763
5764
5765 \return - 0 for success, non zero for failure
5766
5767 --------------------------------------------------------------------------*/
5768
5769VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5770{
5771 VOS_STATUS status = VOS_STATUS_SUCCESS;
5772 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5773 ENTER();
5774
5775
5776 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5777
5778 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5779
5780 if(pHddCtx->fw) {
5781 release_firmware(pHddCtx->fw);
5782 pHddCtx->fw = NULL;
5783 }
5784 else
5785 status = VOS_STATUS_E_FAILURE;
5786 }
5787 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5788 if(pHddCtx->nv) {
5789 release_firmware(pHddCtx->nv);
5790 pHddCtx->nv = NULL;
5791 }
5792 else
5793 status = VOS_STATUS_E_FAILURE;
5794
5795 }
5796
5797 EXIT();
5798 return status;
5799}
5800
5801/**---------------------------------------------------------------------------
5802
5803 \brief hdd_request_firmware() -
5804
5805 This function reads the firmware file using the request firmware
5806 API and returns the the firmware data and the firmware file size.
5807
5808 \param - pfileName - Pointer to the file name.
5809 - pCtx - Pointer to the adapter .
5810 - ppfw_data - Pointer to the pointer of the firmware data.
5811 - pSize - Pointer to the file size.
5812
5813 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5814
5815 --------------------------------------------------------------------------*/
5816
5817
5818VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5819{
5820 int status;
5821 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5822 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5823 ENTER();
5824
5825 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5826
5827 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5828
5829 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5830 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5831 __func__, pfileName);
5832 retval = VOS_STATUS_E_FAILURE;
5833 }
5834
5835 else {
5836 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5837 *pSize = pHddCtx->fw->size;
5838 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5839 __func__, *pSize);
5840 }
5841 }
5842 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5843
5844 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5845
5846 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5847 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5848 __func__, pfileName);
5849 retval = VOS_STATUS_E_FAILURE;
5850 }
5851
5852 else {
5853 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5854 *pSize = pHddCtx->nv->size;
5855 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5856 __func__, *pSize);
5857 }
5858 }
5859
5860 EXIT();
5861 return retval;
5862}
5863/**---------------------------------------------------------------------------
5864 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5865
5866 This is the function invoked by SME to inform the result of a full power
5867 request issued by HDD
5868
5869 \param - callbackcontext - Pointer to cookie
5870 status - result of request
5871
5872 \return - None
5873
5874--------------------------------------------------------------------------*/
5875void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5876{
5877 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5878
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005879 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 if(&pHddCtx->full_pwr_comp_var)
5881 {
5882 complete(&pHddCtx->full_pwr_comp_var);
5883 }
5884}
5885
5886/**---------------------------------------------------------------------------
5887
5888 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5889
5890 This is the function invoked by SME to inform the result of BMPS
5891 request issued by HDD
5892
5893 \param - callbackcontext - Pointer to cookie
5894 status - result of request
5895
5896 \return - None
5897
5898--------------------------------------------------------------------------*/
5899void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5900{
5901
5902 struct completion *completion_var = (struct completion*) callbackContext;
5903
Arif Hussain6d2a3322013-11-17 19:50:10 -08005904 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 if(completion_var != NULL)
5906 {
5907 complete(completion_var);
5908 }
5909}
5910
5911/**---------------------------------------------------------------------------
5912
5913 \brief hdd_get_cfg_file_size() -
5914
5915 This function reads the configuration file using the request firmware
5916 API and returns the configuration file size.
5917
5918 \param - pCtx - Pointer to the adapter .
5919 - pFileName - Pointer to the file name.
5920 - pBufSize - Pointer to the buffer size.
5921
5922 \return - 0 for success, non zero for failure
5923
5924 --------------------------------------------------------------------------*/
5925
5926VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5927{
5928 int status;
5929 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5930
5931 ENTER();
5932
5933 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5934
5935 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5936 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5937 status = VOS_STATUS_E_FAILURE;
5938 }
5939 else {
5940 *pBufSize = pHddCtx->fw->size;
5941 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5942 release_firmware(pHddCtx->fw);
5943 pHddCtx->fw = NULL;
5944 }
5945
5946 EXIT();
5947 return VOS_STATUS_SUCCESS;
5948}
5949
5950/**---------------------------------------------------------------------------
5951
5952 \brief hdd_read_cfg_file() -
5953
5954 This function reads the configuration file using the request firmware
5955 API and returns the cfg data and the buffer size of the configuration file.
5956
5957 \param - pCtx - Pointer to the adapter .
5958 - pFileName - Pointer to the file name.
5959 - pBuffer - Pointer to the data buffer.
5960 - pBufSize - Pointer to the buffer size.
5961
5962 \return - 0 for success, non zero for failure
5963
5964 --------------------------------------------------------------------------*/
5965
5966VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5967 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5968{
5969 int status;
5970 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5971
5972 ENTER();
5973
5974 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5975
5976 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5977 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5978 return VOS_STATUS_E_FAILURE;
5979 }
5980 else {
5981 if(*pBufSize != pHddCtx->fw->size) {
5982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5983 "file size", __func__);
5984 release_firmware(pHddCtx->fw);
5985 pHddCtx->fw = NULL;
5986 return VOS_STATUS_E_FAILURE;
5987 }
5988 else {
5989 if(pBuffer) {
5990 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5991 }
5992 release_firmware(pHddCtx->fw);
5993 pHddCtx->fw = NULL;
5994 }
5995 }
5996
5997 EXIT();
5998
5999 return VOS_STATUS_SUCCESS;
6000}
6001
6002/**---------------------------------------------------------------------------
6003
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306004 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006005
6006 This function sets the user specified mac address using
6007 the command ifconfig wlanX hw ether <mac adress>.
6008
6009 \param - dev - Pointer to the net device.
6010 - addr - Pointer to the sockaddr.
6011 \return - 0 for success, non zero for failure
6012
6013 --------------------------------------------------------------------------*/
6014
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306015static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006016{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306017 hdd_adapter_t *pAdapter;
6018 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 struct sockaddr *psta_mac_addr = addr;
6020 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306021 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006022
6023 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306024 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6025 if (NULL == pAdapter)
6026 {
6027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6028 "%s: Adapter is NULL",__func__);
6029 return -EINVAL;
6030 }
6031 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6032 ret = wlan_hdd_validate_context(pHddCtx);
6033 if (0 != ret)
6034 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306035 return ret;
6036 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006037
6038 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6040
6041 EXIT();
6042 return halStatus;
6043}
6044
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306045/**---------------------------------------------------------------------------
6046
6047 \brief hdd_set_mac_address() -
6048
6049 Wrapper function to protect __hdd_set_mac_address() function from ssr
6050
6051 \param - dev - Pointer to the net device.
6052 - addr - Pointer to the sockaddr.
6053 \return - 0 for success, non zero for failure
6054
6055 --------------------------------------------------------------------------*/
6056static int hdd_set_mac_address(struct net_device *dev, void *addr)
6057{
6058 int ret;
6059
6060 vos_ssr_protect(__func__);
6061 ret = __hdd_set_mac_address(dev, addr);
6062 vos_ssr_unprotect(__func__);
6063
6064 return ret;
6065}
6066
Jeff Johnson295189b2012-06-20 16:38:30 -07006067tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6068{
6069 int i;
6070 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6071 {
Abhishek Singheb183782014-02-06 13:37:21 +05306072 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 break;
6074 }
6075
6076 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6077 return NULL;
6078
6079 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6080 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6081}
6082
6083void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6084{
6085 int i;
6086 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6087 {
6088 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6089 {
6090 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6091 break;
6092 }
6093 }
6094 return;
6095}
6096
6097#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6098 static struct net_device_ops wlan_drv_ops = {
6099 .ndo_open = hdd_open,
6100 .ndo_stop = hdd_stop,
6101 .ndo_uninit = hdd_uninit,
6102 .ndo_start_xmit = hdd_hard_start_xmit,
6103 .ndo_tx_timeout = hdd_tx_timeout,
6104 .ndo_get_stats = hdd_stats,
6105 .ndo_do_ioctl = hdd_ioctl,
6106 .ndo_set_mac_address = hdd_set_mac_address,
6107 .ndo_select_queue = hdd_select_queue,
6108#ifdef WLAN_FEATURE_PACKET_FILTERING
6109#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6110 .ndo_set_rx_mode = hdd_set_multicast_list,
6111#else
6112 .ndo_set_multicast_list = hdd_set_multicast_list,
6113#endif //LINUX_VERSION_CODE
6114#endif
6115 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006116 static struct net_device_ops wlan_mon_drv_ops = {
6117 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306118 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 .ndo_uninit = hdd_uninit,
6120 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6121 .ndo_tx_timeout = hdd_tx_timeout,
6122 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306123 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 .ndo_set_mac_address = hdd_set_mac_address,
6125 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306126
Jeff Johnson295189b2012-06-20 16:38:30 -07006127#endif
6128
6129void hdd_set_station_ops( struct net_device *pWlanDev )
6130{
6131#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006132 pWlanDev->netdev_ops = &wlan_drv_ops;
6133#else
6134 pWlanDev->open = hdd_open;
6135 pWlanDev->stop = hdd_stop;
6136 pWlanDev->uninit = hdd_uninit;
6137 pWlanDev->hard_start_xmit = NULL;
6138 pWlanDev->tx_timeout = hdd_tx_timeout;
6139 pWlanDev->get_stats = hdd_stats;
6140 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006141 pWlanDev->set_mac_address = hdd_set_mac_address;
6142#endif
6143}
6144
Katya Nigam1fd24402015-02-16 14:52:19 +05306145void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6146{
6147 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6148 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6149 #else
6150 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6151 #endif
6152}
6153
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006154static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006155{
6156 struct net_device *pWlanDev = NULL;
6157 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 /*
6159 * cfg80211 initialization and registration....
6160 */
6161 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6162
Jeff Johnson295189b2012-06-20 16:38:30 -07006163 if(pWlanDev != NULL)
6164 {
6165
6166 //Save the pointer to the net_device in the HDD adapter
6167 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6168
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6170
6171 pAdapter->dev = pWlanDev;
6172 pAdapter->pHddCtx = pHddCtx;
6173 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306174 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006175
6176 init_completion(&pAdapter->session_open_comp_var);
6177 init_completion(&pAdapter->session_close_comp_var);
6178 init_completion(&pAdapter->disconnect_comp_var);
6179 init_completion(&pAdapter->linkup_event_var);
6180 init_completion(&pAdapter->cancel_rem_on_chan_var);
6181 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306182 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6184 init_completion(&pAdapter->offchannel_tx_event);
6185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006187#ifdef FEATURE_WLAN_TDLS
6188 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006189 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006190 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306191 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 init_completion(&pHddCtx->mc_sus_event_var);
6194 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306195 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006196 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006197 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006198
Rajeev79dbe4c2013-10-05 11:03:42 +05306199#ifdef FEATURE_WLAN_BATCH_SCAN
6200 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6201 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6202 pAdapter->pBatchScanRsp = NULL;
6203 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006204 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006205 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306206 mutex_init(&pAdapter->hdd_batch_scan_lock);
6207#endif
6208
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 pAdapter->isLinkUpSvcNeeded = FALSE;
6210 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6211 //Init the net_device structure
6212 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6213
6214 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6215 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6216 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6217 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6218
6219 hdd_set_station_ops( pAdapter->dev );
6220
6221 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6223 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6224 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 /* set pWlanDev's parent to underlying device */
6226 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006227
6228 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 }
6230
6231 return pAdapter;
6232}
6233
6234VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6235{
6236 struct net_device *pWlanDev = pAdapter->dev;
6237 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6238 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6239 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6240
6241 if( rtnl_lock_held )
6242 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006243 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6245 {
6246 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6247 return VOS_STATUS_E_FAILURE;
6248 }
6249 }
6250 if (register_netdevice(pWlanDev))
6251 {
6252 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6253 return VOS_STATUS_E_FAILURE;
6254 }
6255 }
6256 else
6257 {
6258 if(register_netdev(pWlanDev))
6259 {
6260 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6261 return VOS_STATUS_E_FAILURE;
6262 }
6263 }
6264 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6265
6266 return VOS_STATUS_SUCCESS;
6267}
6268
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006269static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006270{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006271 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006272
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006273 if (NULL == pAdapter)
6274 {
6275 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6276 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006278
6279 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6280 {
6281 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6282 return eHAL_STATUS_NOT_INITIALIZED;
6283 }
6284
6285 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6286
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006287#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006288 /* need to make sure all of our scheduled work has completed.
6289 * This callback is called from MC thread context, so it is safe to
6290 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006291 *
6292 * Even though this is called from MC thread context, if there is a faulty
6293 * work item in the system, that can hang this call forever. So flushing
6294 * this global work queue is not safe; and now we make sure that
6295 * individual work queues are stopped correctly. But the cancel work queue
6296 * is a GPL only API, so the proprietary version of the driver would still
6297 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006298 */
6299 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006300#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006301
6302 /* We can be blocked while waiting for scheduled work to be
6303 * flushed, and the adapter structure can potentially be freed, in
6304 * which case the magic will have been reset. So make sure the
6305 * magic is still good, and hence the adapter structure is still
6306 * valid, before signaling completion */
6307 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6308 {
6309 complete(&pAdapter->session_close_comp_var);
6310 }
6311
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 return eHAL_STATUS_SUCCESS;
6313}
6314
6315VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6316{
6317 struct net_device *pWlanDev = pAdapter->dev;
6318 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6319 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6320 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6321 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306322 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006323
Nirav Shah7e3c8132015-06-22 23:51:42 +05306324 spin_lock_init( &pAdapter->sta_hash_lock);
6325 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6326
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006328 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 //Open a SME session for future operation
6330 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006331 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6333 {
6334 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006335 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 halStatus, halStatus );
6337 status = VOS_STATUS_E_FAILURE;
6338 goto error_sme_open;
6339 }
6340
6341 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306342 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 &pAdapter->session_open_comp_var,
6344 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306345 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 {
6347 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306348 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 status = VOS_STATUS_E_FAILURE;
6350 goto error_sme_open;
6351 }
6352
6353 // Register wireless extensions
6354 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6355 {
6356 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006357 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 halStatus, halStatus );
6359 status = VOS_STATUS_E_FAILURE;
6360 goto error_register_wext;
6361 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306362
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306364 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6365 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6366 #else
6367 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6368 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006369
6370 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306371 hddLog(VOS_TRACE_LEVEL_INFO,
6372 "%s: Set HDD connState to eConnectionState_NotConnected",
6373 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6375
6376 //Set the default operation channel
6377 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6378
6379 /* Make the default Auth Type as OPEN*/
6380 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6381
6382 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6383 {
6384 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006385 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 status, status );
6387 goto error_init_txrx;
6388 }
6389
6390 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6391
6392 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6393 {
6394 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006395 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 status, status );
6397 goto error_wmm_init;
6398 }
6399
6400 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6401
6402 return VOS_STATUS_SUCCESS;
6403
6404error_wmm_init:
6405 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6406 hdd_deinit_tx_rx(pAdapter);
6407error_init_txrx:
6408 hdd_UnregisterWext(pWlanDev);
6409error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006410 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 {
6412 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006413 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306414 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006415 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306417 unsigned long rc;
6418
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306420 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006422 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306423 if (rc <= 0)
6424 hddLog(VOS_TRACE_LEVEL_ERROR,
6425 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 }
6427}
6428error_sme_open:
6429 return status;
6430}
6431
Jeff Johnson295189b2012-06-20 16:38:30 -07006432void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6433{
6434 hdd_cfg80211_state_t *cfgState;
6435
6436 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6437
6438 if( NULL != cfgState->buf )
6439 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306440 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6442 rc = wait_for_completion_interruptible_timeout(
6443 &pAdapter->tx_action_cnf_event,
6444 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306445 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306448 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6449 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 }
6451 }
6452 return;
6453}
Jeff Johnson295189b2012-06-20 16:38:30 -07006454
c_hpothu002231a2015-02-05 14:58:51 +05306455void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006456{
6457 ENTER();
6458 switch ( pAdapter->device_mode )
6459 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306460 case WLAN_HDD_IBSS:
6461 {
6462 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6463 {
6464 hdd_ibss_deinit_tx_rx( pAdapter );
6465 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6466 }
6467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 case WLAN_HDD_INFRA_STATION:
6469 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006470 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 {
6472 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6473 {
6474 hdd_deinit_tx_rx( pAdapter );
6475 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6476 }
6477
6478 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6479 {
6480 hdd_wmm_adapter_close( pAdapter );
6481 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6482 }
6483
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 break;
6486 }
6487
6488 case WLAN_HDD_SOFTAP:
6489 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306491
6492 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6493 {
6494 hdd_wmm_adapter_close( pAdapter );
6495 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6496 }
6497
Jeff Johnson295189b2012-06-20 16:38:30 -07006498 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006499
c_hpothu002231a2015-02-05 14:58:51 +05306500 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006501 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 break;
6503 }
6504
6505 case WLAN_HDD_MONITOR:
6506 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6508 {
6509 hdd_deinit_tx_rx( pAdapter );
6510 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6511 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 break;
6513 }
6514
6515
6516 default:
6517 break;
6518 }
6519
6520 EXIT();
6521}
6522
6523void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6524{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006525 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306526
6527 ENTER();
6528 if (NULL == pAdapter)
6529 {
6530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6531 "%s: HDD adapter is Null", __func__);
6532 return;
6533 }
6534
6535 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006536
Rajeev79dbe4c2013-10-05 11:03:42 +05306537#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306538 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6539 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006540 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306541 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6542 )
6543 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006544 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306545 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006546 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6547 {
6548 hdd_deinit_batch_scan(pAdapter);
6549 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306550 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006551 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306552#endif
6553
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6555 if( rtnl_held )
6556 {
6557 unregister_netdevice(pWlanDev);
6558 }
6559 else
6560 {
6561 unregister_netdev(pWlanDev);
6562 }
6563 // note that the pAdapter is no longer valid at this point
6564 // since the memory has been reclaimed
6565 }
6566
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306567 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006568}
6569
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006570void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6571{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306572 VOS_STATUS status;
6573 hdd_adapter_t *pAdapter = NULL;
6574 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006575
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306576 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006577
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306578 /*loop through all adapters.*/
6579 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006580 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306581 pAdapter = pAdapterNode->pAdapter;
6582 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6583 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006584
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306585 { // we skip this registration for modes other than STA and P2P client modes.
6586 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6587 pAdapterNode = pNext;
6588 continue;
6589 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006590
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306591 //Apply Dynamic DTIM For P2P
6592 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6593 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6594 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6595 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6596 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6597 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6598 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6599 (eConnectionState_Associated ==
6600 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6601 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6602 {
6603 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006604
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306605 powerRequest.uIgnoreDTIM = 1;
6606 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6607
6608 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6609 {
6610 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6611 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6612 }
6613 else
6614 {
6615 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6616 }
6617
6618 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6619 * specified during Enter/Exit BMPS when LCD off*/
6620 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6621 NULL, eANI_BOOLEAN_FALSE);
6622 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6623 NULL, eANI_BOOLEAN_FALSE);
6624
6625 /* switch to the DTIM specified in cfg.ini */
6626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6627 "Switch to DTIM %d", powerRequest.uListenInterval);
6628 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6629 break;
6630
6631 }
6632
6633 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6634 pAdapterNode = pNext;
6635 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006636}
6637
6638void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6639{
6640 /*Switch back to DTIM 1*/
6641 tSirSetPowerParamsReq powerRequest = { 0 };
6642
6643 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6644 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006645 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006646
6647 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6648 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6649 NULL, eANI_BOOLEAN_FALSE);
6650 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6651 NULL, eANI_BOOLEAN_FALSE);
6652
6653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6654 "Switch to DTIM%d",powerRequest.uListenInterval);
6655 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6656
6657}
6658
Jeff Johnson295189b2012-06-20 16:38:30 -07006659VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6660{
6661 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306662 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6663 {
6664 hddLog( LOGE, FL("Wlan Unload in progress"));
6665 return VOS_STATUS_E_PERM;
6666 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6668 {
6669 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6670 }
6671
6672 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6673 {
6674 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6675 }
6676
6677 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6678 {
6679 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6680 }
6681
6682 return status;
6683}
6684
6685VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6686{
6687 hdd_adapter_t *pAdapter = NULL;
6688 eHalStatus halStatus;
6689 VOS_STATUS status = VOS_STATUS_E_INVAL;
6690 v_BOOL_t disableBmps = FALSE;
6691 v_BOOL_t disableImps = FALSE;
6692
6693 switch(session_type)
6694 {
6695 case WLAN_HDD_INFRA_STATION:
6696 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 case WLAN_HDD_P2P_CLIENT:
6698 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 //Exit BMPS -> Is Sta/P2P Client is already connected
6700 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6701 if((NULL != pAdapter)&&
6702 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6703 {
6704 disableBmps = TRUE;
6705 }
6706
6707 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6708 if((NULL != pAdapter)&&
6709 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6710 {
6711 disableBmps = TRUE;
6712 }
6713
6714 //Exit both Bmps and Imps incase of Go/SAP Mode
6715 if((WLAN_HDD_SOFTAP == session_type) ||
6716 (WLAN_HDD_P2P_GO == session_type))
6717 {
6718 disableBmps = TRUE;
6719 disableImps = TRUE;
6720 }
6721
6722 if(TRUE == disableImps)
6723 {
6724 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6725 {
6726 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6727 }
6728 }
6729
6730 if(TRUE == disableBmps)
6731 {
6732 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6733 {
6734 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6735
6736 if(eHAL_STATUS_SUCCESS != halStatus)
6737 {
6738 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006739 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 VOS_ASSERT(0);
6741 return status;
6742 }
6743 }
6744
6745 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6746 {
6747 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6748
6749 if(eHAL_STATUS_SUCCESS != halStatus)
6750 {
6751 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006752 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006753 VOS_ASSERT(0);
6754 return status;
6755 }
6756 }
6757 }
6758
6759 if((TRUE == disableBmps) ||
6760 (TRUE == disableImps))
6761 {
6762 /* Now, get the chip into Full Power now */
6763 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6764 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6765 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6766
6767 if(halStatus != eHAL_STATUS_SUCCESS)
6768 {
6769 if(halStatus == eHAL_STATUS_PMC_PENDING)
6770 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306771 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306773 ret = wait_for_completion_interruptible_timeout(
6774 &pHddCtx->full_pwr_comp_var,
6775 msecs_to_jiffies(1000));
6776 if (ret <= 0)
6777 {
6778 hddLog(VOS_TRACE_LEVEL_ERROR,
6779 "%s: wait on full_pwr_comp_var failed %ld",
6780 __func__, ret);
6781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 }
6783 else
6784 {
6785 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006786 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 VOS_ASSERT(0);
6788 return status;
6789 }
6790 }
6791
6792 status = VOS_STATUS_SUCCESS;
6793 }
6794
6795 break;
6796 }
6797 return status;
6798}
Katya Nigame7b69a82015-04-28 15:24:06 +05306799void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6800 {
6801 hdd_mon_ctx_t *pMonCtx = NULL;
6802 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6803
6804 pMonCtx->state = 0;
6805 pMonCtx->ChannelNo = 1;
6806 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306807 pMonCtx->crcCheckEnabled = 1;
6808 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6809 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306810 pMonCtx->numOfMacFilters = 0;
6811 }
6812
Jeff Johnson295189b2012-06-20 16:38:30 -07006813
6814hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006815 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 tANI_U8 rtnl_held )
6817{
6818 hdd_adapter_t *pAdapter = NULL;
6819 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6820 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6821 VOS_STATUS exitbmpsStatus;
6822
Arif Hussain6d2a3322013-11-17 19:50:10 -08006823 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006824
Nirav Shah436658f2014-02-28 17:05:45 +05306825 if(macAddr == NULL)
6826 {
6827 /* Not received valid macAddr */
6828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6829 "%s:Unable to add virtual intf: Not able to get"
6830 "valid mac address",__func__);
6831 return NULL;
6832 }
6833
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 //Disable BMPS incase of Concurrency
6835 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6836
6837 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6838 {
6839 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306840 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 VOS_ASSERT(0);
6842 return NULL;
6843 }
6844
6845 switch(session_type)
6846 {
6847 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006849 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 {
6851 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6852
6853 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306854 {
6855 hddLog(VOS_TRACE_LEVEL_FATAL,
6856 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306858 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006859
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306860#ifdef FEATURE_WLAN_TDLS
6861 /* A Mutex Lock is introduced while changing/initializing the mode to
6862 * protect the concurrent access for the Adapters by TDLS module.
6863 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306864 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306865#endif
6866
Jeff Johnsone7245742012-09-05 17:12:55 -07006867 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6868 NL80211_IFTYPE_P2P_CLIENT:
6869 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006870
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306872#ifdef FEATURE_WLAN_TDLS
6873 mutex_unlock(&pHddCtx->tdls_lock);
6874#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306875
6876 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 if( VOS_STATUS_SUCCESS != status )
6878 goto err_free_netdev;
6879
6880 status = hdd_register_interface( pAdapter, rtnl_held );
6881 if( VOS_STATUS_SUCCESS != status )
6882 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306883#ifdef FEATURE_WLAN_TDLS
6884 mutex_lock(&pHddCtx->tdls_lock);
6885#endif
c_hpothu002231a2015-02-05 14:58:51 +05306886 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306887#ifdef FEATURE_WLAN_TDLS
6888 mutex_unlock(&pHddCtx->tdls_lock);
6889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006890 goto err_free_netdev;
6891 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306892
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306893 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306894 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306895
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306896#ifdef WLAN_NS_OFFLOAD
6897 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306898 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306899#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 netif_tx_disable(pAdapter->dev);
6903 //netif_tx_disable(pWlanDev);
6904 netif_carrier_off(pAdapter->dev);
6905
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306906 if (WLAN_HDD_P2P_CLIENT == session_type ||
6907 WLAN_HDD_P2P_DEVICE == session_type)
6908 {
6909 /* Initialize the work queue to defer the
6910 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306911 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306912 hdd_p2p_roc_work_queue);
6913 }
6914
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 break;
6916 }
6917
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 case WLAN_HDD_SOFTAP:
6920 {
6921 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6922 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306923 {
6924 hddLog(VOS_TRACE_LEVEL_FATAL,
6925 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006928
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6930 NL80211_IFTYPE_AP:
6931 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 pAdapter->device_mode = session_type;
6933
6934 status = hdd_init_ap_mode(pAdapter);
6935 if( VOS_STATUS_SUCCESS != status )
6936 goto err_free_netdev;
6937
Nirav Shah7e3c8132015-06-22 23:51:42 +05306938 status = hdd_sta_id_hash_attach(pAdapter);
6939 if (VOS_STATUS_SUCCESS != status)
6940 {
6941 hddLog(VOS_TRACE_LEVEL_FATAL,
6942 FL("failed to attach hash for session %d"), session_type);
6943 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6944 goto err_free_netdev;
6945 }
6946
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 status = hdd_register_hostapd( pAdapter, rtnl_held );
6948 if( VOS_STATUS_SUCCESS != status )
6949 {
c_hpothu002231a2015-02-05 14:58:51 +05306950 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 goto err_free_netdev;
6952 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306953 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 netif_tx_disable(pAdapter->dev);
6955 netif_carrier_off(pAdapter->dev);
6956
6957 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306958
6959 if (WLAN_HDD_P2P_GO == session_type)
6960 {
6961 /* Initialize the work queue to
6962 * defer the back to back RoC request */
6963 INIT_DELAYED_WORK(&pAdapter->roc_work,
6964 hdd_p2p_roc_work_queue);
6965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 break;
6967 }
6968 case WLAN_HDD_MONITOR:
6969 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6971 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306972 {
6973 hddLog(VOS_TRACE_LEVEL_FATAL,
6974 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306976 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006977
Katya Nigame7b69a82015-04-28 15:24:06 +05306978 // Register wireless extensions
6979 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6980 {
6981 hddLog(VOS_TRACE_LEVEL_FATAL,
6982 "hdd_register_wext() failed with status code %08d [x%08x]",
6983 status, status );
6984 status = VOS_STATUS_E_FAILURE;
6985 }
6986
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6988 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006989#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6990 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6991#else
6992 pAdapter->dev->open = hdd_mon_open;
6993 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306994 pAdapter->dev->stop = hdd_mon_stop;
6995 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006996#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05306997 status = hdd_register_interface( pAdapter, rtnl_held );
6998 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 hdd_init_tx_rx( pAdapter );
7000 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307001 //Stop the Interface TX queue.
7002 netif_tx_disable(pAdapter->dev);
7003 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 }
7005 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 case WLAN_HDD_FTM:
7007 {
7008 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7009
7010 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307011 {
7012 hddLog(VOS_TRACE_LEVEL_FATAL,
7013 FL("failed to allocate adapter for session %d"), session_type);
7014 return NULL;
7015 }
7016
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7018 * message while loading driver in FTM mode. */
7019 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7020 pAdapter->device_mode = session_type;
7021 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307022
7023 hdd_init_tx_rx( pAdapter );
7024
7025 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307026 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307027 netif_tx_disable(pAdapter->dev);
7028 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 }
7030 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 default:
7032 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307033 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7034 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 VOS_ASSERT(0);
7036 return NULL;
7037 }
7038 }
7039
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 if( VOS_STATUS_SUCCESS == status )
7041 {
7042 //Add it to the hdd's session list.
7043 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7044 if( NULL == pHddAdapterNode )
7045 {
7046 status = VOS_STATUS_E_NOMEM;
7047 }
7048 else
7049 {
7050 pHddAdapterNode->pAdapter = pAdapter;
7051 status = hdd_add_adapter_back ( pHddCtx,
7052 pHddAdapterNode );
7053 }
7054 }
7055
7056 if( VOS_STATUS_SUCCESS != status )
7057 {
7058 if( NULL != pAdapter )
7059 {
7060 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7061 pAdapter = NULL;
7062 }
7063 if( NULL != pHddAdapterNode )
7064 {
7065 vos_mem_free( pHddAdapterNode );
7066 }
7067
7068 goto resume_bmps;
7069 }
7070
7071 if(VOS_STATUS_SUCCESS == status)
7072 {
7073 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7074
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007075 //Initialize the WoWL service
7076 if(!hdd_init_wowl(pAdapter))
7077 {
7078 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7079 goto err_free_netdev;
7080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007082 return pAdapter;
7083
7084err_free_netdev:
7085 free_netdev(pAdapter->dev);
7086 wlan_hdd_release_intf_addr( pHddCtx,
7087 pAdapter->macAddressCurrent.bytes );
7088
7089resume_bmps:
7090 //If bmps disabled enable it
7091 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7092 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307093 if (pHddCtx->hdd_wlan_suspended)
7094 {
7095 hdd_set_pwrparams(pHddCtx);
7096 }
7097 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 }
7099 return NULL;
7100}
7101
7102VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7103 tANI_U8 rtnl_held )
7104{
7105 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7106 VOS_STATUS status;
7107
7108 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7109 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307110 {
7111 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7112 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007115
7116 while ( pCurrent->pAdapter != pAdapter )
7117 {
7118 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7119 if( VOS_STATUS_SUCCESS != status )
7120 break;
7121
7122 pCurrent = pNext;
7123 }
7124 pAdapterNode = pCurrent;
7125 if( VOS_STATUS_SUCCESS == status )
7126 {
7127 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7128 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307129
7130#ifdef FEATURE_WLAN_TDLS
7131
7132 /* A Mutex Lock is introduced while changing/initializing the mode to
7133 * protect the concurrent access for the Adapters by TDLS module.
7134 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307135 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307136#endif
7137
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 hdd_remove_adapter( pHddCtx, pAdapterNode );
7139 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007140 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007141
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307142#ifdef FEATURE_WLAN_TDLS
7143 mutex_unlock(&pHddCtx->tdls_lock);
7144#endif
7145
Jeff Johnson295189b2012-06-20 16:38:30 -07007146
7147 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307148 if ((!vos_concurrent_open_sessions_running()) &&
7149 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7150 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307152 if (pHddCtx->hdd_wlan_suspended)
7153 {
7154 hdd_set_pwrparams(pHddCtx);
7155 }
7156 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007157 }
7158
7159 return VOS_STATUS_SUCCESS;
7160 }
7161
7162 return VOS_STATUS_E_FAILURE;
7163}
7164
7165VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7166{
7167 hdd_adapter_list_node_t *pHddAdapterNode;
7168 VOS_STATUS status;
7169
7170 ENTER();
7171
7172 do
7173 {
7174 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7175 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7176 {
7177 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7178 vos_mem_free( pHddAdapterNode );
7179 }
7180 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7181
7182 EXIT();
7183
7184 return VOS_STATUS_SUCCESS;
7185}
7186
7187void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7188{
7189 v_U8_t addIE[1] = {0};
7190
7191 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7192 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7193 eANI_BOOLEAN_FALSE) )
7194 {
7195 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007196 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007197 }
7198
7199 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7200 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7201 eANI_BOOLEAN_FALSE) )
7202 {
7203 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007204 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007205 }
7206
7207 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7208 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7209 eANI_BOOLEAN_FALSE) )
7210 {
7211 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007212 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 }
7214}
7215
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307216VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7217 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007218{
7219 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7220 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307221 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307223 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307224 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307225 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007226
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307227 if (pHddCtx->isLogpInProgress) {
7228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7229 "%s:LOGP in Progress. Ignore!!!",__func__);
7230 return VOS_STATUS_E_FAILURE;
7231 }
7232
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307234
Nirav Shah7e3c8132015-06-22 23:51:42 +05307235 status = hdd_sta_id_hash_detach(pAdapter);
7236 if (status != VOS_STATUS_SUCCESS)
7237 hddLog(VOS_TRACE_LEVEL_ERROR,
7238 FL("sta id hash detach failed"));
7239
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307240 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007241 switch(pAdapter->device_mode)
7242 {
7243 case WLAN_HDD_INFRA_STATION:
7244 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007245 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307246 {
7247 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307248#ifdef FEATURE_WLAN_TDLS
7249 mutex_lock(&pHddCtx->tdls_lock);
7250 wlan_hdd_tdls_exit(pAdapter, TRUE);
7251 mutex_unlock(&pHddCtx->tdls_lock);
7252#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307253 if( hdd_connIsConnected(pstation) ||
7254 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 {
7256 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7257 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7258 pAdapter->sessionId,
7259 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7260 else
7261 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7262 pAdapter->sessionId,
7263 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7264 //success implies disconnect command got queued up successfully
7265 if(halStatus == eHAL_STATUS_SUCCESS)
7266 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307267 ret = wait_for_completion_interruptible_timeout(
7268 &pAdapter->disconnect_comp_var,
7269 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7270 if (ret <= 0)
7271 {
7272 hddLog(VOS_TRACE_LEVEL_ERROR,
7273 "%s: wait on disconnect_comp_var failed %ld",
7274 __func__, ret);
7275 }
7276 }
7277 else
7278 {
7279 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7280 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007281 }
7282 memset(&wrqu, '\0', sizeof(wrqu));
7283 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7284 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7285 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7286 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307287 else if(pstation->conn_info.connState ==
7288 eConnectionState_Disconnecting)
7289 {
7290 ret = wait_for_completion_interruptible_timeout(
7291 &pAdapter->disconnect_comp_var,
7292 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7293 if (ret <= 0)
7294 {
7295 hddLog(VOS_TRACE_LEVEL_ERROR,
7296 FL("wait on disconnect_comp_var failed %ld"), ret);
7297 }
7298 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307299 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307301 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307302 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307304 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7305 {
7306 while (pAdapter->is_roc_inprogress)
7307 {
7308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7309 "%s: ROC in progress for session %d!!!",
7310 __func__, pAdapter->sessionId);
7311 // waiting for ROC to expire
7312 msleep(500);
7313 /* In GO present case , if retry exceeds 3,
7314 it means something went wrong. */
7315 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7316 {
7317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7318 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307319 if (eHAL_STATUS_SUCCESS !=
7320 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7321 pAdapter->sessionId ))
7322 {
7323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7324 FL("Failed to Cancel Remain on Channel"));
7325 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307326 wait_for_completion_interruptible_timeout(
7327 &pAdapter->cancel_rem_on_chan_var,
7328 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7329 break;
7330 }
7331 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307332 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307333 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307334#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307335 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307336#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307337
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307338 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307339
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307340 /* It is possible that the caller of this function does not
7341 * wish to close the session
7342 */
7343 if (VOS_TRUE == bCloseSession &&
7344 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 {
7346 INIT_COMPLETION(pAdapter->session_close_comp_var);
7347 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307348 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307349 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307351 unsigned long ret;
7352
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307354 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307355 &pAdapter->session_close_comp_var,
7356 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307357 if ( 0 >= ret)
7358 {
7359 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307360 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 }
7363 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 break;
7366
7367 case WLAN_HDD_SOFTAP:
7368 case WLAN_HDD_P2P_GO:
7369 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307370 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7371 while (pAdapter->is_roc_inprogress) {
7372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7373 "%s: ROC in progress for session %d!!!",
7374 __func__, pAdapter->sessionId);
7375 msleep(500);
7376 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7378 "%s: ROC completion is not received.!!!", __func__);
7379 WLANSAP_CancelRemainOnChannel(
7380 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7381 wait_for_completion_interruptible_timeout(
7382 &pAdapter->cancel_rem_on_chan_var,
7383 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7384 break;
7385 }
7386 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307387
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307388 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007390 mutex_lock(&pHddCtx->sap_lock);
7391 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7392 {
7393 VOS_STATUS status;
7394 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7395
7396 //Stop Bss.
7397 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7398 if (VOS_IS_STATUS_SUCCESS(status))
7399 {
7400 hdd_hostapd_state_t *pHostapdState =
7401 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7402
7403 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7404
7405 if (!VOS_IS_STATUS_SUCCESS(status))
7406 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307407 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7408 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 }
7410 }
7411 else
7412 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007413 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007414 }
7415 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307416 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007417
7418 if (eHAL_STATUS_FAILURE ==
7419 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7420 0, NULL, eANI_BOOLEAN_FALSE))
7421 {
7422 hddLog(LOGE,
7423 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007424 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007425 }
7426
7427 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7428 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7429 eANI_BOOLEAN_FALSE) )
7430 {
7431 hddLog(LOGE,
7432 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7433 }
7434
7435 // Reset WNI_CFG_PROBE_RSP Flags
7436 wlan_hdd_reset_prob_rspies(pAdapter);
7437 kfree(pAdapter->sessionCtx.ap.beacon);
7438 pAdapter->sessionCtx.ap.beacon = NULL;
7439 }
7440 mutex_unlock(&pHddCtx->sap_lock);
7441 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007442
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 case WLAN_HDD_MONITOR:
7444 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007445
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 default:
7447 break;
7448 }
7449
7450 EXIT();
7451 return VOS_STATUS_SUCCESS;
7452}
7453
7454VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7455{
7456 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7457 VOS_STATUS status;
7458 hdd_adapter_t *pAdapter;
7459
7460 ENTER();
7461
7462 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7463
7464 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7465 {
7466 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007467
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307468 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007469
7470 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7471 pAdapterNode = pNext;
7472 }
7473
7474 EXIT();
7475
7476 return VOS_STATUS_SUCCESS;
7477}
7478
Rajeev Kumarf999e582014-01-09 17:33:29 -08007479
7480#ifdef FEATURE_WLAN_BATCH_SCAN
7481/**---------------------------------------------------------------------------
7482
7483 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7484 structures
7485
7486 \param - pAdapter Pointer to HDD adapter
7487
7488 \return - None
7489
7490 --------------------------------------------------------------------------*/
7491void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7492{
7493 tHddBatchScanRsp *pNode;
7494 tHddBatchScanRsp *pPrev;
7495
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307496 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007497 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307498 hddLog(VOS_TRACE_LEVEL_ERROR,
7499 "%s: Adapter context is Null", __func__);
7500 return;
7501 }
7502
7503 pNode = pAdapter->pBatchScanRsp;
7504 while (pNode)
7505 {
7506 pPrev = pNode;
7507 pNode = pNode->pNext;
7508 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007509 }
7510
7511 pAdapter->pBatchScanRsp = NULL;
7512 pAdapter->numScanList = 0;
7513 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7514 pAdapter->prev_batch_id = 0;
7515
7516 return;
7517}
7518#endif
7519
7520
Jeff Johnson295189b2012-06-20 16:38:30 -07007521VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7522{
7523 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7524 VOS_STATUS status;
7525 hdd_adapter_t *pAdapter;
7526
7527 ENTER();
7528
7529 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7530
7531 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7532 {
7533 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307534 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 netif_tx_disable(pAdapter->dev);
7536 netif_carrier_off(pAdapter->dev);
7537
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007538 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7539
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307541
Katya Nigam1fd24402015-02-16 14:52:19 +05307542 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7543 hdd_ibss_deinit_tx_rx(pAdapter);
7544
Nirav Shah7e3c8132015-06-22 23:51:42 +05307545 status = hdd_sta_id_hash_detach(pAdapter);
7546 if (status != VOS_STATUS_SUCCESS)
7547 hddLog(VOS_TRACE_LEVEL_ERROR,
7548 FL("sta id hash detach failed for session id %d"),
7549 pAdapter->sessionId);
7550
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307551 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7552
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307553 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7554 {
7555 hdd_wmm_adapter_close( pAdapter );
7556 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007558
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307559 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7560 {
7561 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7562 }
7563
Rajeev Kumarf999e582014-01-09 17:33:29 -08007564#ifdef FEATURE_WLAN_BATCH_SCAN
7565 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7566 {
7567 hdd_deinit_batch_scan(pAdapter);
7568 }
7569#endif
7570
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307571#ifdef FEATURE_WLAN_TDLS
7572 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307573 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307574 mutex_unlock(&pHddCtx->tdls_lock);
7575#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7577 pAdapterNode = pNext;
7578 }
7579
7580 EXIT();
7581
7582 return VOS_STATUS_SUCCESS;
7583}
7584
7585VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7586{
7587 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7588 VOS_STATUS status;
7589 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307590 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007591
7592 ENTER();
7593
7594 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7595
7596 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7597 {
7598 pAdapter = pAdapterNode->pAdapter;
7599
Kumar Anand82c009f2014-05-29 00:29:42 -07007600 hdd_wmm_init( pAdapter );
7601
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 switch(pAdapter->device_mode)
7603 {
7604 case WLAN_HDD_INFRA_STATION:
7605 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007606 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307607
7608 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7609
Jeff Johnson295189b2012-06-20 16:38:30 -07007610 hdd_init_station_mode(pAdapter);
7611 /* Open the gates for HDD to receive Wext commands */
7612 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007613 pHddCtx->scan_info.mScanPending = FALSE;
7614 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007615
7616 //Trigger the initial scan
7617 hdd_wlan_initial_scan(pAdapter);
7618
7619 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307620 if (eConnectionState_Associated == connState ||
7621 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 {
7623 union iwreq_data wrqu;
7624 memset(&wrqu, '\0', sizeof(wrqu));
7625 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7626 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7627 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007628 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007629
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 /* indicate disconnected event to nl80211 */
7631 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7632 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307634 else if (eConnectionState_Connecting == connState)
7635 {
7636 /*
7637 * Indicate connect failure to supplicant if we were in the
7638 * process of connecting
7639 */
7640 cfg80211_connect_result(pAdapter->dev, NULL,
7641 NULL, 0, NULL, 0,
7642 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7643 GFP_KERNEL);
7644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 break;
7646
7647 case WLAN_HDD_SOFTAP:
7648 /* softAP can handle SSR */
7649 break;
7650
7651 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007653 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007654 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 break;
7656
7657 case WLAN_HDD_MONITOR:
7658 /* monitor interface start */
7659 break;
7660 default:
7661 break;
7662 }
7663
7664 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7665 pAdapterNode = pNext;
7666 }
7667
7668 EXIT();
7669
7670 return VOS_STATUS_SUCCESS;
7671}
7672
7673VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7674{
7675 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7676 hdd_adapter_t *pAdapter;
7677 VOS_STATUS status;
7678 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307679 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007680
7681 ENTER();
7682
7683 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7684
7685 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7686 {
7687 pAdapter = pAdapterNode->pAdapter;
7688
7689 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7690 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7691 {
7692 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7693 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7694
Abhishek Singhf4669da2014-05-26 15:07:49 +05307695 hddLog(VOS_TRACE_LEVEL_INFO,
7696 "%s: Set HDD connState to eConnectionState_NotConnected",
7697 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7699 init_completion(&pAdapter->disconnect_comp_var);
7700 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7701 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7702
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307703 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007704 &pAdapter->disconnect_comp_var,
7705 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307706 if (0 >= ret)
7707 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7708 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007709
7710 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7711 pHddCtx->isAmpAllowed = VOS_FALSE;
7712 sme_RoamConnect(pHddCtx->hHal,
7713 pAdapter->sessionId, &(pWextState->roamProfile),
7714 &roamId);
7715 }
7716
7717 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7718 pAdapterNode = pNext;
7719 }
7720
7721 EXIT();
7722
7723 return VOS_STATUS_SUCCESS;
7724}
7725
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007726void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7727{
7728 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7729 VOS_STATUS status;
7730 hdd_adapter_t *pAdapter;
7731 hdd_station_ctx_t *pHddStaCtx;
7732 hdd_ap_ctx_t *pHddApCtx;
7733 hdd_hostapd_state_t * pHostapdState;
7734 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7735 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7736 const char *p2pMode = "DEV";
7737 const char *ccMode = "Standalone";
7738 int n;
7739
7740 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7741 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7742 {
7743 pAdapter = pAdapterNode->pAdapter;
7744 switch (pAdapter->device_mode) {
7745 case WLAN_HDD_INFRA_STATION:
7746 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7747 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7748 staChannel = pHddStaCtx->conn_info.operationChannel;
7749 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7750 }
7751 break;
7752 case WLAN_HDD_P2P_CLIENT:
7753 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7754 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7755 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7756 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7757 p2pMode = "CLI";
7758 }
7759 break;
7760 case WLAN_HDD_P2P_GO:
7761 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7762 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7763 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7764 p2pChannel = pHddApCtx->operatingChannel;
7765 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7766 }
7767 p2pMode = "GO";
7768 break;
7769 case WLAN_HDD_SOFTAP:
7770 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7771 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7772 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7773 apChannel = pHddApCtx->operatingChannel;
7774 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7775 }
7776 break;
7777 default:
7778 break;
7779 }
7780 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7781 pAdapterNode = pNext;
7782 }
7783 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7784 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7785 }
7786 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7787 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7788 if (p2pChannel > 0) {
7789 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7790 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7791 }
7792 if (apChannel > 0) {
7793 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7794 apChannel, MAC_ADDR_ARRAY(apBssid));
7795 }
7796
7797 if (p2pChannel > 0 && apChannel > 0) {
7798 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7799 }
7800}
7801
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007802bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007803{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007804 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007805}
7806
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007807/* Once SSR is disabled then it cannot be set. */
7808void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007809{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007810 if (HDD_SSR_DISABLED == isSsrRequired)
7811 return;
7812
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 isSsrRequired = value;
7814}
7815
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307816void hdd_set_pre_close( hdd_context_t *pHddCtx)
7817{
7818 sme_PreClose(pHddCtx->hHal);
7819}
7820
Jeff Johnson295189b2012-06-20 16:38:30 -07007821VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7822 hdd_adapter_list_node_t** ppAdapterNode)
7823{
7824 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307825 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007826 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7827 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307828 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 return status;
7830}
7831
7832VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7833 hdd_adapter_list_node_t* pAdapterNode,
7834 hdd_adapter_list_node_t** pNextAdapterNode)
7835{
7836 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307837 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7839 (hdd_list_node_t*) pAdapterNode,
7840 (hdd_list_node_t**)pNextAdapterNode );
7841
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307842 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 return status;
7844}
7845
7846VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7847 hdd_adapter_list_node_t* pAdapterNode)
7848{
7849 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307850 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007851 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7852 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307853 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 return status;
7855}
7856
7857VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7858 hdd_adapter_list_node_t** ppAdapterNode)
7859{
7860 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307861 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007862 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7863 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307864 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 return status;
7866}
7867
7868VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7869 hdd_adapter_list_node_t* pAdapterNode)
7870{
7871 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307872 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007873 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7874 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307875 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 return status;
7877}
7878
7879VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7880 hdd_adapter_list_node_t* pAdapterNode)
7881{
7882 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307883 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007884 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7885 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307886 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 return status;
7888}
7889
7890hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7891 tSirMacAddr macAddr )
7892{
7893 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7894 hdd_adapter_t *pAdapter;
7895 VOS_STATUS status;
7896
7897 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7898
7899 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7900 {
7901 pAdapter = pAdapterNode->pAdapter;
7902
7903 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7904 macAddr, sizeof(tSirMacAddr) ) )
7905 {
7906 return pAdapter;
7907 }
7908 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7909 pAdapterNode = pNext;
7910 }
7911
7912 return NULL;
7913
7914}
7915
7916hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7917{
7918 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7919 hdd_adapter_t *pAdapter;
7920 VOS_STATUS status;
7921
7922 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7923
7924 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7925 {
7926 pAdapter = pAdapterNode->pAdapter;
7927
7928 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7929 IFNAMSIZ ) )
7930 {
7931 return pAdapter;
7932 }
7933 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7934 pAdapterNode = pNext;
7935 }
7936
7937 return NULL;
7938
7939}
7940
7941hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7942{
7943 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7944 hdd_adapter_t *pAdapter;
7945 VOS_STATUS status;
7946
7947 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7948
7949 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7950 {
7951 pAdapter = pAdapterNode->pAdapter;
7952
7953 if( pAdapter && (mode == pAdapter->device_mode) )
7954 {
7955 return pAdapter;
7956 }
7957 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7958 pAdapterNode = pNext;
7959 }
7960
7961 return NULL;
7962
7963}
7964
7965//Remove this function later
7966hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7967{
7968 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7969 hdd_adapter_t *pAdapter;
7970 VOS_STATUS status;
7971
7972 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7973
7974 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7975 {
7976 pAdapter = pAdapterNode->pAdapter;
7977
7978 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7979 {
7980 return pAdapter;
7981 }
7982
7983 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7984 pAdapterNode = pNext;
7985 }
7986
7987 return NULL;
7988
7989}
7990
Jeff Johnson295189b2012-06-20 16:38:30 -07007991/**---------------------------------------------------------------------------
7992
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307993 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007994
7995 This API returns the operating channel of the requested device mode
7996
7997 \param - pHddCtx - Pointer to the HDD context.
7998 - mode - Device mode for which operating channel is required
7999 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8000 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8001 \return - channel number. "0" id the requested device is not found OR it is not connected.
8002 --------------------------------------------------------------------------*/
8003v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8004{
8005 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8006 VOS_STATUS status;
8007 hdd_adapter_t *pAdapter;
8008 v_U8_t operatingChannel = 0;
8009
8010 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8011
8012 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8013 {
8014 pAdapter = pAdapterNode->pAdapter;
8015
8016 if( mode == pAdapter->device_mode )
8017 {
8018 switch(pAdapter->device_mode)
8019 {
8020 case WLAN_HDD_INFRA_STATION:
8021 case WLAN_HDD_P2P_CLIENT:
8022 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8023 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8024 break;
8025 case WLAN_HDD_SOFTAP:
8026 case WLAN_HDD_P2P_GO:
8027 /*softap connection info */
8028 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8029 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8030 break;
8031 default:
8032 break;
8033 }
8034
8035 break; //Found the device of interest. break the loop
8036 }
8037
8038 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8039 pAdapterNode = pNext;
8040 }
8041 return operatingChannel;
8042}
8043
8044#ifdef WLAN_FEATURE_PACKET_FILTERING
8045/**---------------------------------------------------------------------------
8046
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308047 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008048
8049 This used to set the multicast address list.
8050
8051 \param - dev - Pointer to the WLAN device.
8052 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308053 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008054
8055 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308056static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008057{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308058 hdd_adapter_t *pAdapter;
8059 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308061 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008062 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308064 ENTER();
8065
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308066 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308067 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 {
8069 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308070 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 return;
8072 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8074 ret = wlan_hdd_validate_context(pHddCtx);
8075 if (0 != ret)
8076 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308077 return;
8078 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 if (dev->flags & IFF_ALLMULTI)
8080 {
8081 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008082 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308083 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308085 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 {
8087 mc_count = netdev_mc_count(dev);
8088 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008089 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8091 {
8092 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008093 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308094 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 return;
8096 }
8097
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308098 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008099
8100 netdev_for_each_mc_addr(ha, dev) {
8101 if (i == mc_count)
8102 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308103 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8104 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308106 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308107 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 i++;
8109 }
8110 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308111
8112 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 return;
8114}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308115
8116static void hdd_set_multicast_list(struct net_device *dev)
8117{
8118 vos_ssr_protect(__func__);
8119 __hdd_set_multicast_list(dev);
8120 vos_ssr_unprotect(__func__);
8121}
Jeff Johnson295189b2012-06-20 16:38:30 -07008122#endif
8123
8124/**---------------------------------------------------------------------------
8125
8126 \brief hdd_select_queue() -
8127
8128 This function is registered with the Linux OS for network
8129 core to decide which queue to use first.
8130
8131 \param - dev - Pointer to the WLAN device.
8132 - skb - Pointer to OS packet (sk_buff).
8133 \return - ac, Queue Index/access category corresponding to UP in IP header
8134
8135 --------------------------------------------------------------------------*/
8136v_U16_t hdd_select_queue(struct net_device *dev,
8137 struct sk_buff *skb)
8138{
8139 return hdd_wmm_select_queue(dev, skb);
8140}
8141
8142
8143/**---------------------------------------------------------------------------
8144
8145 \brief hdd_wlan_initial_scan() -
8146
8147 This function triggers the initial scan
8148
8149 \param - pAdapter - Pointer to the HDD adapter.
8150
8151 --------------------------------------------------------------------------*/
8152void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8153{
8154 tCsrScanRequest scanReq;
8155 tCsrChannelInfo channelInfo;
8156 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008157 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008158 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8159
8160 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8161 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8162 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8163
8164 if(sme_Is11dSupported(pHddCtx->hHal))
8165 {
8166 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8167 if ( HAL_STATUS_SUCCESS( halStatus ) )
8168 {
8169 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8170 if( !scanReq.ChannelInfo.ChannelList )
8171 {
8172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8173 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008174 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 return;
8176 }
8177 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8178 channelInfo.numOfChannels);
8179 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8180 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008181 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008182 }
8183
8184 scanReq.scanType = eSIR_PASSIVE_SCAN;
8185 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8186 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8187 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8188 }
8189 else
8190 {
8191 scanReq.scanType = eSIR_ACTIVE_SCAN;
8192 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8193 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8194 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8195 }
8196
8197 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8198 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8199 {
8200 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8201 __func__, halStatus );
8202 }
8203
8204 if(sme_Is11dSupported(pHddCtx->hHal))
8205 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8206}
8207
mukul sharmabab477d2015-06-11 17:14:55 +05308208void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8209{
8210 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8211 VOS_STATUS status;
8212 hdd_adapter_t *pAdapter;
8213
8214 ENTER();
8215
8216 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8217
8218 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8219 {
8220 pAdapter = pAdapterNode->pAdapter;
8221
8222 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8223 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8224 pAdapterNode = pNext;
8225 }
8226
8227 EXIT();
8228}
Jeff Johnson295189b2012-06-20 16:38:30 -07008229/**---------------------------------------------------------------------------
8230
8231 \brief hdd_full_power_callback() - HDD full power callback function
8232
8233 This is the function invoked by SME to inform the result of a full power
8234 request issued by HDD
8235
8236 \param - callbackcontext - Pointer to cookie
8237 \param - status - result of request
8238
8239 \return - None
8240
8241 --------------------------------------------------------------------------*/
8242static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8243{
Jeff Johnson72a40512013-12-19 10:14:15 -08008244 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008245
8246 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308247 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008248
8249 if (NULL == callbackContext)
8250 {
8251 hddLog(VOS_TRACE_LEVEL_ERROR,
8252 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008253 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 return;
8255 }
8256
Jeff Johnson72a40512013-12-19 10:14:15 -08008257 /* there is a race condition that exists between this callback
8258 function and the caller since the caller could time out either
8259 before or while this code is executing. we use a spinlock to
8260 serialize these actions */
8261 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008262
8263 if (POWER_CONTEXT_MAGIC != pContext->magic)
8264 {
8265 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008266 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 hddLog(VOS_TRACE_LEVEL_WARN,
8268 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008269 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 return;
8271 }
8272
Jeff Johnson72a40512013-12-19 10:14:15 -08008273 /* context is valid so caller is still waiting */
8274
8275 /* paranoia: invalidate the magic */
8276 pContext->magic = 0;
8277
8278 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008280
8281 /* serialization is complete */
8282 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008283}
8284
Katya Nigamf0511f62015-05-05 16:40:57 +05308285void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8286{
8287 pMonCtx->typeSubtypeBitmap = 0;
8288 if( type%10 ) /* Management Packets */
8289 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8290 type/=10;
8291 if( type%10 ) /* Control Packets */
8292 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8293 type/=10;
8294 if( type%10 ) /* Data Packets */
8295 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8296}
8297
8298VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8299{
8300 vos_msg_t monMsg;
8301
8302 monMsg.type = WDA_MON_START_REQ;
8303 monMsg.reserved = 0;
8304 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8305 monMsg.bodyval = 0;
8306
8307 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8308 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8309 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8310 return VOS_STATUS_E_FAILURE;
8311 }
8312
8313 return VOS_STATUS_SUCCESS;
8314}
8315
8316void wlan_hdd_mon_poststopmsg(void)
8317{
8318 vos_msg_t monMsg;
8319
8320 monMsg.type = WDA_MON_STOP_REQ;
8321 monMsg.reserved = 0;
8322 monMsg.bodyptr = NULL;
8323 monMsg.bodyval = 0;
8324
8325 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8326 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8327 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8328 }
8329}
8330
Katya Nigame7b69a82015-04-28 15:24:06 +05308331void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8332{
8333 VOS_STATUS vosStatus;
8334 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8335 struct wiphy *wiphy = pHddCtx->wiphy;
8336
8337 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8338 if(pAdapter == NULL || pVosContext == NULL)
8339 {
8340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8341 return ;
8342 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308343
8344 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308345 hdd_UnregisterWext(pAdapter->dev);
8346
8347 vos_mon_stop( pVosContext );
8348
8349 vosStatus = vos_sched_close( pVosContext );
8350 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8351 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8352 "%s: Failed to close VOSS Scheduler",__func__);
8353 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8354 }
8355
8356 vosStatus = vos_nv_close();
8357 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8358 {
8359 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8360 "%s: Failed to close NV", __func__);
8361 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8362 }
8363
8364 vos_close(pVosContext);
8365
8366 #ifdef WLAN_KD_READY_NOTIFIER
8367 nl_srv_exit(pHddCtx->ptt_pid);
8368 #else
8369 nl_srv_exit();
8370 #endif
8371
8372 if (pHddCtx->cfg_ini)
8373 {
8374 kfree(pHddCtx->cfg_ini);
8375 pHddCtx->cfg_ini= NULL;
8376 }
8377 hdd_close_all_adapters( pHddCtx );
8378
8379 wiphy_free(wiphy) ;
8380
8381}
Jeff Johnson295189b2012-06-20 16:38:30 -07008382/**---------------------------------------------------------------------------
8383
8384 \brief hdd_wlan_exit() - HDD WLAN exit function
8385
8386 This is the driver exit point (invoked during rmmod)
8387
8388 \param - pHddCtx - Pointer to the HDD Context
8389
8390 \return - None
8391
8392 --------------------------------------------------------------------------*/
8393void hdd_wlan_exit(hdd_context_t *pHddCtx)
8394{
8395 eHalStatus halStatus;
8396 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8397 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308398 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008399 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008400 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308402 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008403
8404 ENTER();
8405
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308406
Katya Nigame7b69a82015-04-28 15:24:06 +05308407 if (VOS_MONITOR_MODE == hdd_get_conparam())
8408 {
8409 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8410 wlan_hdd_mon_close(pHddCtx);
8411 return;
8412 }
8413 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008414 {
8415 // Unloading, restart logic is no more required.
8416 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008417
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308418#ifdef FEATURE_WLAN_TDLS
8419 /* At the time of driver unloading; if tdls connection is present;
8420 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8421 * wlan_hdd_tdls_find_peer always checks for valid context;
8422 * as load/unload in progress there can be a race condition.
8423 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8424 * when tdls state is enabled.
8425 * As soon as driver set load/unload flag; tdls flag also needs
8426 * to be disabled so that hdd_rx_packet_cbk won't call
8427 * wlan_hdd_tdls_find_peer.
8428 */
8429 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8430#endif
8431
c_hpothu5ab05e92014-06-13 17:34:05 +05308432 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8433 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308435 pAdapter = pAdapterNode->pAdapter;
8436 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008437 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308438 /* Disable TX on the interface, after this hard_start_xmit() will
8439 * not be called on that interface
8440 */
8441 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8442 netif_tx_disable(pAdapter->dev);
8443
8444 /* Mark the interface status as "down" for outside world */
8445 netif_carrier_off(pAdapter->dev);
8446
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308447 /* DeInit the adapter. This ensures that all data packets
8448 * are freed.
8449 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308450#ifdef FEATURE_WLAN_TDLS
8451 mutex_lock(&pHddCtx->tdls_lock);
8452#endif
c_hpothu002231a2015-02-05 14:58:51 +05308453 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308454#ifdef FEATURE_WLAN_TDLS
8455 mutex_unlock(&pHddCtx->tdls_lock);
8456#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308457
c_hpothu5ab05e92014-06-13 17:34:05 +05308458 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8459 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8460 {
8461 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8462 hdd_UnregisterWext(pAdapter->dev);
8463 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308464
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308466 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8467 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 }
mukul sharmabab477d2015-06-11 17:14:55 +05308469
8470 //Purge all sme cmd's for all interface
8471 hdd_purge_cmd_list_all_adapters(pHddCtx);
8472
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308473 // Cancel any outstanding scan requests. We are about to close all
8474 // of our adapters, but an adapter structure is what SME passes back
8475 // to our callback function. Hence if there are any outstanding scan
8476 // requests then there is a race condition between when the adapter
8477 // is closed and when the callback is invoked.We try to resolve that
8478 // race condition here by canceling any outstanding scans before we
8479 // close the adapters.
8480 // Note that the scans may be cancelled in an asynchronous manner,
8481 // so ideally there needs to be some kind of synchronization. Rather
8482 // than introduce a new synchronization here, we will utilize the
8483 // fact that we are about to Request Full Power, and since that is
8484 // synchronized, the expectation is that by the time Request Full
8485 // Power has completed all scans will be cancelled.
8486 if (pHddCtx->scan_info.mScanPending)
8487 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308488 if(NULL != pAdapter)
8489 {
8490 hddLog(VOS_TRACE_LEVEL_INFO,
8491 FL("abort scan mode: %d sessionId: %d"),
8492 pAdapter->device_mode,
8493 pAdapter->sessionId);
8494 }
8495 hdd_abort_mac_scan(pHddCtx,
8496 pHddCtx->scan_info.sessionId,
8497 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308498 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308500 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008501 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308502 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308503 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8504 {
8505 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8507 "%s: in middle of FTM START", __func__);
8508 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8509 msecs_to_jiffies(20000));
8510 if(!lrc)
8511 {
8512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8513 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8514 }
8515 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008516 wlan_hdd_ftm_close(pHddCtx);
8517 goto free_hdd_ctx;
8518 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308519
Jeff Johnson295189b2012-06-20 16:38:30 -07008520 /* DeRegister with platform driver as client for Suspend/Resume */
8521 vosStatus = hddDeregisterPmOps(pHddCtx);
8522 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8523 {
8524 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8525 VOS_ASSERT(0);
8526 }
8527
8528 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8529 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8530 {
8531 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008533
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008534 //Stop the traffic monitor timer
8535 if ( VOS_TIMER_STATE_RUNNING ==
8536 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8537 {
8538 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8539 }
8540
8541 // Destroy the traffic monitor timer
8542 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8543 &pHddCtx->tx_rx_trafficTmr)))
8544 {
8545 hddLog(VOS_TRACE_LEVEL_ERROR,
8546 "%s: Cannot deallocate Traffic monitor timer", __func__);
8547 }
8548
Jeff Johnson295189b2012-06-20 16:38:30 -07008549 //Disable IMPS/BMPS as we do not want the device to enter any power
8550 //save mode during shutdown
8551 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8552 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8553 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8554
8555 //Ensure that device is in full power as we will touch H/W during vos_Stop
8556 init_completion(&powerContext.completion);
8557 powerContext.magic = POWER_CONTEXT_MAGIC;
8558
8559 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8560 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8561
8562 if (eHAL_STATUS_SUCCESS != halStatus)
8563 {
8564 if (eHAL_STATUS_PMC_PENDING == halStatus)
8565 {
8566 /* request was sent -- wait for the response */
8567 lrc = wait_for_completion_interruptible_timeout(
8568 &powerContext.completion,
8569 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 if (lrc <= 0)
8571 {
8572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008573 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 }
8575 }
8576 else
8577 {
8578 hddLog(VOS_TRACE_LEVEL_ERROR,
8579 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008580 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008581 /* continue -- need to clean up as much as possible */
8582 }
8583 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308584 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8585 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8586 {
8587 /* This will issue a dump command which will clean up
8588 BTQM queues and unblock MC thread */
8589 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8590 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008591
Jeff Johnson72a40512013-12-19 10:14:15 -08008592 /* either we never sent a request, we sent a request and received a
8593 response or we sent a request and timed out. if we never sent a
8594 request or if we sent a request and got a response, we want to
8595 clear the magic out of paranoia. if we timed out there is a
8596 race condition such that the callback function could be
8597 executing at the same time we are. of primary concern is if the
8598 callback function had already verified the "magic" but had not
8599 yet set the completion variable when a timeout occurred. we
8600 serialize these activities by invalidating the magic while
8601 holding a shared spinlock which will cause us to block if the
8602 callback is currently executing */
8603 spin_lock(&hdd_context_lock);
8604 powerContext.magic = 0;
8605 spin_unlock(&hdd_context_lock);
8606
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308607 /* If Device is shutdown, no point for SME to wait for responses
8608 from device. Pre Close SME */
8609 if(wcnss_device_is_shutdown())
8610 {
8611 sme_PreClose(pHddCtx->hHal);
8612 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008613 hdd_debugfs_exit(pHddCtx);
8614
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308615#ifdef WLAN_NS_OFFLOAD
8616 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8617 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8618#endif
8619 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8620 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8621
Jeff Johnson295189b2012-06-20 16:38:30 -07008622 // Unregister the Net Device Notifier
8623 unregister_netdevice_notifier(&hdd_netdev_notifier);
8624
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 hdd_stop_all_adapters( pHddCtx );
8626
Jeff Johnson295189b2012-06-20 16:38:30 -07008627#ifdef WLAN_BTAMP_FEATURE
8628 vosStatus = WLANBAP_Stop(pVosContext);
8629 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8630 {
8631 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8632 "%s: Failed to stop BAP",__func__);
8633 }
8634#endif //WLAN_BTAMP_FEATURE
8635
8636 //Stop all the modules
8637 vosStatus = vos_stop( pVosContext );
8638 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8639 {
8640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8641 "%s: Failed to stop VOSS",__func__);
8642 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8643 }
8644
Jeff Johnson295189b2012-06-20 16:38:30 -07008645 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008646 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008647
8648 //Close the scheduler before calling vos_close to make sure no thread is
8649 // scheduled after the each module close is called i.e after all the data
8650 // structures are freed.
8651 vosStatus = vos_sched_close( pVosContext );
8652 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8653 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8654 "%s: Failed to close VOSS Scheduler",__func__);
8655 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8656 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008657#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8658 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308659 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008660#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008661 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308662 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008663
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308664#ifdef CONFIG_ENABLE_LINUX_REG
8665 vosStatus = vos_nv_close();
8666 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8667 {
8668 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8669 "%s: Failed to close NV", __func__);
8670 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8671 }
8672#endif
8673
Jeff Johnson295189b2012-06-20 16:38:30 -07008674 //Close VOSS
8675 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8676 vos_close(pVosContext);
8677
Jeff Johnson295189b2012-06-20 16:38:30 -07008678 //Close Watchdog
8679 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8680 vos_watchdog_close(pVosContext);
8681
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308682 //Clean up HDD Nlink Service
8683 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308684
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308685#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308686 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308687 {
8688 wlan_logging_sock_deactivate_svc();
8689 }
8690#endif
8691
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308692#ifdef WLAN_KD_READY_NOTIFIER
8693 nl_srv_exit(pHddCtx->ptt_pid);
8694#else
8695 nl_srv_exit();
8696#endif /* WLAN_KD_READY_NOTIFIER */
8697
8698
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 hdd_close_all_adapters( pHddCtx );
8700
Jeff Johnson295189b2012-06-20 16:38:30 -07008701 /* free the power on lock from platform driver */
8702 if (free_riva_power_on_lock("wlan"))
8703 {
8704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8705 __func__);
8706 }
8707
Jeff Johnson88ba7742013-02-27 14:36:02 -08008708free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308709
8710 //Free up dynamically allocated members inside HDD Adapter
8711 if (pHddCtx->cfg_ini)
8712 {
8713 kfree(pHddCtx->cfg_ini);
8714 pHddCtx->cfg_ini= NULL;
8715 }
8716
Leo Changf04ddad2013-09-18 13:46:38 -07008717 /* FTM mode, WIPHY did not registered
8718 If un-register here, system crash will happen */
8719 if (VOS_FTM_MODE != hdd_get_conparam())
8720 {
8721 wiphy_unregister(wiphy) ;
8722 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 if (hdd_is_ssr_required())
8725 {
8726 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008727 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 msleep(5000);
8729 }
8730 hdd_set_ssr_required (VOS_FALSE);
8731}
8732
8733
8734/**---------------------------------------------------------------------------
8735
8736 \brief hdd_update_config_from_nv() - Function to update the contents of
8737 the running configuration with parameters taken from NV storage
8738
8739 \param - pHddCtx - Pointer to the HDD global context
8740
8741 \return - VOS_STATUS_SUCCESS if successful
8742
8743 --------------------------------------------------------------------------*/
8744static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8745{
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 v_BOOL_t itemIsValid = VOS_FALSE;
8747 VOS_STATUS status;
8748 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8749 v_U8_t macLoop;
8750
8751 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8752 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8753 if(status != VOS_STATUS_SUCCESS)
8754 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008755 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 return VOS_STATUS_E_FAILURE;
8757 }
8758
8759 if (itemIsValid == VOS_TRUE)
8760 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008761 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8763 VOS_MAX_CONCURRENCY_PERSONA);
8764 if(status != VOS_STATUS_SUCCESS)
8765 {
8766 /* Get MAC from NV fail, not update CFG info
8767 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008768 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 return VOS_STATUS_E_FAILURE;
8770 }
8771
8772 /* If first MAC is not valid, treat all others are not valid
8773 * Then all MACs will be got from ini file */
8774 if(vos_is_macaddr_zero(&macFromNV[0]))
8775 {
8776 /* MAC address in NV file is not configured yet */
8777 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8778 return VOS_STATUS_E_INVAL;
8779 }
8780
8781 /* Get MAC address from NV, update CFG info */
8782 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8783 {
8784 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8785 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308786 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008787 /* This MAC is not valid, skip it
8788 * This MAC will be got from ini file */
8789 }
8790 else
8791 {
8792 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8793 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8794 VOS_MAC_ADDR_SIZE);
8795 }
8796 }
8797 }
8798 else
8799 {
8800 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8801 return VOS_STATUS_E_FAILURE;
8802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008803
Jeff Johnson295189b2012-06-20 16:38:30 -07008804
8805 return VOS_STATUS_SUCCESS;
8806}
8807
8808/**---------------------------------------------------------------------------
8809
8810 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8811
8812 \param - pAdapter - Pointer to the HDD
8813
8814 \return - None
8815
8816 --------------------------------------------------------------------------*/
8817VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8818{
8819 eHalStatus halStatus;
8820 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308821 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008822
Jeff Johnson295189b2012-06-20 16:38:30 -07008823
8824 // Send ready indication to the HDD. This will kick off the MAC
8825 // into a 'running' state and should kick off an initial scan.
8826 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8827 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8828 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308829 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 "code %08d [x%08x]",__func__, halStatus, halStatus );
8831 return VOS_STATUS_E_FAILURE;
8832 }
8833
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308834 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8836 // And RIVA will crash
8837 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8838 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308839 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8840 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8841
8842
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 return VOS_STATUS_SUCCESS;
8844}
8845
Jeff Johnson295189b2012-06-20 16:38:30 -07008846/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308847void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008848{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308849
8850 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8851
Jeff Johnson295189b2012-06-20 16:38:30 -07008852}
8853
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308854void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008855{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308856
8857 vos_wake_lock_release(&wlan_wake_lock, reason);
8858
Jeff Johnson295189b2012-06-20 16:38:30 -07008859}
8860
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308861void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008862{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308863
8864 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8865 reason);
8866
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008867}
8868
Jeff Johnson295189b2012-06-20 16:38:30 -07008869/**---------------------------------------------------------------------------
8870
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008871 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8872 information between Host and Riva
8873
8874 This function gets reported version of FW
8875 It also finds the version of Riva headers used to compile the host
8876 It compares the above two and prints a warning if they are different
8877 It gets the SW and HW version string
8878 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8879 indicating the features they support through a bitmap
8880
8881 \param - pHddCtx - Pointer to HDD context
8882
8883 \return - void
8884
8885 --------------------------------------------------------------------------*/
8886
8887void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8888{
8889
8890 tSirVersionType versionCompiled;
8891 tSirVersionType versionReported;
8892 tSirVersionString versionString;
8893 tANI_U8 fwFeatCapsMsgSupported = 0;
8894 VOS_STATUS vstatus;
8895
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008896 memset(&versionCompiled, 0, sizeof(versionCompiled));
8897 memset(&versionReported, 0, sizeof(versionReported));
8898
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008899 /* retrieve and display WCNSS version information */
8900 do {
8901
8902 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8903 &versionCompiled);
8904 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8905 {
8906 hddLog(VOS_TRACE_LEVEL_FATAL,
8907 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008908 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008909 break;
8910 }
8911
8912 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8913 &versionReported);
8914 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8915 {
8916 hddLog(VOS_TRACE_LEVEL_FATAL,
8917 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008918 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008919 break;
8920 }
8921
8922 if ((versionCompiled.major != versionReported.major) ||
8923 (versionCompiled.minor != versionReported.minor) ||
8924 (versionCompiled.version != versionReported.version) ||
8925 (versionCompiled.revision != versionReported.revision))
8926 {
8927 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8928 "Host expected %u.%u.%u.%u\n",
8929 WLAN_MODULE_NAME,
8930 (int)versionReported.major,
8931 (int)versionReported.minor,
8932 (int)versionReported.version,
8933 (int)versionReported.revision,
8934 (int)versionCompiled.major,
8935 (int)versionCompiled.minor,
8936 (int)versionCompiled.version,
8937 (int)versionCompiled.revision);
8938 }
8939 else
8940 {
8941 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8942 WLAN_MODULE_NAME,
8943 (int)versionReported.major,
8944 (int)versionReported.minor,
8945 (int)versionReported.version,
8946 (int)versionReported.revision);
8947 }
8948
8949 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8950 versionString,
8951 sizeof(versionString));
8952 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8953 {
8954 hddLog(VOS_TRACE_LEVEL_FATAL,
8955 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008956 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008957 break;
8958 }
8959
8960 pr_info("%s: WCNSS software version %s\n",
8961 WLAN_MODULE_NAME, versionString);
8962
8963 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8964 versionString,
8965 sizeof(versionString));
8966 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8967 {
8968 hddLog(VOS_TRACE_LEVEL_FATAL,
8969 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008970 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008971 break;
8972 }
8973
8974 pr_info("%s: WCNSS hardware version %s\n",
8975 WLAN_MODULE_NAME, versionString);
8976
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008977 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8978 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008979 send the message only if it the riva is 1.1
8980 minor numbers for different riva branches:
8981 0 -> (1.0)Mainline Build
8982 1 -> (1.1)Mainline Build
8983 2->(1.04) Stability Build
8984 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008985 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008986 ((versionReported.minor>=1) && (versionReported.version>=1)))
8987 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8988 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008989
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008990 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008991 {
8992#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8993 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8994 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8995#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008996 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8997 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8998 {
8999 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9000 }
9001
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009002 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009003 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009004
9005 } while (0);
9006
9007}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309008void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9009{
9010 struct sk_buff *skb;
9011 struct nlmsghdr *nlh;
9012 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309013 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309014
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309015 if (in_interrupt() || irqs_disabled() || in_atomic())
9016 flags = GFP_ATOMIC;
9017
9018 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309019
9020 if(skb == NULL) {
9021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9022 "%s: alloc_skb failed", __func__);
9023 return;
9024 }
9025
9026 nlh = (struct nlmsghdr *)skb->data;
9027 nlh->nlmsg_pid = 0; /* from kernel */
9028 nlh->nlmsg_flags = 0;
9029 nlh->nlmsg_seq = 0;
9030 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9031
9032 ani_hdr = NLMSG_DATA(nlh);
9033 ani_hdr->type = type;
9034
9035 switch(type) {
9036 case WLAN_SVC_SAP_RESTART_IND:
9037 ani_hdr->length = 0;
9038 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9039 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9040 break;
9041 default:
9042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9043 "Attempt to send unknown nlink message %d", type);
9044 kfree_skb(skb);
9045 return;
9046 }
9047
9048 nl_srv_bcast(skb);
9049
9050 return;
9051}
9052
9053
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009054
9055/**---------------------------------------------------------------------------
9056
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309057 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9058
9059 \param - pHddCtx - Pointer to the hdd context
9060
9061 \return - true if hardware supports 5GHz
9062
9063 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309064boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309065{
9066 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9067 * then hardware support 5Ghz.
9068 */
9069 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9070 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309072 return true;
9073 }
9074 else
9075 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309077 __func__);
9078 return false;
9079 }
9080}
9081
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309082/**---------------------------------------------------------------------------
9083
9084 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9085 generate function
9086
9087 This is generate the random mac address for WLAN interface
9088
9089 \param - pHddCtx - Pointer to HDD context
9090 idx - Start interface index to get auto
9091 generated mac addr.
9092 mac_addr - Mac address
9093
9094 \return - 0 for success, < 0 for failure
9095
9096 --------------------------------------------------------------------------*/
9097
9098static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9099 int idx, v_MACADDR_t mac_addr)
9100{
9101 int i;
9102 unsigned int serialno;
9103 serialno = wcnss_get_serial_number();
9104
9105 if (0 != serialno)
9106 {
9107 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9108 bytes of the serial number that can be used to generate
9109 the other 3 bytes of the MAC address. Mask off all but
9110 the lower 3 bytes (this will also make sure we don't
9111 overflow in the next step) */
9112 serialno &= 0x00FFFFFF;
9113
9114 /* we need a unique address for each session */
9115 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9116
9117 /* autogen other Mac addresses */
9118 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9119 {
9120 /* start with the entire default address */
9121 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9122 /* then replace the lower 3 bytes */
9123 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9124 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9125 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9126
9127 serialno++;
9128 hddLog(VOS_TRACE_LEVEL_ERROR,
9129 "%s: Derived Mac Addr: "
9130 MAC_ADDRESS_STR, __func__,
9131 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9132 }
9133
9134 }
9135 else
9136 {
9137 hddLog(LOGE, FL("Failed to Get Serial NO"));
9138 return -1;
9139 }
9140 return 0;
9141}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309142
Katya Nigame7b69a82015-04-28 15:24:06 +05309143int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9144{
9145 VOS_STATUS status;
9146 v_CONTEXT_t pVosContext= NULL;
9147 hdd_adapter_t *pAdapter= NULL;
9148
9149 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9150
9151 if (NULL == pVosContext)
9152 {
9153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9154 "%s: Trying to open VOSS without a PreOpen", __func__);
9155 VOS_ASSERT(0);
9156 return VOS_STATUS_E_FAILURE;
9157 }
9158
9159 status = vos_nv_open();
9160 if (!VOS_IS_STATUS_SUCCESS(status))
9161 {
9162 /* NV module cannot be initialized */
9163 hddLog( VOS_TRACE_LEVEL_FATAL,
9164 "%s: vos_nv_open failed", __func__);
9165 return VOS_STATUS_E_FAILURE;
9166 }
9167
9168 status = vos_init_wiphy_from_nv_bin();
9169 if (!VOS_IS_STATUS_SUCCESS(status))
9170 {
9171 /* NV module cannot be initialized */
9172 hddLog( VOS_TRACE_LEVEL_FATAL,
9173 "%s: vos_init_wiphy failed", __func__);
9174 goto err_vos_nv_close;
9175 }
9176
9177 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9178 if ( !VOS_IS_STATUS_SUCCESS( status ))
9179 {
9180 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9181 goto err_vos_nv_close;
9182 }
9183
9184 status = vos_mon_start( pVosContext );
9185 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9186 {
9187 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9188 goto err_vosclose;
9189 }
9190
9191 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9192 WDA_featureCapsExchange(pVosContext);
9193 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9194
9195 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9196 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9197 if( pAdapter == NULL )
9198 {
9199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9200 goto err_close_adapter;
9201 }
9202
9203 //Initialize the nlink service
9204 if(nl_srv_init() != 0)
9205 {
9206 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9207 goto err_close_adapter;
9208 }
9209 return VOS_STATUS_SUCCESS;
9210
9211err_close_adapter:
9212 hdd_close_all_adapters( pHddCtx );
9213 vos_mon_stop( pVosContext );
9214err_vosclose:
9215 status = vos_sched_close( pVosContext );
9216 if (!VOS_IS_STATUS_SUCCESS(status)) {
9217 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9218 "%s: Failed to close VOSS Scheduler", __func__);
9219 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9220 }
9221 vos_close(pVosContext );
9222
9223err_vos_nv_close:
9224 vos_nv_close();
9225
9226return status;
9227}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309228/**---------------------------------------------------------------------------
9229
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309230 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9231 completed to flush out the scan results
9232
9233 11d scan is done during driver load and is a passive scan on all
9234 channels supported by the device, 11d scans may find some APs on
9235 frequencies which are forbidden to be used in the regulatory domain
9236 the device is operating in. If these APs are notified to the supplicant
9237 it may try to connect to these APs, thus flush out all the scan results
9238 which are present in SME after 11d scan is done.
9239
9240 \return - eHalStatus
9241
9242 --------------------------------------------------------------------------*/
9243static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9244 tANI_U32 scanId, eCsrScanStatus status)
9245{
9246 ENTER();
9247
9248 sme_ScanFlushResult(halHandle, 0);
9249
9250 EXIT();
9251
9252 return eHAL_STATUS_SUCCESS;
9253}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309254/**---------------------------------------------------------------------------
9255
9256 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9257 logging is completed successfully.
9258
9259 \return - None
9260
9261 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309262void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309263{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309264 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309265
9266 if (NULL == pHddCtx)
9267 {
9268 hddLog(VOS_TRACE_LEVEL_ERROR,
9269 "%s: HDD context is NULL",__func__);
9270 return;
9271 }
9272
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309273 if ((VOS_STATUS_SUCCESS == status) &&
9274 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309275 {
9276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9277 pHddCtx->mgmt_frame_logging = TRUE;
9278 }
9279 else
9280 {
9281 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9282 pHddCtx->mgmt_frame_logging = FALSE;
9283 }
9284
9285 return;
9286}
9287/**---------------------------------------------------------------------------
9288
9289 \brief hdd_init_frame_logging - function to initialize frame logging.
9290 Currently only Mgmt Frames are logged in both TX
9291 and Rx direction and are sent to userspace
9292 application using logger thread when queried.
9293
9294 \return - None
9295
9296 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309297void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309298{
9299 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309300 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309301
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309302 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9303 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309304 {
9305 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9306 return;
9307 }
9308
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309309 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9310 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309311 {
9312 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9313 return;
9314 }
9315
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309316 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309317
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309318 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9319 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9320 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9321 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309322
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309323 if (pHddCtx->cfg_ini->enableFWLogging ||
9324 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309325 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309326 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309327 }
9328
Sushant Kaushik46804902015-07-08 14:46:03 +05309329 if (pHddCtx->cfg_ini->enableMgmtLogging)
9330 {
9331 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9332 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309333 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9334 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309335 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309336 }
9337
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309338 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9339 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9340 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9341 wlanFWLoggingInitParam->continuousFrameLogging =
9342 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309343
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309344 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309345
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309346 wlanFWLoggingInitParam->minLogBufferSize =
9347 pHddCtx->cfg_ini->minLoggingBufferSize;
9348 wlanFWLoggingInitParam->maxLogBufferSize =
9349 pHddCtx->cfg_ini->maxLoggingBufferSize;
9350 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9351 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309352
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309353 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309354
9355 if (eHAL_STATUS_SUCCESS != halStatus)
9356 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309357 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309358 }
9359
9360 return;
9361}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309362
9363/**---------------------------------------------------------------------------
9364
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 \brief hdd_wlan_startup() - HDD init function
9366
9367 This is the driver startup code executed once a WLAN device has been detected
9368
9369 \param - dev - Pointer to the underlying device
9370
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009371 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
9373 --------------------------------------------------------------------------*/
9374
9375int hdd_wlan_startup(struct device *dev )
9376{
9377 VOS_STATUS status;
9378 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009379 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 hdd_context_t *pHddCtx = NULL;
9381 v_CONTEXT_t pVosContext= NULL;
9382#ifdef WLAN_BTAMP_FEATURE
9383 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9384 WLANBAP_ConfigType btAmpConfig;
9385 hdd_config_t *pConfig;
9386#endif
9387 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309389 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009390
9391 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 /*
9393 * cfg80211: wiphy allocation
9394 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309395 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009396
9397 if(wiphy == NULL)
9398 {
9399 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009400 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 pHddCtx = wiphy_priv(wiphy);
9403
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 //Initialize the adapter context to zeros.
9405 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9406
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309408 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309409 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009410
9411 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9412
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309413 /* register for riva power on lock to platform driver
9414 * Locking power early to ensure FW doesn't reset by kernel while
9415 * host driver is busy initializing itself */
9416 if (req_riva_power_on_lock("wlan"))
9417 {
9418 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9419 __func__);
9420 goto err_free_hdd_context;
9421 }
9422
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 /*Get vos context here bcoz vos_open requires it*/
9424 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9425
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009426 if(pVosContext == NULL)
9427 {
9428 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9429 goto err_free_hdd_context;
9430 }
9431
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 //Save the Global VOSS context in adapter context for future.
9433 pHddCtx->pvosContext = pVosContext;
9434
9435 //Save the adapter context in global context for future.
9436 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9437
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 pHddCtx->parent_dev = dev;
9439
9440 init_completion(&pHddCtx->full_pwr_comp_var);
9441 init_completion(&pHddCtx->standby_comp_var);
9442 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009443 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009444 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309445 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309446 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009447
9448#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009449 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009450#else
9451 init_completion(&pHddCtx->driver_crda_req);
9452#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009453
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309454 spin_lock_init(&pHddCtx->schedScan_lock);
9455
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9457
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309458#ifdef FEATURE_WLAN_TDLS
9459 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9460 * invoked by other instances also) to protect the concurrent
9461 * access for the Adapters by TDLS module.
9462 */
9463 mutex_init(&pHddCtx->tdls_lock);
9464#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309465 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309466 mutex_init(&pHddCtx->wmmLock);
9467
Agarwal Ashish1f422872014-07-22 00:11:55 +05309468 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309469
Agarwal Ashish1f422872014-07-22 00:11:55 +05309470 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 // Load all config first as TL config is needed during vos_open
9472 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9473 if(pHddCtx->cfg_ini == NULL)
9474 {
9475 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9476 goto err_free_hdd_context;
9477 }
9478
9479 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9480
9481 // Read and parse the qcom_cfg.ini file
9482 status = hdd_parse_config_ini( pHddCtx );
9483 if ( VOS_STATUS_SUCCESS != status )
9484 {
9485 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9486 __func__, WLAN_INI_FILE);
9487 goto err_config;
9488 }
Arif Hussaind5218912013-12-05 01:10:55 -08009489#ifdef MEMORY_DEBUG
9490 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9491 vos_mem_init();
9492
9493 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9494 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009496
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309497 /* INI has been read, initialise the configuredMcastBcastFilter with
9498 * INI value as this will serve as the default value
9499 */
9500 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9501 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9502 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309503
9504 if (false == hdd_is_5g_supported(pHddCtx))
9505 {
9506 //5Ghz is not supported.
9507 if (1 != pHddCtx->cfg_ini->nBandCapability)
9508 {
9509 hddLog(VOS_TRACE_LEVEL_INFO,
9510 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9511 pHddCtx->cfg_ini->nBandCapability = 1;
9512 }
9513 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309514
9515 /* If SNR Monitoring is enabled, FW has to parse all beacons
9516 * for calcaluting and storing the average SNR, so set Nth beacon
9517 * filter to 1 to enable FW to parse all the beaocons
9518 */
9519 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9520 {
9521 /* The log level is deliberately set to WARN as overriding
9522 * nthBeaconFilter to 1 will increase power cosumption and this
9523 * might just prove helpful to detect the power issue.
9524 */
9525 hddLog(VOS_TRACE_LEVEL_WARN,
9526 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9527 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309530 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009532 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009534 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9535 {
9536 hddLog(VOS_TRACE_LEVEL_FATAL,
9537 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9538 goto err_config;
9539 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009541
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009542 // Update VOS trace levels based upon the cfg.ini
9543 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9544 pHddCtx->cfg_ini->vosTraceEnableBAP);
9545 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9546 pHddCtx->cfg_ini->vosTraceEnableTL);
9547 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9548 pHddCtx->cfg_ini->vosTraceEnableWDI);
9549 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9550 pHddCtx->cfg_ini->vosTraceEnableHDD);
9551 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9552 pHddCtx->cfg_ini->vosTraceEnableSME);
9553 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9554 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309555 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9556 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009557 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9558 pHddCtx->cfg_ini->vosTraceEnableWDA);
9559 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9560 pHddCtx->cfg_ini->vosTraceEnableSYS);
9561 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9562 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009563 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9564 pHddCtx->cfg_ini->vosTraceEnableSAP);
9565 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9566 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009567
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 // Update WDI trace levels based upon the cfg.ini
9569 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9570 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9571 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9572 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9573 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9574 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9575 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9576 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009577
Jeff Johnson88ba7742013-02-27 14:36:02 -08009578 if (VOS_FTM_MODE == hdd_get_conparam())
9579 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9581 {
9582 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9583 goto err_free_hdd_context;
9584 }
9585 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309586 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309587 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009589 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009590
Katya Nigame7b69a82015-04-28 15:24:06 +05309591 if( VOS_MONITOR_MODE == hdd_get_conparam())
9592 {
9593 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9594 {
9595 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9596 goto err_free_hdd_context;
9597 }
9598 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9599 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9600 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9601 return VOS_STATUS_SUCCESS;
9602 }
9603
Jeff Johnson88ba7742013-02-27 14:36:02 -08009604 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9606 {
9607 status = vos_watchdog_open(pVosContext,
9608 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9609
9610 if(!VOS_IS_STATUS_SUCCESS( status ))
9611 {
9612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309613 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 }
9615 }
9616
9617 pHddCtx->isLogpInProgress = FALSE;
9618 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9619
Amar Singhala49cbc52013-10-08 18:37:44 -07009620#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009621 /* initialize the NV module. This is required so that
9622 we can initialize the channel information in wiphy
9623 from the NV.bin data. The channel information in
9624 wiphy needs to be initialized before wiphy registration */
9625
9626 status = vos_nv_open();
9627 if (!VOS_IS_STATUS_SUCCESS(status))
9628 {
9629 /* NV module cannot be initialized */
9630 hddLog( VOS_TRACE_LEVEL_FATAL,
9631 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309632 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009633 }
9634
9635 status = vos_init_wiphy_from_nv_bin();
9636 if (!VOS_IS_STATUS_SUCCESS(status))
9637 {
9638 /* NV module cannot be initialized */
9639 hddLog( VOS_TRACE_LEVEL_FATAL,
9640 "%s: vos_init_wiphy failed", __func__);
9641 goto err_vos_nv_close;
9642 }
9643
Amar Singhala49cbc52013-10-08 18:37:44 -07009644#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309645 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309646 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 if ( !VOS_IS_STATUS_SUCCESS( status ))
9648 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009649 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309650 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 }
9652
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9654
9655 if ( NULL == pHddCtx->hHal )
9656 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009657 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 goto err_vosclose;
9659 }
9660
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009661 status = vos_preStart( pHddCtx->pvosContext );
9662 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9663 {
9664 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309665 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009666 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009667
Arif Hussaineaf68602013-12-30 23:10:44 -08009668 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9669 {
9670 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9671 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9672 __func__, enable_dfs_chan_scan);
9673 }
9674 if (0 == enable_11d || 1 == enable_11d)
9675 {
9676 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9678 __func__, enable_11d);
9679 }
9680
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009681 /* Note that the vos_preStart() sequence triggers the cfg download.
9682 The cfg download must occur before we update the SME config
9683 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 status = hdd_set_sme_config( pHddCtx );
9685
9686 if ( VOS_STATUS_SUCCESS != status )
9687 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009688 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309689 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009691
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 /* In the integrated architecture we update the configuration from
9693 the INI file and from NV before vOSS has been started so that
9694 the final contents are available to send down to the cCPU */
9695
9696 // Apply the cfg.ini to cfg.dat
9697 if (FALSE == hdd_update_config_dat(pHddCtx))
9698 {
9699 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309700 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 }
9702
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309703 // Get mac addr from platform driver
9704 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9705
9706 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309708 /* Store the mac addr for first interface */
9709 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9710
9711 hddLog(VOS_TRACE_LEVEL_ERROR,
9712 "%s: WLAN Mac Addr: "
9713 MAC_ADDRESS_STR, __func__,
9714 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9715
9716 /* Here, passing Arg2 as 1 because we do not want to change the
9717 last 3 bytes (means non OUI bytes) of first interface mac
9718 addr.
9719 */
9720 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9721 {
9722 hddLog(VOS_TRACE_LEVEL_ERROR,
9723 "%s: Failed to generate wlan interface mac addr "
9724 "using MAC from ini file ", __func__);
9725 }
9726 }
9727 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9728 {
9729 // Apply the NV to cfg.dat
9730 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009731#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9732 /* There was not a valid set of MAC Addresses in NV. See if the
9733 default addresses were modified by the cfg.ini settings. If so,
9734 we'll use them, but if not, we'll autogenerate a set of MAC
9735 addresses based upon the device serial number */
9736
9737 static const v_MACADDR_t default_address =
9738 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009739
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309740 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9741 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 {
9743 /* cfg.ini has the default address, invoke autogen logic */
9744
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309745 /* Here, passing Arg2 as 0 because we want to change the
9746 last 3 bytes (means non OUI bytes) of all the interfaces
9747 mac addr.
9748 */
9749 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9750 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309752 hddLog(VOS_TRACE_LEVEL_ERROR,
9753 "%s: Failed to generate wlan interface mac addr "
9754 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9755 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 }
9758 else
9759#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9760 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009761 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 "%s: Invalid MAC address in NV, using MAC from ini file "
9763 MAC_ADDRESS_STR, __func__,
9764 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9765 }
9766 }
9767 {
9768 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309769
9770 /* Set the MAC Address Currently this is used by HAL to
9771 * add self sta. Remove this once self sta is added as
9772 * part of session open.
9773 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9775 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9776 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309777
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 if (!HAL_STATUS_SUCCESS( halStatus ))
9779 {
9780 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9781 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309782 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 }
9784 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009785
9786 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9787 Note: Firmware image will be read and downloaded inside vos_start API */
9788 status = vos_start( pHddCtx->pvosContext );
9789 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9790 {
9791 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309792 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 }
9794
Leo Chang6cec3e22014-01-21 15:33:49 -08009795#ifdef FEATURE_WLAN_CH_AVOID
9796 /* Plug in avoid channel notification callback
9797 * This should happen before ADD_SELF_STA
9798 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309799
9800 /* check the Channel Avoidance is enabled */
9801 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9802 {
9803 sme_AddChAvoidCallback(pHddCtx->hHal,
9804 hdd_hostapd_ch_avoid_cb);
9805 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009806#endif /* FEATURE_WLAN_CH_AVOID */
9807
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009808 /* Exchange capability info between Host and FW and also get versioning info from FW */
9809 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009810
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309811#ifdef CONFIG_ENABLE_LINUX_REG
9812 status = wlan_hdd_init_channels(pHddCtx);
9813 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9814 {
9815 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9816 __func__);
9817 goto err_vosstop;
9818 }
9819#endif
9820
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 status = hdd_post_voss_start_config( pHddCtx );
9822 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9823 {
9824 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9825 __func__);
9826 goto err_vosstop;
9827 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009828
9829#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309830 wlan_hdd_cfg80211_update_reg_info( wiphy );
9831
9832 /* registration of wiphy dev with cfg80211 */
9833 if (0 > wlan_hdd_cfg80211_register(wiphy))
9834 {
9835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9836 goto err_vosstop;
9837 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009838#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009839
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309840#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309841 /* registration of wiphy dev with cfg80211 */
9842 if (0 > wlan_hdd_cfg80211_register(wiphy))
9843 {
9844 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9845 goto err_vosstop;
9846 }
9847
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309848 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309849 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9850 {
9851 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9852 __func__);
9853 goto err_unregister_wiphy;
9854 }
9855#endif
9856
c_hpothu4a298be2014-12-22 21:12:51 +05309857 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9858
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9860 {
9861 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9862 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9863 }
9864 else
9865 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9867 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9868 if (pAdapter != NULL)
9869 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309870 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309872 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9873 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9874 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009875
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309876 /* Generate the P2P Device Address. This consists of the device's
9877 * primary MAC address with the locally administered bit set.
9878 */
9879 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009880 }
9881 else
9882 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309883 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9884 if (p2p_dev_addr != NULL)
9885 {
9886 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9887 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9888 }
9889 else
9890 {
9891 hddLog(VOS_TRACE_LEVEL_FATAL,
9892 "%s: Failed to allocate mac_address for p2p_device",
9893 __func__);
9894 goto err_close_adapter;
9895 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009897
9898 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9899 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9900 if ( NULL == pP2pAdapter )
9901 {
9902 hddLog(VOS_TRACE_LEVEL_FATAL,
9903 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009904 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009905 goto err_close_adapter;
9906 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009909
9910 if( pAdapter == NULL )
9911 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9913 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009915
Arif Hussain66559122013-11-21 10:11:40 -08009916 if (country_code)
9917 {
9918 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009919 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009920 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9921#ifndef CONFIG_ENABLE_LINUX_REG
9922 hdd_checkandupdate_phymode(pAdapter, country_code);
9923#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009924 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9925 (void *)(tSmeChangeCountryCallback)
9926 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009927 country_code,
9928 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309929 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009930 if (eHAL_STATUS_SUCCESS == ret)
9931 {
Arif Hussaincb607082013-12-20 11:57:42 -08009932 ret = wait_for_completion_interruptible_timeout(
9933 &pAdapter->change_country_code,
9934 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9935
9936 if (0 >= ret)
9937 {
9938 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9939 "%s: SME while setting country code timed out", __func__);
9940 }
Arif Hussain66559122013-11-21 10:11:40 -08009941 }
9942 else
9943 {
Arif Hussaincb607082013-12-20 11:57:42 -08009944 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9945 "%s: SME Change Country code from module param fail ret=%d",
9946 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009947 }
9948 }
9949
Jeff Johnson295189b2012-06-20 16:38:30 -07009950#ifdef WLAN_BTAMP_FEATURE
9951 vStatus = WLANBAP_Open(pVosContext);
9952 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9953 {
9954 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9955 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009956 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 }
9958
9959 vStatus = BSL_Init(pVosContext);
9960 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9961 {
9962 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9963 "%s: Failed to Init BSL",__func__);
9964 goto err_bap_close;
9965 }
9966 vStatus = WLANBAP_Start(pVosContext);
9967 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9968 {
9969 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9970 "%s: Failed to start TL",__func__);
9971 goto err_bap_close;
9972 }
9973
9974 pConfig = pHddCtx->cfg_ini;
9975 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9976 status = WLANBAP_SetConfig(&btAmpConfig);
9977
9978#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009979
Mihir Shete9c238772014-10-15 14:35:16 +05309980 /*
9981 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9982 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9983 * which is greater than 0xf. So the below check is safe to make
9984 * sure that there is no entry for UapsdMask in the ini
9985 */
9986 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9987 {
9988 if(IS_DYNAMIC_WMM_PS_ENABLED)
9989 {
9990 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9991 __func__);
9992 pHddCtx->cfg_ini->UapsdMask =
9993 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9994 }
9995 else
9996 {
9997 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9998 __func__);
9999 pHddCtx->cfg_ini->UapsdMask =
10000 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10001 }
10002 }
10003
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010004#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10005 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10006 {
10007 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10008 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10009 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10010 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10011 }
10012#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010013
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010014 wlan_hdd_tdls_init(pHddCtx);
10015
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010016 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10017
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 /* Register with platform driver as client for Suspend/Resume */
10019 status = hddRegisterPmOps(pHddCtx);
10020 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10021 {
10022 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10023#ifdef WLAN_BTAMP_FEATURE
10024 goto err_bap_stop;
10025#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010026 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010027#endif //WLAN_BTAMP_FEATURE
10028 }
10029
Yue Ma0d4891e2013-08-06 17:01:45 -070010030 /* Open debugfs interface */
10031 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10032 {
10033 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10034 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010035 }
10036
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 /* Register TM level change handler function to the platform */
10038 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10039 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10040 {
10041 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10042 goto err_unregister_pmops;
10043 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010044
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 // register net device notifier for device change notification
10046 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10047
10048 if(ret < 0)
10049 {
10050 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010051 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 }
10053
10054 //Initialize the nlink service
10055 if(nl_srv_init() != 0)
10056 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010057 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010058 goto err_reg_netdev;
10059 }
10060
Leo Chang4ce1cc52013-10-21 18:27:15 -070010061#ifdef WLAN_KD_READY_NOTIFIER
10062 pHddCtx->kd_nl_init = 1;
10063#endif /* WLAN_KD_READY_NOTIFIER */
10064
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 //Initialize the BTC service
10066 if(btc_activate_service(pHddCtx) != 0)
10067 {
10068 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10069 goto err_nl_srv;
10070 }
10071
10072#ifdef PTT_SOCK_SVC_ENABLE
10073 //Initialize the PTT service
10074 if(ptt_sock_activate_svc(pHddCtx) != 0)
10075 {
10076 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10077 goto err_nl_srv;
10078 }
10079#endif
10080
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010081#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10082 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10083 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010084 if(wlan_logging_sock_activate_svc(
10085 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10086 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10087 {
10088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10089 " failed", __func__);
10090 goto err_nl_srv;
10091 }
10092 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10093 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010094 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10095 pHddCtx->cfg_ini->gEnableDebugLog =
10096 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010097 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010098
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010099 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10100 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010101 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010102 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010103 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010104 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010105 }
10106 else
10107 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010108 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010109 }
10110
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010111#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010112
10113
Sushant Kaushik215778f2015-05-21 14:05:36 +053010114 if (vos_is_multicast_logging())
10115 wlan_logging_set_log_level();
10116
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010120 /* Action frame registered in one adapter which will
10121 * applicable to all interfaces
10122 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010123 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010125
10126 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010127 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010128
Jeff Johnsone7245742012-09-05 17:12:55 -070010129#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10130 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010131 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010132 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010133
Jeff Johnsone7245742012-09-05 17:12:55 -070010134#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010135 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010136 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010137 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010138
Jeff Johnsone7245742012-09-05 17:12:55 -070010139
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010140 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10141 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010142
Katya Nigam5c306ea2014-06-19 15:39:54 +053010143 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010145 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010146
10147#ifdef FEATURE_WLAN_SCAN_PNO
10148 /*SME must send channel update configuration to RIVA*/
10149 sme_UpdateChannelConfig(pHddCtx->hHal);
10150#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010151 /* Send the update default channel list to the FW*/
10152 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010153
10154 /* Fwr capabilities received, Set the Dot11 mode */
10155 sme_SetDefDot11Mode(pHddCtx->hHal);
10156
Abhishek Singha306a442013-11-07 18:39:01 +053010157#ifndef CONFIG_ENABLE_LINUX_REG
10158 /*updating wiphy so that regulatory user hints can be processed*/
10159 if (wiphy)
10160 {
10161 regulatory_hint(wiphy, "00");
10162 }
10163#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010164 // Initialize the restart logic
10165 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010166
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010167 //Register the traffic monitor timer now
10168 if ( pHddCtx->cfg_ini->dynSplitscan)
10169 {
10170 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10171 VOS_TIMER_TYPE_SW,
10172 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10173 (void *)pHddCtx);
10174 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010175 wlan_hdd_cfg80211_nan_init(pHddCtx);
10176
Dino Mycle6fb96c12014-06-10 11:52:40 +053010177#ifdef WLAN_FEATURE_EXTSCAN
10178 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10179 wlan_hdd_cfg80211_extscan_callback,
10180 pHddCtx);
10181#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010182
10183#ifdef WLAN_NS_OFFLOAD
10184 // Register IPv6 notifier to notify if any change in IP
10185 // So that we can reconfigure the offload parameters
10186 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10187 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10188 if (ret)
10189 {
10190 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10191 }
10192 else
10193 {
10194 hddLog(LOGE, FL("Registered IPv6 notifier"));
10195 }
10196#endif
10197
10198 // Register IPv4 notifier to notify if any change in IP
10199 // So that we can reconfigure the offload parameters
10200 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10201 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10202 if (ret)
10203 {
10204 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10205 }
10206 else
10207 {
10208 hddLog(LOGE, FL("Registered IPv4 notifier"));
10209 }
10210
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 goto success;
10212
10213err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010214#ifdef WLAN_KD_READY_NOTIFIER
10215 nl_srv_exit(pHddCtx->ptt_pid);
10216#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010218#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010219err_reg_netdev:
10220 unregister_netdevice_notifier(&hdd_netdev_notifier);
10221
Jeff Johnson295189b2012-06-20 16:38:30 -070010222err_unregister_pmops:
10223 hddDevTmUnregisterNotifyCallback(pHddCtx);
10224 hddDeregisterPmOps(pHddCtx);
10225
Yue Ma0d4891e2013-08-06 17:01:45 -070010226 hdd_debugfs_exit(pHddCtx);
10227
Jeff Johnson295189b2012-06-20 16:38:30 -070010228#ifdef WLAN_BTAMP_FEATURE
10229err_bap_stop:
10230 WLANBAP_Stop(pVosContext);
10231#endif
10232
10233#ifdef WLAN_BTAMP_FEATURE
10234err_bap_close:
10235 WLANBAP_Close(pVosContext);
10236#endif
10237
Jeff Johnson295189b2012-06-20 16:38:30 -070010238err_close_adapter:
10239 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010240#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010241err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010242#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010243 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010244err_vosstop:
10245 vos_stop(pVosContext);
10246
Amar Singhala49cbc52013-10-08 18:37:44 -070010247err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 status = vos_sched_close( pVosContext );
10249 if (!VOS_IS_STATUS_SUCCESS(status)) {
10250 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10251 "%s: Failed to close VOSS Scheduler", __func__);
10252 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10253 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010254 vos_close(pVosContext );
10255
Amar Singhal0a402232013-10-11 20:57:16 -070010256err_vos_nv_close:
10257
c_hpothue6a36282014-03-19 12:27:38 +053010258#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010259 vos_nv_close();
10260
c_hpothu70f8d812014-03-22 22:59:23 +053010261#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010262
10263err_wdclose:
10264 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10265 vos_watchdog_close(pVosContext);
10266
Jeff Johnson295189b2012-06-20 16:38:30 -070010267err_config:
10268 kfree(pHddCtx->cfg_ini);
10269 pHddCtx->cfg_ini= NULL;
10270
10271err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010272 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010273 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010274 wiphy_free(wiphy) ;
10275 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 VOS_BUG(1);
10277
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010278 if (hdd_is_ssr_required())
10279 {
10280 /* WDI timeout had happened during load, so SSR is needed here */
10281 subsystem_restart("wcnss");
10282 msleep(5000);
10283 }
10284 hdd_set_ssr_required (VOS_FALSE);
10285
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010286 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010287
10288success:
10289 EXIT();
10290 return 0;
10291}
10292
10293/**---------------------------------------------------------------------------
10294
Jeff Johnson32d95a32012-09-10 13:15:23 -070010295 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010296
Jeff Johnson32d95a32012-09-10 13:15:23 -070010297 This is the driver entry point - called in different timeline depending
10298 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010299
10300 \param - None
10301
10302 \return - 0 for success, non zero for failure
10303
10304 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010305static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010306{
10307 VOS_STATUS status;
10308 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 struct device *dev = NULL;
10310 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010311#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10312 int max_retries = 0;
10313#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010314#ifdef HAVE_CBC_DONE
10315 int max_cbc_retries = 0;
10316#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010317
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010318#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10319 wlan_logging_sock_init_svc();
10320#endif
10321
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 ENTER();
10323
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010324 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010325
10326 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10327 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10328
Jeff Johnson295189b2012-06-20 16:38:30 -070010329#ifdef ANI_BUS_TYPE_PCI
10330
10331 dev = wcnss_wlan_get_device();
10332
10333#endif // ANI_BUS_TYPE_PCI
10334
10335#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010336
10337#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10338 /* wait until WCNSS driver downloads NV */
10339 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10340 msleep(1000);
10341 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010342
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010343 if (max_retries >= 5) {
10344 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010345 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010346#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10347 wlan_logging_sock_deinit_svc();
10348#endif
10349
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010350 return -ENODEV;
10351 }
10352#endif
10353
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010354#ifdef HAVE_CBC_DONE
10355 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10356 msleep(1000);
10357 }
10358 if (max_cbc_retries >= 10) {
10359 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10360 }
10361#endif
10362
Jeff Johnson295189b2012-06-20 16:38:30 -070010363 dev = wcnss_wlan_get_device();
10364#endif // ANI_BUS_TYPE_PLATFORM
10365
10366
10367 do {
10368 if (NULL == dev) {
10369 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10370 ret_status = -1;
10371 break;
10372 }
10373
Jeff Johnson295189b2012-06-20 16:38:30 -070010374#ifdef TIMER_MANAGER
10375 vos_timer_manager_init();
10376#endif
10377
10378 /* Preopen VOSS so that it is ready to start at least SAL */
10379 status = vos_preOpen(&pVosContext);
10380
10381 if (!VOS_IS_STATUS_SUCCESS(status))
10382 {
10383 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10384 ret_status = -1;
10385 break;
10386 }
10387
Sushant Kaushik02beb352015-06-04 15:15:01 +053010388 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010389#ifndef MODULE
10390 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10391 */
10392 hdd_set_conparam((v_UINT_t)con_mode);
10393#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010394
10395 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010396 if (hdd_wlan_startup(dev))
10397 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010398 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010399 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 vos_preClose( &pVosContext );
10401 ret_status = -1;
10402 break;
10403 }
10404
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 } while (0);
10406
10407 if (0 != ret_status)
10408 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010409#ifdef TIMER_MANAGER
10410 vos_timer_exit();
10411#endif
10412#ifdef MEMORY_DEBUG
10413 vos_mem_exit();
10414#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010415 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010416#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10417 wlan_logging_sock_deinit_svc();
10418#endif
10419
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10421 }
10422 else
10423 {
10424 //Send WLAN UP indication to Nlink Service
10425 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10426
10427 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 }
10429
10430 EXIT();
10431
10432 return ret_status;
10433}
10434
Jeff Johnson32d95a32012-09-10 13:15:23 -070010435/**---------------------------------------------------------------------------
10436
10437 \brief hdd_module_init() - Init Function
10438
10439 This is the driver entry point (invoked when module is loaded using insmod)
10440
10441 \param - None
10442
10443 \return - 0 for success, non zero for failure
10444
10445 --------------------------------------------------------------------------*/
10446#ifdef MODULE
10447static int __init hdd_module_init ( void)
10448{
10449 return hdd_driver_init();
10450}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010451#else /* #ifdef MODULE */
10452static int __init hdd_module_init ( void)
10453{
10454 /* Driver initialization is delayed to fwpath_changed_handler */
10455 return 0;
10456}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010457#endif /* #ifdef MODULE */
10458
Jeff Johnson295189b2012-06-20 16:38:30 -070010459
10460/**---------------------------------------------------------------------------
10461
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010462 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010463
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010464 This is the driver exit point (invoked when module is unloaded using rmmod
10465 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010466
10467 \param - None
10468
10469 \return - None
10470
10471 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010472static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010473{
10474 hdd_context_t *pHddCtx = NULL;
10475 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010476 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010477 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478
10479 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10480
10481 //Get the global vos context
10482 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10483
10484 if(!pVosContext)
10485 {
10486 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10487 goto done;
10488 }
10489
10490 //Get the HDD context.
10491 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10492
10493 if(!pHddCtx)
10494 {
10495 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10496 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010497 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10498 {
10499 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10500 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10501 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10502 hdd_wlan_exit(pHddCtx);
10503 vos_preClose( &pVosContext );
10504 goto done;
10505 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 else
10507 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010508 /* We wait for active entry threads to exit from driver
10509 * by waiting until rtnl_lock is available.
10510 */
10511 rtnl_lock();
10512 rtnl_unlock();
10513
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010514 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10515 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10516 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10517 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010519 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010520 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10521 msecs_to_jiffies(30000));
10522 if(!rc)
10523 {
10524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10525 "%s:SSR timedout, fatal error", __func__);
10526 VOS_BUG(0);
10527 }
10528 }
10529
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010530 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10531 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010532
c_hpothu8adb97b2014-12-08 19:38:20 +053010533 /* Driver Need to send country code 00 in below condition
10534 * 1) If gCountryCodePriority is set to 1; and last country
10535 * code set is through 11d. This needs to be done in case
10536 * when NV country code is 00.
10537 * This Needs to be done as when kernel store last country
10538 * code and if stored country code is not through 11d,
10539 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10540 * in next load/unload as soon as we get any country through
10541 * 11d. In sme_HandleChangeCountryCodeByUser
10542 * pMsg->countryCode will be last countryCode and
10543 * pMac->scan.countryCode11d will be country through 11d so
10544 * due to mismatch driver will disable 11d.
10545 *
10546 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010547
c_hpothu8adb97b2014-12-08 19:38:20 +053010548 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010549 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010550 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010551 {
10552 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010553 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010554 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10555 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010556
c_hpothu8adb97b2014-12-08 19:38:20 +053010557 //Do all the cleanup before deregistering the driver
10558 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010559 }
10560
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 vos_preClose( &pVosContext );
10562
10563#ifdef TIMER_MANAGER
10564 vos_timer_exit();
10565#endif
10566#ifdef MEMORY_DEBUG
10567 vos_mem_exit();
10568#endif
10569
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010570#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10571 wlan_logging_sock_deinit_svc();
10572#endif
10573
Jeff Johnson295189b2012-06-20 16:38:30 -070010574done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010575 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010576
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10578}
10579
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010580/**---------------------------------------------------------------------------
10581
10582 \brief hdd_module_exit() - Exit function
10583
10584 This is the driver exit point (invoked when module is unloaded using rmmod)
10585
10586 \param - None
10587
10588 \return - None
10589
10590 --------------------------------------------------------------------------*/
10591static void __exit hdd_module_exit(void)
10592{
10593 hdd_driver_exit();
10594}
10595
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010596#ifdef MODULE
10597static int fwpath_changed_handler(const char *kmessage,
10598 struct kernel_param *kp)
10599{
Jeff Johnson76052702013-04-16 13:55:05 -070010600 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010601}
10602
10603static int con_mode_handler(const char *kmessage,
10604 struct kernel_param *kp)
10605{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010606 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010607}
10608#else /* #ifdef MODULE */
10609/**---------------------------------------------------------------------------
10610
Jeff Johnson76052702013-04-16 13:55:05 -070010611 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010612
Jeff Johnson76052702013-04-16 13:55:05 -070010613 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010614 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010615 - invoked when module parameter fwpath is modified from userspace to signal
10616 initializing the WLAN driver or when con_mode is modified from userspace
10617 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010618
10619 \return - 0 for success, non zero for failure
10620
10621 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010622static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010623{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010624 int ret_status;
10625
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010626 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010627 ret_status = hdd_driver_init();
10628 wlan_hdd_inited = ret_status ? 0 : 1;
10629 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010630 }
10631
10632 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010633
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010634 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010635
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010636 ret_status = hdd_driver_init();
10637 wlan_hdd_inited = ret_status ? 0 : 1;
10638 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010639}
10640
Jeff Johnson295189b2012-06-20 16:38:30 -070010641/**---------------------------------------------------------------------------
10642
Jeff Johnson76052702013-04-16 13:55:05 -070010643 \brief fwpath_changed_handler() - Handler Function
10644
10645 Handle changes to the fwpath parameter
10646
10647 \return - 0 for success, non zero for failure
10648
10649 --------------------------------------------------------------------------*/
10650static int fwpath_changed_handler(const char *kmessage,
10651 struct kernel_param *kp)
10652{
10653 int ret;
10654
10655 ret = param_set_copystring(kmessage, kp);
10656 if (0 == ret)
10657 ret = kickstart_driver();
10658 return ret;
10659}
10660
10661/**---------------------------------------------------------------------------
10662
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010663 \brief con_mode_handler() -
10664
10665 Handler function for module param con_mode when it is changed by userspace
10666 Dynamically linked - do nothing
10667 Statically linked - exit and init driver, as in rmmod and insmod
10668
Jeff Johnson76052702013-04-16 13:55:05 -070010669 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010670
Jeff Johnson76052702013-04-16 13:55:05 -070010671 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010672
10673 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010674static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010675{
Jeff Johnson76052702013-04-16 13:55:05 -070010676 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010677
Jeff Johnson76052702013-04-16 13:55:05 -070010678 ret = param_set_int(kmessage, kp);
10679 if (0 == ret)
10680 ret = kickstart_driver();
10681 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010682}
10683#endif /* #ifdef MODULE */
10684
10685/**---------------------------------------------------------------------------
10686
Jeff Johnson295189b2012-06-20 16:38:30 -070010687 \brief hdd_get_conparam() -
10688
10689 This is the driver exit point (invoked when module is unloaded using rmmod)
10690
10691 \param - None
10692
10693 \return - tVOS_CON_MODE
10694
10695 --------------------------------------------------------------------------*/
10696tVOS_CON_MODE hdd_get_conparam ( void )
10697{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010698#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010699 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010700#else
10701 return (tVOS_CON_MODE)curr_con_mode;
10702#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010703}
10704void hdd_set_conparam ( v_UINT_t newParam )
10705{
10706 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010707#ifndef MODULE
10708 curr_con_mode = con_mode;
10709#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010710}
10711/**---------------------------------------------------------------------------
10712
10713 \brief hdd_softap_sta_deauth() - function
10714
10715 This to take counter measure to handle deauth req from HDD
10716
10717 \param - pAdapter - Pointer to the HDD
10718
10719 \param - enable - boolean value
10720
10721 \return - None
10722
10723 --------------------------------------------------------------------------*/
10724
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010725VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10726 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010727{
Jeff Johnson295189b2012-06-20 16:38:30 -070010728 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010729 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010730
10731 ENTER();
10732
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010733 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10734 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010735
10736 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010737 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010738 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010739
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010740 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010741
10742 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010743 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010744}
10745
10746/**---------------------------------------------------------------------------
10747
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010748 \brief hdd_del_all_sta() - function
10749
10750 This function removes all the stations associated on stopping AP/P2P GO.
10751
10752 \param - pAdapter - Pointer to the HDD
10753
10754 \return - None
10755
10756 --------------------------------------------------------------------------*/
10757
10758int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10759{
10760 v_U16_t i;
10761 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010762 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10763 ptSapContext pSapCtx = NULL;
10764 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10765 if(pSapCtx == NULL){
10766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10767 FL("psapCtx is NULL"));
10768 return 1;
10769 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010770 ENTER();
10771
10772 hddLog(VOS_TRACE_LEVEL_INFO,
10773 "%s: Delete all STAs associated.",__func__);
10774 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10775 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10776 )
10777 {
10778 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10779 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010780 if ((pSapCtx->aStaInfo[i].isUsed) &&
10781 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010782 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010783 struct tagCsrDelStaParams delStaParams;
10784
10785 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010786 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010787 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10788 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010789 &delStaParams);
10790 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010791 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010792 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010793 }
10794 }
10795 }
10796
10797 EXIT();
10798 return 0;
10799}
10800
10801/**---------------------------------------------------------------------------
10802
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 \brief hdd_softap_sta_disassoc() - function
10804
10805 This to take counter measure to handle deauth req from HDD
10806
10807 \param - pAdapter - Pointer to the HDD
10808
10809 \param - enable - boolean value
10810
10811 \return - None
10812
10813 --------------------------------------------------------------------------*/
10814
10815void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10816{
10817 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10818
10819 ENTER();
10820
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010821 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010822
10823 //Ignore request to disassoc bcmc station
10824 if( pDestMacAddress[0] & 0x1 )
10825 return;
10826
10827 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10828}
10829
10830void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10831{
10832 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10833
10834 ENTER();
10835
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010836 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010837
10838 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10839}
10840
Jeff Johnson295189b2012-06-20 16:38:30 -070010841/**---------------------------------------------------------------------------
10842 *
10843 * \brief hdd_get__concurrency_mode() -
10844 *
10845 *
10846 * \param - None
10847 *
10848 * \return - CONCURRENCY MODE
10849 *
10850 * --------------------------------------------------------------------------*/
10851tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10852{
10853 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10854 hdd_context_t *pHddCtx;
10855
10856 if (NULL != pVosContext)
10857 {
10858 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10859 if (NULL != pHddCtx)
10860 {
10861 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10862 }
10863 }
10864
10865 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010866 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 return VOS_STA;
10868}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010869v_BOOL_t
10870wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10871{
10872 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010873
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010874 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10875 if (pAdapter == NULL)
10876 {
10877 hddLog(VOS_TRACE_LEVEL_INFO,
10878 FL("GO doesn't exist"));
10879 return TRUE;
10880 }
10881 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10882 {
10883 hddLog(VOS_TRACE_LEVEL_INFO,
10884 FL("GO started"));
10885 return TRUE;
10886 }
10887 else
10888 /* wait till GO changes its interface to p2p device */
10889 hddLog(VOS_TRACE_LEVEL_INFO,
10890 FL("Del_bss called, avoid apps suspend"));
10891 return FALSE;
10892
10893}
Jeff Johnson295189b2012-06-20 16:38:30 -070010894/* Decide whether to allow/not the apps power collapse.
10895 * Allow apps power collapse if we are in connected state.
10896 * if not, allow only if we are in IMPS */
10897v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10898{
10899 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010900 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010901 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10903 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10904 hdd_adapter_t *pAdapter = NULL;
10905 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010906 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010907
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10909 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010910
Yathish9f22e662012-12-10 14:21:35 -080010911 concurrent_state = hdd_get_concurrency_mode();
10912
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010913 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10914 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10915 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010916#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010917
Yathish9f22e662012-12-10 14:21:35 -080010918 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010919 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010920 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10921 return TRUE;
10922#endif
10923
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 /*loop through all adapters. TBD fix for Concurrency */
10925 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10926 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10927 {
10928 pAdapter = pAdapterNode->pAdapter;
10929 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10930 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10931 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010932 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010933 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010934 && pmcState != STOPPED && pmcState != STANDBY &&
10935 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010936 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10937 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010939 if(pmcState == FULL_POWER &&
10940 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10941 {
10942 /*
10943 * When SCO indication comes from Coex module , host will
10944 * enter in to full power mode, but this should not prevent
10945 * apps processor power collapse.
10946 */
10947 hddLog(LOG1,
10948 FL("Allow apps power collapse"
10949 "even when sco indication is set"));
10950 return TRUE;
10951 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010952 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010953 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10954 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 return FALSE;
10956 }
10957 }
10958 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10959 pAdapterNode = pNext;
10960 }
10961 return TRUE;
10962}
10963
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010964/* Decides whether to send suspend notification to Riva
10965 * if any adapter is in BMPS; then it is required */
10966v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10967{
10968 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10969 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10970
10971 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10972 {
10973 return TRUE;
10974 }
10975 return FALSE;
10976}
10977
Jeff Johnson295189b2012-06-20 16:38:30 -070010978void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10979{
10980 switch(mode)
10981 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010982 case VOS_STA_MODE:
10983 case VOS_P2P_CLIENT_MODE:
10984 case VOS_P2P_GO_MODE:
10985 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010986 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010987 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010988 break;
10989 default:
10990 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010992 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10993 "Number of open sessions for mode %d = %d"),
10994 pHddCtx->concurrency_mode, mode,
10995 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010996}
10997
10998
10999void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11000{
11001 switch(mode)
11002 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011003 case VOS_STA_MODE:
11004 case VOS_P2P_CLIENT_MODE:
11005 case VOS_P2P_GO_MODE:
11006 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011007 pHddCtx->no_of_open_sessions[mode]--;
11008 if (!(pHddCtx->no_of_open_sessions[mode]))
11009 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 break;
11011 default:
11012 break;
11013 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011014 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11015 "Number of open sessions for mode %d = %d"),
11016 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11017
11018}
11019/**---------------------------------------------------------------------------
11020 *
11021 * \brief wlan_hdd_incr_active_session()
11022 *
11023 * This function increments the number of active sessions
11024 * maintained per device mode
11025 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11026 * Incase of SAP/P2P GO upon bss start it is incremented
11027 *
11028 * \param pHddCtx - HDD Context
11029 * \param mode - device mode
11030 *
11031 * \return - None
11032 *
11033 * --------------------------------------------------------------------------*/
11034void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11035{
11036 switch (mode) {
11037 case VOS_STA_MODE:
11038 case VOS_P2P_CLIENT_MODE:
11039 case VOS_P2P_GO_MODE:
11040 case VOS_STA_SAP_MODE:
11041 pHddCtx->no_of_active_sessions[mode]++;
11042 break;
11043 default:
11044 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11045 break;
11046 }
11047 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11048 mode,
11049 pHddCtx->no_of_active_sessions[mode]);
11050}
11051
11052/**---------------------------------------------------------------------------
11053 *
11054 * \brief wlan_hdd_decr_active_session()
11055 *
11056 * This function decrements the number of active sessions
11057 * maintained per device mode
11058 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11059 * Incase of SAP/P2P GO upon bss stop it is decremented
11060 *
11061 * \param pHddCtx - HDD Context
11062 * \param mode - device mode
11063 *
11064 * \return - None
11065 *
11066 * --------------------------------------------------------------------------*/
11067void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11068{
11069 switch (mode) {
11070 case VOS_STA_MODE:
11071 case VOS_P2P_CLIENT_MODE:
11072 case VOS_P2P_GO_MODE:
11073 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011074 if (pHddCtx->no_of_active_sessions[mode] > 0)
11075 pHddCtx->no_of_active_sessions[mode]--;
11076 else
11077 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11078 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011079 break;
11080 default:
11081 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11082 break;
11083 }
11084 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11085 mode,
11086 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011087}
11088
Jeff Johnsone7245742012-09-05 17:12:55 -070011089/**---------------------------------------------------------------------------
11090 *
11091 * \brief wlan_hdd_restart_init
11092 *
11093 * This function initalizes restart timer/flag. An internal function.
11094 *
11095 * \param - pHddCtx
11096 *
11097 * \return - None
11098 *
11099 * --------------------------------------------------------------------------*/
11100
11101static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11102{
11103 /* Initialize */
11104 pHddCtx->hdd_restart_retries = 0;
11105 atomic_set(&pHddCtx->isRestartInProgress, 0);
11106 vos_timer_init(&pHddCtx->hdd_restart_timer,
11107 VOS_TIMER_TYPE_SW,
11108 wlan_hdd_restart_timer_cb,
11109 pHddCtx);
11110}
11111/**---------------------------------------------------------------------------
11112 *
11113 * \brief wlan_hdd_restart_deinit
11114 *
11115 * This function cleans up the resources used. An internal function.
11116 *
11117 * \param - pHddCtx
11118 *
11119 * \return - None
11120 *
11121 * --------------------------------------------------------------------------*/
11122
11123static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11124{
11125
11126 VOS_STATUS vos_status;
11127 /* Block any further calls */
11128 atomic_set(&pHddCtx->isRestartInProgress, 1);
11129 /* Cleanup */
11130 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11131 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011132 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011133 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11134 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011135 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011136
11137}
11138
11139/**---------------------------------------------------------------------------
11140 *
11141 * \brief wlan_hdd_framework_restart
11142 *
11143 * This function uses a cfg80211 API to start a framework initiated WLAN
11144 * driver module unload/load.
11145 *
11146 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11147 *
11148 *
11149 * \param - pHddCtx
11150 *
11151 * \return - VOS_STATUS_SUCCESS: Success
11152 * VOS_STATUS_E_EMPTY: Adapter is Empty
11153 * VOS_STATUS_E_NOMEM: No memory
11154
11155 * --------------------------------------------------------------------------*/
11156
11157static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11158{
11159 VOS_STATUS status = VOS_STATUS_SUCCESS;
11160 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011161 int len = (sizeof (struct ieee80211_mgmt));
11162 struct ieee80211_mgmt *mgmt = NULL;
11163
11164 /* Prepare the DEAUTH managment frame with reason code */
11165 mgmt = kzalloc(len, GFP_KERNEL);
11166 if(mgmt == NULL)
11167 {
11168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11169 "%s: memory allocation failed (%d bytes)", __func__, len);
11170 return VOS_STATUS_E_NOMEM;
11171 }
11172 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011173
11174 /* Iterate over all adapters/devices */
11175 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011176 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11177 {
11178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11179 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11180 goto end;
11181 }
11182
Jeff Johnsone7245742012-09-05 17:12:55 -070011183 do
11184 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011185 if(pAdapterNode->pAdapter &&
11186 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011187 {
11188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11189 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11190 pAdapterNode->pAdapter->dev->name,
11191 pAdapterNode->pAdapter->device_mode,
11192 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011193 /*
11194 * CFG80211 event to restart the driver
11195 *
11196 * 'cfg80211_send_unprot_deauth' sends a
11197 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11198 * of SME(Linux Kernel) state machine.
11199 *
11200 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11201 * the driver.
11202 *
11203 */
11204
11205 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011206 }
11207 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11208 pAdapterNode = pNext;
11209 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11210
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011211 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011212 /* Free the allocated management frame */
11213 kfree(mgmt);
11214
Jeff Johnsone7245742012-09-05 17:12:55 -070011215 /* Retry until we unload or reach max count */
11216 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11217 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11218
11219 return status;
11220
11221}
11222/**---------------------------------------------------------------------------
11223 *
11224 * \brief wlan_hdd_restart_timer_cb
11225 *
11226 * Restart timer callback. An internal function.
11227 *
11228 * \param - User data:
11229 *
11230 * \return - None
11231 *
11232 * --------------------------------------------------------------------------*/
11233
11234void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11235{
11236 hdd_context_t *pHddCtx = usrDataForCallback;
11237 wlan_hdd_framework_restart(pHddCtx);
11238 return;
11239
11240}
11241
11242
11243/**---------------------------------------------------------------------------
11244 *
11245 * \brief wlan_hdd_restart_driver
11246 *
11247 * This function sends an event to supplicant to restart the WLAN driver.
11248 *
11249 * This function is called from vos_wlanRestart.
11250 *
11251 * \param - pHddCtx
11252 *
11253 * \return - VOS_STATUS_SUCCESS: Success
11254 * VOS_STATUS_E_EMPTY: Adapter is Empty
11255 * VOS_STATUS_E_ALREADY: Request already in progress
11256
11257 * --------------------------------------------------------------------------*/
11258VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11259{
11260 VOS_STATUS status = VOS_STATUS_SUCCESS;
11261
11262 /* A tight check to make sure reentrancy */
11263 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11264 {
Mihir Shetefd528652014-06-23 19:07:50 +053011265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011266 "%s: WLAN restart is already in progress", __func__);
11267
11268 return VOS_STATUS_E_ALREADY;
11269 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011270 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011271#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011272 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011273#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011274
Jeff Johnsone7245742012-09-05 17:12:55 -070011275 return status;
11276}
11277
Mihir Shetee1093ba2014-01-21 20:13:32 +053011278/**---------------------------------------------------------------------------
11279 *
11280 * \brief wlan_hdd_init_channels
11281 *
11282 * This function is used to initialize the channel list in CSR
11283 *
11284 * This function is called from hdd_wlan_startup
11285 *
11286 * \param - pHddCtx: HDD context
11287 *
11288 * \return - VOS_STATUS_SUCCESS: Success
11289 * VOS_STATUS_E_FAULT: Failure reported by SME
11290
11291 * --------------------------------------------------------------------------*/
11292static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11293{
11294 eHalStatus status;
11295
11296 status = sme_InitChannels(pHddCtx->hHal);
11297 if (HAL_STATUS_SUCCESS(status))
11298 {
11299 return VOS_STATUS_SUCCESS;
11300 }
11301 else
11302 {
11303 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11304 __func__, status);
11305 return VOS_STATUS_E_FAULT;
11306 }
11307}
11308
Mihir Shete04206452014-11-20 17:50:58 +053011309#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011310VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011311{
11312 eHalStatus status;
11313
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011314 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011315 if (HAL_STATUS_SUCCESS(status))
11316 {
11317 return VOS_STATUS_SUCCESS;
11318 }
11319 else
11320 {
11321 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11322 __func__, status);
11323 return VOS_STATUS_E_FAULT;
11324 }
11325}
Mihir Shete04206452014-11-20 17:50:58 +053011326#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011327/*
11328 * API to find if there is any STA or P2P-Client is connected
11329 */
11330VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11331{
11332 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11333}
Jeff Johnsone7245742012-09-05 17:12:55 -070011334
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011335
11336/*
11337 * API to find if the firmware will send logs using DXE channel
11338 */
11339v_U8_t hdd_is_fw_logging_enabled(void)
11340{
11341 hdd_context_t *pHddCtx;
11342
11343 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11344 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11345
Sachin Ahuja084313e2015-05-21 17:57:10 +053011346 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011347}
11348
Agarwal Ashish57e84372014-12-05 18:26:53 +053011349/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011350 * API to find if the firmware will send trace logs using DXE channel
11351 */
11352v_U8_t hdd_is_fw_ev_logging_enabled(void)
11353{
11354 hdd_context_t *pHddCtx;
11355
11356 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11357 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11358
11359 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11360}
11361/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011362 * API to find if there is any session connected
11363 */
11364VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11365{
11366 return sme_is_any_session_connected(pHddCtx->hHal);
11367}
11368
11369
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011370int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11371{
11372 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11373 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011374 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011375 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011376
11377 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011378 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011379 if (pScanInfo->mScanPending)
11380 {
c_hpothua3d45d52015-01-05 14:11:17 +053011381 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11382 eCSR_SCAN_ABORT_DEFAULT);
11383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11384 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011385
c_hpothua3d45d52015-01-05 14:11:17 +053011386 /* If there is active scan command lets wait for the completion else
11387 * there is no need to wait as scan command might be in the SME pending
11388 * command list.
11389 */
11390 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11391 {
c_hpothua3d45d52015-01-05 14:11:17 +053011392 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011393 &pScanInfo->abortscan_event_var,
11394 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011395 if (0 >= status)
11396 {
11397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011398 "%s: Timeout or Interrupt occurred while waiting for abort"
11399 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011400 return -ETIMEDOUT;
11401 }
11402 }
11403 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11404 {
11405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11406 FL("hdd_abort_mac_scan failed"));
11407 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011408 }
11409 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011410 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011411}
11412
c_hpothu225aa7c2014-10-22 17:45:13 +053011413VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11414{
11415 hdd_adapter_t *pAdapter;
11416 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11417 VOS_STATUS vosStatus;
11418
11419 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11420 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11421 {
11422 pAdapter = pAdapterNode->pAdapter;
11423 if (NULL != pAdapter)
11424 {
11425 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11426 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11427 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11428 {
11429 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11430 pAdapter->device_mode);
11431 if (VOS_STATUS_SUCCESS !=
11432 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11433 {
11434 hddLog(LOGE, FL("failed to abort ROC"));
11435 return VOS_STATUS_E_FAILURE;
11436 }
11437 }
11438 }
11439 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11440 pAdapterNode = pNext;
11441 }
11442 return VOS_STATUS_SUCCESS;
11443}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011444
Mihir Shete0be28772015-02-17 18:42:14 +053011445hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11446{
11447 hdd_adapter_t *pAdapter;
11448 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11449 hdd_cfg80211_state_t *cfgState;
11450 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11451 VOS_STATUS vosStatus;
11452
11453 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11454 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11455 {
11456 pAdapter = pAdapterNode->pAdapter;
11457 if (NULL != pAdapter)
11458 {
11459 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11460 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11461 if (pRemainChanCtx)
11462 break;
11463 }
11464 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11465 pAdapterNode = pNext;
11466 }
11467 return pRemainChanCtx;
11468}
11469
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011470/**
11471 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11472 *
11473 * @pHddCtx: HDD context within host driver
11474 * @dfsScanMode: dfsScanMode passed from ioctl
11475 *
11476 */
11477
11478VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11479 tANI_U8 dfsScanMode)
11480{
11481 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11482 hdd_adapter_t *pAdapter;
11483 VOS_STATUS vosStatus;
11484 hdd_station_ctx_t *pHddStaCtx;
11485 eHalStatus status = eHAL_STATUS_SUCCESS;
11486
11487 if(!pHddCtx)
11488 {
11489 hddLog(LOGE, FL("HDD context is Null"));
11490 return eHAL_STATUS_FAILURE;
11491 }
11492
11493 if (pHddCtx->scan_info.mScanPending)
11494 {
11495 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11496 pHddCtx->scan_info.sessionId);
11497 hdd_abort_mac_scan(pHddCtx,
11498 pHddCtx->scan_info.sessionId,
11499 eCSR_SCAN_ABORT_DEFAULT);
11500 }
11501
11502 if (!dfsScanMode)
11503 {
11504 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11505 while ((NULL != pAdapterNode) &&
11506 (VOS_STATUS_SUCCESS == vosStatus))
11507 {
11508 pAdapter = pAdapterNode->pAdapter;
11509
11510 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11511 {
11512 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11513
11514 if(!pHddStaCtx)
11515 {
11516 hddLog(LOGE, FL("HDD STA context is Null"));
11517 return eHAL_STATUS_FAILURE;
11518 }
11519
11520 /* if STA is already connected on DFS channel,
11521 disconnect immediately*/
11522 if (hdd_connIsConnected(pHddStaCtx) &&
11523 (NV_CHANNEL_DFS ==
11524 vos_nv_getChannelEnabledState(
11525 pHddStaCtx->conn_info.operationChannel)))
11526 {
11527 status = sme_RoamDisconnect(pHddCtx->hHal,
11528 pAdapter->sessionId,
11529 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11530 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11531 "sme_RoamDisconnect returned with status: %d"
11532 "for sessionid: %d"), pHddStaCtx->conn_info.
11533 operationChannel, status, pAdapter->sessionId);
11534 }
11535 }
11536
11537 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11538 &pNext);
11539 pAdapterNode = pNext;
11540 }
11541 }
11542
11543 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11544 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11545 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11546
11547 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11548 if (!HAL_STATUS_SUCCESS(status))
11549 {
11550 hddLog(LOGE,
11551 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11552 return status;
11553 }
11554
11555 return status;
11556}
11557
Nirav Shah7e3c8132015-06-22 23:51:42 +053011558static int hdd_log2_ceil(unsigned value)
11559{
11560 /* need to switch to unsigned math so that negative values
11561 * will right-shift towards 0 instead of -1
11562 */
11563 unsigned tmp = value;
11564 int log2 = -1;
11565
11566 if (value == 0)
11567 return 0;
11568
11569 while (tmp) {
11570 log2++;
11571 tmp >>= 1;
11572 }
11573 if (1U << log2 != value)
11574 log2++;
11575
11576 return log2;
11577}
11578
11579/**
11580 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11581 * @pAdapter: adapter handle
11582 *
11583 * Return: vos status
11584 */
11585VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11586{
11587 int hash_elem, log2, i;
11588
11589 spin_lock_bh( &pAdapter->sta_hash_lock);
11590 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11591 spin_unlock_bh( &pAdapter->sta_hash_lock);
11592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11593 "%s: hash already attached for session id %d",
11594 __func__, pAdapter->sessionId);
11595 return VOS_STATUS_SUCCESS;
11596 }
11597 spin_unlock_bh( &pAdapter->sta_hash_lock);
11598
11599 hash_elem = WLAN_MAX_STA_COUNT;
11600 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11601 log2 = hdd_log2_ceil(hash_elem);
11602 hash_elem = 1 << log2;
11603
11604 pAdapter->sta_id_hash.mask = hash_elem - 1;
11605 pAdapter->sta_id_hash.idx_bits = log2;
11606 pAdapter->sta_id_hash.bins =
11607 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11608 if (!pAdapter->sta_id_hash.bins) {
11609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11610 "%s: malloc failed for session %d",
11611 __func__, pAdapter->sessionId);
11612 return VOS_STATUS_E_NOMEM;
11613 }
11614
11615 for (i = 0; i < hash_elem; i++)
11616 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11617
11618 spin_lock_bh( &pAdapter->sta_hash_lock);
11619 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11620 spin_unlock_bh( &pAdapter->sta_hash_lock);
11621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11622 "%s: Station ID Hash attached for session id %d",
11623 __func__, pAdapter->sessionId);
11624
11625 return VOS_STATUS_SUCCESS;
11626}
11627
11628/**
11629 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11630 * @pAdapter: adapter handle
11631 *
11632 * Return: vos status
11633 */
11634VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11635{
11636 int hash_elem, i;
11637 v_SIZE_t size;
11638
11639 spin_lock_bh( &pAdapter->sta_hash_lock);
11640 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11641 spin_unlock_bh( &pAdapter->sta_hash_lock);
11642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11643 "%s: hash not initialized for session id %d",
11644 __func__, pAdapter->sessionId);
11645 return VOS_STATUS_SUCCESS;
11646 }
11647
11648 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11649 spin_unlock_bh( &pAdapter->sta_hash_lock);
11650
11651 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11652
11653 /* free all station info*/
11654 for (i = 0; i < hash_elem; i++) {
11655 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11656 if (size != 0) {
11657 VOS_STATUS status;
11658 hdd_staid_hash_node_t *sta_info_node = NULL;
11659 hdd_staid_hash_node_t *next_node = NULL;
11660 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11661 (hdd_list_node_t**) &sta_info_node );
11662
11663 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11664 {
11665 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11666 &sta_info_node->node);
11667 vos_mem_free(sta_info_node);
11668
11669 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11670 (hdd_list_node_t*)sta_info_node,
11671 (hdd_list_node_t**)&next_node);
11672 sta_info_node = next_node;
11673 }
11674 }
11675 }
11676
11677 vos_mem_free(pAdapter->sta_id_hash.bins);
11678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11679 "%s: Station ID Hash detached for session id %d",
11680 __func__, pAdapter->sessionId);
11681 return VOS_STATUS_SUCCESS;
11682}
11683
11684/**
11685 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11686 * @pAdapter: adapter handle
11687 * @mac_addr_in: input mac address
11688 *
11689 * Return: index derived from mac address
11690 */
11691int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11692 v_MACADDR_t *mac_addr_in)
11693{
11694 uint16 index;
11695 struct hdd_align_mac_addr_t * mac_addr =
11696 (struct hdd_align_mac_addr_t *)mac_addr_in;
11697
11698 index = mac_addr->bytes_ab ^
11699 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11700 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11701 index &= pAdapter->sta_id_hash.mask;
11702 return index;
11703}
11704
11705/**
11706 * hdd_sta_id_hash_add_entry() - add entry in hash
11707 * @pAdapter: adapter handle
11708 * @sta_id: station id
11709 * @mac_addr: mac address
11710 *
11711 * Return: vos status
11712 */
11713VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11714 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11715{
11716 uint16 index;
11717 hdd_staid_hash_node_t *sta_info_node = NULL;
11718
11719 spin_lock_bh( &pAdapter->sta_hash_lock);
11720 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11721 spin_unlock_bh( &pAdapter->sta_hash_lock);
11722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11723 "%s: hash is not initialized for session id %d",
11724 __func__, pAdapter->sessionId);
11725 return VOS_STATUS_E_FAILURE;
11726 }
11727
11728 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11729 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11730 if (!sta_info_node) {
11731 spin_unlock_bh( &pAdapter->sta_hash_lock);
11732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11733 "%s: malloc failed", __func__);
11734 return VOS_STATUS_E_NOMEM;
11735 }
11736
11737 sta_info_node->sta_id = sta_id;
11738 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11739
11740 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11741 (hdd_list_node_t*) sta_info_node );
11742 spin_unlock_bh( &pAdapter->sta_hash_lock);
11743 return VOS_STATUS_SUCCESS;
11744}
11745
11746/**
11747 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11748 * @pAdapter: adapter handle
11749 * @sta_id: station id
11750 * @mac_addr: mac address
11751 *
11752 * Return: vos status
11753 */
11754VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11755 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11756{
11757 uint16 index;
11758 VOS_STATUS status;
11759 hdd_staid_hash_node_t *sta_info_node = NULL;
11760 hdd_staid_hash_node_t *next_node = NULL;
11761
11762 spin_lock_bh( &pAdapter->sta_hash_lock);
11763 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11764 spin_unlock_bh( &pAdapter->sta_hash_lock);
11765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11766 "%s: hash is not initialized for session id %d",
11767 __func__, pAdapter->sessionId);
11768 return VOS_STATUS_E_FAILURE;
11769 }
11770
11771 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11772 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11773 (hdd_list_node_t**) &sta_info_node );
11774
11775 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11776 {
11777 if (sta_info_node->sta_id == sta_id) {
11778 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11779 &sta_info_node->node);
11780 vos_mem_free(sta_info_node);
11781 break;
11782 }
11783 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11784 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11785 sta_info_node = next_node;
11786 }
11787 spin_unlock_bh( &pAdapter->sta_hash_lock);
11788 return status;
11789}
11790
11791/**
11792 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11793 * @pAdapter: adapter handle
11794 * @mac_addr_in: mac address
11795 *
11796 * Return: station id
11797 */
11798int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11799 v_MACADDR_t *mac_addr_in)
11800{
11801 uint8 is_found = 0;
11802 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11803 uint16 index;
11804 VOS_STATUS status;
11805 hdd_staid_hash_node_t *sta_info_node = NULL;
11806 hdd_staid_hash_node_t *next_node = NULL;
11807
11808 spin_lock_bh( &pAdapter->sta_hash_lock);
11809 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11810 spin_unlock_bh( &pAdapter->sta_hash_lock);
11811 hddLog(VOS_TRACE_LEVEL_ERROR,
11812 FL("hash is not initialized for session id %d"),
11813 pAdapter->sessionId);
11814 return HDD_WLAN_INVALID_STA_ID;
11815 }
11816
11817 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11818 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11819 (hdd_list_node_t**) &sta_info_node );
11820
11821 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11822 {
11823 if (vos_mem_compare(&sta_info_node->mac_addr,
11824 mac_addr_in, sizeof(v_MACADDR_t))) {
11825 is_found = 1;
11826 sta_id = sta_info_node->sta_id;
11827 break;
11828 }
11829 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11830 (hdd_list_node_t*)sta_info_node,
11831 (hdd_list_node_t**)&next_node);
11832 sta_info_node = next_node;
11833 }
11834 spin_unlock_bh( &pAdapter->sta_hash_lock);
11835 return sta_id;
11836}
11837
Jeff Johnson295189b2012-06-20 16:38:30 -070011838//Register the module init/exit functions
11839module_init(hdd_module_init);
11840module_exit(hdd_module_exit);
11841
11842MODULE_LICENSE("Dual BSD/GPL");
11843MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11844MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11845
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011846module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11847 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011848
Jeff Johnson76052702013-04-16 13:55:05 -070011849module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011850 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011851
11852module_param(enable_dfs_chan_scan, int,
11853 S_IRUSR | S_IRGRP | S_IROTH);
11854
11855module_param(enable_11d, int,
11856 S_IRUSR | S_IRGRP | S_IROTH);
11857
11858module_param(country_code, charp,
11859 S_IRUSR | S_IRGRP | S_IROTH);