blob: 950fb0e15c3ffa3351c67323264aef7de17dcf78 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
210 struct sk_buff *skb);
211
212#ifdef WLAN_FEATURE_PACKET_FILTERING
213static void hdd_set_multicast_list(struct net_device *dev);
214#endif
215
216void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
217
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800218#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800219void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
220static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700221static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
222 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
223 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700224static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
225 tANI_U8 *pTargetApBssid,
226 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800227#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530228
229/* Store WLAN driver info in a global variable such that crash debugger
230 can extract it from driver debug symbol and crashdump for post processing */
231tANI_U8 g_wlan_driver[ ] = "pronto_driver";
232
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530238const char * hdd_device_modetoString(v_U8_t device_mode)
239{
240 switch(device_mode)
241 {
242 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
243 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
246 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
247 CASE_RETURN_STRING( WLAN_HDD_FTM );
248 CASE_RETURN_STRING( WLAN_HDD_IBSS );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
250 default:
251 return "device_mode Unknown";
252 }
253}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530254
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530255static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700256 unsigned long state,
257 void *ndev)
258{
259 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#ifdef WLAN_BTAMP_FEATURE
263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530265 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
267 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700269 (strncmp(dev->name, "p2p", 3)))
270 return NOTIFY_DONE;
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 VOS_ASSERT(0);
279 return NOTIFY_DONE;
280 }
281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
283 if (NULL == pHddCtx)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
286 VOS_ASSERT(0);
287 return NOTIFY_DONE;
288 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800289 if (pHddCtx->isLogpInProgress)
290 return NOTIFY_DONE;
291
Jeff Johnson27cee452013-03-27 11:10:24 -0700292
293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
294 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 switch (state) {
297 case NETDEV_REGISTER:
298 break;
299
300 case NETDEV_UNREGISTER:
301 break;
302
303 case NETDEV_UP:
304 break;
305
306 case NETDEV_DOWN:
307 break;
308
309 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700310 if(TRUE == pAdapter->isLinkUpSvcNeeded)
311 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 break;
313
314 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530316 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
319 "%s: Timeout occurred while waiting for abortscan %ld",
320 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 }
322 else
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530325 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 status = WLANBAP_StopAmp();
330 if(VOS_STATUS_SUCCESS != status )
331 {
332 pHddCtx->isAmpAllowed = VOS_TRUE;
333 hddLog(VOS_TRACE_LEVEL_FATAL,
334 "%s: Failed to stop AMP", __func__);
335 }
336 else
337 {
338 //a state m/c implementation in PAL is TBD to avoid this delay
339 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700340 if ( pHddCtx->isAmpAllowed )
341 {
342 WLANBAP_DeregisterFromHCI();
343 pHddCtx->isAmpAllowed = VOS_FALSE;
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346#endif //WLAN_BTAMP_FEATURE
347 break;
348
349 default:
350 break;
351 }
352
353 return NOTIFY_DONE;
354}
355
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530356static int hdd_netdev_notifier_call(struct notifier_block * nb,
357 unsigned long state,
358 void *ndev)
359{
360 int ret;
361 vos_ssr_protect(__func__);
362 ret = __hdd_netdev_notifier_call( nb, state, ndev);
363 vos_ssr_unprotect(__func__);
364 return ret;
365}
366
Jeff Johnson295189b2012-06-20 16:38:30 -0700367struct notifier_block hdd_netdev_notifier = {
368 .notifier_call = hdd_netdev_notifier_call,
369};
370
371/*---------------------------------------------------------------------------
372 * Function definitions
373 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700374void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
375void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700377static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700378#ifndef MODULE
379/* current con_mode - used only for statically linked driver
380 * con_mode is changed by userspace to indicate a mode change which will
381 * result in calling the module exit and init functions. The module
382 * exit function will clean up based on the value of con_mode prior to it
383 * being changed by userspace. So curr_con_mode records the current con_mode
384 * for exit when con_mode becomes the next mode for init
385 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700386static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700387#endif
388
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800389/**---------------------------------------------------------------------------
390
391 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
392
393 Called immediately after the cfg.ini is read in order to configure
394 the desired trace levels.
395
396 \param - moduleId - module whose trace level is being configured
397 \param - bitmask - bitmask of log levels to be enabled
398
399 \return - void
400
401 --------------------------------------------------------------------------*/
402static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
403{
404 wpt_tracelevel level;
405
406 /* if the bitmask is the default value, then a bitmask was not
407 specified in cfg.ini, so leave the logging level alone (it
408 will remain at the "compiled in" default value) */
409 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
410 {
411 return;
412 }
413
414 /* a mask was specified. start by disabling all logging */
415 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
416
417 /* now cycle through the bitmask until all "set" bits are serviced */
418 level = VOS_TRACE_LEVEL_FATAL;
419 while (0 != bitmask)
420 {
421 if (bitmask & 1)
422 {
423 vos_trace_setValue(moduleId, level, 1);
424 }
425 level++;
426 bitmask >>= 1;
427 }
428}
429
430
Jeff Johnson295189b2012-06-20 16:38:30 -0700431/**---------------------------------------------------------------------------
432
433 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
434
435 Called immediately after the cfg.ini is read in order to configure
436 the desired trace levels in the WDI.
437
438 \param - moduleId - module whose trace level is being configured
439 \param - bitmask - bitmask of log levels to be enabled
440
441 \return - void
442
443 --------------------------------------------------------------------------*/
444static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
445{
446 wpt_tracelevel level;
447
448 /* if the bitmask is the default value, then a bitmask was not
449 specified in cfg.ini, so leave the logging level alone (it
450 will remain at the "compiled in" default value) */
451 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
452 {
453 return;
454 }
455
456 /* a mask was specified. start by disabling all logging */
457 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
458
459 /* now cycle through the bitmask until all "set" bits are serviced */
460 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
461 while (0 != bitmask)
462 {
463 if (bitmask & 1)
464 {
465 wpalTraceSetLevel(moduleId, level, 1);
466 }
467 level++;
468 bitmask >>= 1;
469 }
470}
Jeff Johnson295189b2012-06-20 16:38:30 -0700471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530472/*
473 * FUNCTION: wlan_hdd_validate_context
474 * This function is used to check the HDD context
475 */
476int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
477{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478
479 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
480 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 "%s: HDD context is Null", __func__);
483 return -ENODEV;
484 }
485
486 if (pHddCtx->isLogpInProgress)
487 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530489 "%s: LOGP %s. Ignore!!", __func__,
490 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
491 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 return -EAGAIN;
493 }
494
Mihir Shete18156292014-03-11 15:38:30 +0530495 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530498 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
499 return -EAGAIN;
500 }
501 return 0;
502}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700503#ifdef CONFIG_ENABLE_LINUX_REG
504void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
505{
506 hdd_adapter_t *pAdapter = NULL;
507 hdd_station_ctx_t *pHddStaCtx = NULL;
508 eCsrPhyMode phyMode;
509 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530510
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700511 if (NULL == pHddCtx)
512 {
513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
514 "HDD Context is null !!");
515 return ;
516 }
517
518 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
519 if (NULL == pAdapter)
520 {
521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
522 "pAdapter is null !!");
523 return ;
524 }
525
526 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
527 if (NULL == pHddStaCtx)
528 {
529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
530 "pHddStaCtx is null !!");
531 return ;
532 }
533
534 cfg_param = pHddCtx->cfg_ini;
535 if (NULL == cfg_param)
536 {
537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
538 "cfg_params not available !!");
539 return ;
540 }
541
542 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
543
544 if (!pHddCtx->isVHT80Allowed)
545 {
546 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
547 (eCSR_DOT11_MODE_11ac == phyMode) ||
548 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
549 {
550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
551 "Setting phymode to 11n!!");
552 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
553 }
554 }
555 else
556 {
557 /*New country Supports 11ac as well resetting value back from .ini*/
558 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
559 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
560 return ;
561 }
562
563 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
564 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
565 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
566 {
567 VOS_STATUS vosStatus;
568
569 // need to issue a disconnect to CSR.
570 INIT_COMPLETION(pAdapter->disconnect_comp_var);
571 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
572 pAdapter->sessionId,
573 eCSR_DISCONNECT_REASON_UNSPECIFIED );
574
575 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530576 {
577 long ret;
578
579 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700580 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 if (0 >= ret)
582 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
583 ret);
584 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700585
586 }
587}
588#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
590{
591 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
592 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
593 hdd_config_t *cfg_param;
594 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530595 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530596
597 if (NULL == pHddCtx)
598 {
599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
600 "HDD Context is null !!");
601 return ;
602 }
603
604 cfg_param = pHddCtx->cfg_ini;
605
606 if (NULL == cfg_param)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
609 "cfg_params not available !!");
610 return ;
611 }
612
613 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
614
615 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
616 {
617 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
618 (eCSR_DOT11_MODE_11ac == phyMode) ||
619 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
620 {
621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
622 "Setting phymode to 11n!!");
623 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
624 }
625 }
626 else
627 {
628 /*New country Supports 11ac as well resetting value back from .ini*/
629 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
630 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
631 return ;
632 }
633
634 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
635 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
636 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
637 {
638 VOS_STATUS vosStatus;
639
640 // need to issue a disconnect to CSR.
641 INIT_COMPLETION(pAdapter->disconnect_comp_var);
642 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
643 pAdapter->sessionId,
644 eCSR_DISCONNECT_REASON_UNSPECIFIED );
645
646 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530647 {
648 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530650 if (ret <= 0)
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
653 "wait on disconnect_comp_var is failed %ld", ret);
654 }
655 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
657 }
658}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700659#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530660
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700661void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
662{
663 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
664 hdd_config_t *cfg_param;
665
666 if (NULL == pHddCtx)
667 {
668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
669 "HDD Context is null !!");
670 return ;
671 }
672
673 cfg_param = pHddCtx->cfg_ini;
674
675 if (NULL == cfg_param)
676 {
677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
678 "cfg_params not available !!");
679 return ;
680 }
681
Agarwal Ashish738843c2014-09-25 12:27:56 +0530682 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
683 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700684 {
685 /*New country doesn't support DFS */
686 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
687 }
688 else
689 {
690 /*New country Supports DFS as well resetting value back from .ini*/
691 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
692 }
693
694}
695
Rajeev79dbe4c2013-10-05 11:03:42 +0530696#ifdef FEATURE_WLAN_BATCH_SCAN
697
698/**---------------------------------------------------------------------------
699
700 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
701 input string
702
703 This function extracts assigned integer from string in below format:
704 "STRING=10" : extracts integer 10 from this string
705
706 \param - pInPtr Pointer to input string
707 \param - base Base for string to int conversion(10 for decimal 16 for hex)
708 \param - pOutPtr Pointer to variable in which extracted integer needs to be
709 assigned
710 \param - pLastArg to tell whether it is last arguement in input string or
711 not
712
713 \return - NULL for failure cases
714 pointer to next arguement in input string for success cases
715 --------------------------------------------------------------------------*/
716static tANI_U8 *
717hdd_extract_assigned_int_from_str
718(
719 tANI_U8 *pInPtr,
720 tANI_U8 base,
721 tANI_U32 *pOutPtr,
722 tANI_U8 *pLastArg
723)
724{
725 int tempInt;
726 int v = 0;
727 char buf[32];
728 int val = 0;
729 *pLastArg = FALSE;
730
731 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
732 if (NULL == pInPtr)
733 {
734 return NULL;
735 }
736
737 pInPtr++;
738
739 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
740
741 val = sscanf(pInPtr, "%32s ", buf);
742 if (val < 0 && val > strlen(pInPtr))
743 {
744 return NULL;
745 }
746 pInPtr += val;
747 v = kstrtos32(buf, base, &tempInt);
748 if (v < 0)
749 {
750 return NULL;
751 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800752 if (tempInt < 0)
753 {
754 tempInt = 0;
755 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530756 *pOutPtr = tempInt;
757
758 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
759 if (NULL == pInPtr)
760 {
761 *pLastArg = TRUE;
762 return NULL;
763 }
764 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
765
766 return pInPtr;
767}
768
769/**---------------------------------------------------------------------------
770
771 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
772 input string
773
774 This function extracts assigned character from string in below format:
775 "STRING=A" : extracts char 'A' from this string
776
777 \param - pInPtr Pointer to input string
778 \param - pOutPtr Pointer to variable in which extracted char needs to be
779 assigned
780 \param - pLastArg to tell whether it is last arguement in input string or
781 not
782
783 \return - NULL for failure cases
784 pointer to next arguement in input string for success cases
785 --------------------------------------------------------------------------*/
786static tANI_U8 *
787hdd_extract_assigned_char_from_str
788(
789 tANI_U8 *pInPtr,
790 tANI_U8 *pOutPtr,
791 tANI_U8 *pLastArg
792)
793{
794 *pLastArg = FALSE;
795
796 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
797 if (NULL == pInPtr)
798 {
799 return NULL;
800 }
801
802 pInPtr++;
803
804 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
805
806 *pOutPtr = *pInPtr;
807
808 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
809 if (NULL == pInPtr)
810 {
811 *pLastArg = TRUE;
812 return NULL;
813 }
814 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
815
816 return pInPtr;
817}
818
819
820/**---------------------------------------------------------------------------
821
822 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
823
824 This function parses set batch scan command in below format:
825 WLS_BATCHING_SET <space> followed by below arguements
826 "SCANFREQ=XX" : Optional defaults to 30 sec
827 "MSCAN=XX" : Required number of scans to attempt to batch
828 "BESTN=XX" : Best Network (RSSI) defaults to 16
829 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
830 A. implies only 5 GHz , B. implies only 2.4GHz
831 "RTT=X" : optional defaults to 0
832 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
833 error
834
835 For example input commands:
836 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
837 translated into set batch scan with following parameters:
838 a) Frequence 60 seconds
839 b) Batch 10 scans together
840 c) Best RSSI to be 20
841 d) 5GHz band only
842 e) RTT is equal to 0
843
844 \param - pValue Pointer to input channel list
845 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
846
847 \return - 0 for success non-zero for failure
848
849 --------------------------------------------------------------------------*/
850static int
851hdd_parse_set_batchscan_command
852(
853 tANI_U8 *pValue,
854 tSirSetBatchScanReq *pHddSetBatchScanReq
855)
856{
857 tANI_U8 *inPtr = pValue;
858 tANI_U8 val = 0;
859 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 tANI_U32 nScanFreq;
861 tANI_U32 nMscan;
862 tANI_U32 nBestN;
863 tANI_U8 ucRfBand;
864 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800865 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530866
867 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800868 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
869 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
870 nRtt = 0;
871 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530872
873 /*go to space after WLS_BATCHING_SET command*/
874 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
875 /*no argument after the command*/
876 if (NULL == inPtr)
877 {
878 return -EINVAL;
879 }
880
881 /*no space after the command*/
882 else if (SPACE_ASCII_VALUE != *inPtr)
883 {
884 return -EINVAL;
885 }
886
887 /*removing empty spaces*/
888 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
889
890 /*no argument followed by spaces*/
891 if ('\0' == *inPtr)
892 {
893 return -EINVAL;
894 }
895
896 /*check and parse SCANFREQ*/
897 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
898 {
899 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901
Rajeev Kumarc933d982013-11-18 20:04:20 -0800902 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800904 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800905 }
906
Rajeev79dbe4c2013-10-05 11:03:42 +0530907 if ( (NULL == inPtr) || (TRUE == lastArg))
908 {
909 return -EINVAL;
910 }
911 }
912
913 /*check and parse MSCAN*/
914 if ((strncmp(inPtr, "MSCAN", 5) == 0))
915 {
916 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800917 &nMscan, &lastArg);
918
919 if (0 == nMscan)
920 {
921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
922 "invalid MSCAN=%d", nMscan);
923 return -EINVAL;
924 }
925
Rajeev79dbe4c2013-10-05 11:03:42 +0530926 if (TRUE == lastArg)
927 {
928 goto done;
929 }
930 else if (NULL == inPtr)
931 {
932 return -EINVAL;
933 }
934 }
935 else
936 {
937 return -EINVAL;
938 }
939
940 /*check and parse BESTN*/
941 if ((strncmp(inPtr, "BESTN", 5) == 0))
942 {
943 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945
Rajeev Kumarc933d982013-11-18 20:04:20 -0800946 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800947 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800948 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800949 }
950
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 if (TRUE == lastArg)
952 {
953 goto done;
954 }
955 else if (NULL == inPtr)
956 {
957 return -EINVAL;
958 }
959 }
960
961 /*check and parse CHANNEL*/
962 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
963 {
964 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800965
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 if (('A' == val) || ('a' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else if (('B' == val) || ('b' == val))
971 {
c_hpothuebf89732014-02-25 13:00:24 +0530972 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 }
974 else
975 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800976 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
977 }
978
979 if (TRUE == lastArg)
980 {
981 goto done;
982 }
983 else if (NULL == inPtr)
984 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530985 return -EINVAL;
986 }
987 }
988
989 /*check and parse RTT*/
990 if ((strncmp(inPtr, "RTT", 3) == 0))
991 {
992 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530994 if (TRUE == lastArg)
995 {
996 goto done;
997 }
998 if (NULL == inPtr)
999 {
1000 return -EINVAL;
1001 }
1002 }
1003
1004
1005done:
1006
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001007 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1008 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1009 pHddSetBatchScanReq->bestNetwork = nBestN;
1010 pHddSetBatchScanReq->rfBand = ucRfBand;
1011 pHddSetBatchScanReq->rtt = nRtt;
1012
Rajeev79dbe4c2013-10-05 11:03:42 +05301013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1014 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1015 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1016 pHddSetBatchScanReq->scanFrequency,
1017 pHddSetBatchScanReq->numberOfScansToBatch,
1018 pHddSetBatchScanReq->bestNetwork,
1019 pHddSetBatchScanReq->rfBand,
1020 pHddSetBatchScanReq->rtt);
1021
1022 return 0;
1023}/*End of hdd_parse_set_batchscan_command*/
1024
1025/**---------------------------------------------------------------------------
1026
1027 \brief hdd_set_batch_scan_req_callback () - This function is called after
1028 receiving set batch scan response from FW and it saves set batch scan
1029 response data FW to HDD context and sets the completion event on
1030 which hdd_ioctl is waiting
1031
1032 \param - callbackContext Pointer to HDD adapter
1033 \param - pRsp Pointer to set batch scan response data received from FW
1034
1035 \return - nothing
1036
1037 --------------------------------------------------------------------------*/
1038static void hdd_set_batch_scan_req_callback
1039(
1040 void *callbackContext,
1041 tSirSetBatchScanRsp *pRsp
1042)
1043{
1044 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1045 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1046
1047 /*sanity check*/
1048 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1049 {
1050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1051 "%s: Invalid pAdapter magic", __func__);
1052 VOS_ASSERT(0);
1053 return;
1054 }
1055 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1056
1057 /*save set batch scan response*/
1058 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1059
1060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1061 "Received set batch scan rsp from FW with nScansToBatch=%d",
1062 pHddSetBatchScanRsp->nScansToBatch);
1063
1064 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1065 complete(&pAdapter->hdd_set_batch_scan_req_var);
1066
1067 return;
1068}/*End of hdd_set_batch_scan_req_callback*/
1069
1070
1071/**---------------------------------------------------------------------------
1072
1073 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1074 info in hdd batch scan response queue
1075
1076 \param - pAdapter Pointer to hdd adapter
1077 \param - pAPMetaInfo Pointer to access point meta info
1078 \param - scanId scan ID of batch scan response
1079 \param - isLastAp tells whether AP is last AP in batch scan response or not
1080
1081 \return - nothing
1082
1083 --------------------------------------------------------------------------*/
1084static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1085 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1086{
1087 tHddBatchScanRsp *pHead;
1088 tHddBatchScanRsp *pNode;
1089 tHddBatchScanRsp *pPrev;
1090 tHddBatchScanRsp *pTemp;
1091 tANI_U8 ssidLen;
1092
1093 /*head of hdd batch scan response queue*/
1094 pHead = pAdapter->pBatchScanRsp;
1095
1096 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1097 if (NULL == pNode)
1098 {
1099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1100 "%s: Could not allocate memory", __func__);
1101 VOS_ASSERT(0);
1102 return;
1103 }
1104
1105 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1106 sizeof(pNode->ApInfo.bssid));
1107 ssidLen = strlen(pApMetaInfo->ssid);
1108 if (SIR_MAX_SSID_SIZE < ssidLen)
1109 {
1110 /*invalid scan result*/
1111 vos_mem_free(pNode);
1112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1113 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1114 return;
1115 }
1116 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1117 /*null terminate ssid*/
1118 pNode->ApInfo.ssid[ssidLen] = '\0';
1119 pNode->ApInfo.ch = pApMetaInfo->ch;
1120 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1121 pNode->ApInfo.age = pApMetaInfo->timestamp;
1122 pNode->ApInfo.batchId = scanId;
1123 pNode->ApInfo.isLastAp = isLastAp;
1124
1125 pNode->pNext = NULL;
1126 if (NULL == pHead)
1127 {
1128 pAdapter->pBatchScanRsp = pNode;
1129 }
1130 else
1131 {
1132 pTemp = pHead;
1133 while (NULL != pTemp)
1134 {
1135 pPrev = pTemp;
1136 pTemp = pTemp->pNext;
1137 }
1138 pPrev->pNext = pNode;
1139 }
1140
1141 return;
1142}/*End of hdd_populate_batch_scan_rsp_queue*/
1143
1144/**---------------------------------------------------------------------------
1145
1146 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1147 receiving batch scan response indication from FW. It saves get batch scan
1148 response data in HDD batch scan response queue. This callback sets the
1149 completion event on which hdd_ioctl is waiting only after getting complete
1150 batch scan response data from FW
1151
1152 \param - callbackContext Pointer to HDD adapter
1153 \param - pRsp Pointer to get batch scan response data received from FW
1154
1155 \return - nothing
1156
1157 --------------------------------------------------------------------------*/
1158static void hdd_batch_scan_result_ind_callback
1159(
1160 void *callbackContext,
1161 void *pRsp
1162)
1163{
1164 v_BOOL_t isLastAp;
1165 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001166 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301167 tANI_U32 numberScanList;
1168 tANI_U32 nextScanListOffset;
1169 tANI_U32 nextApMetaInfoOffset;
1170 hdd_adapter_t* pAdapter;
1171 tpSirBatchScanList pScanList;
1172 tpSirBatchScanNetworkInfo pApMetaInfo;
1173 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1174 tSirSetBatchScanReq *pReq;
1175
1176 pAdapter = (hdd_adapter_t *)callbackContext;
1177 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001178 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301179 {
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1181 "%s: Invalid pAdapter magic", __func__);
1182 VOS_ASSERT(0);
1183 return;
1184 }
1185
1186 /*initialize locals*/
1187 pReq = &pAdapter->hddSetBatchScanReq;
1188 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1189 isLastAp = FALSE;
1190 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001191 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301192 numberScanList = 0;
1193 nextScanListOffset = 0;
1194 nextApMetaInfoOffset = 0;
1195 pScanList = NULL;
1196 pApMetaInfo = NULL;
1197
1198 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1202 isLastAp = TRUE;
1203 goto done;
1204 }
1205
1206 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1208 "Batch scan rsp: numberScalList %d", numberScanList);
1209
1210 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1211 {
1212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1213 "%s: numberScanList %d", __func__, numberScanList);
1214 isLastAp = TRUE;
1215 goto done;
1216 }
1217
1218 while (numberScanList)
1219 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001220 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301221 nextScanListOffset);
1222 if (NULL == pScanList)
1223 {
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1225 "%s: pScanList is %p", __func__, pScanList);
1226 isLastAp = TRUE;
1227 goto done;
1228 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001229 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001231 "Batch scan rsp: numApMetaInfo %d scanId %d",
1232 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301233
1234 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1235 {
1236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1237 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1238 isLastAp = TRUE;
1239 goto done;
1240 }
1241
Rajeev Kumarce651e42013-10-21 18:57:15 -07001242 /*Initialize next AP meta info offset for next scan list*/
1243 nextApMetaInfoOffset = 0;
1244
Rajeev79dbe4c2013-10-05 11:03:42 +05301245 while (numApMetaInfo)
1246 {
1247 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1248 nextApMetaInfoOffset);
1249 if (NULL == pApMetaInfo)
1250 {
1251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1252 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1253 isLastAp = TRUE;
1254 goto done;
1255 }
1256 /*calculate AP age*/
1257 pApMetaInfo->timestamp =
1258 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1259
1260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001261 "%s: bssId "MAC_ADDRESS_STR
1262 " ch %d rssi %d timestamp %d", __func__,
1263 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1264 pApMetaInfo->ch, pApMetaInfo->rssi,
1265 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301266
1267 /*mark last AP in batch scan response*/
1268 if ((TRUE == pBatchScanRsp->isLastResult) &&
1269 (1 == numberScanList) && (1 == numApMetaInfo))
1270 {
1271 isLastAp = TRUE;
1272 }
1273
1274 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1275 /*store batch scan repsonse in hdd queue*/
1276 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1277 pScanList->scanId, isLastAp);
1278 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1279
1280 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1281 numApMetaInfo--;
1282 }
1283
Rajeev Kumarce651e42013-10-21 18:57:15 -07001284 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1285 + (sizeof(tSirBatchScanNetworkInfo)
1286 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301287 numberScanList--;
1288 }
1289
1290done:
1291
1292 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1293 requested from hdd_ioctl*/
1294 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1295 (TRUE == isLastAp))
1296 {
1297 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1298 complete(&pAdapter->hdd_get_batch_scan_req_var);
1299 }
1300
1301 return;
1302}/*End of hdd_batch_scan_result_ind_callback*/
1303
1304/**---------------------------------------------------------------------------
1305
1306 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1307 response as per batch scan FR request format by putting proper markers
1308
1309 \param - pDest pointer to destination buffer
1310 \param - cur_len current length
1311 \param - tot_len total remaining size which can be written to user space
1312 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1313 \param - pAdapter Pointer to HDD adapter
1314
1315 \return - ret no of characters written
1316
1317 --------------------------------------------------------------------------*/
1318static tANI_U32
1319hdd_format_batch_scan_rsp
1320(
1321 tANI_U8 *pDest,
1322 tANI_U32 cur_len,
1323 tANI_U32 tot_len,
1324 tHddBatchScanRsp *pApMetaInfo,
1325 hdd_adapter_t* pAdapter
1326)
1327{
1328 tANI_U32 ret = 0;
1329 tANI_U32 rem_len = 0;
1330 tANI_U8 temp_len = 0;
1331 tANI_U8 temp_total_len = 0;
1332 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1333 tANI_U8 *pTemp = temp;
1334
1335 /*Batch scan reponse needs to be returned to user space in
1336 following format:
1337 "scancount=X\n" where X is the number of scans in current batch
1338 batch
1339 "trunc\n" optional present if current scan truncated
1340 "bssid=XX:XX:XX:XX:XX:XX\n"
1341 "ssid=XXXX\n"
1342 "freq=X\n" frequency in Mhz
1343 "level=XX\n"
1344 "age=X\n" ms
1345 "dist=X\n" cm (-1 if not available)
1346 "errror=X\n" (-1if not available)
1347 "====\n" (end of ap marker)
1348 "####\n" (end of scan marker)
1349 "----\n" (end of results)*/
1350 /*send scan result in above format to user space based on
1351 available length*/
1352 /*The GET response may have more data than the driver can return in its
1353 buffer. In that case the buffer should be filled to the nearest complete
1354 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1355 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1356 The final buffer should end with "----\n"*/
1357
1358 /*sanity*/
1359 if (cur_len > tot_len)
1360 {
1361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1362 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1363 return 0;
1364 }
1365 else
1366 {
1367 rem_len = (tot_len - cur_len);
1368 }
1369
1370 /*end scan marker*/
1371 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1372 {
1373 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1374 pTemp += temp_len;
1375 temp_total_len += temp_len;
1376 }
1377
1378 /*bssid*/
1379 temp_len = snprintf(pTemp, sizeof(temp),
1380 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1381 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1382 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1383 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1384 pTemp += temp_len;
1385 temp_total_len += temp_len;
1386
1387 /*ssid*/
1388 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1389 pApMetaInfo->ApInfo.ssid);
1390 pTemp += temp_len;
1391 temp_total_len += temp_len;
1392
1393 /*freq*/
1394 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001395 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*level*/
1400 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1401 pApMetaInfo->ApInfo.rssi);
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404
1405 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001406 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301407 pApMetaInfo->ApInfo.age);
1408 pTemp += temp_len;
1409 temp_total_len += temp_len;
1410
1411 /*dist*/
1412 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1413 pTemp += temp_len;
1414 temp_total_len += temp_len;
1415
1416 /*error*/
1417 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1418 pTemp += temp_len;
1419 temp_total_len += temp_len;
1420
1421 /*end AP marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*last AP in batch scan response*/
1427 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1428 {
1429 /*end scan marker*/
1430 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1431 pTemp += temp_len;
1432 temp_total_len += temp_len;
1433
1434 /*end batch scan result marker*/
1435 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1436 pTemp += temp_len;
1437 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001438
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
1440
1441 if (temp_total_len < rem_len)
1442 {
1443 ret = temp_total_len + 1;
1444 strlcpy(pDest, temp, ret);
1445 pAdapter->isTruncated = FALSE;
1446 }
1447 else
1448 {
1449 pAdapter->isTruncated = TRUE;
1450 if (rem_len >= strlen("%%%%"))
1451 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001452 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301453 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001454 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301455 {
1456 ret = 0;
1457 }
1458 }
1459
1460 return ret;
1461
1462}/*End of hdd_format_batch_scan_rsp*/
1463
1464/**---------------------------------------------------------------------------
1465
1466 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1467 buffer starting with head of hdd batch scan response queue
1468
1469 \param - pAdapter Pointer to HDD adapter
1470 \param - pDest Pointer to user data buffer
1471 \param - cur_len current offset in user buffer
1472 \param - rem_len remaining no of bytes in user buffer
1473
1474 \return - number of bytes written in user buffer
1475
1476 --------------------------------------------------------------------------*/
1477
1478tANI_U32 hdd_populate_user_batch_scan_rsp
1479(
1480 hdd_adapter_t* pAdapter,
1481 tANI_U8 *pDest,
1482 tANI_U32 cur_len,
1483 tANI_U32 rem_len
1484)
1485{
1486 tHddBatchScanRsp *pHead;
1487 tHddBatchScanRsp *pPrev;
1488 tANI_U32 len;
1489
Rajeev79dbe4c2013-10-05 11:03:42 +05301490 pAdapter->isTruncated = FALSE;
1491
1492 /*head of hdd batch scan response queue*/
1493 pHead = pAdapter->pBatchScanRsp;
1494 while (pHead)
1495 {
1496 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1497 pAdapter);
1498 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001499 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301500 cur_len += len;
1501 if(TRUE == pAdapter->isTruncated)
1502 {
1503 /*result is truncated return rest of scan rsp in next req*/
1504 cur_len = rem_len;
1505 break;
1506 }
1507 pPrev = pHead;
1508 pHead = pHead->pNext;
1509 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001510 if (TRUE == pPrev->ApInfo.isLastAp)
1511 {
1512 pAdapter->prev_batch_id = 0;
1513 }
1514 else
1515 {
1516 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1517 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301518 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001519 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 }
1521
1522 return cur_len;
1523}/*End of hdd_populate_user_batch_scan_rsp*/
1524
1525/**---------------------------------------------------------------------------
1526
1527 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1528 scan response data from HDD queue to user space
1529 It does following in detail:
1530 a) if HDD has enough data in its queue then it 1st copies data to user
1531 space and then send get batch scan indication message to FW. In this
1532 case it does not wait on any event and batch scan response data will
1533 be populated in HDD response queue in MC thread context after receiving
1534 indication from FW
1535 b) else send get batch scan indication message to FW and wait on an event
1536 which will be set once HDD receives complete batch scan response from
1537 FW and then this function returns batch scan response to user space
1538
1539 \param - pAdapter Pointer to HDD adapter
1540 \param - pPrivData Pointer to priv_data
1541
1542 \return - 0 for success -EFAULT for failure
1543
1544 --------------------------------------------------------------------------*/
1545
1546int hdd_return_batch_scan_rsp_to_user
1547(
1548 hdd_adapter_t* pAdapter,
1549 hdd_priv_data_t *pPrivData,
1550 tANI_U8 *command
1551)
1552{
1553 tANI_U8 *pDest;
1554 tANI_U32 count = 0;
1555 tANI_U32 len = 0;
1556 tANI_U32 cur_len = 0;
1557 tANI_U32 rem_len = 0;
1558 eHalStatus halStatus;
1559 unsigned long rc;
1560 tSirTriggerBatchScanResultInd *pReq;
1561
1562 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1563 pReq->param = 0;/*batch scan client*/
1564 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1565 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1566
1567 cur_len = pPrivData->used_len;
1568 if (pPrivData->total_len > pPrivData->used_len)
1569 {
1570 rem_len = pPrivData->total_len - pPrivData->used_len;
1571 }
1572 else
1573 {
1574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1575 "%s: Invalid user data buffer total_len %d used_len %d",
1576 __func__, pPrivData->total_len, pPrivData->used_len);
1577 return -EFAULT;
1578 }
1579
1580 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1581 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1582 cur_len, rem_len);
1583 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1584
1585 /*enough scan result available in cache to return to user space or
1586 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001587 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301588 {
1589 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1590 halStatus = sme_TriggerBatchScanResultInd(
1591 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1592 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1593 pAdapter);
1594 if ( eHAL_STATUS_SUCCESS == halStatus )
1595 {
1596 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1597 {
1598 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1599 rc = wait_for_completion_timeout(
1600 &pAdapter->hdd_get_batch_scan_req_var,
1601 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1602 if (0 == rc)
1603 {
1604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1605 "%s: Timeout waiting to fetch batch scan rsp from fw",
1606 __func__);
1607 return -EFAULT;
1608 }
1609 }
1610
1611 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001612 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301613 pDest += len;
1614 cur_len += len;
1615
1616 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1617 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1618 cur_len, rem_len);
1619 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1620
1621 count = 0;
1622 len = (len - pPrivData->used_len);
1623 pDest = (command + pPrivData->used_len);
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001625 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301626 while(count < len)
1627 {
1628 printk("%c", *(pDest + count));
1629 count++;
1630 }
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: copy %d data to user buffer", __func__, len);
1633 if (copy_to_user(pPrivData->buf, pDest, len))
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "%s: failed to copy data to user buffer", __func__);
1637 return -EFAULT;
1638 }
1639 }
1640 else
1641 {
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1643 "sme_GetBatchScanScan returned failure halStatus %d",
1644 halStatus);
1645 return -EINVAL;
1646 }
1647 }
1648 else
1649 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301650 count = 0;
1651 len = (len - pPrivData->used_len);
1652 pDest = (command + pPrivData->used_len);
1653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001654 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 while(count < len)
1656 {
1657 printk("%c", *(pDest + count));
1658 count++;
1659 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301662 if (copy_to_user(pPrivData->buf, pDest, len))
1663 {
1664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 "%s: failed to copy data to user buffer", __func__);
1666 return -EFAULT;
1667 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301668 }
1669
1670 return 0;
1671} /*End of hdd_return_batch_scan_rsp_to_user*/
1672
Rajeev Kumar8b373292014-01-08 20:36:55 -08001673
1674/**---------------------------------------------------------------------------
1675
1676 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1677 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1678 WLS_BATCHING VERSION
1679 WLS_BATCHING SET
1680 WLS_BATCHING GET
1681 WLS_BATCHING STOP
1682
1683 \param - pAdapter Pointer to HDD adapter
1684 \param - pPrivdata Pointer to priv_data
1685 \param - command Pointer to command
1686
1687 \return - 0 for success -EFAULT for failure
1688
1689 --------------------------------------------------------------------------*/
1690
1691int hdd_handle_batch_scan_ioctl
1692(
1693 hdd_adapter_t *pAdapter,
1694 hdd_priv_data_t *pPrivdata,
1695 tANI_U8 *command
1696)
1697{
1698 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001699 hdd_context_t *pHddCtx;
1700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301701 ENTER();
1702
Yue Mae36e3552014-03-05 17:06:20 -08001703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1704 ret = wlan_hdd_validate_context(pHddCtx);
1705 if (ret)
1706 {
Yue Mae36e3552014-03-05 17:06:20 -08001707 goto exit;
1708 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001709
1710 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1711 {
1712 char extra[32];
1713 tANI_U8 len = 0;
1714 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1715
1716 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1717 {
1718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1719 "%s: Batch scan feature is not supported by FW", __func__);
1720 ret = -EINVAL;
1721 goto exit;
1722 }
1723
1724 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1725 version);
1726 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1727 {
1728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1729 "%s: failed to copy data to user buffer", __func__);
1730 ret = -EFAULT;
1731 goto exit;
1732 }
1733 ret = HDD_BATCH_SCAN_VERSION;
1734 }
1735 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1736 {
1737 int status;
1738 tANI_U8 *value = (command + 16);
1739 eHalStatus halStatus;
1740 unsigned long rc;
1741 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1742 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1743
1744 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1745 {
1746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1747 "%s: Batch scan feature is not supported by FW", __func__);
1748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1753 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1754 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1755 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1756 {
1757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301758 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001759 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301760 hdd_device_modetoString(pAdapter->device_mode),
1761 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001762 ret = -EINVAL;
1763 goto exit;
1764 }
1765
1766 status = hdd_parse_set_batchscan_command(value, pReq);
1767 if (status)
1768 {
1769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "Invalid WLS_BATCHING SET command");
1771 ret = -EINVAL;
1772 goto exit;
1773 }
1774
1775
1776 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1777 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1778 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1779 pAdapter);
1780
1781 if ( eHAL_STATUS_SUCCESS == halStatus )
1782 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301783 char extra[32];
1784 tANI_U8 len = 0;
1785 tANI_U8 mScan = 0;
1786
Rajeev Kumar8b373292014-01-08 20:36:55 -08001787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1788 "sme_SetBatchScanReq returned success halStatus %d",
1789 halStatus);
1790 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1791 {
1792 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1793 rc = wait_for_completion_timeout(
1794 &pAdapter->hdd_set_batch_scan_req_var,
1795 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1796 if (0 == rc)
1797 {
1798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: Timeout waiting for set batch scan to complete",
1800 __func__);
1801 ret = -EINVAL;
1802 goto exit;
1803 }
1804 }
1805 if ( !pRsp->nScansToBatch )
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1808 "%s: Received set batch scan failure response from FW",
1809 __func__);
1810 ret = -EINVAL;
1811 goto exit;
1812 }
1813 /*As per the Batch Scan Framework API we should return the MIN of
1814 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301815 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816
1817 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1818
1819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301821 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1822 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1823 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: failed to copy MSCAN value to user buffer", __func__);
1827 ret = -EFAULT;
1828 goto exit;
1829 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001830 }
1831 else
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "sme_SetBatchScanReq returned failure halStatus %d",
1835 halStatus);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839 }
1840 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1841 {
1842 eHalStatus halStatus;
1843 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1844 pInd->param = 0;
1845
1846 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "%s: Batch scan feature is not supported by FW", __func__);
1850 ret = -EINVAL;
1851 goto exit;
1852 }
1853
1854 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1855 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001857 "Batch scan is not yet enabled batch scan state %d",
1858 pAdapter->batchScanState);
1859 ret = -EINVAL;
1860 goto exit;
1861 }
1862
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 hdd_deinit_batch_scan(pAdapter);
1865 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1866
Rajeev Kumar8b373292014-01-08 20:36:55 -08001867 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1868
1869 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1870 pAdapter->sessionId);
1871 if ( eHAL_STATUS_SUCCESS == halStatus )
1872 {
1873 ret = 0;
1874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1875 "sme_StopBatchScanInd returned success halStatus %d",
1876 halStatus);
1877 }
1878 else
1879 {
1880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1881 "sme_StopBatchScanInd returned failure halStatus %d",
1882 halStatus);
1883 ret = -EINVAL;
1884 goto exit;
1885 }
1886 }
1887 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1888 {
1889 tANI_U32 remain_len;
1890
1891 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "%s: Batch scan feature is not supported by FW", __func__);
1895 ret = -EINVAL;
1896 goto exit;
1897 }
1898
1899 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1900 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001902 "Batch scan is not yet enabled could not return results"
1903 "Batch Scan state %d",
1904 pAdapter->batchScanState);
1905 ret = -EINVAL;
1906 goto exit;
1907 }
1908
1909 pPrivdata->used_len = 16;
1910 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1911 if (remain_len < pPrivdata->total_len)
1912 {
1913 /*Clear previous batch scan response data if any*/
1914 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1915 }
1916 else
1917 {
1918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1919 "Invalid total length from user space can't fetch batch"
1920 " scan response total_len %d used_len %d remain len %d",
1921 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1922 ret = -EINVAL;
1923 goto exit;
1924 }
1925 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1926 }
1927
1928exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301929 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001930 return ret;
1931}
1932
1933
Rajeev79dbe4c2013-10-05 11:03:42 +05301934#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1935
c_hpothu92367912014-05-01 15:18:17 +05301936static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1937{
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 bcnMissRateContext_t *pCBCtx;
1939
1940 if (NULL == data)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1943 return;
1944 }
c_hpothu92367912014-05-01 15:18:17 +05301945
1946 /* there is a race condition that exists between this callback
1947 function and the caller since the caller could time out either
1948 before or while this code is executing. we use a spinlock to
1949 serialize these actions */
1950 spin_lock(&hdd_context_lock);
1951
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301953 gbcnMissRate = -1;
1954
c_hpothu39eb1e32014-06-26 16:31:50 +05301955 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301958 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301959 spin_unlock(&hdd_context_lock);
1960 return ;
1961 }
1962
1963 if (VOS_STATUS_SUCCESS == status)
1964 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301965 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301966 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301967 else
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1970 }
1971
c_hpothu92367912014-05-01 15:18:17 +05301972 complete(&(pCBCtx->completion));
1973 spin_unlock(&hdd_context_lock);
1974
1975 return;
1976}
1977
Abhishek Singh08aa7762014-12-16 13:59:03 +05301978void hdd_FWStatisCB( VOS_STATUS status,
1979 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301980{
1981 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301982 hdd_adapter_t *pAdapter;
1983
1984 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1985
Abhishek Singh08aa7762014-12-16 13:59:03 +05301986 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1989 return;
1990 }
1991 /* there is a race condition that exists between this callback
1992 function and the caller since the caller could time out either
1993 before or while this code is executing. we use a spinlock to
1994 serialize these actions */
1995 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301996 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301997 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_ERROR,
2000 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2001 spin_unlock(&hdd_context_lock);
2002 return;
2003 }
2004 pAdapter = fwStatsCtx->pAdapter;
2005 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("pAdapter returned is NULL or invalid"));
2009 spin_unlock(&hdd_context_lock);
2010 return;
2011 }
2012 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302013 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302014 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302015 switch( fwStatsResult->type )
2016 {
2017 case FW_UBSP_STATS:
2018 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302019 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 hddLog(VOS_TRACE_LEVEL_INFO,
2021 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302022 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2023 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302024 }
2025 break;
2026 default:
2027 {
2028 hddLog(VOS_TRACE_LEVEL_ERROR,
2029 FL(" No handling for stats type %d"),fwStatsResult->type);
2030 }
2031 }
2032 }
2033 complete(&(fwStatsCtx->completion));
2034 spin_unlock(&hdd_context_lock);
2035 return;
2036}
2037
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302038static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2039{
2040 int ret = 0;
2041
2042 if (!pCfg || !command || !extra || !len)
2043 {
2044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2045 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2046 ret = -EINVAL;
2047 return ret;
2048 }
2049
2050 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2051 {
2052 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2053 (int)pCfg->nActiveMaxChnTime);
2054 return ret;
2055 }
2056 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2057 {
2058 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2059 (int)pCfg->nActiveMinChnTime);
2060 return ret;
2061 }
2062 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2063 {
2064 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2065 (int)pCfg->nPassiveMaxChnTime);
2066 return ret;
2067 }
2068 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2069 {
2070 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2071 (int)pCfg->nPassiveMinChnTime);
2072 return ret;
2073 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302074 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2075 {
2076 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2077 (int)pCfg->nActiveMaxChnTime);
2078 return ret;
2079 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080 else
2081 {
2082 ret = -EINVAL;
2083 }
2084
2085 return ret;
2086}
2087
2088static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2089{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091 hdd_config_t *pCfg;
2092 tANI_U8 *value = command;
2093 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302094 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302095
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302096 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2097 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302098 {
2099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2100 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2101 ret = -EINVAL;
2102 return ret;
2103 }
2104
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302105 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2106 sme_GetConfigParam(hHal, &smeConfig);
2107
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302108 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2109 {
2110 value = value + 24;
2111 temp = kstrtou32(value, 10, &val);
2112 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2113 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2114 {
2115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2116 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2117 ret = -EFAULT;
2118 return ret;
2119 }
2120 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302121 smeConfig.csrConfig.nActiveMaxChnTime = val;
2122 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302123 }
2124 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2125 {
2126 value = value + 24;
2127 temp = kstrtou32(value, 10, &val);
2128 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2129 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2130 {
2131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2132 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2133 ret = -EFAULT;
2134 return ret;
2135 }
2136 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302137 smeConfig.csrConfig.nActiveMinChnTime = val;
2138 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302139 }
2140 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2141 {
2142 value = value + 25;
2143 temp = kstrtou32(value, 10, &val);
2144 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2145 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2146 {
2147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2148 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2149 ret = -EFAULT;
2150 return ret;
2151 }
2152 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302153 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2154 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302155 }
2156 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2157 {
2158 value = value + 25;
2159 temp = kstrtou32(value, 10, &val);
2160 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2161 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2165 ret = -EFAULT;
2166 return ret;
2167 }
2168 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302169 smeConfig.csrConfig.nPassiveMinChnTime = val;
2170 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302171 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302172 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2173 {
2174 value = value + 13;
2175 temp = kstrtou32(value, 10, &val);
2176 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2177 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2178 {
2179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2180 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2181 ret = -EFAULT;
2182 return ret;
2183 }
2184 pCfg->nActiveMaxChnTime = val;
2185 smeConfig.csrConfig.nActiveMaxChnTime = val;
2186 sme_UpdateConfig(hHal, &smeConfig);
2187 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302188 else
2189 {
2190 ret = -EINVAL;
2191 }
2192
2193 return ret;
2194}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302195static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2196 tANI_U8 cmd_len)
2197{
2198 tANI_U8 *value;
2199 tANI_U8 fcc_constraint;
2200
2201 eHalStatus status;
2202 int ret = 0;
2203 value = cmd + cmd_len + 1;
2204
2205 ret = kstrtou8(value, 10, &fcc_constraint);
2206 if ((ret < 0) || (fcc_constraint > 1)) {
2207 /*
2208 * If the input value is greater than max value of datatype,
2209 * then also it is a failure
2210 */
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 "%s: value out of range", __func__);
2213 return -EINVAL;
2214 }
2215
2216 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2217 if (status != eHAL_STATUS_SUCCESS)
2218 ret = -EPERM;
2219
2220 return ret;
2221}
2222
2223
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302224
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002225static int hdd_driver_command(hdd_adapter_t *pAdapter,
2226 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002227{
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 hdd_priv_data_t priv_data;
2229 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302230 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2231 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002232 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302233 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302234
2235 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002236 /*
2237 * Note that valid pointers are provided by caller
2238 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002239
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002240 /* copy to local struct to avoid numerous changes to legacy code */
2241 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002242
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002243 if (priv_data.total_len <= 0 ||
2244 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002245 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002246 hddLog(VOS_TRACE_LEVEL_WARN,
2247 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2248 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002249 ret = -EINVAL;
2250 goto exit;
2251 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302252 status = wlan_hdd_validate_context(pHddCtx);
2253 if (0 != status)
2254 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302255 ret = -EINVAL;
2256 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302257 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002258 /* Allocate +1 for '\0' */
2259 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 if (!command)
2261 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002264 ret = -ENOMEM;
2265 goto exit;
2266 }
2267
2268 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2269 {
2270 ret = -EFAULT;
2271 goto exit;
2272 }
2273
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002274 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002275 command[priv_data.total_len] = '\0';
2276
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002277 /* at one time the following block of code was conditional. braces
2278 * have been retained to avoid re-indenting the legacy code
2279 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 {
2281 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2282
2283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002284 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002285
2286 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2287 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2289 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2290 pAdapter->sessionId, (unsigned)
2291 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2292 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2293 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2294 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2296 sizeof(tSirMacAddr)))
2297 {
2298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002299 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 ret = -EFAULT;
2301 }
2302 }
Amar Singhal0974e402013-02-12 14:27:46 -08002303 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002304 {
Amar Singhal0974e402013-02-12 14:27:46 -08002305 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002306
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002308
2309 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002312 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Anand N Sunkad27354cf2015-07-13 14:39:11 +05302313 if(VOS_FTM_MODE != hdd_get_conparam())
2314 {
2315 /* Change band request received */
2316 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2317 if(ret < 0)
2318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2319 "%s: failed to set band ret=%d", __func__, ret);
2320 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002321 }
Kiet Lamf040f472013-11-20 21:15:23 +05302322 else if(strncmp(command, "SETWMMPS", 8) == 0)
2323 {
2324 tANI_U8 *ptr = command;
2325 ret = hdd_wmmps_helper(pAdapter, ptr);
2326 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302327
2328 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2329 {
2330 tANI_U8 *ptr = command;
2331 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2332 }
2333
Jeff Johnson32d95a32012-09-10 13:15:23 -07002334 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2335 {
2336 char *country_code;
2337
2338 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002339
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002340 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002341 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002342#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302343 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002344#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002345 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2346 (void *)(tSmeChangeCountryCallback)
2347 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302348 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002349 if (eHAL_STATUS_SUCCESS == ret)
2350 {
2351 ret = wait_for_completion_interruptible_timeout(
2352 &pAdapter->change_country_code,
2353 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2354 if (0 >= ret)
2355 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302357 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002358 }
2359 }
2360 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002361 {
2362 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002363 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002364 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002365 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002366
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002367 }
2368 /*
2369 command should be a string having format
2370 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2371 */
Amar Singhal0974e402013-02-12 14:27:46 -08002372 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002373 {
Amar Singhal0974e402013-02-12 14:27:46 -08002374 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002375
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002377 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002378
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002379 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002380 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002381 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2382 {
2383 int suspend = 0;
2384 tANI_U8 *ptr = (tANI_U8*)command + 15;
2385
2386 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2388 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2389 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002390 hdd_set_wlan_suspend_mode(suspend);
2391 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002392#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2393 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2394 {
2395 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002396 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002397 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2398 eHalStatus status = eHAL_STATUS_SUCCESS;
2399
2400 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2401 value = value + 15;
2402
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002403 /* Convert the value from ascii to integer */
2404 ret = kstrtos8(value, 10, &rssi);
2405 if (ret < 0)
2406 {
2407 /* If the input value is greater than max value of datatype, then also
2408 kstrtou8 fails */
2409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002411 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002412 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2413 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2414 ret = -EINVAL;
2415 goto exit;
2416 }
2417
Srinivas Girigowdade697412013-02-14 16:31:48 -08002418 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002419
Srinivas Girigowdade697412013-02-14 16:31:48 -08002420 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2421 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2422 {
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2424 "Neighbor lookup threshold value %d is out of range"
2425 " (Min: %d Max: %d)", lookUpThreshold,
2426 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2427 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2428 ret = -EINVAL;
2429 goto exit;
2430 }
2431
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302432 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2433 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2434 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2436 "%s: Received Command to Set Roam trigger"
2437 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2438
2439 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2440 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2441 if (eHAL_STATUS_SUCCESS != status)
2442 {
2443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2444 "%s: Failed to set roam trigger, try again", __func__);
2445 ret = -EPERM;
2446 goto exit;
2447 }
2448
2449 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302450 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002451 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2452 }
2453 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2454 {
2455 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2456 int rssi = (-1) * lookUpThreshold;
2457 char extra[32];
2458 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2461 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002462 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302463 len = VOS_MIN(priv_data.total_len, len + 1);
2464 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002465 {
2466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2467 "%s: failed to copy data to user buffer", __func__);
2468 ret = -EFAULT;
2469 goto exit;
2470 }
2471 }
2472 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2473 {
2474 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002475 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002476 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478 /* input refresh period is in terms of seconds */
2479 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2480 value = value + 18;
2481 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002482 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002483 if (ret < 0)
2484 {
2485 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002486 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002488 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002489 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002490 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2491 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002492 ret = -EINVAL;
2493 goto exit;
2494 }
2495
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2497 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500 "Roam scan period value %d is out of range"
2501 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002502 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2503 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002504 ret = -EINVAL;
2505 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302506 }
2507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2508 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2509 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002511
2512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2513 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002514 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002516 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2517 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002518 }
2519 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2520 {
2521 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2522 char extra[32];
2523 tANI_U8 len = 0;
2524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2526 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2527 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002528 len = scnprintf(extra, sizeof(extra), "%s %d",
2529 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002530 /* Returned value is in units of seconds */
2531 if (copy_to_user(priv_data.buf, &extra, len + 1))
2532 {
2533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2534 "%s: failed to copy data to user buffer", __func__);
2535 ret = -EFAULT;
2536 goto exit;
2537 }
2538 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002539 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2540 {
2541 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 /* input refresh period is in terms of seconds */
2546 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2547 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002548
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002549 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002550 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002551 if (ret < 0)
2552 {
2553 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002554 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002556 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002557 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002558 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2559 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2560 ret = -EINVAL;
2561 goto exit;
2562 }
2563
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002564 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2565 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2566 {
2567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2568 "Neighbor scan results refresh period value %d is out of range"
2569 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2570 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2571 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2572 ret = -EINVAL;
2573 goto exit;
2574 }
2575 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2576
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2578 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002579 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002580
2581 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2582 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2583 }
2584 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2585 {
2586 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2587 char extra[32];
2588 tANI_U8 len = 0;
2589
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002590 len = scnprintf(extra, sizeof(extra), "%s %d",
2591 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002592 /* Returned value is in units of seconds */
2593 if (copy_to_user(priv_data.buf, &extra, len + 1))
2594 {
2595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2596 "%s: failed to copy data to user buffer", __func__);
2597 ret = -EFAULT;
2598 goto exit;
2599 }
2600 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002601#ifdef FEATURE_WLAN_LFR
2602 /* SETROAMMODE */
2603 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2604 {
2605 tANI_U8 *value = command;
2606 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2607
2608 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2609 value = value + SIZE_OF_SETROAMMODE + 1;
2610
2611 /* Convert the value from ascii to integer */
2612 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2613 if (ret < 0)
2614 {
2615 /* If the input value is greater than max value of datatype, then also
2616 kstrtou8 fails */
2617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2618 "%s: kstrtou8 failed range [%d - %d]", __func__,
2619 CFG_LFR_FEATURE_ENABLED_MIN,
2620 CFG_LFR_FEATURE_ENABLED_MAX);
2621 ret = -EINVAL;
2622 goto exit;
2623 }
2624 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2625 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2626 {
2627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2628 "Roam Mode value %d is out of range"
2629 " (Min: %d Max: %d)", roamMode,
2630 CFG_LFR_FEATURE_ENABLED_MIN,
2631 CFG_LFR_FEATURE_ENABLED_MAX);
2632 ret = -EINVAL;
2633 goto exit;
2634 }
2635
2636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2637 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2638 /*
2639 * Note that
2640 * SETROAMMODE 0 is to enable LFR while
2641 * SETROAMMODE 1 is to disable LFR, but
2642 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2643 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2644 */
2645 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2646 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2647 else
2648 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2649
2650 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2651 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2652 }
2653 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302654 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002655 {
2656 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2657 char extra[32];
2658 tANI_U8 len = 0;
2659
2660 /*
2661 * roamMode value shall be inverted because the sementics is different.
2662 */
2663 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2664 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2665 else
2666 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2667
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002668 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002669 if (copy_to_user(priv_data.buf, &extra, len + 1))
2670 {
2671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2672 "%s: failed to copy data to user buffer", __func__);
2673 ret = -EFAULT;
2674 goto exit;
2675 }
2676 }
2677#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002678#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002679#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2681 {
2682 tANI_U8 *value = command;
2683 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2684
2685 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2686 value = value + 13;
2687 /* Convert the value from ascii to integer */
2688 ret = kstrtou8(value, 10, &roamRssiDiff);
2689 if (ret < 0)
2690 {
2691 /* If the input value is greater than max value of datatype, then also
2692 kstrtou8 fails */
2693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2694 "%s: kstrtou8 failed range [%d - %d]", __func__,
2695 CFG_ROAM_RSSI_DIFF_MIN,
2696 CFG_ROAM_RSSI_DIFF_MAX);
2697 ret = -EINVAL;
2698 goto exit;
2699 }
2700
2701 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2702 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2703 {
2704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2705 "Roam rssi diff value %d is out of range"
2706 " (Min: %d Max: %d)", roamRssiDiff,
2707 CFG_ROAM_RSSI_DIFF_MIN,
2708 CFG_ROAM_RSSI_DIFF_MAX);
2709 ret = -EINVAL;
2710 goto exit;
2711 }
2712
2713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2714 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2715
2716 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2717 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2718 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302719 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002720 {
2721 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2722 char extra[32];
2723 tANI_U8 len = 0;
2724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2726 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2727 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002728 len = scnprintf(extra, sizeof(extra), "%s %d",
2729 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 if (copy_to_user(priv_data.buf, &extra, len + 1))
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: failed to copy data to user buffer", __func__);
2734 ret = -EFAULT;
2735 goto exit;
2736 }
2737 }
2738#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002739#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002740 else if (strncmp(command, "GETBAND", 7) == 0)
2741 {
2742 int band = -1;
2743 char extra[32];
2744 tANI_U8 len = 0;
2745 hdd_getBand_helper(pHddCtx, &band);
2746
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2748 TRACE_CODE_HDD_GETBAND_IOCTL,
2749 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002750 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002751 if (copy_to_user(priv_data.buf, &extra, len + 1))
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: failed to copy data to user buffer", __func__);
2755 ret = -EFAULT;
2756 goto exit;
2757 }
2758 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002759 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 *value = command;
2762 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2763 tANI_U8 numChannels = 0;
2764 eHalStatus status = eHAL_STATUS_SUCCESS;
2765
2766 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2767 if (eHAL_STATUS_SUCCESS != status)
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: Failed to parse channel list information", __func__);
2771 ret = -EINVAL;
2772 goto exit;
2773 }
2774
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2782 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2783 ret = -EINVAL;
2784 goto exit;
2785 }
2786 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2787 numChannels);
2788 if (eHAL_STATUS_SUCCESS != status)
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: Failed to update channel list information", __func__);
2792 ret = -EINVAL;
2793 goto exit;
2794 }
2795 }
2796 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2797 {
2798 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2799 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002800 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002801 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002802 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002803
2804 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2805 ChannelList, &numChannels ))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2808 "%s: failed to get roam scan channel list", __func__);
2809 ret = -EFAULT;
2810 goto exit;
2811 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2813 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2814 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 /* output channel list is of the format
2816 [Number of roam scan channels][Channel1][Channel2]... */
2817 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002818 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002819 for (j = 0; (j < numChannels); j++)
2820 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002821 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2822 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002823 }
2824
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05302825 len = VOS_MIN(priv_data.total_len, len + 1);
2826 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002827 {
2828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2829 "%s: failed to copy data to user buffer", __func__);
2830 ret = -EFAULT;
2831 goto exit;
2832 }
2833 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002834 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2835 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002836 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002837 char extra[32];
2838 tANI_U8 len = 0;
2839
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002840 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002841 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002842 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002843 hdd_is_okc_mode_enabled(pHddCtx) &&
2844 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2845 {
2846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002847 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002848 " hence this operation is not permitted!", __func__);
2849 ret = -EPERM;
2850 goto exit;
2851 }
2852
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002853 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002854 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05302855 len = VOS_MIN(priv_data.total_len, len + 1);
2856 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002857 {
2858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2859 "%s: failed to copy data to user buffer", __func__);
2860 ret = -EFAULT;
2861 goto exit;
2862 }
2863 }
2864 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2865 {
2866 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2867 char extra[32];
2868 tANI_U8 len = 0;
2869
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002870 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002871 then this operation is not permitted (return FAILURE) */
2872 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002873 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002874 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2875 {
2876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002877 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002878 " hence this operation is not permitted!", __func__);
2879 ret = -EPERM;
2880 goto exit;
2881 }
2882
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002883 len = scnprintf(extra, sizeof(extra), "%s %d",
2884 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05302885 len = VOS_MIN(priv_data.total_len, len + 1);
2886 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002887 {
2888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2889 "%s: failed to copy data to user buffer", __func__);
2890 ret = -EFAULT;
2891 goto exit;
2892 }
2893 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002894 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002895 {
2896 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2897 char extra[32];
2898 tANI_U8 len = 0;
2899
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002900 len = scnprintf(extra, sizeof(extra), "%s %d",
2901 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302902 len = VOS_MIN(priv_data.total_len, len + 1);
2903 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002904 {
2905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2906 "%s: failed to copy data to user buffer", __func__);
2907 ret = -EFAULT;
2908 goto exit;
2909 }
2910 }
2911 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2912 {
2913 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2914 char extra[32];
2915 tANI_U8 len = 0;
2916
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002917 len = scnprintf(extra, sizeof(extra), "%s %d",
2918 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302919 len = VOS_MIN(priv_data.total_len, len + 1);
2920 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002921 {
2922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2923 "%s: failed to copy data to user buffer", __func__);
2924 ret = -EFAULT;
2925 goto exit;
2926 }
2927 }
2928 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2929 {
2930 tANI_U8 *value = command;
2931 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2932
2933 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2934 value = value + 26;
2935 /* Convert the value from ascii to integer */
2936 ret = kstrtou8(value, 10, &minTime);
2937 if (ret < 0)
2938 {
2939 /* If the input value is greater than max value of datatype, then also
2940 kstrtou8 fails */
2941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2942 "%s: kstrtou8 failed range [%d - %d]", __func__,
2943 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2944 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2945 ret = -EINVAL;
2946 goto exit;
2947 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002948 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2949 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2950 {
2951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2952 "scan min channel time value %d is out of range"
2953 " (Min: %d Max: %d)", minTime,
2954 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2955 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2956 ret = -EINVAL;
2957 goto exit;
2958 }
2959
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2961 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2962 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2964 "%s: Received Command to change channel min time = %d", __func__, minTime);
2965
2966 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2967 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2968 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002969 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2970 {
2971 tANI_U8 *value = command;
2972 tANI_U8 channel = 0;
2973 tANI_U8 dwellTime = 0;
2974 tANI_U8 bufLen = 0;
2975 tANI_U8 *buf = NULL;
2976 tSirMacAddr targetApBssid;
2977 eHalStatus status = eHAL_STATUS_SUCCESS;
2978 struct ieee80211_channel chan;
2979 tANI_U8 finalLen = 0;
2980 tANI_U8 *finalBuf = NULL;
2981 tANI_U8 temp = 0;
2982 u64 cookie;
2983 hdd_station_ctx_t *pHddStaCtx = NULL;
2984 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2985
2986 /* if not associated, no need to send action frame */
2987 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2988 {
2989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2990 ret = -EINVAL;
2991 goto exit;
2992 }
2993
2994 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2995 &dwellTime, &buf, &bufLen);
2996 if (eHAL_STATUS_SUCCESS != status)
2997 {
2998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2999 "%s: Failed to parse send action frame data", __func__);
3000 ret = -EINVAL;
3001 goto exit;
3002 }
3003
3004 /* if the target bssid is different from currently associated AP,
3005 then no need to send action frame */
3006 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3007 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3008 {
3009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3010 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003011 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003012 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003013 goto exit;
3014 }
3015
3016 /* if the channel number is different from operating channel then
3017 no need to send action frame */
3018 if (channel != pHddStaCtx->conn_info.operationChannel)
3019 {
3020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3021 "%s: channel(%d) is different from operating channel(%d)",
3022 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3023 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003024 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003025 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003026 goto exit;
3027 }
3028 chan.center_freq = sme_ChnToFreq(channel);
3029
3030 finalLen = bufLen + 24;
3031 finalBuf = vos_mem_malloc(finalLen);
3032 if (NULL == finalBuf)
3033 {
3034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3035 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003036 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003037 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003038 goto exit;
3039 }
3040 vos_mem_zero(finalBuf, finalLen);
3041
3042 /* Fill subtype */
3043 temp = SIR_MAC_MGMT_ACTION << 4;
3044 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3045
3046 /* Fill type */
3047 temp = SIR_MAC_MGMT_FRAME;
3048 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3049
3050 /* Fill destination address (bssid of the AP) */
3051 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3052
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003053 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003054 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3055
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003056 /* Fill BSSID (AP mac address) */
3057 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003058
3059 /* Fill received buffer from 24th address */
3060 vos_mem_copy(finalBuf + 24, buf, bufLen);
3061
Jeff Johnson11c33152013-04-16 17:52:40 -07003062 /* done with the parsed buffer */
3063 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003064 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003065
DARAM SUDHA39eede62014-02-12 11:16:40 +05303066 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3068 &(pAdapter->wdev),
3069#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003070 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003071#endif
3072 &chan, 0,
3073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3074 NL80211_CHAN_HT20, 1,
3075#endif
3076 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003077 1, &cookie );
3078 vos_mem_free(finalBuf);
3079 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003080 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3081 {
3082 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3083 char extra[32];
3084 tANI_U8 len = 0;
3085
3086 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003087 len = scnprintf(extra, sizeof(extra), "%s %d",
3088 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303089 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3090 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3091 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303092 len = VOS_MIN(priv_data.total_len, len + 1);
3093 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003094 {
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3096 "%s: failed to copy data to user buffer", __func__);
3097 ret = -EFAULT;
3098 goto exit;
3099 }
3100 }
3101 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3102 {
3103 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003104 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003105
3106 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3107 value = value + 19;
3108 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003109 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003110 if (ret < 0)
3111 {
3112 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003113 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003115 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003116 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3117 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3118 ret = -EINVAL;
3119 goto exit;
3120 }
3121
3122 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3123 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3124 {
3125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3126 "lfr mode value %d is out of range"
3127 " (Min: %d Max: %d)", maxTime,
3128 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3129 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3130 ret = -EINVAL;
3131 goto exit;
3132 }
3133
3134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3135 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3136
3137 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3138 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3139 }
3140 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3141 {
3142 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3143 char extra[32];
3144 tANI_U8 len = 0;
3145
3146 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003147 len = scnprintf(extra, sizeof(extra), "%s %d",
3148 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05303149 len = VOS_MIN(priv_data.total_len, len + 1);
3150 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003151 {
3152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3153 "%s: failed to copy data to user buffer", __func__);
3154 ret = -EFAULT;
3155 goto exit;
3156 }
3157 }
3158 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3159 {
3160 tANI_U8 *value = command;
3161 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3162
3163 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3164 value = value + 16;
3165 /* Convert the value from ascii to integer */
3166 ret = kstrtou16(value, 10, &val);
3167 if (ret < 0)
3168 {
3169 /* If the input value is greater than max value of datatype, then also
3170 kstrtou16 fails */
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "%s: kstrtou16 failed range [%d - %d]", __func__,
3173 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3174 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3175 ret = -EINVAL;
3176 goto exit;
3177 }
3178
3179 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3180 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3181 {
3182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3183 "scan home time value %d is out of range"
3184 " (Min: %d Max: %d)", val,
3185 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3186 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3187 ret = -EINVAL;
3188 goto exit;
3189 }
3190
3191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3192 "%s: Received Command to change scan home time = %d", __func__, val);
3193
3194 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3195 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3196 }
3197 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3198 {
3199 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3200 char extra[32];
3201 tANI_U8 len = 0;
3202
3203 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003204 len = scnprintf(extra, sizeof(extra), "%s %d",
3205 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003206 if (copy_to_user(priv_data.buf, &extra, len + 1))
3207 {
3208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3209 "%s: failed to copy data to user buffer", __func__);
3210 ret = -EFAULT;
3211 goto exit;
3212 }
3213 }
3214 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3215 {
3216 tANI_U8 *value = command;
3217 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3218
3219 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3220 value = value + 17;
3221 /* Convert the value from ascii to integer */
3222 ret = kstrtou8(value, 10, &val);
3223 if (ret < 0)
3224 {
3225 /* If the input value is greater than max value of datatype, then also
3226 kstrtou8 fails */
3227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3228 "%s: kstrtou8 failed range [%d - %d]", __func__,
3229 CFG_ROAM_INTRA_BAND_MIN,
3230 CFG_ROAM_INTRA_BAND_MAX);
3231 ret = -EINVAL;
3232 goto exit;
3233 }
3234
3235 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3236 (val > CFG_ROAM_INTRA_BAND_MAX))
3237 {
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3239 "intra band mode value %d is out of range"
3240 " (Min: %d Max: %d)", val,
3241 CFG_ROAM_INTRA_BAND_MIN,
3242 CFG_ROAM_INTRA_BAND_MAX);
3243 ret = -EINVAL;
3244 goto exit;
3245 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3247 "%s: Received Command to change intra band = %d", __func__, val);
3248
3249 pHddCtx->cfg_ini->nRoamIntraBand = val;
3250 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3251 }
3252 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3253 {
3254 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3255 char extra[32];
3256 tANI_U8 len = 0;
3257
3258 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003259 len = scnprintf(extra, sizeof(extra), "%s %d",
3260 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05303261 len = VOS_MIN(priv_data.total_len, len + 1);
3262 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003263 {
3264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3265 "%s: failed to copy data to user buffer", __func__);
3266 ret = -EFAULT;
3267 goto exit;
3268 }
3269 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003270 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3271 {
3272 tANI_U8 *value = command;
3273 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3274
3275 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3276 value = value + 15;
3277 /* Convert the value from ascii to integer */
3278 ret = kstrtou8(value, 10, &nProbes);
3279 if (ret < 0)
3280 {
3281 /* If the input value is greater than max value of datatype, then also
3282 kstrtou8 fails */
3283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3284 "%s: kstrtou8 failed range [%d - %d]", __func__,
3285 CFG_ROAM_SCAN_N_PROBES_MIN,
3286 CFG_ROAM_SCAN_N_PROBES_MAX);
3287 ret = -EINVAL;
3288 goto exit;
3289 }
3290
3291 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3292 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3293 {
3294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3295 "NProbes value %d is out of range"
3296 " (Min: %d Max: %d)", nProbes,
3297 CFG_ROAM_SCAN_N_PROBES_MIN,
3298 CFG_ROAM_SCAN_N_PROBES_MAX);
3299 ret = -EINVAL;
3300 goto exit;
3301 }
3302
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3304 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3305
3306 pHddCtx->cfg_ini->nProbes = nProbes;
3307 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3308 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303309 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003310 {
3311 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3312 char extra[32];
3313 tANI_U8 len = 0;
3314
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003315 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003316 if (copy_to_user(priv_data.buf, &extra, len + 1))
3317 {
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3319 "%s: failed to copy data to user buffer", __func__);
3320 ret = -EFAULT;
3321 goto exit;
3322 }
3323 }
3324 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3325 {
3326 tANI_U8 *value = command;
3327 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3328
3329 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3330 /* input value is in units of msec */
3331 value = value + 20;
3332 /* Convert the value from ascii to integer */
3333 ret = kstrtou16(value, 10, &homeAwayTime);
3334 if (ret < 0)
3335 {
3336 /* If the input value is greater than max value of datatype, then also
3337 kstrtou8 fails */
3338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3339 "%s: kstrtou8 failed range [%d - %d]", __func__,
3340 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3341 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3342 ret = -EINVAL;
3343 goto exit;
3344 }
3345
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003346 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3347 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3348 {
3349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3350 "homeAwayTime value %d is out of range"
3351 " (Min: %d Max: %d)", homeAwayTime,
3352 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3353 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3354 ret = -EINVAL;
3355 goto exit;
3356 }
3357
3358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3359 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003360 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3361 {
3362 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3363 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3364 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003365 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303366 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003367 {
3368 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3369 char extra[32];
3370 tANI_U8 len = 0;
3371
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003372 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003373 if (copy_to_user(priv_data.buf, &extra, len + 1))
3374 {
3375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3376 "%s: failed to copy data to user buffer", __func__);
3377 ret = -EFAULT;
3378 goto exit;
3379 }
3380 }
3381 else if (strncmp(command, "REASSOC", 7) == 0)
3382 {
3383 tANI_U8 *value = command;
3384 tANI_U8 channel = 0;
3385 tSirMacAddr targetApBssid;
3386 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003387#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3388 tCsrHandoffRequest handoffInfo;
3389#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003390 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003391 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3392
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003393 /* if not associated, no need to proceed with reassoc */
3394 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3395 {
3396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3397 ret = -EINVAL;
3398 goto exit;
3399 }
3400
3401 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3402 if (eHAL_STATUS_SUCCESS != status)
3403 {
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "%s: Failed to parse reassoc command data", __func__);
3406 ret = -EINVAL;
3407 goto exit;
3408 }
3409
3410 /* if the target bssid is same as currently associated AP,
3411 then no need to proceed with reassoc */
3412 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3413 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3414 {
3415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3416 ret = -EINVAL;
3417 goto exit;
3418 }
3419
3420 /* Check channel number is a valid channel number */
3421 if(VOS_STATUS_SUCCESS !=
3422 wlan_hdd_validate_operation_channel(pAdapter, channel))
3423 {
3424 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003425 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003426 return -EINVAL;
3427 }
3428
3429 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003430#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3431 handoffInfo.channel = channel;
3432 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3433 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3434#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003435 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003436 else if (strncmp(command, "SETWESMODE", 10) == 0)
3437 {
3438 tANI_U8 *value = command;
3439 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3440
3441 /* Move pointer to ahead of SETWESMODE<delimiter> */
3442 value = value + 11;
3443 /* Convert the value from ascii to integer */
3444 ret = kstrtou8(value, 10, &wesMode);
3445 if (ret < 0)
3446 {
3447 /* If the input value is greater than max value of datatype, then also
3448 kstrtou8 fails */
3449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3450 "%s: kstrtou8 failed range [%d - %d]", __func__,
3451 CFG_ENABLE_WES_MODE_NAME_MIN,
3452 CFG_ENABLE_WES_MODE_NAME_MAX);
3453 ret = -EINVAL;
3454 goto exit;
3455 }
3456
3457 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3458 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3459 {
3460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3461 "WES Mode value %d is out of range"
3462 " (Min: %d Max: %d)", wesMode,
3463 CFG_ENABLE_WES_MODE_NAME_MIN,
3464 CFG_ENABLE_WES_MODE_NAME_MAX);
3465 ret = -EINVAL;
3466 goto exit;
3467 }
3468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3469 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3470
3471 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3472 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3473 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303474 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003475 {
3476 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3477 char extra[32];
3478 tANI_U8 len = 0;
3479
Arif Hussain826d9412013-11-12 16:44:54 -08003480 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003481 if (copy_to_user(priv_data.buf, &extra, len + 1))
3482 {
3483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3484 "%s: failed to copy data to user buffer", __func__);
3485 ret = -EFAULT;
3486 goto exit;
3487 }
3488 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003489#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003490#ifdef FEATURE_WLAN_LFR
3491 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3492 {
3493 tANI_U8 *value = command;
3494 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3495
3496 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3497 value = value + 12;
3498 /* Convert the value from ascii to integer */
3499 ret = kstrtou8(value, 10, &lfrMode);
3500 if (ret < 0)
3501 {
3502 /* If the input value is greater than max value of datatype, then also
3503 kstrtou8 fails */
3504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3505 "%s: kstrtou8 failed range [%d - %d]", __func__,
3506 CFG_LFR_FEATURE_ENABLED_MIN,
3507 CFG_LFR_FEATURE_ENABLED_MAX);
3508 ret = -EINVAL;
3509 goto exit;
3510 }
3511
3512 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3513 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3514 {
3515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3516 "lfr mode value %d is out of range"
3517 " (Min: %d Max: %d)", lfrMode,
3518 CFG_LFR_FEATURE_ENABLED_MIN,
3519 CFG_LFR_FEATURE_ENABLED_MAX);
3520 ret = -EINVAL;
3521 goto exit;
3522 }
3523
3524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3525 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3526
3527 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3528 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3529 }
3530#endif
3531#ifdef WLAN_FEATURE_VOWIFI_11R
3532 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3533 {
3534 tANI_U8 *value = command;
3535 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3536
3537 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3538 value = value + 18;
3539 /* Convert the value from ascii to integer */
3540 ret = kstrtou8(value, 10, &ft);
3541 if (ret < 0)
3542 {
3543 /* If the input value is greater than max value of datatype, then also
3544 kstrtou8 fails */
3545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3546 "%s: kstrtou8 failed range [%d - %d]", __func__,
3547 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3548 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3549 ret = -EINVAL;
3550 goto exit;
3551 }
3552
3553 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3554 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3555 {
3556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3557 "ft mode value %d is out of range"
3558 " (Min: %d Max: %d)", ft,
3559 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3560 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3561 ret = -EINVAL;
3562 goto exit;
3563 }
3564
3565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3566 "%s: Received Command to change ft mode = %d", __func__, ft);
3567
3568 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3569 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3570 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303571 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3572 {
3573 tANI_U8 *value = command;
3574 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303575
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303576 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3577 value = value + 15;
3578 /* Convert the value from ascii to integer */
3579 ret = kstrtou8(value, 10, &dfsScanMode);
3580 if (ret < 0)
3581 {
3582 /* If the input value is greater than max value of
3583 datatype, then also kstrtou8 fails
3584 */
3585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3586 "%s: kstrtou8 failed range [%d - %d]", __func__,
3587 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3588 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3589 ret = -EINVAL;
3590 goto exit;
3591 }
3592
3593 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3594 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3595 {
3596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3597 "dfsScanMode value %d is out of range"
3598 " (Min: %d Max: %d)", dfsScanMode,
3599 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3600 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3601 ret = -EINVAL;
3602 goto exit;
3603 }
3604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3605 "%s: Received Command to Set DFS Scan Mode = %d",
3606 __func__, dfsScanMode);
3607
3608 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3609 }
3610 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3611 {
3612 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3613 char extra[32];
3614 tANI_U8 len = 0;
3615
3616 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3617 if (copy_to_user(priv_data.buf, &extra, len + 1))
3618 {
3619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3620 "%s: failed to copy data to user buffer", __func__);
3621 ret = -EFAULT;
3622 goto exit;
3623 }
3624 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303625 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3626 {
3627 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303628 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303629 tSirMacAddr targetApBssid;
3630 tANI_U8 trigger = 0;
3631 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303632 tHalHandle hHal;
3633 v_U32_t roamId = 0;
3634 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303635 hdd_station_ctx_t *pHddStaCtx = NULL;
3636 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303637 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303638
3639 /* if not associated, no need to proceed with reassoc */
3640 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3641 {
3642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3643 ret = -EINVAL;
3644 goto exit;
3645 }
3646
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303647 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303648 if (eHAL_STATUS_SUCCESS != status)
3649 {
3650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3651 "%s: Failed to parse reassoc command data", __func__);
3652 ret = -EINVAL;
3653 goto exit;
3654 }
3655
3656 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303657 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303658 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3659 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3660 {
3661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3662 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3663 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303664 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3665 &modProfileFields);
3666 sme_RoamReassoc(hHal, pAdapter->sessionId,
3667 NULL, modProfileFields, &roamId, 1);
3668 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303669 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303670
3671 /* Check channel number is a valid channel number */
3672 if(VOS_STATUS_SUCCESS !=
3673 wlan_hdd_validate_operation_channel(pAdapter, channel))
3674 {
3675 hddLog(VOS_TRACE_LEVEL_ERROR,
3676 "%s: Invalid Channel [%d]", __func__, channel);
3677 return -EINVAL;
3678 }
3679
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303680 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303681
3682 /* Proceed with scan/roam */
3683 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3684 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303685 (tSmeFastRoamTrigger)(trigger),
3686 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303687 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003688#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003689#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003690 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3691 {
3692 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003693 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003694
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003695 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003696 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003697 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003698 hdd_is_okc_mode_enabled(pHddCtx) &&
3699 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3700 {
3701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003702 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003703 " hence this operation is not permitted!", __func__);
3704 ret = -EPERM;
3705 goto exit;
3706 }
3707
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003708 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3709 value = value + 11;
3710 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003711 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003712 if (ret < 0)
3713 {
3714 /* If the input value is greater than max value of datatype, then also
3715 kstrtou8 fails */
3716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3717 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003718 CFG_ESE_FEATURE_ENABLED_MIN,
3719 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003720 ret = -EINVAL;
3721 goto exit;
3722 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003723 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3724 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003725 {
3726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003727 "Ese mode value %d is out of range"
3728 " (Min: %d Max: %d)", eseMode,
3729 CFG_ESE_FEATURE_ENABLED_MIN,
3730 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003731 ret = -EINVAL;
3732 goto exit;
3733 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003735 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003736
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003737 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3738 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003739 }
3740#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003741 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3742 {
3743 tANI_U8 *value = command;
3744 tANI_BOOLEAN roamScanControl = 0;
3745
3746 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3747 value = value + 19;
3748 /* Convert the value from ascii to integer */
3749 ret = kstrtou8(value, 10, &roamScanControl);
3750 if (ret < 0)
3751 {
3752 /* If the input value is greater than max value of datatype, then also
3753 kstrtou8 fails */
3754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3755 "%s: kstrtou8 failed ", __func__);
3756 ret = -EINVAL;
3757 goto exit;
3758 }
3759
3760 if (0 != roamScanControl)
3761 {
3762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3763 "roam scan control invalid value = %d",
3764 roamScanControl);
3765 ret = -EINVAL;
3766 goto exit;
3767 }
3768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3769 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3770
3771 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3772 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003773#ifdef FEATURE_WLAN_OKC
3774 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3775 {
3776 tANI_U8 *value = command;
3777 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3778
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003779 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003780 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003781 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003782 hdd_is_okc_mode_enabled(pHddCtx) &&
3783 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3784 {
3785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003786 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003787 " hence this operation is not permitted!", __func__);
3788 ret = -EPERM;
3789 goto exit;
3790 }
3791
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003792 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3793 value = value + 11;
3794 /* Convert the value from ascii to integer */
3795 ret = kstrtou8(value, 10, &okcMode);
3796 if (ret < 0)
3797 {
3798 /* If the input value is greater than max value of datatype, then also
3799 kstrtou8 fails */
3800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3801 "%s: kstrtou8 failed range [%d - %d]", __func__,
3802 CFG_OKC_FEATURE_ENABLED_MIN,
3803 CFG_OKC_FEATURE_ENABLED_MAX);
3804 ret = -EINVAL;
3805 goto exit;
3806 }
3807
3808 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3809 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3810 {
3811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3812 "Okc mode value %d is out of range"
3813 " (Min: %d Max: %d)", okcMode,
3814 CFG_OKC_FEATURE_ENABLED_MIN,
3815 CFG_OKC_FEATURE_ENABLED_MAX);
3816 ret = -EINVAL;
3817 goto exit;
3818 }
3819
3820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3821 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3822
3823 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3824 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003825#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303826 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003827 {
3828 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3829 char extra[32];
3830 tANI_U8 len = 0;
3831
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003832 len = scnprintf(extra, sizeof(extra), "%s %d",
3833 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003834 if (copy_to_user(priv_data.buf, &extra, len + 1))
3835 {
3836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3837 "%s: failed to copy data to user buffer", __func__);
3838 ret = -EFAULT;
3839 goto exit;
3840 }
3841 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303842#ifdef WLAN_FEATURE_PACKET_FILTERING
3843 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3844 {
3845 tANI_U8 filterType = 0;
3846 tANI_U8 *value = command;
3847
3848 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3849 value = value + 22;
3850
3851 /* Convert the value from ascii to integer */
3852 ret = kstrtou8(value, 10, &filterType);
3853 if (ret < 0)
3854 {
3855 /* If the input value is greater than max value of datatype,
3856 * then also kstrtou8 fails
3857 */
3858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3859 "%s: kstrtou8 failed range ", __func__);
3860 ret = -EINVAL;
3861 goto exit;
3862 }
3863
3864 if (filterType != 0 && filterType != 1)
3865 {
3866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3867 "%s: Accepted Values are 0 and 1 ", __func__);
3868 ret = -EINVAL;
3869 goto exit;
3870 }
3871 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3872 pAdapter->sessionId);
3873 }
3874#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303875 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3876 {
Kiet Lamad161252014-07-22 11:23:32 -07003877 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303878 int ret;
3879
Kiet Lamad161252014-07-22 11:23:32 -07003880 dhcpPhase = command + 11;
3881 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303882 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003884 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303885
3886 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003887
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303888 ret = wlan_hdd_scan_abort(pAdapter);
3889 if (ret < 0)
3890 {
3891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3892 FL("failed to abort existing scan %d"), ret);
3893 }
3894
Kiet Lamad161252014-07-22 11:23:32 -07003895 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3896 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303897 }
Kiet Lamad161252014-07-22 11:23:32 -07003898 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303899 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003901 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303902
3903 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003904
3905 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3906 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303907 }
3908 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003909 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3910 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3912 FL("making default scan to ACTIVE"));
3913 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003914 }
3915 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3916 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3918 FL("making default scan to PASSIVE"));
3919 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003920 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303921 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3922 {
3923 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3924 char extra[32];
3925 tANI_U8 len = 0;
3926
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303927 memset(extra, 0, sizeof(extra));
3928 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3929 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303930 {
3931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3932 "%s: failed to copy data to user buffer", __func__);
3933 ret = -EFAULT;
3934 goto exit;
3935 }
3936 ret = len;
3937 }
3938 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3939 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303940 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303941 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003942 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3943 {
3944 tANI_U8 filterType = 0;
3945 tANI_U8 *value;
3946 value = command + 9;
3947
3948 /* Convert the value from ascii to integer */
3949 ret = kstrtou8(value, 10, &filterType);
3950 if (ret < 0)
3951 {
3952 /* If the input value is greater than max value of datatype,
3953 * then also kstrtou8 fails
3954 */
3955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3956 "%s: kstrtou8 failed range ", __func__);
3957 ret = -EINVAL;
3958 goto exit;
3959 }
3960 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3961 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3962 {
3963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3964 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3965 " 2-Sink ", __func__);
3966 ret = -EINVAL;
3967 goto exit;
3968 }
3969 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3970 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303971 pScanInfo = &pHddCtx->scan_info;
3972 if (filterType && pScanInfo != NULL &&
3973 pHddCtx->scan_info.mScanPending)
3974 {
3975 /*Miracast Session started. Abort Scan */
3976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3977 "%s, Aborting Scan For Miracast",__func__);
3978 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3979 eCSR_SCAN_ABORT_DEFAULT);
3980 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003981 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303982 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003983 }
Leo Chang614d2072013-08-22 14:59:44 -07003984 else if (strncmp(command, "SETMCRATE", 9) == 0)
3985 {
Leo Chang614d2072013-08-22 14:59:44 -07003986 tANI_U8 *value = command;
3987 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003988 tSirRateUpdateInd *rateUpdate;
3989 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003990
3991 /* Only valid for SAP mode */
3992 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3993 {
3994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3995 "%s: SAP mode is not running", __func__);
3996 ret = -EFAULT;
3997 goto exit;
3998 }
3999
4000 /* Move pointer to ahead of SETMCRATE<delimiter> */
4001 /* input value is in units of hundred kbps */
4002 value = value + 10;
4003 /* Convert the value from ascii to integer, decimal base */
4004 ret = kstrtouint(value, 10, &targetRate);
4005
Leo Chang1f98cbd2013-10-17 15:03:52 -07004006 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4007 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004008 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004009 hddLog(VOS_TRACE_LEVEL_ERROR,
4010 "%s: SETMCRATE indication alloc fail", __func__);
4011 ret = -EFAULT;
4012 goto exit;
4013 }
4014 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4015
4016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4017 "MC Target rate %d", targetRate);
4018 /* Ignore unicast */
4019 rateUpdate->ucastDataRate = -1;
4020 rateUpdate->mcastDataRate24GHz = targetRate;
4021 rateUpdate->mcastDataRate5GHz = targetRate;
4022 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4023 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4024 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4025 if (eHAL_STATUS_SUCCESS != status)
4026 {
4027 hddLog(VOS_TRACE_LEVEL_ERROR,
4028 "%s: SET_MC_RATE failed", __func__);
4029 vos_mem_free(rateUpdate);
4030 ret = -EFAULT;
4031 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004032 }
4033 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304034#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004035 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304036 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004037 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304038 }
4039#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004040#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004041 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4042 {
4043 tANI_U8 *value = command;
4044 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4045 tANI_U8 numChannels = 0;
4046 eHalStatus status = eHAL_STATUS_SUCCESS;
4047
4048 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4049 if (eHAL_STATUS_SUCCESS != status)
4050 {
4051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4052 "%s: Failed to parse channel list information", __func__);
4053 ret = -EINVAL;
4054 goto exit;
4055 }
4056
4057 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4058 {
4059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4060 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4061 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4062 ret = -EINVAL;
4063 goto exit;
4064 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004065 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004066 ChannelList,
4067 numChannels);
4068 if (eHAL_STATUS_SUCCESS != status)
4069 {
4070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4071 "%s: Failed to update channel list information", __func__);
4072 ret = -EINVAL;
4073 goto exit;
4074 }
4075 }
4076 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4077 {
4078 tANI_U8 *value = command;
4079 char extra[128] = {0};
4080 int len = 0;
4081 tANI_U8 tid = 0;
4082 hdd_station_ctx_t *pHddStaCtx = NULL;
4083 tAniTrafStrmMetrics tsmMetrics;
4084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4085
4086 /* if not associated, return error */
4087 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4088 {
4089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4090 ret = -EINVAL;
4091 goto exit;
4092 }
4093
4094 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4095 value = value + 12;
4096 /* Convert the value from ascii to integer */
4097 ret = kstrtou8(value, 10, &tid);
4098 if (ret < 0)
4099 {
4100 /* If the input value is greater than max value of datatype, then also
4101 kstrtou8 fails */
4102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4103 "%s: kstrtou8 failed range [%d - %d]", __func__,
4104 TID_MIN_VALUE,
4105 TID_MAX_VALUE);
4106 ret = -EINVAL;
4107 goto exit;
4108 }
4109
4110 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4111 {
4112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4113 "tid value %d is out of range"
4114 " (Min: %d Max: %d)", tid,
4115 TID_MIN_VALUE,
4116 TID_MAX_VALUE);
4117 ret = -EINVAL;
4118 goto exit;
4119 }
4120
4121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4122 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4123
4124 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4125 {
4126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4127 "%s: failed to get tsm stats", __func__);
4128 ret = -EFAULT;
4129 goto exit;
4130 }
4131
4132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4133 "UplinkPktQueueDly(%d)\n"
4134 "UplinkPktQueueDlyHist[0](%d)\n"
4135 "UplinkPktQueueDlyHist[1](%d)\n"
4136 "UplinkPktQueueDlyHist[2](%d)\n"
4137 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304138 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004139 "UplinkPktLoss(%d)\n"
4140 "UplinkPktCount(%d)\n"
4141 "RoamingCount(%d)\n"
4142 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4143 tsmMetrics.UplinkPktQueueDlyHist[0],
4144 tsmMetrics.UplinkPktQueueDlyHist[1],
4145 tsmMetrics.UplinkPktQueueDlyHist[2],
4146 tsmMetrics.UplinkPktQueueDlyHist[3],
4147 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4148 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4149
4150 /* Output TSM stats is of the format
4151 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4152 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004153 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004154 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4155 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4156 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4157 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4158 tsmMetrics.RoamingDly);
4159
4160 if (copy_to_user(priv_data.buf, &extra, len + 1))
4161 {
4162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4163 "%s: failed to copy data to user buffer", __func__);
4164 ret = -EFAULT;
4165 goto exit;
4166 }
4167 }
4168 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4169 {
4170 tANI_U8 *value = command;
4171 tANI_U8 *cckmIe = NULL;
4172 tANI_U8 cckmIeLen = 0;
4173 eHalStatus status = eHAL_STATUS_SUCCESS;
4174
4175 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4176 if (eHAL_STATUS_SUCCESS != status)
4177 {
4178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4179 "%s: Failed to parse cckm ie data", __func__);
4180 ret = -EINVAL;
4181 goto exit;
4182 }
4183
4184 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4185 {
4186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4187 "%s: CCKM Ie input length is more than max[%d]", __func__,
4188 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004189 vos_mem_free(cckmIe);
4190 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004191 ret = -EINVAL;
4192 goto exit;
4193 }
4194 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004195 vos_mem_free(cckmIe);
4196 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004197 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004198 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4199 {
4200 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004201 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004202 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004203
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004204 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004205 if (eHAL_STATUS_SUCCESS != status)
4206 {
4207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004208 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004209 ret = -EINVAL;
4210 goto exit;
4211 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004212 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4214 hdd_indicateEseBcnReportNoResults (pAdapter,
4215 eseBcnReq.bcnReq[0].measurementToken,
4216 0x02, //BIT(1) set for measurement done
4217 0); // no BSS
4218 goto exit;
4219 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004220
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004221 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4222 if (eHAL_STATUS_SUCCESS != status)
4223 {
4224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4225 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4226 ret = -EINVAL;
4227 goto exit;
4228 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004229 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004230#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304231 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4232 {
4233 eHalStatus status;
4234 char buf[32], len;
4235 long waitRet;
4236 bcnMissRateContext_t getBcnMissRateCtx;
4237
4238 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4239
4240 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4241 {
4242 hddLog(VOS_TRACE_LEVEL_WARN,
4243 FL("GETBCNMISSRATE: STA is not in connected state"));
4244 ret = -1;
4245 goto exit;
4246 }
4247
4248 init_completion(&(getBcnMissRateCtx.completion));
4249 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4250
4251 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4252 pAdapter->sessionId,
4253 (void *)getBcnMissRateCB,
4254 (void *)(&getBcnMissRateCtx));
4255 if( eHAL_STATUS_SUCCESS != status)
4256 {
4257 hddLog(VOS_TRACE_LEVEL_INFO,
4258 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4259 ret = -EINVAL;
4260 goto exit;
4261 }
4262
4263 waitRet = wait_for_completion_interruptible_timeout
4264 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4265 if(waitRet <= 0)
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR,
4268 FL("failed to wait on bcnMissRateComp %d"), ret);
4269
4270 //Make magic number to zero so that callback is not called.
4271 spin_lock(&hdd_context_lock);
4272 getBcnMissRateCtx.magic = 0x0;
4273 spin_unlock(&hdd_context_lock);
4274 ret = -EINVAL;
4275 goto exit;
4276 }
4277
4278 hddLog(VOS_TRACE_LEVEL_INFO,
4279 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4280
4281 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4282 if (copy_to_user(priv_data.buf, &buf, len + 1))
4283 {
4284 hddLog(VOS_TRACE_LEVEL_ERROR,
4285 "%s: failed to copy data to user buffer", __func__);
4286 ret = -EFAULT;
4287 goto exit;
4288 }
4289 ret = len;
4290 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304291#ifdef FEATURE_WLAN_TDLS
4292 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4293 tANI_U8 *value = command;
4294 int set_value;
4295 /* Move pointer to ahead of TDLSOFFCH*/
4296 value += 26;
4297 sscanf(value, "%d", &set_value);
4298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4299 "%s: Tdls offchannel offset:%d",
4300 __func__, set_value);
4301 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4302 if (ret < 0)
4303 {
4304 ret = -EINVAL;
4305 goto exit;
4306 }
4307
4308 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4309 tANI_U8 *value = command;
4310 int set_value;
4311 /* Move pointer to ahead of tdlsoffchnmode*/
4312 value += 18;
4313 sscanf(value, "%d", &set_value);
4314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4315 "%s: Tdls offchannel mode:%d",
4316 __func__, set_value);
4317 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4318 if (ret < 0)
4319 {
4320 ret = -EINVAL;
4321 goto exit;
4322 }
4323 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4324 tANI_U8 *value = command;
4325 int set_value;
4326 /* Move pointer to ahead of TDLSOFFCH*/
4327 value += 14;
4328 sscanf(value, "%d", &set_value);
4329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4330 "%s: Tdls offchannel num: %d",
4331 __func__, set_value);
4332 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4333 if (ret < 0)
4334 {
4335 ret = -EINVAL;
4336 goto exit;
4337 }
4338 }
4339#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304340 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4341 {
4342 eHalStatus status;
4343 char *buf = NULL;
4344 char len;
4345 long waitRet;
4346 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304347 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304348 tANI_U8 *ptr = command;
4349 int stats = *(ptr + 11) - '0';
4350
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4352 if (!IS_FEATURE_FW_STATS_ENABLE)
4353 {
4354 hddLog(VOS_TRACE_LEVEL_INFO,
4355 FL("Get Firmware stats feature not supported"));
4356 ret = -EINVAL;
4357 goto exit;
4358 }
4359
4360 if (FW_STATS_MAX <= stats || 0 >= stats)
4361 {
4362 hddLog(VOS_TRACE_LEVEL_INFO,
4363 FL(" stats %d not supported"),stats);
4364 ret = -EINVAL;
4365 goto exit;
4366 }
4367
4368 init_completion(&(fwStatsCtx.completion));
4369 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4370 fwStatsCtx.pAdapter = pAdapter;
4371 fwStatsRsp->type = 0;
4372 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304373 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304374 if (eHAL_STATUS_SUCCESS != status)
4375 {
4376 hddLog(VOS_TRACE_LEVEL_ERROR,
4377 FL(" fail to post WDA cmd status = %d"), status);
4378 ret = -EINVAL;
4379 goto exit;
4380 }
4381 waitRet = wait_for_completion_timeout
4382 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4383 if (waitRet <= 0)
4384 {
4385 hddLog(VOS_TRACE_LEVEL_ERROR,
4386 FL("failed to wait on GwtFwstats"));
4387 //Make magic number to zero so that callback is not executed.
4388 spin_lock(&hdd_context_lock);
4389 fwStatsCtx.magic = 0x0;
4390 spin_unlock(&hdd_context_lock);
4391 ret = -EINVAL;
4392 goto exit;
4393 }
4394 if (fwStatsRsp->type)
4395 {
4396 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4397 if (!buf)
4398 {
4399 hddLog(VOS_TRACE_LEVEL_ERROR,
4400 FL(" failed to allocate memory"));
4401 ret = -ENOMEM;
4402 goto exit;
4403 }
4404 switch( fwStatsRsp->type )
4405 {
4406 case FW_UBSP_STATS:
4407 {
4408 len = snprintf(buf, FW_STATE_RSP_LEN,
4409 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304410 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4411 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304412 }
4413 break;
4414 default:
4415 {
4416 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4417 ret = -EFAULT;
4418 kfree(buf);
4419 goto exit;
4420 }
4421 }
4422 if (copy_to_user(priv_data.buf, buf, len + 1))
4423 {
4424 hddLog(VOS_TRACE_LEVEL_ERROR,
4425 FL(" failed to copy data to user buffer"));
4426 ret = -EFAULT;
4427 kfree(buf);
4428 goto exit;
4429 }
4430 ret = len;
4431 kfree(buf);
4432 }
4433 else
4434 {
4435 hddLog(VOS_TRACE_LEVEL_ERROR,
4436 FL("failed to fetch the stats"));
4437 ret = -EFAULT;
4438 goto exit;
4439 }
4440
4441 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304442 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4443 {
4444 /*
4445 * this command wld be called by user-space when it detects WLAN
4446 * ON after airplane mode is set. When APM is set, WLAN turns off.
4447 * But it can be turned back on. Otherwise; when APM is turned back
4448 * off, WLAN wld turn back on. So at that point the command is
4449 * expected to come down. 0 means disable, 1 means enable. The
4450 * constraint is removed when parameter 1 is set or different
4451 * country code is set
4452 */
4453 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4454 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004455 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304456 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4457 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4458 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304459 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4460 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004461 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004462 }
4463exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304464 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004465 if (command)
4466 {
4467 kfree(command);
4468 }
4469 return ret;
4470}
4471
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004472#ifdef CONFIG_COMPAT
4473static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4474{
4475 struct {
4476 compat_uptr_t buf;
4477 int used_len;
4478 int total_len;
4479 } compat_priv_data;
4480 hdd_priv_data_t priv_data;
4481 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004482
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004483 /*
4484 * Note that pAdapter and ifr have already been verified by caller,
4485 * and HDD context has also been validated
4486 */
4487 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4488 sizeof(compat_priv_data))) {
4489 ret = -EFAULT;
4490 goto exit;
4491 }
4492 priv_data.buf = compat_ptr(compat_priv_data.buf);
4493 priv_data.used_len = compat_priv_data.used_len;
4494 priv_data.total_len = compat_priv_data.total_len;
4495 ret = hdd_driver_command(pAdapter, &priv_data);
4496 exit:
4497 return ret;
4498}
4499#else /* CONFIG_COMPAT */
4500static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4501{
4502 /* will never be invoked */
4503 return 0;
4504}
4505#endif /* CONFIG_COMPAT */
4506
4507static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4508{
4509 hdd_priv_data_t priv_data;
4510 int ret = 0;
4511
4512 /*
4513 * Note that pAdapter and ifr have already been verified by caller,
4514 * and HDD context has also been validated
4515 */
4516 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4517 ret = -EFAULT;
4518 } else {
4519 ret = hdd_driver_command(pAdapter, &priv_data);
4520 }
4521 return ret;
4522}
4523
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304524int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004525{
4526 hdd_adapter_t *pAdapter;
4527 hdd_context_t *pHddCtx;
4528 int ret;
4529
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304530 ENTER();
4531
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004532 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4533 if (NULL == pAdapter) {
4534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4535 "%s: HDD adapter context is Null", __func__);
4536 ret = -ENODEV;
4537 goto exit;
4538 }
4539 if (dev != pAdapter->dev) {
4540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4541 "%s: HDD adapter/dev inconsistency", __func__);
4542 ret = -ENODEV;
4543 goto exit;
4544 }
4545
4546 if ((!ifr) || (!ifr->ifr_data)) {
4547 ret = -EINVAL;
4548 goto exit;
4549 }
4550
4551 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4552 ret = wlan_hdd_validate_context(pHddCtx);
4553 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004554 ret = -EBUSY;
4555 goto exit;
4556 }
4557
4558 switch (cmd) {
4559 case (SIOCDEVPRIVATE + 1):
4560 if (is_compat_task())
4561 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4562 else
4563 ret = hdd_driver_ioctl(pAdapter, ifr);
4564 break;
4565 default:
4566 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4567 __func__, cmd);
4568 ret = -EINVAL;
4569 break;
4570 }
4571 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304572 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004573 return ret;
4574}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004575
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304576int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4577{
4578 int ret;
4579
4580 vos_ssr_protect(__func__);
4581 ret = __hdd_ioctl(dev, ifr, cmd);
4582 vos_ssr_unprotect(__func__);
4583
4584 return ret;
4585}
4586
Katya Nigame7b69a82015-04-28 15:24:06 +05304587int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4588{
4589 return 0;
4590}
4591
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004592#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004593/**---------------------------------------------------------------------------
4594
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004595 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004596
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004598 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4599 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4600 <space>Scan Mode N<space>Meas Duration N
4601 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4602 then take N.
4603 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4604 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4605 This function does not take care of removing duplicate channels from the list
4606
4607 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004608 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004609
4610 \return - 0 for success non-zero for failure
4611
4612 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004613static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4614 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004615{
4616 tANI_U8 *inPtr = pValue;
4617 int tempInt = 0;
4618 int j = 0, i = 0, v = 0;
4619 char buf[32];
4620
4621 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4622 /*no argument after the command*/
4623 if (NULL == inPtr)
4624 {
4625 return -EINVAL;
4626 }
4627 /*no space after the command*/
4628 else if (SPACE_ASCII_VALUE != *inPtr)
4629 {
4630 return -EINVAL;
4631 }
4632
4633 /*removing empty spaces*/
4634 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4635
4636 /*no argument followed by spaces*/
4637 if ('\0' == *inPtr) return -EINVAL;
4638
4639 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004640 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004641 if (1 != v) return -EINVAL;
4642
4643 v = kstrtos32(buf, 10, &tempInt);
4644 if ( v < 0) return -EINVAL;
4645
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004646 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004647
4648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004649 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004650
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004651 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004652 {
4653 for (i = 0; i < 4; i++)
4654 {
4655 /*inPtr pointing to the beginning of first space after number of ie fields*/
4656 inPtr = strpbrk( inPtr, " " );
4657 /*no ie data after the number of ie fields argument*/
4658 if (NULL == inPtr) return -EINVAL;
4659
4660 /*removing empty space*/
4661 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4662
4663 /*no ie data after the number of ie fields argument and spaces*/
4664 if ( '\0' == *inPtr ) return -EINVAL;
4665
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004666 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004667 if (1 != v) return -EINVAL;
4668
4669 v = kstrtos32(buf, 10, &tempInt);
4670 if (v < 0) return -EINVAL;
4671
4672 switch (i)
4673 {
4674 case 0: /* Measurement token */
4675 if (tempInt <= 0)
4676 {
4677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4678 "Invalid Measurement Token(%d)", tempInt);
4679 return -EINVAL;
4680 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004681 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004682 break;
4683
4684 case 1: /* Channel number */
4685 if ((tempInt <= 0) ||
4686 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4687 {
4688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4689 "Invalid Channel Number(%d)", tempInt);
4690 return -EINVAL;
4691 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004692 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004693 break;
4694
4695 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004696 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004697 {
4698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4699 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4700 return -EINVAL;
4701 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004702 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004703 break;
4704
4705 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004706 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4707 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004708 {
4709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4710 "Invalid Measurement Duration(%d)", tempInt);
4711 return -EINVAL;
4712 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004713 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004714 break;
4715 }
4716 }
4717 }
4718
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004719 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004720 {
4721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304722 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004723 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004724 pEseBcnReq->bcnReq[j].measurementToken,
4725 pEseBcnReq->bcnReq[j].channel,
4726 pEseBcnReq->bcnReq[j].scanMode,
4727 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004728 }
4729
4730 return VOS_STATUS_SUCCESS;
4731}
4732
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004733static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4734{
4735 struct statsContext *pStatsContext = NULL;
4736 hdd_adapter_t *pAdapter = NULL;
4737
4738 if (NULL == pContext)
4739 {
4740 hddLog(VOS_TRACE_LEVEL_ERROR,
4741 "%s: Bad param, pContext [%p]",
4742 __func__, pContext);
4743 return;
4744 }
4745
Jeff Johnson72a40512013-12-19 10:14:15 -08004746 /* there is a race condition that exists between this callback
4747 function and the caller since the caller could time out either
4748 before or while this code is executing. we use a spinlock to
4749 serialize these actions */
4750 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004751
4752 pStatsContext = pContext;
4753 pAdapter = pStatsContext->pAdapter;
4754 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4755 {
4756 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004757 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004758 hddLog(VOS_TRACE_LEVEL_WARN,
4759 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4760 __func__, pAdapter, pStatsContext->magic);
4761 return;
4762 }
4763
Jeff Johnson72a40512013-12-19 10:14:15 -08004764 /* context is valid so caller is still waiting */
4765
4766 /* paranoia: invalidate the magic */
4767 pStatsContext->magic = 0;
4768
4769 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004770 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4771 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4772 tsmMetrics.UplinkPktQueueDlyHist,
4773 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4774 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4775 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4776 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4777 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4778 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4779 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4780
Jeff Johnson72a40512013-12-19 10:14:15 -08004781 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004782 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004783
4784 /* serialization is complete */
4785 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004786}
4787
4788
4789
4790static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4791 tAniTrafStrmMetrics* pTsmMetrics)
4792{
4793 hdd_station_ctx_t *pHddStaCtx = NULL;
4794 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004795 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004796 long lrc;
4797 struct statsContext context;
4798 hdd_context_t *pHddCtx = NULL;
4799
4800 if (NULL == pAdapter)
4801 {
4802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4803 return VOS_STATUS_E_FAULT;
4804 }
4805
4806 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4807 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4808
4809 /* we are connected prepare our callback context */
4810 init_completion(&context.completion);
4811 context.pAdapter = pAdapter;
4812 context.magic = STATS_CONTEXT_MAGIC;
4813
4814 /* query tsm stats */
4815 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4816 pHddStaCtx->conn_info.staId[ 0 ],
4817 pHddStaCtx->conn_info.bssId,
4818 &context, pHddCtx->pvosContext, tid);
4819
4820 if (eHAL_STATUS_SUCCESS != hstatus)
4821 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4823 __func__);
4824 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004825 }
4826 else
4827 {
4828 /* request was sent -- wait for the response */
4829 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4830 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004831 if (lrc <= 0)
4832 {
4833 hddLog(VOS_TRACE_LEVEL_ERROR,
4834 "%s: SME %s while retrieving statistics",
4835 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004836 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004837 }
4838 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004839
Jeff Johnson72a40512013-12-19 10:14:15 -08004840 /* either we never sent a request, we sent a request and received a
4841 response or we sent a request and timed out. if we never sent a
4842 request or if we sent a request and got a response, we want to
4843 clear the magic out of paranoia. if we timed out there is a
4844 race condition such that the callback function could be
4845 executing at the same time we are. of primary concern is if the
4846 callback function had already verified the "magic" but had not
4847 yet set the completion variable when a timeout occurred. we
4848 serialize these activities by invalidating the magic while
4849 holding a shared spinlock which will cause us to block if the
4850 callback is currently executing */
4851 spin_lock(&hdd_context_lock);
4852 context.magic = 0;
4853 spin_unlock(&hdd_context_lock);
4854
4855 if (VOS_STATUS_SUCCESS == vstatus)
4856 {
4857 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4858 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4859 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4860 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4861 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4862 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4863 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4864 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4865 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4866 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4867 }
4868 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004869}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004870#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004871
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004872#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004873void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4874{
4875 eCsrBand band = -1;
4876 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4877 switch (band)
4878 {
4879 case eCSR_BAND_ALL:
4880 *pBand = WLAN_HDD_UI_BAND_AUTO;
4881 break;
4882
4883 case eCSR_BAND_24:
4884 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4885 break;
4886
4887 case eCSR_BAND_5G:
4888 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4889 break;
4890
4891 default:
4892 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4893 *pBand = -1;
4894 break;
4895 }
4896}
4897
4898/**---------------------------------------------------------------------------
4899
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004900 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4901
4902 This function parses the send action frame data passed in the format
4903 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4904
Srinivas Girigowda56076852013-08-20 14:00:50 -07004905 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004906 \param - pTargetApBssid Pointer to target Ap bssid
4907 \param - pChannel Pointer to the Target AP channel
4908 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4909 \param - pBuf Pointer to data
4910 \param - pBufLen Pointer to data length
4911
4912 \return - 0 for success non-zero for failure
4913
4914 --------------------------------------------------------------------------*/
4915VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4916 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4917{
4918 tANI_U8 *inPtr = pValue;
4919 tANI_U8 *dataEnd;
4920 int tempInt;
4921 int j = 0;
4922 int i = 0;
4923 int v = 0;
4924 tANI_U8 tempBuf[32];
4925 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004926 /* 12 hexa decimal digits, 5 ':' and '\0' */
4927 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004928
4929 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4930 /*no argument after the command*/
4931 if (NULL == inPtr)
4932 {
4933 return -EINVAL;
4934 }
4935
4936 /*no space after the command*/
4937 else if (SPACE_ASCII_VALUE != *inPtr)
4938 {
4939 return -EINVAL;
4940 }
4941
4942 /*removing empty spaces*/
4943 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4944
4945 /*no argument followed by spaces*/
4946 if ('\0' == *inPtr)
4947 {
4948 return -EINVAL;
4949 }
4950
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004951 v = sscanf(inPtr, "%17s", macAddress);
4952 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004953 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4955 "Invalid MAC address or All hex inputs are not read (%d)", v);
4956 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004957 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004958
4959 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4960 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4961 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4962 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4963 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4964 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004965
4966 /* point to the next argument */
4967 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4968 /*no argument after the command*/
4969 if (NULL == inPtr) return -EINVAL;
4970
4971 /*removing empty spaces*/
4972 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4973
4974 /*no argument followed by spaces*/
4975 if ('\0' == *inPtr)
4976 {
4977 return -EINVAL;
4978 }
4979
4980 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004981 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004982 if (1 != v) return -EINVAL;
4983
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004984 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304985 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304986 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004987
4988 *pChannel = tempInt;
4989
4990 /* point to the next argument */
4991 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4992 /*no argument after the command*/
4993 if (NULL == inPtr) return -EINVAL;
4994 /*removing empty spaces*/
4995 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4996
4997 /*no argument followed by spaces*/
4998 if ('\0' == *inPtr)
4999 {
5000 return -EINVAL;
5001 }
5002
5003 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005004 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005005 if (1 != v) return -EINVAL;
5006
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005007 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005008 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005009
5010 *pDwellTime = tempInt;
5011
5012 /* point to the next argument */
5013 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5014 /*no argument after the command*/
5015 if (NULL == inPtr) return -EINVAL;
5016 /*removing empty spaces*/
5017 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5018
5019 /*no argument followed by spaces*/
5020 if ('\0' == *inPtr)
5021 {
5022 return -EINVAL;
5023 }
5024
5025 /* find the length of data */
5026 dataEnd = inPtr;
5027 while(('\0' != *dataEnd) )
5028 {
5029 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005030 }
Kiet Lambe150c22013-11-21 16:30:32 +05305031 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005032 if ( *pBufLen <= 0) return -EINVAL;
5033
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005034 /* Allocate the number of bytes based on the number of input characters
5035 whether it is even or odd.
5036 if the number of input characters are even, then we need N/2 byte.
5037 if the number of input characters are odd, then we need do (N+1)/2 to
5038 compensate rounding off.
5039 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5040 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5041 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005042 if (NULL == *pBuf)
5043 {
5044 hddLog(VOS_TRACE_LEVEL_FATAL,
5045 "%s: vos_mem_alloc failed ", __func__);
5046 return -EINVAL;
5047 }
5048
5049 /* the buffer received from the upper layer is character buffer,
5050 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5051 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5052 and f0 in 3rd location */
5053 for (i = 0, j = 0; j < *pBufLen; j += 2)
5054 {
Kiet Lambe150c22013-11-21 16:30:32 +05305055 if( j+1 == *pBufLen)
5056 {
5057 tempByte = hdd_parse_hex(inPtr[j]);
5058 }
5059 else
5060 {
5061 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5062 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005063 (*pBuf)[i++] = tempByte;
5064 }
5065 *pBufLen = i;
5066 return VOS_STATUS_SUCCESS;
5067}
5068
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005069/**---------------------------------------------------------------------------
5070
Srinivas Girigowdade697412013-02-14 16:31:48 -08005071 \brief hdd_parse_channellist() - HDD Parse channel list
5072
5073 This function parses the channel list passed in the format
5074 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005075 if the Number of channels (N) does not match with the actual number of channels passed
5076 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5077 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5078 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5079 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005080
5081 \param - pValue Pointer to input channel list
5082 \param - ChannelList Pointer to local output array to record channel list
5083 \param - pNumChannels Pointer to number of roam scan channels
5084
5085 \return - 0 for success non-zero for failure
5086
5087 --------------------------------------------------------------------------*/
5088VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5089{
5090 tANI_U8 *inPtr = pValue;
5091 int tempInt;
5092 int j = 0;
5093 int v = 0;
5094 char buf[32];
5095
5096 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5097 /*no argument after the command*/
5098 if (NULL == inPtr)
5099 {
5100 return -EINVAL;
5101 }
5102
5103 /*no space after the command*/
5104 else if (SPACE_ASCII_VALUE != *inPtr)
5105 {
5106 return -EINVAL;
5107 }
5108
5109 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005110 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005111
5112 /*no argument followed by spaces*/
5113 if ('\0' == *inPtr)
5114 {
5115 return -EINVAL;
5116 }
5117
5118 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005119 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005120 if (1 != v) return -EINVAL;
5121
Srinivas Girigowdade697412013-02-14 16:31:48 -08005122 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005123 if ((v < 0) ||
5124 (tempInt <= 0) ||
5125 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5126 {
5127 return -EINVAL;
5128 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005129
5130 *pNumChannels = tempInt;
5131
5132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5133 "Number of channels are: %d", *pNumChannels);
5134
5135 for (j = 0; j < (*pNumChannels); j++)
5136 {
5137 /*inPtr pointing to the beginning of first space after number of channels*/
5138 inPtr = strpbrk( inPtr, " " );
5139 /*no channel list after the number of channels argument*/
5140 if (NULL == inPtr)
5141 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005142 if (0 != j)
5143 {
5144 *pNumChannels = j;
5145 return VOS_STATUS_SUCCESS;
5146 }
5147 else
5148 {
5149 return -EINVAL;
5150 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005151 }
5152
5153 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005154 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005155
5156 /*no channel list after the number of channels argument and spaces*/
5157 if ( '\0' == *inPtr )
5158 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005159 if (0 != j)
5160 {
5161 *pNumChannels = j;
5162 return VOS_STATUS_SUCCESS;
5163 }
5164 else
5165 {
5166 return -EINVAL;
5167 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005168 }
5169
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005170 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005171 if (1 != v) return -EINVAL;
5172
Srinivas Girigowdade697412013-02-14 16:31:48 -08005173 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005174 if ((v < 0) ||
5175 (tempInt <= 0) ||
5176 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5177 {
5178 return -EINVAL;
5179 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005180 pChannelList[j] = tempInt;
5181
5182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5183 "Channel %d added to preferred channel list",
5184 pChannelList[j] );
5185 }
5186
Srinivas Girigowdade697412013-02-14 16:31:48 -08005187 return VOS_STATUS_SUCCESS;
5188}
5189
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005190
5191/**---------------------------------------------------------------------------
5192
5193 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5194
5195 This function parses the reasoc command data passed in the format
5196 REASSOC<space><bssid><space><channel>
5197
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005198 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005199 \param - pTargetApBssid Pointer to target Ap bssid
5200 \param - pChannel Pointer to the Target AP channel
5201
5202 \return - 0 for success non-zero for failure
5203
5204 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005205VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5206 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005207{
5208 tANI_U8 *inPtr = pValue;
5209 int tempInt;
5210 int v = 0;
5211 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005212 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005213 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005214
5215 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5216 /*no argument after the command*/
5217 if (NULL == inPtr)
5218 {
5219 return -EINVAL;
5220 }
5221
5222 /*no space after the command*/
5223 else if (SPACE_ASCII_VALUE != *inPtr)
5224 {
5225 return -EINVAL;
5226 }
5227
5228 /*removing empty spaces*/
5229 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5230
5231 /*no argument followed by spaces*/
5232 if ('\0' == *inPtr)
5233 {
5234 return -EINVAL;
5235 }
5236
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005237 v = sscanf(inPtr, "%17s", macAddress);
5238 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005239 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5241 "Invalid MAC address or All hex inputs are not read (%d)", v);
5242 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005243 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005244
5245 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5246 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5247 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5248 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5249 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5250 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005251
5252 /* point to the next argument */
5253 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5254 /*no argument after the command*/
5255 if (NULL == inPtr) return -EINVAL;
5256
5257 /*removing empty spaces*/
5258 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5259
5260 /*no argument followed by spaces*/
5261 if ('\0' == *inPtr)
5262 {
5263 return -EINVAL;
5264 }
5265
5266 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005267 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005268 if (1 != v) return -EINVAL;
5269
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005270 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005271 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305272 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005273 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5274 {
5275 return -EINVAL;
5276 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005277
5278 *pChannel = tempInt;
5279 return VOS_STATUS_SUCCESS;
5280}
5281
5282#endif
5283
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005284#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005285/**---------------------------------------------------------------------------
5286
5287 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5288
5289 This function parses the SETCCKM IE command
5290 SETCCKMIE<space><ie data>
5291
5292 \param - pValue Pointer to input data
5293 \param - pCckmIe Pointer to output cckm Ie
5294 \param - pCckmIeLen Pointer to output cckm ie length
5295
5296 \return - 0 for success non-zero for failure
5297
5298 --------------------------------------------------------------------------*/
5299VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5300 tANI_U8 *pCckmIeLen)
5301{
5302 tANI_U8 *inPtr = pValue;
5303 tANI_U8 *dataEnd;
5304 int j = 0;
5305 int i = 0;
5306 tANI_U8 tempByte = 0;
5307
5308 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5309 /*no argument after the command*/
5310 if (NULL == inPtr)
5311 {
5312 return -EINVAL;
5313 }
5314
5315 /*no space after the command*/
5316 else if (SPACE_ASCII_VALUE != *inPtr)
5317 {
5318 return -EINVAL;
5319 }
5320
5321 /*removing empty spaces*/
5322 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5323
5324 /*no argument followed by spaces*/
5325 if ('\0' == *inPtr)
5326 {
5327 return -EINVAL;
5328 }
5329
5330 /* find the length of data */
5331 dataEnd = inPtr;
5332 while(('\0' != *dataEnd) )
5333 {
5334 dataEnd++;
5335 ++(*pCckmIeLen);
5336 }
5337 if ( *pCckmIeLen <= 0) return -EINVAL;
5338
5339 /* Allocate the number of bytes based on the number of input characters
5340 whether it is even or odd.
5341 if the number of input characters are even, then we need N/2 byte.
5342 if the number of input characters are odd, then we need do (N+1)/2 to
5343 compensate rounding off.
5344 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5345 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5346 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5347 if (NULL == *pCckmIe)
5348 {
5349 hddLog(VOS_TRACE_LEVEL_FATAL,
5350 "%s: vos_mem_alloc failed ", __func__);
5351 return -EINVAL;
5352 }
5353 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5354 /* the buffer received from the upper layer is character buffer,
5355 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5356 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5357 and f0 in 3rd location */
5358 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5359 {
5360 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5361 (*pCckmIe)[i++] = tempByte;
5362 }
5363 *pCckmIeLen = i;
5364
5365 return VOS_STATUS_SUCCESS;
5366}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005367#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005368
Jeff Johnson295189b2012-06-20 16:38:30 -07005369/**---------------------------------------------------------------------------
5370
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005371 \brief hdd_is_valid_mac_address() - Validate MAC address
5372
5373 This function validates whether the given MAC address is valid or not
5374 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5375 where X is the hexa decimal digit character and separated by ':'
5376 This algorithm works even if MAC address is not separated by ':'
5377
5378 This code checks given input string mac contains exactly 12 hexadecimal digits.
5379 and a separator colon : appears in the input string only after
5380 an even number of hex digits.
5381
5382 \param - pMacAddr pointer to the input MAC address
5383 \return - 1 for valid and 0 for invalid
5384
5385 --------------------------------------------------------------------------*/
5386
5387v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5388{
5389 int xdigit = 0;
5390 int separator = 0;
5391 while (*pMacAddr)
5392 {
5393 if (isxdigit(*pMacAddr))
5394 {
5395 xdigit++;
5396 }
5397 else if (':' == *pMacAddr)
5398 {
5399 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5400 break;
5401
5402 ++separator;
5403 }
5404 else
5405 {
5406 separator = -1;
5407 /* Invalid MAC found */
5408 return 0;
5409 }
5410 ++pMacAddr;
5411 }
5412 return (xdigit == 12 && (separator == 5 || separator == 0));
5413}
5414
5415/**---------------------------------------------------------------------------
5416
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305417 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005418
5419 \param - dev Pointer to net_device structure
5420
5421 \return - 0 for success non-zero for failure
5422
5423 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305424int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005425{
5426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5427 hdd_context_t *pHddCtx;
5428 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5429 VOS_STATUS status;
5430 v_BOOL_t in_standby = TRUE;
5431
5432 if (NULL == pAdapter)
5433 {
5434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305435 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 return -ENODEV;
5437 }
5438
5439 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305440 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5441 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 if (NULL == pHddCtx)
5443 {
5444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005445 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 return -ENODEV;
5447 }
5448
5449 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5450 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5451 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005452 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5453 {
5454 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305455 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005456 in_standby = FALSE;
5457 break;
5458 }
5459 else
5460 {
5461 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5462 pAdapterNode = pNext;
5463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 }
5465
5466 if (TRUE == in_standby)
5467 {
5468 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5469 {
5470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5471 "wlan out of power save", __func__);
5472 return -EINVAL;
5473 }
5474 }
5475
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005476 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5478 {
5479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005480 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005481 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 netif_tx_start_all_queues(dev);
5484 }
5485
5486 return 0;
5487}
5488
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305489/**---------------------------------------------------------------------------
5490
5491 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5492
5493 This is called in response to ifconfig up
5494
5495 \param - dev Pointer to net_device structure
5496
5497 \return - 0 for success non-zero for failure
5498
5499 --------------------------------------------------------------------------*/
5500int hdd_open(struct net_device *dev)
5501{
5502 int ret;
5503
5504 vos_ssr_protect(__func__);
5505 ret = __hdd_open(dev);
5506 vos_ssr_unprotect(__func__);
5507
5508 return ret;
5509}
5510
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305511int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005512{
5513 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5514
5515 if(pAdapter == NULL) {
5516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005517 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005518 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 }
5520
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 return 0;
5522}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305523
5524int hdd_mon_open (struct net_device *dev)
5525{
5526 int ret;
5527
5528 vos_ssr_protect(__func__);
5529 ret = __hdd_mon_open(dev);
5530 vos_ssr_unprotect(__func__);
5531
5532 return ret;
5533}
5534
Katya Nigame7b69a82015-04-28 15:24:06 +05305535int hdd_mon_stop(struct net_device *dev)
5536{
5537 return 0;
5538}
5539
Jeff Johnson295189b2012-06-20 16:38:30 -07005540/**---------------------------------------------------------------------------
5541
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305542 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005543
5544 \param - dev Pointer to net_device structure
5545
5546 \return - 0 for success non-zero for failure
5547
5548 --------------------------------------------------------------------------*/
5549
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305550int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005551{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305552 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5554 hdd_context_t *pHddCtx;
5555 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5556 VOS_STATUS status;
5557 v_BOOL_t enter_standby = TRUE;
5558
5559 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 if (NULL == pAdapter)
5561 {
5562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305563 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005564 return -ENODEV;
5565 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305566 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305567 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305568
5569 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5570 ret = wlan_hdd_validate_context(pHddCtx);
5571 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305573 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 }
5575
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305576 /* Nothing to be done if the interface is not opened */
5577 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5578 {
5579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5580 "%s: NETDEV Interface is not OPENED", __func__);
5581 return -ENODEV;
5582 }
5583
5584 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005585 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305587
5588 /* Disable TX on the interface, after this hard_start_xmit() will not
5589 * be called on that interface
5590 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305591 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305593
5594 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 netif_carrier_off(pAdapter->dev);
5596
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305597 /* The interface is marked as down for outside world (aka kernel)
5598 * But the driver is pretty much alive inside. The driver needs to
5599 * tear down the existing connection on the netdev (session)
5600 * cleanup the data pipes and wait until the control plane is stabilized
5601 * for this interface. The call also needs to wait until the above
5602 * mentioned actions are completed before returning to the caller.
5603 * Notice that the hdd_stop_adapter is requested not to close the session
5604 * That is intentional to be able to scan if it is a STA/P2P interface
5605 */
5606 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305607#ifdef FEATURE_WLAN_TDLS
5608 mutex_lock(&pHddCtx->tdls_lock);
5609#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305610 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305611 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305612#ifdef FEATURE_WLAN_TDLS
5613 mutex_unlock(&pHddCtx->tdls_lock);
5614#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 /* SoftAP ifaces should never go in power save mode
5616 making sure same here. */
5617 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5618 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005620 )
5621 {
5622 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5624 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 EXIT();
5626 return 0;
5627 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305628 /* Find if any iface is up. If any iface is up then can't put device to
5629 * sleep/power save mode
5630 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5632 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5633 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005634 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5635 {
5636 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305637 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005638 enter_standby = FALSE;
5639 break;
5640 }
5641 else
5642 {
5643 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5644 pAdapterNode = pNext;
5645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005646 }
5647
5648 if (TRUE == enter_standby)
5649 {
5650 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5651 "entering standby", __func__);
5652 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5653 {
5654 /*log and return success*/
5655 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5656 "wlan in power save", __func__);
5657 }
5658 }
5659
5660 EXIT();
5661 return 0;
5662}
5663
5664/**---------------------------------------------------------------------------
5665
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305666 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005667
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305668 This is called in response to ifconfig down
5669
5670 \param - dev Pointer to net_device structure
5671
5672 \return - 0 for success non-zero for failure
5673-----------------------------------------------------------------------------*/
5674int hdd_stop (struct net_device *dev)
5675{
5676 int ret;
5677
5678 vos_ssr_protect(__func__);
5679 ret = __hdd_stop(dev);
5680 vos_ssr_unprotect(__func__);
5681
5682 return ret;
5683}
5684
5685/**---------------------------------------------------------------------------
5686
5687 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005688
5689 \param - dev Pointer to net_device structure
5690
5691 \return - void
5692
5693 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305694static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005695{
5696 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305697 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 ENTER();
5699
5700 do
5701 {
5702 if (NULL == pAdapter)
5703 {
5704 hddLog(VOS_TRACE_LEVEL_FATAL,
5705 "%s: NULL pAdapter", __func__);
5706 break;
5707 }
5708
5709 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5710 {
5711 hddLog(VOS_TRACE_LEVEL_FATAL,
5712 "%s: Invalid magic", __func__);
5713 break;
5714 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305715 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5716 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 {
5718 hddLog(VOS_TRACE_LEVEL_FATAL,
5719 "%s: NULL pHddCtx", __func__);
5720 break;
5721 }
5722
5723 if (dev != pAdapter->dev)
5724 {
5725 hddLog(VOS_TRACE_LEVEL_FATAL,
5726 "%s: Invalid device reference", __func__);
5727 /* we haven't validated all cases so let this go for now */
5728 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305729#ifdef FEATURE_WLAN_TDLS
5730 mutex_lock(&pHddCtx->tdls_lock);
5731#endif
c_hpothu002231a2015-02-05 14:58:51 +05305732 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305733#ifdef FEATURE_WLAN_TDLS
5734 mutex_unlock(&pHddCtx->tdls_lock);
5735#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005736
5737 /* after uninit our adapter structure will no longer be valid */
5738 pAdapter->dev = NULL;
5739 pAdapter->magic = 0;
5740 } while (0);
5741
5742 EXIT();
5743}
5744
5745/**---------------------------------------------------------------------------
5746
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305747 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5748
5749 This is called during the netdev unregister to uninitialize all data
5750associated with the device
5751
5752 \param - dev Pointer to net_device structure
5753
5754 \return - void
5755
5756 --------------------------------------------------------------------------*/
5757static void hdd_uninit (struct net_device *dev)
5758{
5759 vos_ssr_protect(__func__);
5760 __hdd_uninit(dev);
5761 vos_ssr_unprotect(__func__);
5762}
5763
5764/**---------------------------------------------------------------------------
5765
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 \brief hdd_release_firmware() -
5767
5768 This function calls the release firmware API to free the firmware buffer.
5769
5770 \param - pFileName Pointer to the File Name.
5771 pCtx - Pointer to the adapter .
5772
5773
5774 \return - 0 for success, non zero for failure
5775
5776 --------------------------------------------------------------------------*/
5777
5778VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5779{
5780 VOS_STATUS status = VOS_STATUS_SUCCESS;
5781 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5782 ENTER();
5783
5784
5785 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5786
5787 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5788
5789 if(pHddCtx->fw) {
5790 release_firmware(pHddCtx->fw);
5791 pHddCtx->fw = NULL;
5792 }
5793 else
5794 status = VOS_STATUS_E_FAILURE;
5795 }
5796 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5797 if(pHddCtx->nv) {
5798 release_firmware(pHddCtx->nv);
5799 pHddCtx->nv = NULL;
5800 }
5801 else
5802 status = VOS_STATUS_E_FAILURE;
5803
5804 }
5805
5806 EXIT();
5807 return status;
5808}
5809
5810/**---------------------------------------------------------------------------
5811
5812 \brief hdd_request_firmware() -
5813
5814 This function reads the firmware file using the request firmware
5815 API and returns the the firmware data and the firmware file size.
5816
5817 \param - pfileName - Pointer to the file name.
5818 - pCtx - Pointer to the adapter .
5819 - ppfw_data - Pointer to the pointer of the firmware data.
5820 - pSize - Pointer to the file size.
5821
5822 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5823
5824 --------------------------------------------------------------------------*/
5825
5826
5827VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5828{
5829 int status;
5830 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5831 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5832 ENTER();
5833
5834 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5835
5836 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5837
5838 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5839 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5840 __func__, pfileName);
5841 retval = VOS_STATUS_E_FAILURE;
5842 }
5843
5844 else {
5845 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5846 *pSize = pHddCtx->fw->size;
5847 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5848 __func__, *pSize);
5849 }
5850 }
5851 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5852
5853 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5854
5855 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5856 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5857 __func__, pfileName);
5858 retval = VOS_STATUS_E_FAILURE;
5859 }
5860
5861 else {
5862 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5863 *pSize = pHddCtx->nv->size;
5864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5865 __func__, *pSize);
5866 }
5867 }
5868
5869 EXIT();
5870 return retval;
5871}
5872/**---------------------------------------------------------------------------
5873 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5874
5875 This is the function invoked by SME to inform the result of a full power
5876 request issued by HDD
5877
5878 \param - callbackcontext - Pointer to cookie
5879 status - result of request
5880
5881 \return - None
5882
5883--------------------------------------------------------------------------*/
5884void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5885{
5886 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5887
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005888 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 if(&pHddCtx->full_pwr_comp_var)
5890 {
5891 complete(&pHddCtx->full_pwr_comp_var);
5892 }
5893}
5894
5895/**---------------------------------------------------------------------------
5896
5897 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5898
5899 This is the function invoked by SME to inform the result of BMPS
5900 request issued by HDD
5901
5902 \param - callbackcontext - Pointer to cookie
5903 status - result of request
5904
5905 \return - None
5906
5907--------------------------------------------------------------------------*/
5908void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5909{
5910
5911 struct completion *completion_var = (struct completion*) callbackContext;
5912
Arif Hussain6d2a3322013-11-17 19:50:10 -08005913 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 if(completion_var != NULL)
5915 {
5916 complete(completion_var);
5917 }
5918}
5919
5920/**---------------------------------------------------------------------------
5921
5922 \brief hdd_get_cfg_file_size() -
5923
5924 This function reads the configuration file using the request firmware
5925 API and returns the configuration file size.
5926
5927 \param - pCtx - Pointer to the adapter .
5928 - pFileName - Pointer to the file name.
5929 - pBufSize - Pointer to the buffer size.
5930
5931 \return - 0 for success, non zero for failure
5932
5933 --------------------------------------------------------------------------*/
5934
5935VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5936{
5937 int status;
5938 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5939
5940 ENTER();
5941
5942 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5943
5944 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5945 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5946 status = VOS_STATUS_E_FAILURE;
5947 }
5948 else {
5949 *pBufSize = pHddCtx->fw->size;
5950 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5951 release_firmware(pHddCtx->fw);
5952 pHddCtx->fw = NULL;
5953 }
5954
5955 EXIT();
5956 return VOS_STATUS_SUCCESS;
5957}
5958
5959/**---------------------------------------------------------------------------
5960
5961 \brief hdd_read_cfg_file() -
5962
5963 This function reads the configuration file using the request firmware
5964 API and returns the cfg data and the buffer size of the configuration file.
5965
5966 \param - pCtx - Pointer to the adapter .
5967 - pFileName - Pointer to the file name.
5968 - pBuffer - Pointer to the data buffer.
5969 - pBufSize - Pointer to the buffer size.
5970
5971 \return - 0 for success, non zero for failure
5972
5973 --------------------------------------------------------------------------*/
5974
5975VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5976 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5977{
5978 int status;
5979 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5980
5981 ENTER();
5982
5983 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5984
5985 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5986 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5987 return VOS_STATUS_E_FAILURE;
5988 }
5989 else {
5990 if(*pBufSize != pHddCtx->fw->size) {
5991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5992 "file size", __func__);
5993 release_firmware(pHddCtx->fw);
5994 pHddCtx->fw = NULL;
5995 return VOS_STATUS_E_FAILURE;
5996 }
5997 else {
5998 if(pBuffer) {
5999 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6000 }
6001 release_firmware(pHddCtx->fw);
6002 pHddCtx->fw = NULL;
6003 }
6004 }
6005
6006 EXIT();
6007
6008 return VOS_STATUS_SUCCESS;
6009}
6010
6011/**---------------------------------------------------------------------------
6012
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306013 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006014
6015 This function sets the user specified mac address using
6016 the command ifconfig wlanX hw ether <mac adress>.
6017
6018 \param - dev - Pointer to the net device.
6019 - addr - Pointer to the sockaddr.
6020 \return - 0 for success, non zero for failure
6021
6022 --------------------------------------------------------------------------*/
6023
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306024static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006025{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306026 hdd_adapter_t *pAdapter;
6027 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 struct sockaddr *psta_mac_addr = addr;
6029 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306030 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006031
6032 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306033 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6034 if (NULL == pAdapter)
6035 {
6036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6037 "%s: Adapter is NULL",__func__);
6038 return -EINVAL;
6039 }
6040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6041 ret = wlan_hdd_validate_context(pHddCtx);
6042 if (0 != ret)
6043 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306044 return ret;
6045 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006046
6047 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6049
6050 EXIT();
6051 return halStatus;
6052}
6053
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306054/**---------------------------------------------------------------------------
6055
6056 \brief hdd_set_mac_address() -
6057
6058 Wrapper function to protect __hdd_set_mac_address() function from ssr
6059
6060 \param - dev - Pointer to the net device.
6061 - addr - Pointer to the sockaddr.
6062 \return - 0 for success, non zero for failure
6063
6064 --------------------------------------------------------------------------*/
6065static int hdd_set_mac_address(struct net_device *dev, void *addr)
6066{
6067 int ret;
6068
6069 vos_ssr_protect(__func__);
6070 ret = __hdd_set_mac_address(dev, addr);
6071 vos_ssr_unprotect(__func__);
6072
6073 return ret;
6074}
6075
Jeff Johnson295189b2012-06-20 16:38:30 -07006076tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6077{
6078 int i;
6079 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6080 {
Abhishek Singheb183782014-02-06 13:37:21 +05306081 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006082 break;
6083 }
6084
6085 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6086 return NULL;
6087
6088 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6089 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6090}
6091
6092void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6093{
6094 int i;
6095 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6096 {
6097 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6098 {
6099 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6100 break;
6101 }
6102 }
6103 return;
6104}
6105
6106#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6107 static struct net_device_ops wlan_drv_ops = {
6108 .ndo_open = hdd_open,
6109 .ndo_stop = hdd_stop,
6110 .ndo_uninit = hdd_uninit,
6111 .ndo_start_xmit = hdd_hard_start_xmit,
6112 .ndo_tx_timeout = hdd_tx_timeout,
6113 .ndo_get_stats = hdd_stats,
6114 .ndo_do_ioctl = hdd_ioctl,
6115 .ndo_set_mac_address = hdd_set_mac_address,
6116 .ndo_select_queue = hdd_select_queue,
6117#ifdef WLAN_FEATURE_PACKET_FILTERING
6118#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6119 .ndo_set_rx_mode = hdd_set_multicast_list,
6120#else
6121 .ndo_set_multicast_list = hdd_set_multicast_list,
6122#endif //LINUX_VERSION_CODE
6123#endif
6124 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 static struct net_device_ops wlan_mon_drv_ops = {
6126 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306127 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006128 .ndo_uninit = hdd_uninit,
6129 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6130 .ndo_tx_timeout = hdd_tx_timeout,
6131 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306132 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 .ndo_set_mac_address = hdd_set_mac_address,
6134 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306135
Jeff Johnson295189b2012-06-20 16:38:30 -07006136#endif
6137
6138void hdd_set_station_ops( struct net_device *pWlanDev )
6139{
6140#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006141 pWlanDev->netdev_ops = &wlan_drv_ops;
6142#else
6143 pWlanDev->open = hdd_open;
6144 pWlanDev->stop = hdd_stop;
6145 pWlanDev->uninit = hdd_uninit;
6146 pWlanDev->hard_start_xmit = NULL;
6147 pWlanDev->tx_timeout = hdd_tx_timeout;
6148 pWlanDev->get_stats = hdd_stats;
6149 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 pWlanDev->set_mac_address = hdd_set_mac_address;
6151#endif
6152}
6153
Katya Nigam1fd24402015-02-16 14:52:19 +05306154void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6155{
6156 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6157 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6158 #else
6159 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6160 #endif
6161}
6162
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006163static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006164{
6165 struct net_device *pWlanDev = NULL;
6166 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 /*
6168 * cfg80211 initialization and registration....
6169 */
6170 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6171
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 if(pWlanDev != NULL)
6173 {
6174
6175 //Save the pointer to the net_device in the HDD adapter
6176 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6177
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6179
6180 pAdapter->dev = pWlanDev;
6181 pAdapter->pHddCtx = pHddCtx;
6182 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306183 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006184
6185 init_completion(&pAdapter->session_open_comp_var);
6186 init_completion(&pAdapter->session_close_comp_var);
6187 init_completion(&pAdapter->disconnect_comp_var);
6188 init_completion(&pAdapter->linkup_event_var);
6189 init_completion(&pAdapter->cancel_rem_on_chan_var);
6190 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306191 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6193 init_completion(&pAdapter->offchannel_tx_event);
6194#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006196#ifdef FEATURE_WLAN_TDLS
6197 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006198 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006199 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306200 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006201#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 init_completion(&pHddCtx->mc_sus_event_var);
6203 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306204 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006205 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006206 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006207
Rajeev79dbe4c2013-10-05 11:03:42 +05306208#ifdef FEATURE_WLAN_BATCH_SCAN
6209 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6210 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6211 pAdapter->pBatchScanRsp = NULL;
6212 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006213 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006214 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306215 mutex_init(&pAdapter->hdd_batch_scan_lock);
6216#endif
6217
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 pAdapter->isLinkUpSvcNeeded = FALSE;
6219 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6220 //Init the net_device structure
6221 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6222
6223 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6224 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6225 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6226 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6227
6228 hdd_set_station_ops( pAdapter->dev );
6229
6230 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6232 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6233 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 /* set pWlanDev's parent to underlying device */
6235 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006236
6237 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 }
6239
6240 return pAdapter;
6241}
6242
6243VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6244{
6245 struct net_device *pWlanDev = pAdapter->dev;
6246 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6247 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6248 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6249
6250 if( rtnl_lock_held )
6251 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006252 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6254 {
6255 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6256 return VOS_STATUS_E_FAILURE;
6257 }
6258 }
6259 if (register_netdevice(pWlanDev))
6260 {
6261 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6262 return VOS_STATUS_E_FAILURE;
6263 }
6264 }
6265 else
6266 {
6267 if(register_netdev(pWlanDev))
6268 {
6269 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6270 return VOS_STATUS_E_FAILURE;
6271 }
6272 }
6273 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6274
6275 return VOS_STATUS_SUCCESS;
6276}
6277
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006278static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006279{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006280 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006281
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006282 if (NULL == pAdapter)
6283 {
6284 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6285 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006287
6288 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6289 {
6290 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6291 return eHAL_STATUS_NOT_INITIALIZED;
6292 }
6293
6294 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6295
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006296#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006297 /* need to make sure all of our scheduled work has completed.
6298 * This callback is called from MC thread context, so it is safe to
6299 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006300 *
6301 * Even though this is called from MC thread context, if there is a faulty
6302 * work item in the system, that can hang this call forever. So flushing
6303 * this global work queue is not safe; and now we make sure that
6304 * individual work queues are stopped correctly. But the cancel work queue
6305 * is a GPL only API, so the proprietary version of the driver would still
6306 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006307 */
6308 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006309#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006310
6311 /* We can be blocked while waiting for scheduled work to be
6312 * flushed, and the adapter structure can potentially be freed, in
6313 * which case the magic will have been reset. So make sure the
6314 * magic is still good, and hence the adapter structure is still
6315 * valid, before signaling completion */
6316 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6317 {
6318 complete(&pAdapter->session_close_comp_var);
6319 }
6320
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 return eHAL_STATUS_SUCCESS;
6322}
6323
6324VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6325{
6326 struct net_device *pWlanDev = pAdapter->dev;
6327 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6328 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6329 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6330 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306331 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006332
Nirav Shah7e3c8132015-06-22 23:51:42 +05306333 spin_lock_init( &pAdapter->sta_hash_lock);
6334 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6335
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006337 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 //Open a SME session for future operation
6339 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006340 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6342 {
6343 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006344 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 halStatus, halStatus );
6346 status = VOS_STATUS_E_FAILURE;
6347 goto error_sme_open;
6348 }
6349
6350 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306351 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 &pAdapter->session_open_comp_var,
6353 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306354 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 {
6356 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306357 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 status = VOS_STATUS_E_FAILURE;
6359 goto error_sme_open;
6360 }
6361
6362 // Register wireless extensions
6363 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6364 {
6365 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006366 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 halStatus, halStatus );
6368 status = VOS_STATUS_E_FAILURE;
6369 goto error_register_wext;
6370 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306371
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306373 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6374 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6375 #else
6376 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6377 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006378
6379 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306380 hddLog(VOS_TRACE_LEVEL_INFO,
6381 "%s: Set HDD connState to eConnectionState_NotConnected",
6382 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6384
6385 //Set the default operation channel
6386 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6387
6388 /* Make the default Auth Type as OPEN*/
6389 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6390
6391 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6392 {
6393 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006394 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 status, status );
6396 goto error_init_txrx;
6397 }
6398
6399 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6400
6401 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6402 {
6403 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006404 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 status, status );
6406 goto error_wmm_init;
6407 }
6408
6409 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6410
6411 return VOS_STATUS_SUCCESS;
6412
6413error_wmm_init:
6414 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6415 hdd_deinit_tx_rx(pAdapter);
6416error_init_txrx:
6417 hdd_UnregisterWext(pWlanDev);
6418error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006419 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 {
6421 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006422 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306423 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006424 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306426 unsigned long rc;
6427
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306429 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006431 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306432 if (rc <= 0)
6433 hddLog(VOS_TRACE_LEVEL_ERROR,
6434 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 }
6436}
6437error_sme_open:
6438 return status;
6439}
6440
Jeff Johnson295189b2012-06-20 16:38:30 -07006441void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6442{
6443 hdd_cfg80211_state_t *cfgState;
6444
6445 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6446
6447 if( NULL != cfgState->buf )
6448 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306449 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6451 rc = wait_for_completion_interruptible_timeout(
6452 &pAdapter->tx_action_cnf_event,
6453 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306454 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306457 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6458 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 }
6460 }
6461 return;
6462}
Jeff Johnson295189b2012-06-20 16:38:30 -07006463
c_hpothu002231a2015-02-05 14:58:51 +05306464void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006465{
6466 ENTER();
6467 switch ( pAdapter->device_mode )
6468 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306469 case WLAN_HDD_IBSS:
6470 {
6471 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6472 {
6473 hdd_ibss_deinit_tx_rx( pAdapter );
6474 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6475 }
6476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 case WLAN_HDD_INFRA_STATION:
6478 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006479 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 {
6481 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6482 {
6483 hdd_deinit_tx_rx( pAdapter );
6484 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6485 }
6486
6487 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6488 {
6489 hdd_wmm_adapter_close( pAdapter );
6490 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6491 }
6492
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 break;
6495 }
6496
6497 case WLAN_HDD_SOFTAP:
6498 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306500
6501 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6502 {
6503 hdd_wmm_adapter_close( pAdapter );
6504 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6505 }
6506
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006508
c_hpothu002231a2015-02-05 14:58:51 +05306509 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 break;
6512 }
6513
6514 case WLAN_HDD_MONITOR:
6515 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6517 {
6518 hdd_deinit_tx_rx( pAdapter );
6519 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6520 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006521 break;
6522 }
6523
6524
6525 default:
6526 break;
6527 }
6528
6529 EXIT();
6530}
6531
6532void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6533{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006534 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306535
6536 ENTER();
6537 if (NULL == pAdapter)
6538 {
6539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6540 "%s: HDD adapter is Null", __func__);
6541 return;
6542 }
6543
6544 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006545
Rajeev79dbe4c2013-10-05 11:03:42 +05306546#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306547 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6548 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006549 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306550 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6551 )
6552 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006553 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306554 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006555 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6556 {
6557 hdd_deinit_batch_scan(pAdapter);
6558 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306559 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006560 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306561#endif
6562
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6564 if( rtnl_held )
6565 {
6566 unregister_netdevice(pWlanDev);
6567 }
6568 else
6569 {
6570 unregister_netdev(pWlanDev);
6571 }
6572 // note that the pAdapter is no longer valid at this point
6573 // since the memory has been reclaimed
6574 }
6575
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306576 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006577}
6578
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006579void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6580{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306581 VOS_STATUS status;
6582 hdd_adapter_t *pAdapter = NULL;
6583 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006584
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306585 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006586
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306587 /*loop through all adapters.*/
6588 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006589 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306590 pAdapter = pAdapterNode->pAdapter;
6591 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6592 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006593
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306594 { // we skip this registration for modes other than STA and P2P client modes.
6595 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6596 pAdapterNode = pNext;
6597 continue;
6598 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006599
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306600 //Apply Dynamic DTIM For P2P
6601 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6602 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6603 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6604 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6605 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6606 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6607 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6608 (eConnectionState_Associated ==
6609 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6610 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6611 {
6612 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006613
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306614 powerRequest.uIgnoreDTIM = 1;
6615 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6616
6617 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6618 {
6619 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6620 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6621 }
6622 else
6623 {
6624 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6625 }
6626
6627 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6628 * specified during Enter/Exit BMPS when LCD off*/
6629 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6630 NULL, eANI_BOOLEAN_FALSE);
6631 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6632 NULL, eANI_BOOLEAN_FALSE);
6633
6634 /* switch to the DTIM specified in cfg.ini */
6635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6636 "Switch to DTIM %d", powerRequest.uListenInterval);
6637 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6638 break;
6639
6640 }
6641
6642 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6643 pAdapterNode = pNext;
6644 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006645}
6646
6647void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6648{
6649 /*Switch back to DTIM 1*/
6650 tSirSetPowerParamsReq powerRequest = { 0 };
6651
6652 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6653 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006654 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006655
6656 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6657 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6658 NULL, eANI_BOOLEAN_FALSE);
6659 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6660 NULL, eANI_BOOLEAN_FALSE);
6661
6662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6663 "Switch to DTIM%d",powerRequest.uListenInterval);
6664 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6665
6666}
6667
Jeff Johnson295189b2012-06-20 16:38:30 -07006668VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6669{
6670 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306671 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6672 {
6673 hddLog( LOGE, FL("Wlan Unload in progress"));
6674 return VOS_STATUS_E_PERM;
6675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6677 {
6678 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6679 }
6680
6681 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6682 {
6683 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6684 }
6685
6686 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6687 {
6688 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6689 }
6690
6691 return status;
6692}
6693
6694VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6695{
6696 hdd_adapter_t *pAdapter = NULL;
6697 eHalStatus halStatus;
6698 VOS_STATUS status = VOS_STATUS_E_INVAL;
6699 v_BOOL_t disableBmps = FALSE;
6700 v_BOOL_t disableImps = FALSE;
6701
6702 switch(session_type)
6703 {
6704 case WLAN_HDD_INFRA_STATION:
6705 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 case WLAN_HDD_P2P_CLIENT:
6707 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 //Exit BMPS -> Is Sta/P2P Client is already connected
6709 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6710 if((NULL != pAdapter)&&
6711 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6712 {
6713 disableBmps = TRUE;
6714 }
6715
6716 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6717 if((NULL != pAdapter)&&
6718 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6719 {
6720 disableBmps = TRUE;
6721 }
6722
6723 //Exit both Bmps and Imps incase of Go/SAP Mode
6724 if((WLAN_HDD_SOFTAP == session_type) ||
6725 (WLAN_HDD_P2P_GO == session_type))
6726 {
6727 disableBmps = TRUE;
6728 disableImps = TRUE;
6729 }
6730
6731 if(TRUE == disableImps)
6732 {
6733 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6734 {
6735 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6736 }
6737 }
6738
6739 if(TRUE == disableBmps)
6740 {
6741 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6742 {
6743 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6744
6745 if(eHAL_STATUS_SUCCESS != halStatus)
6746 {
6747 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006748 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006749 VOS_ASSERT(0);
6750 return status;
6751 }
6752 }
6753
6754 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6755 {
6756 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6757
6758 if(eHAL_STATUS_SUCCESS != halStatus)
6759 {
6760 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006761 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 VOS_ASSERT(0);
6763 return status;
6764 }
6765 }
6766 }
6767
6768 if((TRUE == disableBmps) ||
6769 (TRUE == disableImps))
6770 {
6771 /* Now, get the chip into Full Power now */
6772 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6773 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6774 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6775
6776 if(halStatus != eHAL_STATUS_SUCCESS)
6777 {
6778 if(halStatus == eHAL_STATUS_PMC_PENDING)
6779 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306780 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306782 ret = wait_for_completion_interruptible_timeout(
6783 &pHddCtx->full_pwr_comp_var,
6784 msecs_to_jiffies(1000));
6785 if (ret <= 0)
6786 {
6787 hddLog(VOS_TRACE_LEVEL_ERROR,
6788 "%s: wait on full_pwr_comp_var failed %ld",
6789 __func__, ret);
6790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 }
6792 else
6793 {
6794 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006795 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 VOS_ASSERT(0);
6797 return status;
6798 }
6799 }
6800
6801 status = VOS_STATUS_SUCCESS;
6802 }
6803
6804 break;
6805 }
6806 return status;
6807}
Katya Nigame7b69a82015-04-28 15:24:06 +05306808void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6809 {
6810 hdd_mon_ctx_t *pMonCtx = NULL;
6811 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6812
6813 pMonCtx->state = 0;
6814 pMonCtx->ChannelNo = 1;
6815 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306816 pMonCtx->crcCheckEnabled = 1;
6817 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6818 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306819 pMonCtx->numOfMacFilters = 0;
6820 }
6821
Jeff Johnson295189b2012-06-20 16:38:30 -07006822
6823hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006824 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 tANI_U8 rtnl_held )
6826{
6827 hdd_adapter_t *pAdapter = NULL;
6828 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6829 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6830 VOS_STATUS exitbmpsStatus;
6831
Arif Hussain6d2a3322013-11-17 19:50:10 -08006832 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006833
Nirav Shah436658f2014-02-28 17:05:45 +05306834 if(macAddr == NULL)
6835 {
6836 /* Not received valid macAddr */
6837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6838 "%s:Unable to add virtual intf: Not able to get"
6839 "valid mac address",__func__);
6840 return NULL;
6841 }
6842
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 //Disable BMPS incase of Concurrency
6844 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6845
6846 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6847 {
6848 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306849 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 VOS_ASSERT(0);
6851 return NULL;
6852 }
6853
6854 switch(session_type)
6855 {
6856 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006858 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 {
6860 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6861
6862 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306863 {
6864 hddLog(VOS_TRACE_LEVEL_FATAL,
6865 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006866 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306867 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006868
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306869#ifdef FEATURE_WLAN_TDLS
6870 /* A Mutex Lock is introduced while changing/initializing the mode to
6871 * protect the concurrent access for the Adapters by TDLS module.
6872 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306873 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306874#endif
6875
Jeff Johnsone7245742012-09-05 17:12:55 -07006876 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6877 NL80211_IFTYPE_P2P_CLIENT:
6878 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006879
Jeff Johnson295189b2012-06-20 16:38:30 -07006880 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306881#ifdef FEATURE_WLAN_TDLS
6882 mutex_unlock(&pHddCtx->tdls_lock);
6883#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306884
6885 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 if( VOS_STATUS_SUCCESS != status )
6887 goto err_free_netdev;
6888
6889 status = hdd_register_interface( pAdapter, rtnl_held );
6890 if( VOS_STATUS_SUCCESS != status )
6891 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306892#ifdef FEATURE_WLAN_TDLS
6893 mutex_lock(&pHddCtx->tdls_lock);
6894#endif
c_hpothu002231a2015-02-05 14:58:51 +05306895 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306896#ifdef FEATURE_WLAN_TDLS
6897 mutex_unlock(&pHddCtx->tdls_lock);
6898#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 goto err_free_netdev;
6900 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306901
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306902 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306903 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306904
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306905#ifdef WLAN_NS_OFFLOAD
6906 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306907 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306908#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006909 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306910 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 netif_tx_disable(pAdapter->dev);
6912 //netif_tx_disable(pWlanDev);
6913 netif_carrier_off(pAdapter->dev);
6914
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306915 if (WLAN_HDD_P2P_CLIENT == session_type ||
6916 WLAN_HDD_P2P_DEVICE == session_type)
6917 {
6918 /* Initialize the work queue to defer the
6919 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306920 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306921 hdd_p2p_roc_work_queue);
6922 }
6923
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 break;
6925 }
6926
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006928 case WLAN_HDD_SOFTAP:
6929 {
6930 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6931 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306932 {
6933 hddLog(VOS_TRACE_LEVEL_FATAL,
6934 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306936 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006937
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6939 NL80211_IFTYPE_AP:
6940 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 pAdapter->device_mode = session_type;
6942
6943 status = hdd_init_ap_mode(pAdapter);
6944 if( VOS_STATUS_SUCCESS != status )
6945 goto err_free_netdev;
6946
Nirav Shah7e3c8132015-06-22 23:51:42 +05306947 status = hdd_sta_id_hash_attach(pAdapter);
6948 if (VOS_STATUS_SUCCESS != status)
6949 {
6950 hddLog(VOS_TRACE_LEVEL_FATAL,
6951 FL("failed to attach hash for session %d"), session_type);
6952 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6953 goto err_free_netdev;
6954 }
6955
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 status = hdd_register_hostapd( pAdapter, rtnl_held );
6957 if( VOS_STATUS_SUCCESS != status )
6958 {
c_hpothu002231a2015-02-05 14:58:51 +05306959 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 goto err_free_netdev;
6961 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306962 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 netif_tx_disable(pAdapter->dev);
6964 netif_carrier_off(pAdapter->dev);
6965
6966 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306967
6968 if (WLAN_HDD_P2P_GO == session_type)
6969 {
6970 /* Initialize the work queue to
6971 * defer the back to back RoC request */
6972 INIT_DELAYED_WORK(&pAdapter->roc_work,
6973 hdd_p2p_roc_work_queue);
6974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 break;
6976 }
6977 case WLAN_HDD_MONITOR:
6978 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6980 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306981 {
6982 hddLog(VOS_TRACE_LEVEL_FATAL,
6983 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306985 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006986
Katya Nigame7b69a82015-04-28 15:24:06 +05306987 // Register wireless extensions
6988 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6989 {
6990 hddLog(VOS_TRACE_LEVEL_FATAL,
6991 "hdd_register_wext() failed with status code %08d [x%08x]",
6992 status, status );
6993 status = VOS_STATUS_E_FAILURE;
6994 }
6995
Jeff Johnson295189b2012-06-20 16:38:30 -07006996 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6997 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006998#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6999 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7000#else
7001 pAdapter->dev->open = hdd_mon_open;
7002 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307003 pAdapter->dev->stop = hdd_mon_stop;
7004 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007005#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307006 status = hdd_register_interface( pAdapter, rtnl_held );
7007 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 hdd_init_tx_rx( pAdapter );
7009 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307010 //Stop the Interface TX queue.
7011 netif_tx_disable(pAdapter->dev);
7012 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 }
7014 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 case WLAN_HDD_FTM:
7016 {
7017 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7018
7019 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307020 {
7021 hddLog(VOS_TRACE_LEVEL_FATAL,
7022 FL("failed to allocate adapter for session %d"), session_type);
7023 return NULL;
7024 }
7025
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7027 * message while loading driver in FTM mode. */
7028 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7029 pAdapter->device_mode = session_type;
7030 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307031
7032 hdd_init_tx_rx( pAdapter );
7033
7034 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307035 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307036 netif_tx_disable(pAdapter->dev);
7037 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 }
7039 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 default:
7041 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307042 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7043 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 VOS_ASSERT(0);
7045 return NULL;
7046 }
7047 }
7048
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 if( VOS_STATUS_SUCCESS == status )
7050 {
7051 //Add it to the hdd's session list.
7052 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7053 if( NULL == pHddAdapterNode )
7054 {
7055 status = VOS_STATUS_E_NOMEM;
7056 }
7057 else
7058 {
7059 pHddAdapterNode->pAdapter = pAdapter;
7060 status = hdd_add_adapter_back ( pHddCtx,
7061 pHddAdapterNode );
7062 }
7063 }
7064
7065 if( VOS_STATUS_SUCCESS != status )
7066 {
7067 if( NULL != pAdapter )
7068 {
7069 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7070 pAdapter = NULL;
7071 }
7072 if( NULL != pHddAdapterNode )
7073 {
7074 vos_mem_free( pHddAdapterNode );
7075 }
7076
7077 goto resume_bmps;
7078 }
7079
7080 if(VOS_STATUS_SUCCESS == status)
7081 {
7082 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7083
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007084 //Initialize the WoWL service
7085 if(!hdd_init_wowl(pAdapter))
7086 {
7087 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7088 goto err_free_netdev;
7089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007090 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 return pAdapter;
7092
7093err_free_netdev:
7094 free_netdev(pAdapter->dev);
7095 wlan_hdd_release_intf_addr( pHddCtx,
7096 pAdapter->macAddressCurrent.bytes );
7097
7098resume_bmps:
7099 //If bmps disabled enable it
7100 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7101 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307102 if (pHddCtx->hdd_wlan_suspended)
7103 {
7104 hdd_set_pwrparams(pHddCtx);
7105 }
7106 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 }
7108 return NULL;
7109}
7110
7111VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7112 tANI_U8 rtnl_held )
7113{
7114 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7115 VOS_STATUS status;
7116
7117 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7118 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307119 {
7120 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7121 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007124
7125 while ( pCurrent->pAdapter != pAdapter )
7126 {
7127 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7128 if( VOS_STATUS_SUCCESS != status )
7129 break;
7130
7131 pCurrent = pNext;
7132 }
7133 pAdapterNode = pCurrent;
7134 if( VOS_STATUS_SUCCESS == status )
7135 {
7136 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7137 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307138
7139#ifdef FEATURE_WLAN_TDLS
7140
7141 /* A Mutex Lock is introduced while changing/initializing the mode to
7142 * protect the concurrent access for the Adapters by TDLS module.
7143 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307144 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307145#endif
7146
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 hdd_remove_adapter( pHddCtx, pAdapterNode );
7148 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007149 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007150
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307151#ifdef FEATURE_WLAN_TDLS
7152 mutex_unlock(&pHddCtx->tdls_lock);
7153#endif
7154
Jeff Johnson295189b2012-06-20 16:38:30 -07007155
7156 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307157 if ((!vos_concurrent_open_sessions_running()) &&
7158 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7159 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307161 if (pHddCtx->hdd_wlan_suspended)
7162 {
7163 hdd_set_pwrparams(pHddCtx);
7164 }
7165 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 }
7167
7168 return VOS_STATUS_SUCCESS;
7169 }
7170
7171 return VOS_STATUS_E_FAILURE;
7172}
7173
7174VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7175{
7176 hdd_adapter_list_node_t *pHddAdapterNode;
7177 VOS_STATUS status;
7178
7179 ENTER();
7180
7181 do
7182 {
7183 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7184 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7185 {
7186 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7187 vos_mem_free( pHddAdapterNode );
7188 }
7189 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7190
7191 EXIT();
7192
7193 return VOS_STATUS_SUCCESS;
7194}
7195
7196void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7197{
7198 v_U8_t addIE[1] = {0};
7199
7200 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7201 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7202 eANI_BOOLEAN_FALSE) )
7203 {
7204 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007205 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 }
7207
7208 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7209 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7210 eANI_BOOLEAN_FALSE) )
7211 {
7212 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007213 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007214 }
7215
7216 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7217 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7218 eANI_BOOLEAN_FALSE) )
7219 {
7220 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007221 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 }
7223}
7224
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307225VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7226 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007227{
7228 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7229 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307230 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307232 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307233 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307234 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007235
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307236 if (pHddCtx->isLogpInProgress) {
7237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7238 "%s:LOGP in Progress. Ignore!!!",__func__);
7239 return VOS_STATUS_E_FAILURE;
7240 }
7241
Jeff Johnson295189b2012-06-20 16:38:30 -07007242 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307243
Nirav Shah7e3c8132015-06-22 23:51:42 +05307244 status = hdd_sta_id_hash_detach(pAdapter);
7245 if (status != VOS_STATUS_SUCCESS)
7246 hddLog(VOS_TRACE_LEVEL_ERROR,
7247 FL("sta id hash detach failed"));
7248
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307249 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 switch(pAdapter->device_mode)
7251 {
7252 case WLAN_HDD_INFRA_STATION:
7253 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007254 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307255 {
7256 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307257#ifdef FEATURE_WLAN_TDLS
7258 mutex_lock(&pHddCtx->tdls_lock);
7259 wlan_hdd_tdls_exit(pAdapter, TRUE);
7260 mutex_unlock(&pHddCtx->tdls_lock);
7261#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307262 if( hdd_connIsConnected(pstation) ||
7263 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007264 {
7265 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7266 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7267 pAdapter->sessionId,
7268 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7269 else
7270 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7271 pAdapter->sessionId,
7272 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7273 //success implies disconnect command got queued up successfully
7274 if(halStatus == eHAL_STATUS_SUCCESS)
7275 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307276 ret = wait_for_completion_interruptible_timeout(
7277 &pAdapter->disconnect_comp_var,
7278 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7279 if (ret <= 0)
7280 {
7281 hddLog(VOS_TRACE_LEVEL_ERROR,
7282 "%s: wait on disconnect_comp_var failed %ld",
7283 __func__, ret);
7284 }
7285 }
7286 else
7287 {
7288 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7289 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 }
7291 memset(&wrqu, '\0', sizeof(wrqu));
7292 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7293 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7294 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7295 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307296 else if(pstation->conn_info.connState ==
7297 eConnectionState_Disconnecting)
7298 {
7299 ret = wait_for_completion_interruptible_timeout(
7300 &pAdapter->disconnect_comp_var,
7301 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7302 if (ret <= 0)
7303 {
7304 hddLog(VOS_TRACE_LEVEL_ERROR,
7305 FL("wait on disconnect_comp_var failed %ld"), ret);
7306 }
7307 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307308 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307310 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307311 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007312 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307313 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7314 {
7315 while (pAdapter->is_roc_inprogress)
7316 {
7317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7318 "%s: ROC in progress for session %d!!!",
7319 __func__, pAdapter->sessionId);
7320 // waiting for ROC to expire
7321 msleep(500);
7322 /* In GO present case , if retry exceeds 3,
7323 it means something went wrong. */
7324 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7325 {
7326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307328 if (eHAL_STATUS_SUCCESS !=
7329 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7330 pAdapter->sessionId ))
7331 {
7332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7333 FL("Failed to Cancel Remain on Channel"));
7334 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307335 wait_for_completion_interruptible_timeout(
7336 &pAdapter->cancel_rem_on_chan_var,
7337 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7338 break;
7339 }
7340 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307341 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307342 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307343#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307344 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307345#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307346
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307347 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307348
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307349 /* It is possible that the caller of this function does not
7350 * wish to close the session
7351 */
7352 if (VOS_TRUE == bCloseSession &&
7353 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 {
7355 INIT_COMPLETION(pAdapter->session_close_comp_var);
7356 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307357 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307358 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307360 unsigned long ret;
7361
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307363 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307364 &pAdapter->session_close_comp_var,
7365 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307366 if ( 0 >= ret)
7367 {
7368 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307369 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 }
7372 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 break;
7375
7376 case WLAN_HDD_SOFTAP:
7377 case WLAN_HDD_P2P_GO:
7378 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307379 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7380 while (pAdapter->is_roc_inprogress) {
7381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7382 "%s: ROC in progress for session %d!!!",
7383 __func__, pAdapter->sessionId);
7384 msleep(500);
7385 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7387 "%s: ROC completion is not received.!!!", __func__);
7388 WLANSAP_CancelRemainOnChannel(
7389 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7390 wait_for_completion_interruptible_timeout(
7391 &pAdapter->cancel_rem_on_chan_var,
7392 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7393 break;
7394 }
7395 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307396
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307397 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307398 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 mutex_lock(&pHddCtx->sap_lock);
7400 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7401 {
7402 VOS_STATUS status;
7403 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7404
7405 //Stop Bss.
7406 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7407 if (VOS_IS_STATUS_SUCCESS(status))
7408 {
7409 hdd_hostapd_state_t *pHostapdState =
7410 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7411
7412 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7413
7414 if (!VOS_IS_STATUS_SUCCESS(status))
7415 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307416 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7417 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 }
7419 }
7420 else
7421 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007422 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 }
7424 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307425 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007426
7427 if (eHAL_STATUS_FAILURE ==
7428 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7429 0, NULL, eANI_BOOLEAN_FALSE))
7430 {
7431 hddLog(LOGE,
7432 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007433 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 }
7435
7436 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7437 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7438 eANI_BOOLEAN_FALSE) )
7439 {
7440 hddLog(LOGE,
7441 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7442 }
7443
7444 // Reset WNI_CFG_PROBE_RSP Flags
7445 wlan_hdd_reset_prob_rspies(pAdapter);
7446 kfree(pAdapter->sessionCtx.ap.beacon);
7447 pAdapter->sessionCtx.ap.beacon = NULL;
7448 }
7449 mutex_unlock(&pHddCtx->sap_lock);
7450 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007451
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 case WLAN_HDD_MONITOR:
7453 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007454
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 default:
7456 break;
7457 }
7458
7459 EXIT();
7460 return VOS_STATUS_SUCCESS;
7461}
7462
7463VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7464{
7465 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7466 VOS_STATUS status;
7467 hdd_adapter_t *pAdapter;
7468
7469 ENTER();
7470
7471 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7472
7473 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7474 {
7475 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007476
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307477 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007478
7479 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7480 pAdapterNode = pNext;
7481 }
7482
7483 EXIT();
7484
7485 return VOS_STATUS_SUCCESS;
7486}
7487
Rajeev Kumarf999e582014-01-09 17:33:29 -08007488
7489#ifdef FEATURE_WLAN_BATCH_SCAN
7490/**---------------------------------------------------------------------------
7491
7492 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7493 structures
7494
7495 \param - pAdapter Pointer to HDD adapter
7496
7497 \return - None
7498
7499 --------------------------------------------------------------------------*/
7500void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7501{
7502 tHddBatchScanRsp *pNode;
7503 tHddBatchScanRsp *pPrev;
7504
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307505 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007506 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307507 hddLog(VOS_TRACE_LEVEL_ERROR,
7508 "%s: Adapter context is Null", __func__);
7509 return;
7510 }
7511
7512 pNode = pAdapter->pBatchScanRsp;
7513 while (pNode)
7514 {
7515 pPrev = pNode;
7516 pNode = pNode->pNext;
7517 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007518 }
7519
7520 pAdapter->pBatchScanRsp = NULL;
7521 pAdapter->numScanList = 0;
7522 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7523 pAdapter->prev_batch_id = 0;
7524
7525 return;
7526}
7527#endif
7528
7529
Jeff Johnson295189b2012-06-20 16:38:30 -07007530VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7531{
7532 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7533 VOS_STATUS status;
7534 hdd_adapter_t *pAdapter;
7535
7536 ENTER();
7537
7538 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7539
7540 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7541 {
7542 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 netif_tx_disable(pAdapter->dev);
7545 netif_carrier_off(pAdapter->dev);
7546
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007547 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7548
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307550
Katya Nigam1fd24402015-02-16 14:52:19 +05307551 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7552 hdd_ibss_deinit_tx_rx(pAdapter);
7553
Nirav Shah7e3c8132015-06-22 23:51:42 +05307554 status = hdd_sta_id_hash_detach(pAdapter);
7555 if (status != VOS_STATUS_SUCCESS)
7556 hddLog(VOS_TRACE_LEVEL_ERROR,
7557 FL("sta id hash detach failed for session id %d"),
7558 pAdapter->sessionId);
7559
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307560 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7561
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307562 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7563 {
7564 hdd_wmm_adapter_close( pAdapter );
7565 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7566 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007567
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307568 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7569 {
7570 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7571 }
7572
Rajeev Kumarf999e582014-01-09 17:33:29 -08007573#ifdef FEATURE_WLAN_BATCH_SCAN
7574 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7575 {
7576 hdd_deinit_batch_scan(pAdapter);
7577 }
7578#endif
7579
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307580#ifdef FEATURE_WLAN_TDLS
7581 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307582 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307583 mutex_unlock(&pHddCtx->tdls_lock);
7584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007585 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7586 pAdapterNode = pNext;
7587 }
7588
7589 EXIT();
7590
7591 return VOS_STATUS_SUCCESS;
7592}
7593
7594VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7595{
7596 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7597 VOS_STATUS status;
7598 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307599 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007600
7601 ENTER();
7602
7603 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7604
7605 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7606 {
7607 pAdapter = pAdapterNode->pAdapter;
7608
Kumar Anand82c009f2014-05-29 00:29:42 -07007609 hdd_wmm_init( pAdapter );
7610
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 switch(pAdapter->device_mode)
7612 {
7613 case WLAN_HDD_INFRA_STATION:
7614 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007615 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307616
7617 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7618
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 hdd_init_station_mode(pAdapter);
7620 /* Open the gates for HDD to receive Wext commands */
7621 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007622 pHddCtx->scan_info.mScanPending = FALSE;
7623 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007624
7625 //Trigger the initial scan
7626 hdd_wlan_initial_scan(pAdapter);
7627
7628 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307629 if (eConnectionState_Associated == connState ||
7630 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 {
7632 union iwreq_data wrqu;
7633 memset(&wrqu, '\0', sizeof(wrqu));
7634 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7635 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7636 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007637 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007638
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 /* indicate disconnected event to nl80211 */
7640 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7641 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307643 else if (eConnectionState_Connecting == connState)
7644 {
7645 /*
7646 * Indicate connect failure to supplicant if we were in the
7647 * process of connecting
7648 */
7649 cfg80211_connect_result(pAdapter->dev, NULL,
7650 NULL, 0, NULL, 0,
7651 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7652 GFP_KERNEL);
7653 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007654 break;
7655
7656 case WLAN_HDD_SOFTAP:
7657 /* softAP can handle SSR */
7658 break;
7659
7660 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007663 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 break;
7665
7666 case WLAN_HDD_MONITOR:
7667 /* monitor interface start */
7668 break;
7669 default:
7670 break;
7671 }
7672
7673 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7674 pAdapterNode = pNext;
7675 }
7676
7677 EXIT();
7678
7679 return VOS_STATUS_SUCCESS;
7680}
7681
7682VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7683{
7684 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7685 hdd_adapter_t *pAdapter;
7686 VOS_STATUS status;
7687 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307688 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007689
7690 ENTER();
7691
7692 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7693
7694 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7695 {
7696 pAdapter = pAdapterNode->pAdapter;
7697
7698 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7699 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7700 {
7701 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7702 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7703
Abhishek Singhf4669da2014-05-26 15:07:49 +05307704 hddLog(VOS_TRACE_LEVEL_INFO,
7705 "%s: Set HDD connState to eConnectionState_NotConnected",
7706 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007707 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7708 init_completion(&pAdapter->disconnect_comp_var);
7709 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7710 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7711
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307712 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 &pAdapter->disconnect_comp_var,
7714 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307715 if (0 >= ret)
7716 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7717 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007718
7719 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7720 pHddCtx->isAmpAllowed = VOS_FALSE;
7721 sme_RoamConnect(pHddCtx->hHal,
7722 pAdapter->sessionId, &(pWextState->roamProfile),
7723 &roamId);
7724 }
7725
7726 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7727 pAdapterNode = pNext;
7728 }
7729
7730 EXIT();
7731
7732 return VOS_STATUS_SUCCESS;
7733}
7734
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007735void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7736{
7737 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7738 VOS_STATUS status;
7739 hdd_adapter_t *pAdapter;
7740 hdd_station_ctx_t *pHddStaCtx;
7741 hdd_ap_ctx_t *pHddApCtx;
7742 hdd_hostapd_state_t * pHostapdState;
7743 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7744 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7745 const char *p2pMode = "DEV";
7746 const char *ccMode = "Standalone";
7747 int n;
7748
7749 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7750 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7751 {
7752 pAdapter = pAdapterNode->pAdapter;
7753 switch (pAdapter->device_mode) {
7754 case WLAN_HDD_INFRA_STATION:
7755 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7756 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7757 staChannel = pHddStaCtx->conn_info.operationChannel;
7758 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7759 }
7760 break;
7761 case WLAN_HDD_P2P_CLIENT:
7762 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7763 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7764 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7765 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7766 p2pMode = "CLI";
7767 }
7768 break;
7769 case WLAN_HDD_P2P_GO:
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 p2pChannel = pHddApCtx->operatingChannel;
7774 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7775 }
7776 p2pMode = "GO";
7777 break;
7778 case WLAN_HDD_SOFTAP:
7779 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7780 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7781 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7782 apChannel = pHddApCtx->operatingChannel;
7783 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7784 }
7785 break;
7786 default:
7787 break;
7788 }
7789 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7790 pAdapterNode = pNext;
7791 }
7792 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7793 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7794 }
7795 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7796 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7797 if (p2pChannel > 0) {
7798 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7799 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7800 }
7801 if (apChannel > 0) {
7802 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7803 apChannel, MAC_ADDR_ARRAY(apBssid));
7804 }
7805
7806 if (p2pChannel > 0 && apChannel > 0) {
7807 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7808 }
7809}
7810
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007811bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007812{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007813 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007814}
7815
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007816/* Once SSR is disabled then it cannot be set. */
7817void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007818{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007819 if (HDD_SSR_DISABLED == isSsrRequired)
7820 return;
7821
Jeff Johnson295189b2012-06-20 16:38:30 -07007822 isSsrRequired = value;
7823}
7824
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307825void hdd_set_pre_close( hdd_context_t *pHddCtx)
7826{
7827 sme_PreClose(pHddCtx->hHal);
7828}
7829
Jeff Johnson295189b2012-06-20 16:38:30 -07007830VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7831 hdd_adapter_list_node_t** ppAdapterNode)
7832{
7833 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307834 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7836 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307837 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 return status;
7839}
7840
7841VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7842 hdd_adapter_list_node_t* pAdapterNode,
7843 hdd_adapter_list_node_t** pNextAdapterNode)
7844{
7845 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307846 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007847 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7848 (hdd_list_node_t*) pAdapterNode,
7849 (hdd_list_node_t**)pNextAdapterNode );
7850
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307851 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007852 return status;
7853}
7854
7855VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7856 hdd_adapter_list_node_t* pAdapterNode)
7857{
7858 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307859 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7861 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307862 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 return status;
7864}
7865
7866VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7867 hdd_adapter_list_node_t** ppAdapterNode)
7868{
7869 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307870 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7872 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307873 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 return status;
7875}
7876
7877VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7878 hdd_adapter_list_node_t* pAdapterNode)
7879{
7880 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307881 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7883 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307884 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 return status;
7886}
7887
7888VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7889 hdd_adapter_list_node_t* pAdapterNode)
7890{
7891 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307892 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007893 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7894 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307895 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 return status;
7897}
7898
7899hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7900 tSirMacAddr macAddr )
7901{
7902 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7903 hdd_adapter_t *pAdapter;
7904 VOS_STATUS status;
7905
7906 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7907
7908 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7909 {
7910 pAdapter = pAdapterNode->pAdapter;
7911
7912 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7913 macAddr, sizeof(tSirMacAddr) ) )
7914 {
7915 return pAdapter;
7916 }
7917 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7918 pAdapterNode = pNext;
7919 }
7920
7921 return NULL;
7922
7923}
7924
7925hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7926{
7927 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7928 hdd_adapter_t *pAdapter;
7929 VOS_STATUS status;
7930
7931 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7932
7933 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7934 {
7935 pAdapter = pAdapterNode->pAdapter;
7936
7937 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7938 IFNAMSIZ ) )
7939 {
7940 return pAdapter;
7941 }
7942 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7943 pAdapterNode = pNext;
7944 }
7945
7946 return NULL;
7947
7948}
7949
7950hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7951{
7952 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7953 hdd_adapter_t *pAdapter;
7954 VOS_STATUS status;
7955
7956 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7957
7958 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7959 {
7960 pAdapter = pAdapterNode->pAdapter;
7961
7962 if( pAdapter && (mode == pAdapter->device_mode) )
7963 {
7964 return pAdapter;
7965 }
7966 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7967 pAdapterNode = pNext;
7968 }
7969
7970 return NULL;
7971
7972}
7973
7974//Remove this function later
7975hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7976{
7977 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7978 hdd_adapter_t *pAdapter;
7979 VOS_STATUS status;
7980
7981 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7982
7983 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7984 {
7985 pAdapter = pAdapterNode->pAdapter;
7986
7987 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7988 {
7989 return pAdapter;
7990 }
7991
7992 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7993 pAdapterNode = pNext;
7994 }
7995
7996 return NULL;
7997
7998}
7999
Jeff Johnson295189b2012-06-20 16:38:30 -07008000/**---------------------------------------------------------------------------
8001
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308002 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008003
8004 This API returns the operating channel of the requested device mode
8005
8006 \param - pHddCtx - Pointer to the HDD context.
8007 - mode - Device mode for which operating channel is required
8008 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8009 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8010 \return - channel number. "0" id the requested device is not found OR it is not connected.
8011 --------------------------------------------------------------------------*/
8012v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8013{
8014 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8015 VOS_STATUS status;
8016 hdd_adapter_t *pAdapter;
8017 v_U8_t operatingChannel = 0;
8018
8019 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8020
8021 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8022 {
8023 pAdapter = pAdapterNode->pAdapter;
8024
8025 if( mode == pAdapter->device_mode )
8026 {
8027 switch(pAdapter->device_mode)
8028 {
8029 case WLAN_HDD_INFRA_STATION:
8030 case WLAN_HDD_P2P_CLIENT:
8031 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8032 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8033 break;
8034 case WLAN_HDD_SOFTAP:
8035 case WLAN_HDD_P2P_GO:
8036 /*softap connection info */
8037 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8038 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8039 break;
8040 default:
8041 break;
8042 }
8043
8044 break; //Found the device of interest. break the loop
8045 }
8046
8047 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8048 pAdapterNode = pNext;
8049 }
8050 return operatingChannel;
8051}
8052
8053#ifdef WLAN_FEATURE_PACKET_FILTERING
8054/**---------------------------------------------------------------------------
8055
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308056 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008057
8058 This used to set the multicast address list.
8059
8060 \param - dev - Pointer to the WLAN device.
8061 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308062 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008063
8064 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308065static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008066{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308067 hdd_adapter_t *pAdapter;
8068 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308070 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308072
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308073 ENTER();
8074
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308075 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308076 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 {
8078 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308079 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 return;
8081 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308082 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8083 ret = wlan_hdd_validate_context(pHddCtx);
8084 if (0 != ret)
8085 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308086 return;
8087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 if (dev->flags & IFF_ALLMULTI)
8089 {
8090 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008091 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308092 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308094 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 {
8096 mc_count = netdev_mc_count(dev);
8097 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008098 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8100 {
8101 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008102 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308103 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 return;
8105 }
8106
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308107 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008108
8109 netdev_for_each_mc_addr(ha, dev) {
8110 if (i == mc_count)
8111 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308112 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8113 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008114 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308115 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308116 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 i++;
8118 }
8119 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308120
8121 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 return;
8123}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308124
8125static void hdd_set_multicast_list(struct net_device *dev)
8126{
8127 vos_ssr_protect(__func__);
8128 __hdd_set_multicast_list(dev);
8129 vos_ssr_unprotect(__func__);
8130}
Jeff Johnson295189b2012-06-20 16:38:30 -07008131#endif
8132
8133/**---------------------------------------------------------------------------
8134
8135 \brief hdd_select_queue() -
8136
8137 This function is registered with the Linux OS for network
8138 core to decide which queue to use first.
8139
8140 \param - dev - Pointer to the WLAN device.
8141 - skb - Pointer to OS packet (sk_buff).
8142 \return - ac, Queue Index/access category corresponding to UP in IP header
8143
8144 --------------------------------------------------------------------------*/
8145v_U16_t hdd_select_queue(struct net_device *dev,
8146 struct sk_buff *skb)
8147{
8148 return hdd_wmm_select_queue(dev, skb);
8149}
8150
8151
8152/**---------------------------------------------------------------------------
8153
8154 \brief hdd_wlan_initial_scan() -
8155
8156 This function triggers the initial scan
8157
8158 \param - pAdapter - Pointer to the HDD adapter.
8159
8160 --------------------------------------------------------------------------*/
8161void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8162{
8163 tCsrScanRequest scanReq;
8164 tCsrChannelInfo channelInfo;
8165 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008166 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8168
8169 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8170 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8171 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8172
8173 if(sme_Is11dSupported(pHddCtx->hHal))
8174 {
8175 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8176 if ( HAL_STATUS_SUCCESS( halStatus ) )
8177 {
8178 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8179 if( !scanReq.ChannelInfo.ChannelList )
8180 {
8181 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8182 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008183 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 return;
8185 }
8186 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8187 channelInfo.numOfChannels);
8188 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8189 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008190 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008191 }
8192
8193 scanReq.scanType = eSIR_PASSIVE_SCAN;
8194 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8195 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8196 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8197 }
8198 else
8199 {
8200 scanReq.scanType = eSIR_ACTIVE_SCAN;
8201 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8202 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8203 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8204 }
8205
8206 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8207 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8208 {
8209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8210 __func__, halStatus );
8211 }
8212
8213 if(sme_Is11dSupported(pHddCtx->hHal))
8214 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8215}
8216
mukul sharmabab477d2015-06-11 17:14:55 +05308217void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8218{
8219 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8220 VOS_STATUS status;
8221 hdd_adapter_t *pAdapter;
8222
8223 ENTER();
8224
8225 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8226
8227 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8228 {
8229 pAdapter = pAdapterNode->pAdapter;
8230
8231 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8232 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8233 pAdapterNode = pNext;
8234 }
8235
8236 EXIT();
8237}
Jeff Johnson295189b2012-06-20 16:38:30 -07008238/**---------------------------------------------------------------------------
8239
8240 \brief hdd_full_power_callback() - HDD full power callback function
8241
8242 This is the function invoked by SME to inform the result of a full power
8243 request issued by HDD
8244
8245 \param - callbackcontext - Pointer to cookie
8246 \param - status - result of request
8247
8248 \return - None
8249
8250 --------------------------------------------------------------------------*/
8251static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8252{
Jeff Johnson72a40512013-12-19 10:14:15 -08008253 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008254
8255 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308256 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008257
8258 if (NULL == callbackContext)
8259 {
8260 hddLog(VOS_TRACE_LEVEL_ERROR,
8261 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008262 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 return;
8264 }
8265
Jeff Johnson72a40512013-12-19 10:14:15 -08008266 /* there is a race condition that exists between this callback
8267 function and the caller since the caller could time out either
8268 before or while this code is executing. we use a spinlock to
8269 serialize these actions */
8270 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008271
8272 if (POWER_CONTEXT_MAGIC != pContext->magic)
8273 {
8274 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008275 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 hddLog(VOS_TRACE_LEVEL_WARN,
8277 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008278 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 return;
8280 }
8281
Jeff Johnson72a40512013-12-19 10:14:15 -08008282 /* context is valid so caller is still waiting */
8283
8284 /* paranoia: invalidate the magic */
8285 pContext->magic = 0;
8286
8287 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008289
8290 /* serialization is complete */
8291 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008292}
8293
Katya Nigamf0511f62015-05-05 16:40:57 +05308294void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8295{
8296 pMonCtx->typeSubtypeBitmap = 0;
8297 if( type%10 ) /* Management Packets */
8298 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8299 type/=10;
8300 if( type%10 ) /* Control Packets */
8301 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8302 type/=10;
8303 if( type%10 ) /* Data Packets */
8304 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8305}
8306
8307VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8308{
8309 vos_msg_t monMsg;
8310
8311 monMsg.type = WDA_MON_START_REQ;
8312 monMsg.reserved = 0;
8313 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8314 monMsg.bodyval = 0;
8315
8316 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8317 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8318 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8319 return VOS_STATUS_E_FAILURE;
8320 }
8321
8322 return VOS_STATUS_SUCCESS;
8323}
8324
8325void wlan_hdd_mon_poststopmsg(void)
8326{
8327 vos_msg_t monMsg;
8328
8329 monMsg.type = WDA_MON_STOP_REQ;
8330 monMsg.reserved = 0;
8331 monMsg.bodyptr = NULL;
8332 monMsg.bodyval = 0;
8333
8334 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8335 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8336 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8337 }
8338}
8339
Katya Nigame7b69a82015-04-28 15:24:06 +05308340void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8341{
8342 VOS_STATUS vosStatus;
8343 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8344 struct wiphy *wiphy = pHddCtx->wiphy;
8345
8346 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8347 if(pAdapter == NULL || pVosContext == NULL)
8348 {
8349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8350 return ;
8351 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308352
8353 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308354 hdd_UnregisterWext(pAdapter->dev);
8355
8356 vos_mon_stop( pVosContext );
8357
8358 vosStatus = vos_sched_close( pVosContext );
8359 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8360 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8361 "%s: Failed to close VOSS Scheduler",__func__);
8362 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8363 }
8364
8365 vosStatus = vos_nv_close();
8366 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8367 {
8368 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8369 "%s: Failed to close NV", __func__);
8370 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8371 }
8372
8373 vos_close(pVosContext);
8374
8375 #ifdef WLAN_KD_READY_NOTIFIER
8376 nl_srv_exit(pHddCtx->ptt_pid);
8377 #else
8378 nl_srv_exit();
8379 #endif
8380
8381 if (pHddCtx->cfg_ini)
8382 {
8383 kfree(pHddCtx->cfg_ini);
8384 pHddCtx->cfg_ini= NULL;
8385 }
8386 hdd_close_all_adapters( pHddCtx );
8387
8388 wiphy_free(wiphy) ;
8389
8390}
Jeff Johnson295189b2012-06-20 16:38:30 -07008391/**---------------------------------------------------------------------------
8392
8393 \brief hdd_wlan_exit() - HDD WLAN exit function
8394
8395 This is the driver exit point (invoked during rmmod)
8396
8397 \param - pHddCtx - Pointer to the HDD Context
8398
8399 \return - None
8400
8401 --------------------------------------------------------------------------*/
8402void hdd_wlan_exit(hdd_context_t *pHddCtx)
8403{
8404 eHalStatus halStatus;
8405 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8406 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308407 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008408 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008409 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308411 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008412
8413 ENTER();
8414
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308415
Katya Nigame7b69a82015-04-28 15:24:06 +05308416 if (VOS_MONITOR_MODE == hdd_get_conparam())
8417 {
8418 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8419 wlan_hdd_mon_close(pHddCtx);
8420 return;
8421 }
8422 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008423 {
8424 // Unloading, restart logic is no more required.
8425 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008426
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308427#ifdef FEATURE_WLAN_TDLS
8428 /* At the time of driver unloading; if tdls connection is present;
8429 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8430 * wlan_hdd_tdls_find_peer always checks for valid context;
8431 * as load/unload in progress there can be a race condition.
8432 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8433 * when tdls state is enabled.
8434 * As soon as driver set load/unload flag; tdls flag also needs
8435 * to be disabled so that hdd_rx_packet_cbk won't call
8436 * wlan_hdd_tdls_find_peer.
8437 */
8438 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8439#endif
8440
c_hpothu5ab05e92014-06-13 17:34:05 +05308441 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8442 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308444 pAdapter = pAdapterNode->pAdapter;
8445 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308447 /* Disable TX on the interface, after this hard_start_xmit() will
8448 * not be called on that interface
8449 */
8450 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8451 netif_tx_disable(pAdapter->dev);
8452
8453 /* Mark the interface status as "down" for outside world */
8454 netif_carrier_off(pAdapter->dev);
8455
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308456 /* DeInit the adapter. This ensures that all data packets
8457 * are freed.
8458 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308459#ifdef FEATURE_WLAN_TDLS
8460 mutex_lock(&pHddCtx->tdls_lock);
8461#endif
c_hpothu002231a2015-02-05 14:58:51 +05308462 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308463#ifdef FEATURE_WLAN_TDLS
8464 mutex_unlock(&pHddCtx->tdls_lock);
8465#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308466
c_hpothu5ab05e92014-06-13 17:34:05 +05308467 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8468 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8469 {
8470 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8471 hdd_UnregisterWext(pAdapter->dev);
8472 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308473
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308475 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8476 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 }
mukul sharmabab477d2015-06-11 17:14:55 +05308478
8479 //Purge all sme cmd's for all interface
8480 hdd_purge_cmd_list_all_adapters(pHddCtx);
8481
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308482 // Cancel any outstanding scan requests. We are about to close all
8483 // of our adapters, but an adapter structure is what SME passes back
8484 // to our callback function. Hence if there are any outstanding scan
8485 // requests then there is a race condition between when the adapter
8486 // is closed and when the callback is invoked.We try to resolve that
8487 // race condition here by canceling any outstanding scans before we
8488 // close the adapters.
8489 // Note that the scans may be cancelled in an asynchronous manner,
8490 // so ideally there needs to be some kind of synchronization. Rather
8491 // than introduce a new synchronization here, we will utilize the
8492 // fact that we are about to Request Full Power, and since that is
8493 // synchronized, the expectation is that by the time Request Full
8494 // Power has completed all scans will be cancelled.
8495 if (pHddCtx->scan_info.mScanPending)
8496 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308497 if(NULL != pAdapter)
8498 {
8499 hddLog(VOS_TRACE_LEVEL_INFO,
8500 FL("abort scan mode: %d sessionId: %d"),
8501 pAdapter->device_mode,
8502 pAdapter->sessionId);
8503 }
8504 hdd_abort_mac_scan(pHddCtx,
8505 pHddCtx->scan_info.sessionId,
8506 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308507 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308509 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008510 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308511 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308512 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8513 {
8514 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8516 "%s: in middle of FTM START", __func__);
8517 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8518 msecs_to_jiffies(20000));
8519 if(!lrc)
8520 {
8521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8522 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8523 }
8524 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008525 wlan_hdd_ftm_close(pHddCtx);
8526 goto free_hdd_ctx;
8527 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308528
Jeff Johnson295189b2012-06-20 16:38:30 -07008529 /* DeRegister with platform driver as client for Suspend/Resume */
8530 vosStatus = hddDeregisterPmOps(pHddCtx);
8531 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8532 {
8533 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8534 VOS_ASSERT(0);
8535 }
8536
8537 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8538 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8539 {
8540 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008542
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008543 //Stop the traffic monitor timer
8544 if ( VOS_TIMER_STATE_RUNNING ==
8545 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8546 {
8547 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8548 }
8549
8550 // Destroy the traffic monitor timer
8551 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8552 &pHddCtx->tx_rx_trafficTmr)))
8553 {
8554 hddLog(VOS_TRACE_LEVEL_ERROR,
8555 "%s: Cannot deallocate Traffic monitor timer", __func__);
8556 }
8557
Jeff Johnson295189b2012-06-20 16:38:30 -07008558 //Disable IMPS/BMPS as we do not want the device to enter any power
8559 //save mode during shutdown
8560 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8561 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8562 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8563
8564 //Ensure that device is in full power as we will touch H/W during vos_Stop
8565 init_completion(&powerContext.completion);
8566 powerContext.magic = POWER_CONTEXT_MAGIC;
8567
8568 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8569 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8570
8571 if (eHAL_STATUS_SUCCESS != halStatus)
8572 {
8573 if (eHAL_STATUS_PMC_PENDING == halStatus)
8574 {
8575 /* request was sent -- wait for the response */
8576 lrc = wait_for_completion_interruptible_timeout(
8577 &powerContext.completion,
8578 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 if (lrc <= 0)
8580 {
8581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008582 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008583 }
8584 }
8585 else
8586 {
8587 hddLog(VOS_TRACE_LEVEL_ERROR,
8588 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008589 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008590 /* continue -- need to clean up as much as possible */
8591 }
8592 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308593 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8594 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8595 {
8596 /* This will issue a dump command which will clean up
8597 BTQM queues and unblock MC thread */
8598 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8599 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008600
Jeff Johnson72a40512013-12-19 10:14:15 -08008601 /* either we never sent a request, we sent a request and received a
8602 response or we sent a request and timed out. if we never sent a
8603 request or if we sent a request and got a response, we want to
8604 clear the magic out of paranoia. if we timed out there is a
8605 race condition such that the callback function could be
8606 executing at the same time we are. of primary concern is if the
8607 callback function had already verified the "magic" but had not
8608 yet set the completion variable when a timeout occurred. we
8609 serialize these activities by invalidating the magic while
8610 holding a shared spinlock which will cause us to block if the
8611 callback is currently executing */
8612 spin_lock(&hdd_context_lock);
8613 powerContext.magic = 0;
8614 spin_unlock(&hdd_context_lock);
8615
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308616 /* If Device is shutdown, no point for SME to wait for responses
8617 from device. Pre Close SME */
8618 if(wcnss_device_is_shutdown())
8619 {
8620 sme_PreClose(pHddCtx->hHal);
8621 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008622 hdd_debugfs_exit(pHddCtx);
8623
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308624#ifdef WLAN_NS_OFFLOAD
8625 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8626 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8627#endif
8628 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8629 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8630
Jeff Johnson295189b2012-06-20 16:38:30 -07008631 // Unregister the Net Device Notifier
8632 unregister_netdevice_notifier(&hdd_netdev_notifier);
8633
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 hdd_stop_all_adapters( pHddCtx );
8635
Jeff Johnson295189b2012-06-20 16:38:30 -07008636#ifdef WLAN_BTAMP_FEATURE
8637 vosStatus = WLANBAP_Stop(pVosContext);
8638 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8639 {
8640 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8641 "%s: Failed to stop BAP",__func__);
8642 }
8643#endif //WLAN_BTAMP_FEATURE
8644
8645 //Stop all the modules
8646 vosStatus = vos_stop( pVosContext );
8647 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8648 {
8649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8650 "%s: Failed to stop VOSS",__func__);
8651 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8652 }
8653
Jeff Johnson295189b2012-06-20 16:38:30 -07008654 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008655 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008656
8657 //Close the scheduler before calling vos_close to make sure no thread is
8658 // scheduled after the each module close is called i.e after all the data
8659 // structures are freed.
8660 vosStatus = vos_sched_close( pVosContext );
8661 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8662 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8663 "%s: Failed to close VOSS Scheduler",__func__);
8664 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8665 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008666#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8667 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308668 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008669#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008670 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308671 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008672
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308673#ifdef CONFIG_ENABLE_LINUX_REG
8674 vosStatus = vos_nv_close();
8675 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8676 {
8677 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8678 "%s: Failed to close NV", __func__);
8679 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8680 }
8681#endif
8682
Jeff Johnson295189b2012-06-20 16:38:30 -07008683 //Close VOSS
8684 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8685 vos_close(pVosContext);
8686
Jeff Johnson295189b2012-06-20 16:38:30 -07008687 //Close Watchdog
8688 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8689 vos_watchdog_close(pVosContext);
8690
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308691 //Clean up HDD Nlink Service
8692 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308693
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308694#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308695 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308696 {
8697 wlan_logging_sock_deactivate_svc();
8698 }
8699#endif
8700
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308701#ifdef WLAN_KD_READY_NOTIFIER
8702 nl_srv_exit(pHddCtx->ptt_pid);
8703#else
8704 nl_srv_exit();
8705#endif /* WLAN_KD_READY_NOTIFIER */
8706
8707
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 hdd_close_all_adapters( pHddCtx );
8709
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 /* free the power on lock from platform driver */
8711 if (free_riva_power_on_lock("wlan"))
8712 {
8713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8714 __func__);
8715 }
8716
Jeff Johnson88ba7742013-02-27 14:36:02 -08008717free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308718
8719 //Free up dynamically allocated members inside HDD Adapter
8720 if (pHddCtx->cfg_ini)
8721 {
8722 kfree(pHddCtx->cfg_ini);
8723 pHddCtx->cfg_ini= NULL;
8724 }
8725
Leo Changf04ddad2013-09-18 13:46:38 -07008726 /* FTM mode, WIPHY did not registered
8727 If un-register here, system crash will happen */
8728 if (VOS_FTM_MODE != hdd_get_conparam())
8729 {
8730 wiphy_unregister(wiphy) ;
8731 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 if (hdd_is_ssr_required())
8734 {
8735 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008736 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 msleep(5000);
8738 }
8739 hdd_set_ssr_required (VOS_FALSE);
8740}
8741
8742
8743/**---------------------------------------------------------------------------
8744
8745 \brief hdd_update_config_from_nv() - Function to update the contents of
8746 the running configuration with parameters taken from NV storage
8747
8748 \param - pHddCtx - Pointer to the HDD global context
8749
8750 \return - VOS_STATUS_SUCCESS if successful
8751
8752 --------------------------------------------------------------------------*/
8753static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8754{
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 v_BOOL_t itemIsValid = VOS_FALSE;
8756 VOS_STATUS status;
8757 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8758 v_U8_t macLoop;
8759
8760 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8761 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8762 if(status != VOS_STATUS_SUCCESS)
8763 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008764 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 return VOS_STATUS_E_FAILURE;
8766 }
8767
8768 if (itemIsValid == VOS_TRUE)
8769 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008770 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8772 VOS_MAX_CONCURRENCY_PERSONA);
8773 if(status != VOS_STATUS_SUCCESS)
8774 {
8775 /* Get MAC from NV fail, not update CFG info
8776 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008777 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 return VOS_STATUS_E_FAILURE;
8779 }
8780
8781 /* If first MAC is not valid, treat all others are not valid
8782 * Then all MACs will be got from ini file */
8783 if(vos_is_macaddr_zero(&macFromNV[0]))
8784 {
8785 /* MAC address in NV file is not configured yet */
8786 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8787 return VOS_STATUS_E_INVAL;
8788 }
8789
8790 /* Get MAC address from NV, update CFG info */
8791 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8792 {
8793 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8794 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308795 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 /* This MAC is not valid, skip it
8797 * This MAC will be got from ini file */
8798 }
8799 else
8800 {
8801 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8802 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8803 VOS_MAC_ADDR_SIZE);
8804 }
8805 }
8806 }
8807 else
8808 {
8809 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8810 return VOS_STATUS_E_FAILURE;
8811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008812
Jeff Johnson295189b2012-06-20 16:38:30 -07008813
8814 return VOS_STATUS_SUCCESS;
8815}
8816
8817/**---------------------------------------------------------------------------
8818
8819 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8820
8821 \param - pAdapter - Pointer to the HDD
8822
8823 \return - None
8824
8825 --------------------------------------------------------------------------*/
8826VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8827{
8828 eHalStatus halStatus;
8829 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308830 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008831
Jeff Johnson295189b2012-06-20 16:38:30 -07008832
8833 // Send ready indication to the HDD. This will kick off the MAC
8834 // into a 'running' state and should kick off an initial scan.
8835 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8836 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8837 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308838 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 "code %08d [x%08x]",__func__, halStatus, halStatus );
8840 return VOS_STATUS_E_FAILURE;
8841 }
8842
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308843 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8845 // And RIVA will crash
8846 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8847 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308848 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8849 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8850
8851
Jeff Johnson295189b2012-06-20 16:38:30 -07008852 return VOS_STATUS_SUCCESS;
8853}
8854
Jeff Johnson295189b2012-06-20 16:38:30 -07008855/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308856void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008857{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308858
8859 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8860
Jeff Johnson295189b2012-06-20 16:38:30 -07008861}
8862
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308863void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008864{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308865
8866 vos_wake_lock_release(&wlan_wake_lock, reason);
8867
Jeff Johnson295189b2012-06-20 16:38:30 -07008868}
8869
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308870void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008871{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308872
8873 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8874 reason);
8875
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008876}
8877
Jeff Johnson295189b2012-06-20 16:38:30 -07008878/**---------------------------------------------------------------------------
8879
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008880 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8881 information between Host and Riva
8882
8883 This function gets reported version of FW
8884 It also finds the version of Riva headers used to compile the host
8885 It compares the above two and prints a warning if they are different
8886 It gets the SW and HW version string
8887 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8888 indicating the features they support through a bitmap
8889
8890 \param - pHddCtx - Pointer to HDD context
8891
8892 \return - void
8893
8894 --------------------------------------------------------------------------*/
8895
8896void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8897{
8898
8899 tSirVersionType versionCompiled;
8900 tSirVersionType versionReported;
8901 tSirVersionString versionString;
8902 tANI_U8 fwFeatCapsMsgSupported = 0;
8903 VOS_STATUS vstatus;
8904
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008905 memset(&versionCompiled, 0, sizeof(versionCompiled));
8906 memset(&versionReported, 0, sizeof(versionReported));
8907
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008908 /* retrieve and display WCNSS version information */
8909 do {
8910
8911 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8912 &versionCompiled);
8913 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8914 {
8915 hddLog(VOS_TRACE_LEVEL_FATAL,
8916 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008917 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008918 break;
8919 }
8920
8921 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8922 &versionReported);
8923 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8924 {
8925 hddLog(VOS_TRACE_LEVEL_FATAL,
8926 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008927 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008928 break;
8929 }
8930
8931 if ((versionCompiled.major != versionReported.major) ||
8932 (versionCompiled.minor != versionReported.minor) ||
8933 (versionCompiled.version != versionReported.version) ||
8934 (versionCompiled.revision != versionReported.revision))
8935 {
8936 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8937 "Host expected %u.%u.%u.%u\n",
8938 WLAN_MODULE_NAME,
8939 (int)versionReported.major,
8940 (int)versionReported.minor,
8941 (int)versionReported.version,
8942 (int)versionReported.revision,
8943 (int)versionCompiled.major,
8944 (int)versionCompiled.minor,
8945 (int)versionCompiled.version,
8946 (int)versionCompiled.revision);
8947 }
8948 else
8949 {
8950 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8951 WLAN_MODULE_NAME,
8952 (int)versionReported.major,
8953 (int)versionReported.minor,
8954 (int)versionReported.version,
8955 (int)versionReported.revision);
8956 }
8957
8958 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8959 versionString,
8960 sizeof(versionString));
8961 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8962 {
8963 hddLog(VOS_TRACE_LEVEL_FATAL,
8964 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008965 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008966 break;
8967 }
8968
8969 pr_info("%s: WCNSS software version %s\n",
8970 WLAN_MODULE_NAME, versionString);
8971
8972 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8973 versionString,
8974 sizeof(versionString));
8975 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8976 {
8977 hddLog(VOS_TRACE_LEVEL_FATAL,
8978 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008979 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008980 break;
8981 }
8982
8983 pr_info("%s: WCNSS hardware version %s\n",
8984 WLAN_MODULE_NAME, versionString);
8985
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008986 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8987 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008988 send the message only if it the riva is 1.1
8989 minor numbers for different riva branches:
8990 0 -> (1.0)Mainline Build
8991 1 -> (1.1)Mainline Build
8992 2->(1.04) Stability Build
8993 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008994 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008995 ((versionReported.minor>=1) && (versionReported.version>=1)))
8996 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8997 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008998
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008999 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009000 {
9001#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9002 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9003 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9004#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009005 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9006 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9007 {
9008 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9009 }
9010
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009011 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009012 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009013
9014 } while (0);
9015
9016}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309017void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9018{
9019 struct sk_buff *skb;
9020 struct nlmsghdr *nlh;
9021 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309022 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309023
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309024 if (in_interrupt() || irqs_disabled() || in_atomic())
9025 flags = GFP_ATOMIC;
9026
9027 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309028
9029 if(skb == NULL) {
9030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9031 "%s: alloc_skb failed", __func__);
9032 return;
9033 }
9034
9035 nlh = (struct nlmsghdr *)skb->data;
9036 nlh->nlmsg_pid = 0; /* from kernel */
9037 nlh->nlmsg_flags = 0;
9038 nlh->nlmsg_seq = 0;
9039 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9040
9041 ani_hdr = NLMSG_DATA(nlh);
9042 ani_hdr->type = type;
9043
9044 switch(type) {
9045 case WLAN_SVC_SAP_RESTART_IND:
9046 ani_hdr->length = 0;
9047 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9048 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9049 break;
9050 default:
9051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9052 "Attempt to send unknown nlink message %d", type);
9053 kfree_skb(skb);
9054 return;
9055 }
9056
9057 nl_srv_bcast(skb);
9058
9059 return;
9060}
9061
9062
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009063
9064/**---------------------------------------------------------------------------
9065
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309066 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9067
9068 \param - pHddCtx - Pointer to the hdd context
9069
9070 \return - true if hardware supports 5GHz
9071
9072 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309073boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309074{
9075 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9076 * then hardware support 5Ghz.
9077 */
9078 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9079 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309081 return true;
9082 }
9083 else
9084 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309086 __func__);
9087 return false;
9088 }
9089}
9090
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309091/**---------------------------------------------------------------------------
9092
9093 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9094 generate function
9095
9096 This is generate the random mac address for WLAN interface
9097
9098 \param - pHddCtx - Pointer to HDD context
9099 idx - Start interface index to get auto
9100 generated mac addr.
9101 mac_addr - Mac address
9102
9103 \return - 0 for success, < 0 for failure
9104
9105 --------------------------------------------------------------------------*/
9106
9107static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9108 int idx, v_MACADDR_t mac_addr)
9109{
9110 int i;
9111 unsigned int serialno;
9112 serialno = wcnss_get_serial_number();
9113
9114 if (0 != serialno)
9115 {
9116 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9117 bytes of the serial number that can be used to generate
9118 the other 3 bytes of the MAC address. Mask off all but
9119 the lower 3 bytes (this will also make sure we don't
9120 overflow in the next step) */
9121 serialno &= 0x00FFFFFF;
9122
9123 /* we need a unique address for each session */
9124 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9125
9126 /* autogen other Mac addresses */
9127 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9128 {
9129 /* start with the entire default address */
9130 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9131 /* then replace the lower 3 bytes */
9132 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9133 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9134 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9135
9136 serialno++;
9137 hddLog(VOS_TRACE_LEVEL_ERROR,
9138 "%s: Derived Mac Addr: "
9139 MAC_ADDRESS_STR, __func__,
9140 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9141 }
9142
9143 }
9144 else
9145 {
9146 hddLog(LOGE, FL("Failed to Get Serial NO"));
9147 return -1;
9148 }
9149 return 0;
9150}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309151
Katya Nigame7b69a82015-04-28 15:24:06 +05309152int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9153{
9154 VOS_STATUS status;
9155 v_CONTEXT_t pVosContext= NULL;
9156 hdd_adapter_t *pAdapter= NULL;
9157
9158 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9159
9160 if (NULL == pVosContext)
9161 {
9162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9163 "%s: Trying to open VOSS without a PreOpen", __func__);
9164 VOS_ASSERT(0);
9165 return VOS_STATUS_E_FAILURE;
9166 }
9167
9168 status = vos_nv_open();
9169 if (!VOS_IS_STATUS_SUCCESS(status))
9170 {
9171 /* NV module cannot be initialized */
9172 hddLog( VOS_TRACE_LEVEL_FATAL,
9173 "%s: vos_nv_open failed", __func__);
9174 return VOS_STATUS_E_FAILURE;
9175 }
9176
9177 status = vos_init_wiphy_from_nv_bin();
9178 if (!VOS_IS_STATUS_SUCCESS(status))
9179 {
9180 /* NV module cannot be initialized */
9181 hddLog( VOS_TRACE_LEVEL_FATAL,
9182 "%s: vos_init_wiphy failed", __func__);
9183 goto err_vos_nv_close;
9184 }
9185
9186 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9187 if ( !VOS_IS_STATUS_SUCCESS( status ))
9188 {
9189 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9190 goto err_vos_nv_close;
9191 }
9192
9193 status = vos_mon_start( pVosContext );
9194 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9195 {
9196 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9197 goto err_vosclose;
9198 }
9199
9200 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9201 WDA_featureCapsExchange(pVosContext);
9202 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9203
9204 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9205 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9206 if( pAdapter == NULL )
9207 {
9208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9209 goto err_close_adapter;
9210 }
9211
9212 //Initialize the nlink service
9213 if(nl_srv_init() != 0)
9214 {
9215 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9216 goto err_close_adapter;
9217 }
9218 return VOS_STATUS_SUCCESS;
9219
9220err_close_adapter:
9221 hdd_close_all_adapters( pHddCtx );
9222 vos_mon_stop( pVosContext );
9223err_vosclose:
9224 status = vos_sched_close( pVosContext );
9225 if (!VOS_IS_STATUS_SUCCESS(status)) {
9226 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9227 "%s: Failed to close VOSS Scheduler", __func__);
9228 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9229 }
9230 vos_close(pVosContext );
9231
9232err_vos_nv_close:
9233 vos_nv_close();
9234
9235return status;
9236}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309237/**---------------------------------------------------------------------------
9238
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309239 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9240 completed to flush out the scan results
9241
9242 11d scan is done during driver load and is a passive scan on all
9243 channels supported by the device, 11d scans may find some APs on
9244 frequencies which are forbidden to be used in the regulatory domain
9245 the device is operating in. If these APs are notified to the supplicant
9246 it may try to connect to these APs, thus flush out all the scan results
9247 which are present in SME after 11d scan is done.
9248
9249 \return - eHalStatus
9250
9251 --------------------------------------------------------------------------*/
9252static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9253 tANI_U32 scanId, eCsrScanStatus status)
9254{
9255 ENTER();
9256
9257 sme_ScanFlushResult(halHandle, 0);
9258
9259 EXIT();
9260
9261 return eHAL_STATUS_SUCCESS;
9262}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309263/**---------------------------------------------------------------------------
9264
9265 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9266 logging is completed successfully.
9267
9268 \return - None
9269
9270 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309271void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309272{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309273 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309274
9275 if (NULL == pHddCtx)
9276 {
9277 hddLog(VOS_TRACE_LEVEL_ERROR,
9278 "%s: HDD context is NULL",__func__);
9279 return;
9280 }
9281
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309282 if ((VOS_STATUS_SUCCESS == status) &&
9283 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309284 {
9285 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9286 pHddCtx->mgmt_frame_logging = TRUE;
9287 }
9288 else
9289 {
9290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9291 pHddCtx->mgmt_frame_logging = FALSE;
9292 }
9293
9294 return;
9295}
9296/**---------------------------------------------------------------------------
9297
9298 \brief hdd_init_frame_logging - function to initialize frame logging.
9299 Currently only Mgmt Frames are logged in both TX
9300 and Rx direction and are sent to userspace
9301 application using logger thread when queried.
9302
9303 \return - None
9304
9305 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309306void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309307{
9308 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309309 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309310
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309311 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9312 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309313 {
9314 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9315 return;
9316 }
9317
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309318 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9319 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309320 {
9321 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9322 return;
9323 }
9324
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309325 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309326
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9328 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9329 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9330 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309331
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309332 if (pHddCtx->cfg_ini->enableFWLogging ||
9333 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309334 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309335 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309336 }
9337
Sushant Kaushik46804902015-07-08 14:46:03 +05309338 if (pHddCtx->cfg_ini->enableMgmtLogging)
9339 {
9340 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9341 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309342 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9343 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309344 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309345 }
9346
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309347 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9348 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9349 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9350 wlanFWLoggingInitParam->continuousFrameLogging =
9351 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309352
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309353 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309354
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309355 wlanFWLoggingInitParam->minLogBufferSize =
9356 pHddCtx->cfg_ini->minLoggingBufferSize;
9357 wlanFWLoggingInitParam->maxLogBufferSize =
9358 pHddCtx->cfg_ini->maxLoggingBufferSize;
9359 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9360 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309361
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309362 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309363
9364 if (eHAL_STATUS_SUCCESS != halStatus)
9365 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309366 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309367 }
9368
9369 return;
9370}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309371
9372/**---------------------------------------------------------------------------
9373
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 \brief hdd_wlan_startup() - HDD init function
9375
9376 This is the driver startup code executed once a WLAN device has been detected
9377
9378 \param - dev - Pointer to the underlying device
9379
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009380 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009381
9382 --------------------------------------------------------------------------*/
9383
9384int hdd_wlan_startup(struct device *dev )
9385{
9386 VOS_STATUS status;
9387 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009388 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 hdd_context_t *pHddCtx = NULL;
9390 v_CONTEXT_t pVosContext= NULL;
9391#ifdef WLAN_BTAMP_FEATURE
9392 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9393 WLANBAP_ConfigType btAmpConfig;
9394 hdd_config_t *pConfig;
9395#endif
9396 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309398 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009399
9400 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 /*
9402 * cfg80211: wiphy allocation
9403 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309404 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009405
9406 if(wiphy == NULL)
9407 {
9408 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009409 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 pHddCtx = wiphy_priv(wiphy);
9412
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 //Initialize the adapter context to zeros.
9414 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9415
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309417 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309418 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009419
9420 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9421
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309422 /* register for riva power on lock to platform driver
9423 * Locking power early to ensure FW doesn't reset by kernel while
9424 * host driver is busy initializing itself */
9425 if (req_riva_power_on_lock("wlan"))
9426 {
9427 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9428 __func__);
9429 goto err_free_hdd_context;
9430 }
9431
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 /*Get vos context here bcoz vos_open requires it*/
9433 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9434
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009435 if(pVosContext == NULL)
9436 {
9437 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9438 goto err_free_hdd_context;
9439 }
9440
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 //Save the Global VOSS context in adapter context for future.
9442 pHddCtx->pvosContext = pVosContext;
9443
9444 //Save the adapter context in global context for future.
9445 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9446
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 pHddCtx->parent_dev = dev;
9448
9449 init_completion(&pHddCtx->full_pwr_comp_var);
9450 init_completion(&pHddCtx->standby_comp_var);
9451 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009452 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009453 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309454 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309455 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009456
9457#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009458 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009459#else
9460 init_completion(&pHddCtx->driver_crda_req);
9461#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009462
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309463 spin_lock_init(&pHddCtx->schedScan_lock);
9464
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9466
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309467#ifdef FEATURE_WLAN_TDLS
9468 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9469 * invoked by other instances also) to protect the concurrent
9470 * access for the Adapters by TDLS module.
9471 */
9472 mutex_init(&pHddCtx->tdls_lock);
9473#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309474 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309475 mutex_init(&pHddCtx->wmmLock);
9476
Agarwal Ashish1f422872014-07-22 00:11:55 +05309477 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309478
Agarwal Ashish1f422872014-07-22 00:11:55 +05309479 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 // Load all config first as TL config is needed during vos_open
9481 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9482 if(pHddCtx->cfg_ini == NULL)
9483 {
9484 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9485 goto err_free_hdd_context;
9486 }
9487
9488 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9489
9490 // Read and parse the qcom_cfg.ini file
9491 status = hdd_parse_config_ini( pHddCtx );
9492 if ( VOS_STATUS_SUCCESS != status )
9493 {
9494 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9495 __func__, WLAN_INI_FILE);
9496 goto err_config;
9497 }
Arif Hussaind5218912013-12-05 01:10:55 -08009498#ifdef MEMORY_DEBUG
9499 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9500 vos_mem_init();
9501
9502 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9503 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9504#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009505
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309506 /* INI has been read, initialise the configuredMcastBcastFilter with
9507 * INI value as this will serve as the default value
9508 */
9509 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9510 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9511 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309512
9513 if (false == hdd_is_5g_supported(pHddCtx))
9514 {
9515 //5Ghz is not supported.
9516 if (1 != pHddCtx->cfg_ini->nBandCapability)
9517 {
9518 hddLog(VOS_TRACE_LEVEL_INFO,
9519 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9520 pHddCtx->cfg_ini->nBandCapability = 1;
9521 }
9522 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309523
9524 /* If SNR Monitoring is enabled, FW has to parse all beacons
9525 * for calcaluting and storing the average SNR, so set Nth beacon
9526 * filter to 1 to enable FW to parse all the beaocons
9527 */
9528 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9529 {
9530 /* The log level is deliberately set to WARN as overriding
9531 * nthBeaconFilter to 1 will increase power cosumption and this
9532 * might just prove helpful to detect the power issue.
9533 */
9534 hddLog(VOS_TRACE_LEVEL_WARN,
9535 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9536 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309539 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009541 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009543 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9544 {
9545 hddLog(VOS_TRACE_LEVEL_FATAL,
9546 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9547 goto err_config;
9548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009550
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009551 // Update VOS trace levels based upon the cfg.ini
9552 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9553 pHddCtx->cfg_ini->vosTraceEnableBAP);
9554 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9555 pHddCtx->cfg_ini->vosTraceEnableTL);
9556 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9557 pHddCtx->cfg_ini->vosTraceEnableWDI);
9558 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9559 pHddCtx->cfg_ini->vosTraceEnableHDD);
9560 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9561 pHddCtx->cfg_ini->vosTraceEnableSME);
9562 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9563 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309564 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9565 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009566 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9567 pHddCtx->cfg_ini->vosTraceEnableWDA);
9568 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9569 pHddCtx->cfg_ini->vosTraceEnableSYS);
9570 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9571 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009572 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9573 pHddCtx->cfg_ini->vosTraceEnableSAP);
9574 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9575 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009576
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 // Update WDI trace levels based upon the cfg.ini
9578 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9579 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9580 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9581 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9582 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9583 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9584 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9585 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009586
Jeff Johnson88ba7742013-02-27 14:36:02 -08009587 if (VOS_FTM_MODE == hdd_get_conparam())
9588 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9590 {
9591 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9592 goto err_free_hdd_context;
9593 }
9594 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309595 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309596 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009598 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009599
Katya Nigame7b69a82015-04-28 15:24:06 +05309600 if( VOS_MONITOR_MODE == hdd_get_conparam())
9601 {
9602 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9603 {
9604 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9605 goto err_free_hdd_context;
9606 }
9607 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9608 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9609 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9610 return VOS_STATUS_SUCCESS;
9611 }
9612
Jeff Johnson88ba7742013-02-27 14:36:02 -08009613 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9615 {
9616 status = vos_watchdog_open(pVosContext,
9617 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9618
9619 if(!VOS_IS_STATUS_SUCCESS( status ))
9620 {
9621 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309622 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 }
9624 }
9625
9626 pHddCtx->isLogpInProgress = FALSE;
9627 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9628
Amar Singhala49cbc52013-10-08 18:37:44 -07009629#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009630 /* initialize the NV module. This is required so that
9631 we can initialize the channel information in wiphy
9632 from the NV.bin data. The channel information in
9633 wiphy needs to be initialized before wiphy registration */
9634
9635 status = vos_nv_open();
9636 if (!VOS_IS_STATUS_SUCCESS(status))
9637 {
9638 /* NV module cannot be initialized */
9639 hddLog( VOS_TRACE_LEVEL_FATAL,
9640 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309641 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009642 }
9643
9644 status = vos_init_wiphy_from_nv_bin();
9645 if (!VOS_IS_STATUS_SUCCESS(status))
9646 {
9647 /* NV module cannot be initialized */
9648 hddLog( VOS_TRACE_LEVEL_FATAL,
9649 "%s: vos_init_wiphy failed", __func__);
9650 goto err_vos_nv_close;
9651 }
9652
Amar Singhala49cbc52013-10-08 18:37:44 -07009653#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309654 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309655 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 if ( !VOS_IS_STATUS_SUCCESS( status ))
9657 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009658 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309659 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 }
9661
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9663
9664 if ( NULL == pHddCtx->hHal )
9665 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009666 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 goto err_vosclose;
9668 }
9669
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009670 status = vos_preStart( pHddCtx->pvosContext );
9671 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9672 {
9673 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309674 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009675 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009676
Arif Hussaineaf68602013-12-30 23:10:44 -08009677 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9678 {
9679 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9680 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9681 __func__, enable_dfs_chan_scan);
9682 }
9683 if (0 == enable_11d || 1 == enable_11d)
9684 {
9685 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9686 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9687 __func__, enable_11d);
9688 }
9689
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009690 /* Note that the vos_preStart() sequence triggers the cfg download.
9691 The cfg download must occur before we update the SME config
9692 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 status = hdd_set_sme_config( pHddCtx );
9694
9695 if ( VOS_STATUS_SUCCESS != status )
9696 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009697 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309698 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009699 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009700
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 /* In the integrated architecture we update the configuration from
9702 the INI file and from NV before vOSS has been started so that
9703 the final contents are available to send down to the cCPU */
9704
9705 // Apply the cfg.ini to cfg.dat
9706 if (FALSE == hdd_update_config_dat(pHddCtx))
9707 {
9708 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309709 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 }
9711
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309712 // Get mac addr from platform driver
9713 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9714
9715 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309717 /* Store the mac addr for first interface */
9718 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9719
9720 hddLog(VOS_TRACE_LEVEL_ERROR,
9721 "%s: WLAN Mac Addr: "
9722 MAC_ADDRESS_STR, __func__,
9723 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9724
9725 /* Here, passing Arg2 as 1 because we do not want to change the
9726 last 3 bytes (means non OUI bytes) of first interface mac
9727 addr.
9728 */
9729 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9730 {
9731 hddLog(VOS_TRACE_LEVEL_ERROR,
9732 "%s: Failed to generate wlan interface mac addr "
9733 "using MAC from ini file ", __func__);
9734 }
9735 }
9736 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9737 {
9738 // Apply the NV to cfg.dat
9739 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009740#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9741 /* There was not a valid set of MAC Addresses in NV. See if the
9742 default addresses were modified by the cfg.ini settings. If so,
9743 we'll use them, but if not, we'll autogenerate a set of MAC
9744 addresses based upon the device serial number */
9745
9746 static const v_MACADDR_t default_address =
9747 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009748
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309749 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9750 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 {
9752 /* cfg.ini has the default address, invoke autogen logic */
9753
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309754 /* Here, passing Arg2 as 0 because we want to change the
9755 last 3 bytes (means non OUI bytes) of all the interfaces
9756 mac addr.
9757 */
9758 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9759 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309761 hddLog(VOS_TRACE_LEVEL_ERROR,
9762 "%s: Failed to generate wlan interface mac addr "
9763 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9764 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 }
9767 else
9768#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9769 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009770 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 "%s: Invalid MAC address in NV, using MAC from ini file "
9772 MAC_ADDRESS_STR, __func__,
9773 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9774 }
9775 }
9776 {
9777 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309778
9779 /* Set the MAC Address Currently this is used by HAL to
9780 * add self sta. Remove this once self sta is added as
9781 * part of session open.
9782 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9784 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9785 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309786
Jeff Johnson295189b2012-06-20 16:38:30 -07009787 if (!HAL_STATUS_SUCCESS( halStatus ))
9788 {
9789 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9790 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309791 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 }
9793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009794
9795 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9796 Note: Firmware image will be read and downloaded inside vos_start API */
9797 status = vos_start( pHddCtx->pvosContext );
9798 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9799 {
9800 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309801 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 }
9803
Leo Chang6cec3e22014-01-21 15:33:49 -08009804#ifdef FEATURE_WLAN_CH_AVOID
9805 /* Plug in avoid channel notification callback
9806 * This should happen before ADD_SELF_STA
9807 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309808
9809 /* check the Channel Avoidance is enabled */
9810 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9811 {
9812 sme_AddChAvoidCallback(pHddCtx->hHal,
9813 hdd_hostapd_ch_avoid_cb);
9814 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009815#endif /* FEATURE_WLAN_CH_AVOID */
9816
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009817 /* Exchange capability info between Host and FW and also get versioning info from FW */
9818 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009819
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309820#ifdef CONFIG_ENABLE_LINUX_REG
9821 status = wlan_hdd_init_channels(pHddCtx);
9822 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9823 {
9824 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9825 __func__);
9826 goto err_vosstop;
9827 }
9828#endif
9829
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 status = hdd_post_voss_start_config( pHddCtx );
9831 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9832 {
9833 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9834 __func__);
9835 goto err_vosstop;
9836 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009837
9838#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309839 wlan_hdd_cfg80211_update_reg_info( wiphy );
9840
9841 /* 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 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009847#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009848
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309849#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309850 /* registration of wiphy dev with cfg80211 */
9851 if (0 > wlan_hdd_cfg80211_register(wiphy))
9852 {
9853 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9854 goto err_vosstop;
9855 }
9856
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309857 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309858 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9859 {
9860 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9861 __func__);
9862 goto err_unregister_wiphy;
9863 }
9864#endif
9865
c_hpothu4a298be2014-12-22 21:12:51 +05309866 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9867
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9869 {
9870 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9871 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9872 }
9873 else
9874 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9876 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9877 if (pAdapter != NULL)
9878 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309879 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309881 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9882 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9883 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009884
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309885 /* Generate the P2P Device Address. This consists of the device's
9886 * primary MAC address with the locally administered bit set.
9887 */
9888 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009889 }
9890 else
9891 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309892 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9893 if (p2p_dev_addr != NULL)
9894 {
9895 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9896 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9897 }
9898 else
9899 {
9900 hddLog(VOS_TRACE_LEVEL_FATAL,
9901 "%s: Failed to allocate mac_address for p2p_device",
9902 __func__);
9903 goto err_close_adapter;
9904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009906
9907 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9908 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9909 if ( NULL == pP2pAdapter )
9910 {
9911 hddLog(VOS_TRACE_LEVEL_FATAL,
9912 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009913 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009914 goto err_close_adapter;
9915 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009916 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009918
9919 if( pAdapter == NULL )
9920 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009921 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9922 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009924
Arif Hussain66559122013-11-21 10:11:40 -08009925 if (country_code)
9926 {
9927 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009928 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009929 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9930#ifndef CONFIG_ENABLE_LINUX_REG
9931 hdd_checkandupdate_phymode(pAdapter, country_code);
9932#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009933 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9934 (void *)(tSmeChangeCountryCallback)
9935 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009936 country_code,
9937 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309938 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009939 if (eHAL_STATUS_SUCCESS == ret)
9940 {
Arif Hussaincb607082013-12-20 11:57:42 -08009941 ret = wait_for_completion_interruptible_timeout(
9942 &pAdapter->change_country_code,
9943 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9944
9945 if (0 >= ret)
9946 {
9947 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9948 "%s: SME while setting country code timed out", __func__);
9949 }
Arif Hussain66559122013-11-21 10:11:40 -08009950 }
9951 else
9952 {
Arif Hussaincb607082013-12-20 11:57:42 -08009953 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9954 "%s: SME Change Country code from module param fail ret=%d",
9955 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009956 }
9957 }
9958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959#ifdef WLAN_BTAMP_FEATURE
9960 vStatus = WLANBAP_Open(pVosContext);
9961 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9962 {
9963 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9964 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009965 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 }
9967
9968 vStatus = BSL_Init(pVosContext);
9969 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9970 {
9971 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9972 "%s: Failed to Init BSL",__func__);
9973 goto err_bap_close;
9974 }
9975 vStatus = WLANBAP_Start(pVosContext);
9976 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9977 {
9978 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9979 "%s: Failed to start TL",__func__);
9980 goto err_bap_close;
9981 }
9982
9983 pConfig = pHddCtx->cfg_ini;
9984 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9985 status = WLANBAP_SetConfig(&btAmpConfig);
9986
9987#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009988
Mihir Shete9c238772014-10-15 14:35:16 +05309989 /*
9990 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9991 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9992 * which is greater than 0xf. So the below check is safe to make
9993 * sure that there is no entry for UapsdMask in the ini
9994 */
9995 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9996 {
9997 if(IS_DYNAMIC_WMM_PS_ENABLED)
9998 {
9999 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10000 __func__);
10001 pHddCtx->cfg_ini->UapsdMask =
10002 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10003 }
10004 else
10005 {
10006 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10007 __func__);
10008 pHddCtx->cfg_ini->UapsdMask =
10009 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10010 }
10011 }
10012
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010013#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10014 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10015 {
10016 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10017 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10018 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10019 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10020 }
10021#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010022
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010023 wlan_hdd_tdls_init(pHddCtx);
10024
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010025 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10026
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 /* Register with platform driver as client for Suspend/Resume */
10028 status = hddRegisterPmOps(pHddCtx);
10029 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10030 {
10031 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10032#ifdef WLAN_BTAMP_FEATURE
10033 goto err_bap_stop;
10034#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010035 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010036#endif //WLAN_BTAMP_FEATURE
10037 }
10038
Yue Ma0d4891e2013-08-06 17:01:45 -070010039 /* Open debugfs interface */
10040 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10041 {
10042 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10043 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010044 }
10045
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 /* Register TM level change handler function to the platform */
10047 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10048 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10049 {
10050 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10051 goto err_unregister_pmops;
10052 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010053
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 // register net device notifier for device change notification
10055 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10056
10057 if(ret < 0)
10058 {
10059 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010060 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 }
10062
10063 //Initialize the nlink service
10064 if(nl_srv_init() != 0)
10065 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010066 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 goto err_reg_netdev;
10068 }
10069
Leo Chang4ce1cc52013-10-21 18:27:15 -070010070#ifdef WLAN_KD_READY_NOTIFIER
10071 pHddCtx->kd_nl_init = 1;
10072#endif /* WLAN_KD_READY_NOTIFIER */
10073
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 //Initialize the BTC service
10075 if(btc_activate_service(pHddCtx) != 0)
10076 {
10077 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10078 goto err_nl_srv;
10079 }
10080
10081#ifdef PTT_SOCK_SVC_ENABLE
10082 //Initialize the PTT service
10083 if(ptt_sock_activate_svc(pHddCtx) != 0)
10084 {
10085 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10086 goto err_nl_srv;
10087 }
10088#endif
10089
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010090#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10091 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10092 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010093 if(wlan_logging_sock_activate_svc(
10094 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10095 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10096 {
10097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10098 " failed", __func__);
10099 goto err_nl_srv;
10100 }
10101 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10102 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010103 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10104 pHddCtx->cfg_ini->gEnableDebugLog =
10105 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010106 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010107
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010108 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10109 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010110 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010111 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010112 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010113 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010114 }
10115 else
10116 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010117 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010118 }
10119
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010120#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010121
10122
Sushant Kaushik215778f2015-05-21 14:05:36 +053010123 if (vos_is_multicast_logging())
10124 wlan_logging_set_log_level();
10125
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010129 /* Action frame registered in one adapter which will
10130 * applicable to all interfaces
10131 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010132 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010134
10135 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010136 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010137
Jeff Johnsone7245742012-09-05 17:12:55 -070010138#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10139 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010140 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010141 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010142
Jeff Johnsone7245742012-09-05 17:12:55 -070010143#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010144 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010145 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010146 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010147
Jeff Johnsone7245742012-09-05 17:12:55 -070010148
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010149 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10150 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010151
Katya Nigam5c306ea2014-06-19 15:39:54 +053010152 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010153 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010154 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010155
10156#ifdef FEATURE_WLAN_SCAN_PNO
10157 /*SME must send channel update configuration to RIVA*/
10158 sme_UpdateChannelConfig(pHddCtx->hHal);
10159#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010160 /* Send the update default channel list to the FW*/
10161 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010162
10163 /* Fwr capabilities received, Set the Dot11 mode */
10164 sme_SetDefDot11Mode(pHddCtx->hHal);
10165
Abhishek Singha306a442013-11-07 18:39:01 +053010166#ifndef CONFIG_ENABLE_LINUX_REG
10167 /*updating wiphy so that regulatory user hints can be processed*/
10168 if (wiphy)
10169 {
10170 regulatory_hint(wiphy, "00");
10171 }
10172#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010173 // Initialize the restart logic
10174 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010175
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010176 //Register the traffic monitor timer now
10177 if ( pHddCtx->cfg_ini->dynSplitscan)
10178 {
10179 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10180 VOS_TIMER_TYPE_SW,
10181 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10182 (void *)pHddCtx);
10183 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010184 wlan_hdd_cfg80211_nan_init(pHddCtx);
10185
Dino Mycle6fb96c12014-06-10 11:52:40 +053010186#ifdef WLAN_FEATURE_EXTSCAN
10187 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10188 wlan_hdd_cfg80211_extscan_callback,
10189 pHddCtx);
10190#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010191
10192#ifdef WLAN_NS_OFFLOAD
10193 // Register IPv6 notifier to notify if any change in IP
10194 // So that we can reconfigure the offload parameters
10195 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10196 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10197 if (ret)
10198 {
10199 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10200 }
10201 else
10202 {
10203 hddLog(LOGE, FL("Registered IPv6 notifier"));
10204 }
10205#endif
10206
10207 // Register IPv4 notifier to notify if any change in IP
10208 // So that we can reconfigure the offload parameters
10209 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10210 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10211 if (ret)
10212 {
10213 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10214 }
10215 else
10216 {
10217 hddLog(LOGE, FL("Registered IPv4 notifier"));
10218 }
10219
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 goto success;
10221
10222err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010223#ifdef WLAN_KD_READY_NOTIFIER
10224 nl_srv_exit(pHddCtx->ptt_pid);
10225#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010227#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010228err_reg_netdev:
10229 unregister_netdevice_notifier(&hdd_netdev_notifier);
10230
Jeff Johnson295189b2012-06-20 16:38:30 -070010231err_unregister_pmops:
10232 hddDevTmUnregisterNotifyCallback(pHddCtx);
10233 hddDeregisterPmOps(pHddCtx);
10234
Yue Ma0d4891e2013-08-06 17:01:45 -070010235 hdd_debugfs_exit(pHddCtx);
10236
Jeff Johnson295189b2012-06-20 16:38:30 -070010237#ifdef WLAN_BTAMP_FEATURE
10238err_bap_stop:
10239 WLANBAP_Stop(pVosContext);
10240#endif
10241
10242#ifdef WLAN_BTAMP_FEATURE
10243err_bap_close:
10244 WLANBAP_Close(pVosContext);
10245#endif
10246
Jeff Johnson295189b2012-06-20 16:38:30 -070010247err_close_adapter:
10248 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010249#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010250err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010251#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010252 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010253err_vosstop:
10254 vos_stop(pVosContext);
10255
Amar Singhala49cbc52013-10-08 18:37:44 -070010256err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 status = vos_sched_close( pVosContext );
10258 if (!VOS_IS_STATUS_SUCCESS(status)) {
10259 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10260 "%s: Failed to close VOSS Scheduler", __func__);
10261 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10262 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010263 vos_close(pVosContext );
10264
Amar Singhal0a402232013-10-11 20:57:16 -070010265err_vos_nv_close:
10266
c_hpothue6a36282014-03-19 12:27:38 +053010267#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010268 vos_nv_close();
10269
c_hpothu70f8d812014-03-22 22:59:23 +053010270#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010271
10272err_wdclose:
10273 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10274 vos_watchdog_close(pVosContext);
10275
Jeff Johnson295189b2012-06-20 16:38:30 -070010276err_config:
10277 kfree(pHddCtx->cfg_ini);
10278 pHddCtx->cfg_ini= NULL;
10279
10280err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010281 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010282 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 wiphy_free(wiphy) ;
10284 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010285 VOS_BUG(1);
10286
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010287 if (hdd_is_ssr_required())
10288 {
10289 /* WDI timeout had happened during load, so SSR is needed here */
10290 subsystem_restart("wcnss");
10291 msleep(5000);
10292 }
10293 hdd_set_ssr_required (VOS_FALSE);
10294
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010295 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010296
10297success:
10298 EXIT();
10299 return 0;
10300}
10301
10302/**---------------------------------------------------------------------------
10303
Jeff Johnson32d95a32012-09-10 13:15:23 -070010304 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010305
Jeff Johnson32d95a32012-09-10 13:15:23 -070010306 This is the driver entry point - called in different timeline depending
10307 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010308
10309 \param - None
10310
10311 \return - 0 for success, non zero for failure
10312
10313 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010314static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010315{
10316 VOS_STATUS status;
10317 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 struct device *dev = NULL;
10319 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010320#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10321 int max_retries = 0;
10322#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010323#ifdef HAVE_CBC_DONE
10324 int max_cbc_retries = 0;
10325#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010326
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010327#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10328 wlan_logging_sock_init_svc();
10329#endif
10330
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 ENTER();
10332
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010333 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010334
10335 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10336 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10337
Jeff Johnson295189b2012-06-20 16:38:30 -070010338#ifdef ANI_BUS_TYPE_PCI
10339
10340 dev = wcnss_wlan_get_device();
10341
10342#endif // ANI_BUS_TYPE_PCI
10343
10344#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010345
10346#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10347 /* wait until WCNSS driver downloads NV */
10348 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10349 msleep(1000);
10350 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010351
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010352 if (max_retries >= 5) {
10353 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010354 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010355#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10356 wlan_logging_sock_deinit_svc();
10357#endif
10358
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010359 return -ENODEV;
10360 }
10361#endif
10362
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010363#ifdef HAVE_CBC_DONE
10364 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10365 msleep(1000);
10366 }
10367 if (max_cbc_retries >= 10) {
10368 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10369 }
10370#endif
10371
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 dev = wcnss_wlan_get_device();
10373#endif // ANI_BUS_TYPE_PLATFORM
10374
10375
10376 do {
10377 if (NULL == dev) {
10378 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10379 ret_status = -1;
10380 break;
10381 }
10382
Jeff Johnson295189b2012-06-20 16:38:30 -070010383#ifdef TIMER_MANAGER
10384 vos_timer_manager_init();
10385#endif
10386
10387 /* Preopen VOSS so that it is ready to start at least SAL */
10388 status = vos_preOpen(&pVosContext);
10389
10390 if (!VOS_IS_STATUS_SUCCESS(status))
10391 {
10392 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10393 ret_status = -1;
10394 break;
10395 }
10396
Sushant Kaushik02beb352015-06-04 15:15:01 +053010397 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010398#ifndef MODULE
10399 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10400 */
10401 hdd_set_conparam((v_UINT_t)con_mode);
10402#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010403
10404 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010405 if (hdd_wlan_startup(dev))
10406 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010408 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 vos_preClose( &pVosContext );
10410 ret_status = -1;
10411 break;
10412 }
10413
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 } while (0);
10415
10416 if (0 != ret_status)
10417 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010418#ifdef TIMER_MANAGER
10419 vos_timer_exit();
10420#endif
10421#ifdef MEMORY_DEBUG
10422 vos_mem_exit();
10423#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010424 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010425#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10426 wlan_logging_sock_deinit_svc();
10427#endif
10428
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10430 }
10431 else
10432 {
10433 //Send WLAN UP indication to Nlink Service
10434 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10435
10436 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 }
10438
10439 EXIT();
10440
10441 return ret_status;
10442}
10443
Jeff Johnson32d95a32012-09-10 13:15:23 -070010444/**---------------------------------------------------------------------------
10445
10446 \brief hdd_module_init() - Init Function
10447
10448 This is the driver entry point (invoked when module is loaded using insmod)
10449
10450 \param - None
10451
10452 \return - 0 for success, non zero for failure
10453
10454 --------------------------------------------------------------------------*/
10455#ifdef MODULE
10456static int __init hdd_module_init ( void)
10457{
10458 return hdd_driver_init();
10459}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010460#else /* #ifdef MODULE */
10461static int __init hdd_module_init ( void)
10462{
10463 /* Driver initialization is delayed to fwpath_changed_handler */
10464 return 0;
10465}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010466#endif /* #ifdef MODULE */
10467
Jeff Johnson295189b2012-06-20 16:38:30 -070010468
10469/**---------------------------------------------------------------------------
10470
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010471 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010472
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010473 This is the driver exit point (invoked when module is unloaded using rmmod
10474 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010475
10476 \param - None
10477
10478 \return - None
10479
10480 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010481static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010482{
10483 hdd_context_t *pHddCtx = NULL;
10484 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010485 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010486 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010487
10488 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10489
10490 //Get the global vos context
10491 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10492
10493 if(!pVosContext)
10494 {
10495 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10496 goto done;
10497 }
10498
10499 //Get the HDD context.
10500 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10501
10502 if(!pHddCtx)
10503 {
10504 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10505 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010506 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10507 {
10508 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10509 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10510 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10511 hdd_wlan_exit(pHddCtx);
10512 vos_preClose( &pVosContext );
10513 goto done;
10514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 else
10516 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010517 /* We wait for active entry threads to exit from driver
10518 * by waiting until rtnl_lock is available.
10519 */
10520 rtnl_lock();
10521 rtnl_unlock();
10522
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010523 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10524 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10525 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10526 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010528 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010529 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10530 msecs_to_jiffies(30000));
10531 if(!rc)
10532 {
10533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10534 "%s:SSR timedout, fatal error", __func__);
10535 VOS_BUG(0);
10536 }
10537 }
10538
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010539 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10540 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010541
c_hpothu8adb97b2014-12-08 19:38:20 +053010542 /* Driver Need to send country code 00 in below condition
10543 * 1) If gCountryCodePriority is set to 1; and last country
10544 * code set is through 11d. This needs to be done in case
10545 * when NV country code is 00.
10546 * This Needs to be done as when kernel store last country
10547 * code and if stored country code is not through 11d,
10548 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10549 * in next load/unload as soon as we get any country through
10550 * 11d. In sme_HandleChangeCountryCodeByUser
10551 * pMsg->countryCode will be last countryCode and
10552 * pMac->scan.countryCode11d will be country through 11d so
10553 * due to mismatch driver will disable 11d.
10554 *
10555 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010556
c_hpothu8adb97b2014-12-08 19:38:20 +053010557 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010558 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010559 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010560 {
10561 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010562 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010563 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10564 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010565
c_hpothu8adb97b2014-12-08 19:38:20 +053010566 //Do all the cleanup before deregistering the driver
10567 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 }
10569
Jeff Johnson295189b2012-06-20 16:38:30 -070010570 vos_preClose( &pVosContext );
10571
10572#ifdef TIMER_MANAGER
10573 vos_timer_exit();
10574#endif
10575#ifdef MEMORY_DEBUG
10576 vos_mem_exit();
10577#endif
10578
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010579#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10580 wlan_logging_sock_deinit_svc();
10581#endif
10582
Jeff Johnson295189b2012-06-20 16:38:30 -070010583done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010584 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010585
Jeff Johnson295189b2012-06-20 16:38:30 -070010586 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10587}
10588
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010589/**---------------------------------------------------------------------------
10590
10591 \brief hdd_module_exit() - Exit function
10592
10593 This is the driver exit point (invoked when module is unloaded using rmmod)
10594
10595 \param - None
10596
10597 \return - None
10598
10599 --------------------------------------------------------------------------*/
10600static void __exit hdd_module_exit(void)
10601{
10602 hdd_driver_exit();
10603}
10604
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010605#ifdef MODULE
10606static int fwpath_changed_handler(const char *kmessage,
10607 struct kernel_param *kp)
10608{
Jeff Johnson76052702013-04-16 13:55:05 -070010609 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010610}
10611
10612static int con_mode_handler(const char *kmessage,
10613 struct kernel_param *kp)
10614{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010615 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010616}
10617#else /* #ifdef MODULE */
10618/**---------------------------------------------------------------------------
10619
Jeff Johnson76052702013-04-16 13:55:05 -070010620 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010621
Jeff Johnson76052702013-04-16 13:55:05 -070010622 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010623 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010624 - invoked when module parameter fwpath is modified from userspace to signal
10625 initializing the WLAN driver or when con_mode is modified from userspace
10626 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010627
10628 \return - 0 for success, non zero for failure
10629
10630 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010631static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010632{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010633 int ret_status;
10634
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010635 if (!wlan_hdd_inited) {
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
10641 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010642
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010643 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010644
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010645 ret_status = hdd_driver_init();
10646 wlan_hdd_inited = ret_status ? 0 : 1;
10647 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010648}
10649
Jeff Johnson295189b2012-06-20 16:38:30 -070010650/**---------------------------------------------------------------------------
10651
Jeff Johnson76052702013-04-16 13:55:05 -070010652 \brief fwpath_changed_handler() - Handler Function
10653
10654 Handle changes to the fwpath parameter
10655
10656 \return - 0 for success, non zero for failure
10657
10658 --------------------------------------------------------------------------*/
10659static int fwpath_changed_handler(const char *kmessage,
10660 struct kernel_param *kp)
10661{
10662 int ret;
10663
10664 ret = param_set_copystring(kmessage, kp);
10665 if (0 == ret)
10666 ret = kickstart_driver();
10667 return ret;
10668}
10669
10670/**---------------------------------------------------------------------------
10671
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010672 \brief con_mode_handler() -
10673
10674 Handler function for module param con_mode when it is changed by userspace
10675 Dynamically linked - do nothing
10676 Statically linked - exit and init driver, as in rmmod and insmod
10677
Jeff Johnson76052702013-04-16 13:55:05 -070010678 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010679
Jeff Johnson76052702013-04-16 13:55:05 -070010680 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010681
10682 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010683static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010684{
Jeff Johnson76052702013-04-16 13:55:05 -070010685 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010686
Jeff Johnson76052702013-04-16 13:55:05 -070010687 ret = param_set_int(kmessage, kp);
10688 if (0 == ret)
10689 ret = kickstart_driver();
10690 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010691}
10692#endif /* #ifdef MODULE */
10693
10694/**---------------------------------------------------------------------------
10695
Jeff Johnson295189b2012-06-20 16:38:30 -070010696 \brief hdd_get_conparam() -
10697
10698 This is the driver exit point (invoked when module is unloaded using rmmod)
10699
10700 \param - None
10701
10702 \return - tVOS_CON_MODE
10703
10704 --------------------------------------------------------------------------*/
10705tVOS_CON_MODE hdd_get_conparam ( void )
10706{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010707#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010709#else
10710 return (tVOS_CON_MODE)curr_con_mode;
10711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010712}
10713void hdd_set_conparam ( v_UINT_t newParam )
10714{
10715 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010716#ifndef MODULE
10717 curr_con_mode = con_mode;
10718#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010719}
10720/**---------------------------------------------------------------------------
10721
10722 \brief hdd_softap_sta_deauth() - function
10723
10724 This to take counter measure to handle deauth req from HDD
10725
10726 \param - pAdapter - Pointer to the HDD
10727
10728 \param - enable - boolean value
10729
10730 \return - None
10731
10732 --------------------------------------------------------------------------*/
10733
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010734VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10735 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010736{
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010738 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010739
10740 ENTER();
10741
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010742 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10743 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010744
10745 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010746 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010747 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010748
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010749 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010750
10751 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010752 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010753}
10754
10755/**---------------------------------------------------------------------------
10756
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010757 \brief hdd_del_all_sta() - function
10758
10759 This function removes all the stations associated on stopping AP/P2P GO.
10760
10761 \param - pAdapter - Pointer to the HDD
10762
10763 \return - None
10764
10765 --------------------------------------------------------------------------*/
10766
10767int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10768{
10769 v_U16_t i;
10770 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010771 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10772 ptSapContext pSapCtx = NULL;
10773 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10774 if(pSapCtx == NULL){
10775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10776 FL("psapCtx is NULL"));
10777 return 1;
10778 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010779 ENTER();
10780
10781 hddLog(VOS_TRACE_LEVEL_INFO,
10782 "%s: Delete all STAs associated.",__func__);
10783 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10784 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10785 )
10786 {
10787 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10788 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010789 if ((pSapCtx->aStaInfo[i].isUsed) &&
10790 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010791 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010792 struct tagCsrDelStaParams delStaParams;
10793
10794 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010795 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010796 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10797 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010798 &delStaParams);
10799 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010800 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010801 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010802 }
10803 }
10804 }
10805
10806 EXIT();
10807 return 0;
10808}
10809
10810/**---------------------------------------------------------------------------
10811
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 \brief hdd_softap_sta_disassoc() - function
10813
10814 This to take counter measure to handle deauth req from HDD
10815
10816 \param - pAdapter - Pointer to the HDD
10817
10818 \param - enable - boolean value
10819
10820 \return - None
10821
10822 --------------------------------------------------------------------------*/
10823
10824void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10825{
10826 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10827
10828 ENTER();
10829
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010830 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010831
10832 //Ignore request to disassoc bcmc station
10833 if( pDestMacAddress[0] & 0x1 )
10834 return;
10835
10836 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10837}
10838
10839void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10840{
10841 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10842
10843 ENTER();
10844
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010845 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010846
10847 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10848}
10849
Jeff Johnson295189b2012-06-20 16:38:30 -070010850/**---------------------------------------------------------------------------
10851 *
10852 * \brief hdd_get__concurrency_mode() -
10853 *
10854 *
10855 * \param - None
10856 *
10857 * \return - CONCURRENCY MODE
10858 *
10859 * --------------------------------------------------------------------------*/
10860tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10861{
10862 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10863 hdd_context_t *pHddCtx;
10864
10865 if (NULL != pVosContext)
10866 {
10867 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10868 if (NULL != pHddCtx)
10869 {
10870 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10871 }
10872 }
10873
10874 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010875 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010876 return VOS_STA;
10877}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010878v_BOOL_t
10879wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10880{
10881 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010882
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010883 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10884 if (pAdapter == NULL)
10885 {
10886 hddLog(VOS_TRACE_LEVEL_INFO,
10887 FL("GO doesn't exist"));
10888 return TRUE;
10889 }
10890 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10891 {
10892 hddLog(VOS_TRACE_LEVEL_INFO,
10893 FL("GO started"));
10894 return TRUE;
10895 }
10896 else
10897 /* wait till GO changes its interface to p2p device */
10898 hddLog(VOS_TRACE_LEVEL_INFO,
10899 FL("Del_bss called, avoid apps suspend"));
10900 return FALSE;
10901
10902}
Jeff Johnson295189b2012-06-20 16:38:30 -070010903/* Decide whether to allow/not the apps power collapse.
10904 * Allow apps power collapse if we are in connected state.
10905 * if not, allow only if we are in IMPS */
10906v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10907{
10908 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010909 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010910 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010911 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10912 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10913 hdd_adapter_t *pAdapter = NULL;
10914 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010915 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010916
Jeff Johnson295189b2012-06-20 16:38:30 -070010917 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10918 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010919
Yathish9f22e662012-12-10 14:21:35 -080010920 concurrent_state = hdd_get_concurrency_mode();
10921
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010922 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10923 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10924 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010925#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010926
Yathish9f22e662012-12-10 14:21:35 -080010927 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010928 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010929 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10930 return TRUE;
10931#endif
10932
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 /*loop through all adapters. TBD fix for Concurrency */
10934 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10935 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10936 {
10937 pAdapter = pAdapterNode->pAdapter;
10938 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10939 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10940 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010941 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010942 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010943 && pmcState != STOPPED && pmcState != STANDBY &&
10944 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010945 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10946 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010948 if(pmcState == FULL_POWER &&
10949 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10950 {
10951 /*
10952 * When SCO indication comes from Coex module , host will
10953 * enter in to full power mode, but this should not prevent
10954 * apps processor power collapse.
10955 */
10956 hddLog(LOG1,
10957 FL("Allow apps power collapse"
10958 "even when sco indication is set"));
10959 return TRUE;
10960 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010961 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010962 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10963 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010964 return FALSE;
10965 }
10966 }
10967 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10968 pAdapterNode = pNext;
10969 }
10970 return TRUE;
10971}
10972
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010973/* Decides whether to send suspend notification to Riva
10974 * if any adapter is in BMPS; then it is required */
10975v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10976{
10977 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10978 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10979
10980 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10981 {
10982 return TRUE;
10983 }
10984 return FALSE;
10985}
10986
Jeff Johnson295189b2012-06-20 16:38:30 -070010987void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10988{
10989 switch(mode)
10990 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010991 case VOS_STA_MODE:
10992 case VOS_P2P_CLIENT_MODE:
10993 case VOS_P2P_GO_MODE:
10994 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010995 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010996 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 break;
10998 default:
10999 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011000 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011001 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11002 "Number of open sessions for mode %d = %d"),
11003 pHddCtx->concurrency_mode, mode,
11004 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011005}
11006
11007
11008void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11009{
11010 switch(mode)
11011 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011012 case VOS_STA_MODE:
11013 case VOS_P2P_CLIENT_MODE:
11014 case VOS_P2P_GO_MODE:
11015 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011016 pHddCtx->no_of_open_sessions[mode]--;
11017 if (!(pHddCtx->no_of_open_sessions[mode]))
11018 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011019 break;
11020 default:
11021 break;
11022 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011023 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11024 "Number of open sessions for mode %d = %d"),
11025 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11026
11027}
11028/**---------------------------------------------------------------------------
11029 *
11030 * \brief wlan_hdd_incr_active_session()
11031 *
11032 * This function increments the number of active sessions
11033 * maintained per device mode
11034 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11035 * Incase of SAP/P2P GO upon bss start it is incremented
11036 *
11037 * \param pHddCtx - HDD Context
11038 * \param mode - device mode
11039 *
11040 * \return - None
11041 *
11042 * --------------------------------------------------------------------------*/
11043void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11044{
11045 switch (mode) {
11046 case VOS_STA_MODE:
11047 case VOS_P2P_CLIENT_MODE:
11048 case VOS_P2P_GO_MODE:
11049 case VOS_STA_SAP_MODE:
11050 pHddCtx->no_of_active_sessions[mode]++;
11051 break;
11052 default:
11053 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11054 break;
11055 }
11056 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11057 mode,
11058 pHddCtx->no_of_active_sessions[mode]);
11059}
11060
11061/**---------------------------------------------------------------------------
11062 *
11063 * \brief wlan_hdd_decr_active_session()
11064 *
11065 * This function decrements the number of active sessions
11066 * maintained per device mode
11067 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11068 * Incase of SAP/P2P GO upon bss stop it is decremented
11069 *
11070 * \param pHddCtx - HDD Context
11071 * \param mode - device mode
11072 *
11073 * \return - None
11074 *
11075 * --------------------------------------------------------------------------*/
11076void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11077{
11078 switch (mode) {
11079 case VOS_STA_MODE:
11080 case VOS_P2P_CLIENT_MODE:
11081 case VOS_P2P_GO_MODE:
11082 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011083 if (pHddCtx->no_of_active_sessions[mode] > 0)
11084 pHddCtx->no_of_active_sessions[mode]--;
11085 else
11086 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11087 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011088 break;
11089 default:
11090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11091 break;
11092 }
11093 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11094 mode,
11095 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011096}
11097
Jeff Johnsone7245742012-09-05 17:12:55 -070011098/**---------------------------------------------------------------------------
11099 *
11100 * \brief wlan_hdd_restart_init
11101 *
11102 * This function initalizes restart timer/flag. An internal function.
11103 *
11104 * \param - pHddCtx
11105 *
11106 * \return - None
11107 *
11108 * --------------------------------------------------------------------------*/
11109
11110static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11111{
11112 /* Initialize */
11113 pHddCtx->hdd_restart_retries = 0;
11114 atomic_set(&pHddCtx->isRestartInProgress, 0);
11115 vos_timer_init(&pHddCtx->hdd_restart_timer,
11116 VOS_TIMER_TYPE_SW,
11117 wlan_hdd_restart_timer_cb,
11118 pHddCtx);
11119}
11120/**---------------------------------------------------------------------------
11121 *
11122 * \brief wlan_hdd_restart_deinit
11123 *
11124 * This function cleans up the resources used. An internal function.
11125 *
11126 * \param - pHddCtx
11127 *
11128 * \return - None
11129 *
11130 * --------------------------------------------------------------------------*/
11131
11132static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11133{
11134
11135 VOS_STATUS vos_status;
11136 /* Block any further calls */
11137 atomic_set(&pHddCtx->isRestartInProgress, 1);
11138 /* Cleanup */
11139 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11140 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011141 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011142 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11143 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011144 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011145
11146}
11147
11148/**---------------------------------------------------------------------------
11149 *
11150 * \brief wlan_hdd_framework_restart
11151 *
11152 * This function uses a cfg80211 API to start a framework initiated WLAN
11153 * driver module unload/load.
11154 *
11155 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11156 *
11157 *
11158 * \param - pHddCtx
11159 *
11160 * \return - VOS_STATUS_SUCCESS: Success
11161 * VOS_STATUS_E_EMPTY: Adapter is Empty
11162 * VOS_STATUS_E_NOMEM: No memory
11163
11164 * --------------------------------------------------------------------------*/
11165
11166static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11167{
11168 VOS_STATUS status = VOS_STATUS_SUCCESS;
11169 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011170 int len = (sizeof (struct ieee80211_mgmt));
11171 struct ieee80211_mgmt *mgmt = NULL;
11172
11173 /* Prepare the DEAUTH managment frame with reason code */
11174 mgmt = kzalloc(len, GFP_KERNEL);
11175 if(mgmt == NULL)
11176 {
11177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11178 "%s: memory allocation failed (%d bytes)", __func__, len);
11179 return VOS_STATUS_E_NOMEM;
11180 }
11181 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011182
11183 /* Iterate over all adapters/devices */
11184 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011185 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11186 {
11187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11188 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11189 goto end;
11190 }
11191
Jeff Johnsone7245742012-09-05 17:12:55 -070011192 do
11193 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011194 if(pAdapterNode->pAdapter &&
11195 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011196 {
11197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11198 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11199 pAdapterNode->pAdapter->dev->name,
11200 pAdapterNode->pAdapter->device_mode,
11201 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011202 /*
11203 * CFG80211 event to restart the driver
11204 *
11205 * 'cfg80211_send_unprot_deauth' sends a
11206 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11207 * of SME(Linux Kernel) state machine.
11208 *
11209 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11210 * the driver.
11211 *
11212 */
11213
11214 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011215 }
11216 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11217 pAdapterNode = pNext;
11218 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11219
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011220 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011221 /* Free the allocated management frame */
11222 kfree(mgmt);
11223
Jeff Johnsone7245742012-09-05 17:12:55 -070011224 /* Retry until we unload or reach max count */
11225 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11226 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11227
11228 return status;
11229
11230}
11231/**---------------------------------------------------------------------------
11232 *
11233 * \brief wlan_hdd_restart_timer_cb
11234 *
11235 * Restart timer callback. An internal function.
11236 *
11237 * \param - User data:
11238 *
11239 * \return - None
11240 *
11241 * --------------------------------------------------------------------------*/
11242
11243void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11244{
11245 hdd_context_t *pHddCtx = usrDataForCallback;
11246 wlan_hdd_framework_restart(pHddCtx);
11247 return;
11248
11249}
11250
11251
11252/**---------------------------------------------------------------------------
11253 *
11254 * \brief wlan_hdd_restart_driver
11255 *
11256 * This function sends an event to supplicant to restart the WLAN driver.
11257 *
11258 * This function is called from vos_wlanRestart.
11259 *
11260 * \param - pHddCtx
11261 *
11262 * \return - VOS_STATUS_SUCCESS: Success
11263 * VOS_STATUS_E_EMPTY: Adapter is Empty
11264 * VOS_STATUS_E_ALREADY: Request already in progress
11265
11266 * --------------------------------------------------------------------------*/
11267VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11268{
11269 VOS_STATUS status = VOS_STATUS_SUCCESS;
11270
11271 /* A tight check to make sure reentrancy */
11272 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11273 {
Mihir Shetefd528652014-06-23 19:07:50 +053011274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011275 "%s: WLAN restart is already in progress", __func__);
11276
11277 return VOS_STATUS_E_ALREADY;
11278 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011279 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011280#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011281 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011282#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011283
Jeff Johnsone7245742012-09-05 17:12:55 -070011284 return status;
11285}
11286
Mihir Shetee1093ba2014-01-21 20:13:32 +053011287/**---------------------------------------------------------------------------
11288 *
11289 * \brief wlan_hdd_init_channels
11290 *
11291 * This function is used to initialize the channel list in CSR
11292 *
11293 * This function is called from hdd_wlan_startup
11294 *
11295 * \param - pHddCtx: HDD context
11296 *
11297 * \return - VOS_STATUS_SUCCESS: Success
11298 * VOS_STATUS_E_FAULT: Failure reported by SME
11299
11300 * --------------------------------------------------------------------------*/
11301static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11302{
11303 eHalStatus status;
11304
11305 status = sme_InitChannels(pHddCtx->hHal);
11306 if (HAL_STATUS_SUCCESS(status))
11307 {
11308 return VOS_STATUS_SUCCESS;
11309 }
11310 else
11311 {
11312 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11313 __func__, status);
11314 return VOS_STATUS_E_FAULT;
11315 }
11316}
11317
Mihir Shete04206452014-11-20 17:50:58 +053011318#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011319VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011320{
11321 eHalStatus status;
11322
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011323 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011324 if (HAL_STATUS_SUCCESS(status))
11325 {
11326 return VOS_STATUS_SUCCESS;
11327 }
11328 else
11329 {
11330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11331 __func__, status);
11332 return VOS_STATUS_E_FAULT;
11333 }
11334}
Mihir Shete04206452014-11-20 17:50:58 +053011335#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011336/*
11337 * API to find if there is any STA or P2P-Client is connected
11338 */
11339VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11340{
11341 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11342}
Jeff Johnsone7245742012-09-05 17:12:55 -070011343
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011344
11345/*
11346 * API to find if the firmware will send logs using DXE channel
11347 */
11348v_U8_t hdd_is_fw_logging_enabled(void)
11349{
11350 hdd_context_t *pHddCtx;
11351
11352 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11353 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11354
Sachin Ahuja084313e2015-05-21 17:57:10 +053011355 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011356}
11357
Agarwal Ashish57e84372014-12-05 18:26:53 +053011358/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011359 * API to find if the firmware will send trace logs using DXE channel
11360 */
11361v_U8_t hdd_is_fw_ev_logging_enabled(void)
11362{
11363 hdd_context_t *pHddCtx;
11364
11365 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11366 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11367
11368 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11369}
11370/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011371 * API to find if there is any session connected
11372 */
11373VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11374{
11375 return sme_is_any_session_connected(pHddCtx->hHal);
11376}
11377
11378
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011379int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11380{
11381 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11382 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011383 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011384 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011385
11386 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011387 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011388 if (pScanInfo->mScanPending)
11389 {
c_hpothua3d45d52015-01-05 14:11:17 +053011390 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11391 eCSR_SCAN_ABORT_DEFAULT);
11392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11393 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011394
c_hpothua3d45d52015-01-05 14:11:17 +053011395 /* If there is active scan command lets wait for the completion else
11396 * there is no need to wait as scan command might be in the SME pending
11397 * command list.
11398 */
11399 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11400 {
c_hpothua3d45d52015-01-05 14:11:17 +053011401 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011402 &pScanInfo->abortscan_event_var,
11403 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011404 if (0 >= status)
11405 {
11406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011407 "%s: Timeout or Interrupt occurred while waiting for abort"
11408 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011409 return -ETIMEDOUT;
11410 }
11411 }
11412 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11413 {
11414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11415 FL("hdd_abort_mac_scan failed"));
11416 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011417 }
11418 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011419 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011420}
11421
c_hpothu225aa7c2014-10-22 17:45:13 +053011422VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11423{
11424 hdd_adapter_t *pAdapter;
11425 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11426 VOS_STATUS vosStatus;
11427
11428 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11429 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11430 {
11431 pAdapter = pAdapterNode->pAdapter;
11432 if (NULL != pAdapter)
11433 {
11434 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11435 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11436 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11437 {
11438 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11439 pAdapter->device_mode);
11440 if (VOS_STATUS_SUCCESS !=
11441 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11442 {
11443 hddLog(LOGE, FL("failed to abort ROC"));
11444 return VOS_STATUS_E_FAILURE;
11445 }
11446 }
11447 }
11448 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11449 pAdapterNode = pNext;
11450 }
11451 return VOS_STATUS_SUCCESS;
11452}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011453
Mihir Shete0be28772015-02-17 18:42:14 +053011454hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11455{
11456 hdd_adapter_t *pAdapter;
11457 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11458 hdd_cfg80211_state_t *cfgState;
11459 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11460 VOS_STATUS vosStatus;
11461
11462 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11463 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11464 {
11465 pAdapter = pAdapterNode->pAdapter;
11466 if (NULL != pAdapter)
11467 {
11468 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11469 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11470 if (pRemainChanCtx)
11471 break;
11472 }
11473 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11474 pAdapterNode = pNext;
11475 }
11476 return pRemainChanCtx;
11477}
11478
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011479/**
11480 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11481 *
11482 * @pHddCtx: HDD context within host driver
11483 * @dfsScanMode: dfsScanMode passed from ioctl
11484 *
11485 */
11486
11487VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11488 tANI_U8 dfsScanMode)
11489{
11490 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11491 hdd_adapter_t *pAdapter;
11492 VOS_STATUS vosStatus;
11493 hdd_station_ctx_t *pHddStaCtx;
11494 eHalStatus status = eHAL_STATUS_SUCCESS;
11495
11496 if(!pHddCtx)
11497 {
11498 hddLog(LOGE, FL("HDD context is Null"));
11499 return eHAL_STATUS_FAILURE;
11500 }
11501
11502 if (pHddCtx->scan_info.mScanPending)
11503 {
11504 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11505 pHddCtx->scan_info.sessionId);
11506 hdd_abort_mac_scan(pHddCtx,
11507 pHddCtx->scan_info.sessionId,
11508 eCSR_SCAN_ABORT_DEFAULT);
11509 }
11510
11511 if (!dfsScanMode)
11512 {
11513 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11514 while ((NULL != pAdapterNode) &&
11515 (VOS_STATUS_SUCCESS == vosStatus))
11516 {
11517 pAdapter = pAdapterNode->pAdapter;
11518
11519 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11520 {
11521 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11522
11523 if(!pHddStaCtx)
11524 {
11525 hddLog(LOGE, FL("HDD STA context is Null"));
11526 return eHAL_STATUS_FAILURE;
11527 }
11528
11529 /* if STA is already connected on DFS channel,
11530 disconnect immediately*/
11531 if (hdd_connIsConnected(pHddStaCtx) &&
11532 (NV_CHANNEL_DFS ==
11533 vos_nv_getChannelEnabledState(
11534 pHddStaCtx->conn_info.operationChannel)))
11535 {
11536 status = sme_RoamDisconnect(pHddCtx->hHal,
11537 pAdapter->sessionId,
11538 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11539 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11540 "sme_RoamDisconnect returned with status: %d"
11541 "for sessionid: %d"), pHddStaCtx->conn_info.
11542 operationChannel, status, pAdapter->sessionId);
11543 }
11544 }
11545
11546 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11547 &pNext);
11548 pAdapterNode = pNext;
11549 }
11550 }
11551
11552 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11553 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11554 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11555
11556 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11557 if (!HAL_STATUS_SUCCESS(status))
11558 {
11559 hddLog(LOGE,
11560 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11561 return status;
11562 }
11563
11564 return status;
11565}
11566
Nirav Shah7e3c8132015-06-22 23:51:42 +053011567static int hdd_log2_ceil(unsigned value)
11568{
11569 /* need to switch to unsigned math so that negative values
11570 * will right-shift towards 0 instead of -1
11571 */
11572 unsigned tmp = value;
11573 int log2 = -1;
11574
11575 if (value == 0)
11576 return 0;
11577
11578 while (tmp) {
11579 log2++;
11580 tmp >>= 1;
11581 }
11582 if (1U << log2 != value)
11583 log2++;
11584
11585 return log2;
11586}
11587
11588/**
11589 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11590 * @pAdapter: adapter handle
11591 *
11592 * Return: vos status
11593 */
11594VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11595{
11596 int hash_elem, log2, i;
11597
11598 spin_lock_bh( &pAdapter->sta_hash_lock);
11599 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11600 spin_unlock_bh( &pAdapter->sta_hash_lock);
11601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11602 "%s: hash already attached for session id %d",
11603 __func__, pAdapter->sessionId);
11604 return VOS_STATUS_SUCCESS;
11605 }
11606 spin_unlock_bh( &pAdapter->sta_hash_lock);
11607
11608 hash_elem = WLAN_MAX_STA_COUNT;
11609 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11610 log2 = hdd_log2_ceil(hash_elem);
11611 hash_elem = 1 << log2;
11612
11613 pAdapter->sta_id_hash.mask = hash_elem - 1;
11614 pAdapter->sta_id_hash.idx_bits = log2;
11615 pAdapter->sta_id_hash.bins =
11616 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11617 if (!pAdapter->sta_id_hash.bins) {
11618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11619 "%s: malloc failed for session %d",
11620 __func__, pAdapter->sessionId);
11621 return VOS_STATUS_E_NOMEM;
11622 }
11623
11624 for (i = 0; i < hash_elem; i++)
11625 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11626
11627 spin_lock_bh( &pAdapter->sta_hash_lock);
11628 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11629 spin_unlock_bh( &pAdapter->sta_hash_lock);
11630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11631 "%s: Station ID Hash attached for session id %d",
11632 __func__, pAdapter->sessionId);
11633
11634 return VOS_STATUS_SUCCESS;
11635}
11636
11637/**
11638 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11639 * @pAdapter: adapter handle
11640 *
11641 * Return: vos status
11642 */
11643VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11644{
11645 int hash_elem, i;
11646 v_SIZE_t size;
11647
11648 spin_lock_bh( &pAdapter->sta_hash_lock);
11649 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11650 spin_unlock_bh( &pAdapter->sta_hash_lock);
11651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11652 "%s: hash not initialized for session id %d",
11653 __func__, pAdapter->sessionId);
11654 return VOS_STATUS_SUCCESS;
11655 }
11656
11657 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11658 spin_unlock_bh( &pAdapter->sta_hash_lock);
11659
11660 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11661
11662 /* free all station info*/
11663 for (i = 0; i < hash_elem; i++) {
11664 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11665 if (size != 0) {
11666 VOS_STATUS status;
11667 hdd_staid_hash_node_t *sta_info_node = NULL;
11668 hdd_staid_hash_node_t *next_node = NULL;
11669 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11670 (hdd_list_node_t**) &sta_info_node );
11671
11672 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11673 {
11674 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11675 &sta_info_node->node);
11676 vos_mem_free(sta_info_node);
11677
11678 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11679 (hdd_list_node_t*)sta_info_node,
11680 (hdd_list_node_t**)&next_node);
11681 sta_info_node = next_node;
11682 }
11683 }
11684 }
11685
11686 vos_mem_free(pAdapter->sta_id_hash.bins);
11687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11688 "%s: Station ID Hash detached for session id %d",
11689 __func__, pAdapter->sessionId);
11690 return VOS_STATUS_SUCCESS;
11691}
11692
11693/**
11694 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11695 * @pAdapter: adapter handle
11696 * @mac_addr_in: input mac address
11697 *
11698 * Return: index derived from mac address
11699 */
11700int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11701 v_MACADDR_t *mac_addr_in)
11702{
11703 uint16 index;
11704 struct hdd_align_mac_addr_t * mac_addr =
11705 (struct hdd_align_mac_addr_t *)mac_addr_in;
11706
11707 index = mac_addr->bytes_ab ^
11708 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11709 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11710 index &= pAdapter->sta_id_hash.mask;
11711 return index;
11712}
11713
11714/**
11715 * hdd_sta_id_hash_add_entry() - add entry in hash
11716 * @pAdapter: adapter handle
11717 * @sta_id: station id
11718 * @mac_addr: mac address
11719 *
11720 * Return: vos status
11721 */
11722VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11723 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11724{
11725 uint16 index;
11726 hdd_staid_hash_node_t *sta_info_node = NULL;
11727
11728 spin_lock_bh( &pAdapter->sta_hash_lock);
11729 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11730 spin_unlock_bh( &pAdapter->sta_hash_lock);
11731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11732 "%s: hash is not initialized for session id %d",
11733 __func__, pAdapter->sessionId);
11734 return VOS_STATUS_E_FAILURE;
11735 }
11736
11737 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11738 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11739 if (!sta_info_node) {
11740 spin_unlock_bh( &pAdapter->sta_hash_lock);
11741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11742 "%s: malloc failed", __func__);
11743 return VOS_STATUS_E_NOMEM;
11744 }
11745
11746 sta_info_node->sta_id = sta_id;
11747 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11748
11749 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11750 (hdd_list_node_t*) sta_info_node );
11751 spin_unlock_bh( &pAdapter->sta_hash_lock);
11752 return VOS_STATUS_SUCCESS;
11753}
11754
11755/**
11756 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11757 * @pAdapter: adapter handle
11758 * @sta_id: station id
11759 * @mac_addr: mac address
11760 *
11761 * Return: vos status
11762 */
11763VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11764 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11765{
11766 uint16 index;
11767 VOS_STATUS status;
11768 hdd_staid_hash_node_t *sta_info_node = NULL;
11769 hdd_staid_hash_node_t *next_node = NULL;
11770
11771 spin_lock_bh( &pAdapter->sta_hash_lock);
11772 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11773 spin_unlock_bh( &pAdapter->sta_hash_lock);
11774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11775 "%s: hash is not initialized for session id %d",
11776 __func__, pAdapter->sessionId);
11777 return VOS_STATUS_E_FAILURE;
11778 }
11779
11780 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11781 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11782 (hdd_list_node_t**) &sta_info_node );
11783
11784 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11785 {
11786 if (sta_info_node->sta_id == sta_id) {
11787 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11788 &sta_info_node->node);
11789 vos_mem_free(sta_info_node);
11790 break;
11791 }
11792 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11793 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11794 sta_info_node = next_node;
11795 }
11796 spin_unlock_bh( &pAdapter->sta_hash_lock);
11797 return status;
11798}
11799
11800/**
11801 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11802 * @pAdapter: adapter handle
11803 * @mac_addr_in: mac address
11804 *
11805 * Return: station id
11806 */
11807int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11808 v_MACADDR_t *mac_addr_in)
11809{
11810 uint8 is_found = 0;
11811 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11812 uint16 index;
11813 VOS_STATUS status;
11814 hdd_staid_hash_node_t *sta_info_node = NULL;
11815 hdd_staid_hash_node_t *next_node = NULL;
11816
11817 spin_lock_bh( &pAdapter->sta_hash_lock);
11818 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11819 spin_unlock_bh( &pAdapter->sta_hash_lock);
11820 hddLog(VOS_TRACE_LEVEL_ERROR,
11821 FL("hash is not initialized for session id %d"),
11822 pAdapter->sessionId);
11823 return HDD_WLAN_INVALID_STA_ID;
11824 }
11825
11826 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11827 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11828 (hdd_list_node_t**) &sta_info_node );
11829
11830 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11831 {
11832 if (vos_mem_compare(&sta_info_node->mac_addr,
11833 mac_addr_in, sizeof(v_MACADDR_t))) {
11834 is_found = 1;
11835 sta_id = sta_info_node->sta_id;
11836 break;
11837 }
11838 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11839 (hdd_list_node_t*)sta_info_node,
11840 (hdd_list_node_t**)&next_node);
11841 sta_info_node = next_node;
11842 }
11843 spin_unlock_bh( &pAdapter->sta_hash_lock);
11844 return sta_id;
11845}
11846
Jeff Johnson295189b2012-06-20 16:38:30 -070011847//Register the module init/exit functions
11848module_init(hdd_module_init);
11849module_exit(hdd_module_exit);
11850
11851MODULE_LICENSE("Dual BSD/GPL");
11852MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11853MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11854
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011855module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11856 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011857
Jeff Johnson76052702013-04-16 13:55:05 -070011858module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011859 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011860
11861module_param(enable_dfs_chan_scan, int,
11862 S_IRUSR | S_IRGRP | S_IROTH);
11863
11864module_param(enable_11d, int,
11865 S_IRUSR | S_IRGRP | S_IROTH);
11866
11867module_param(country_code, charp,
11868 S_IRUSR | S_IRGRP | S_IROTH);