blob: a8e9f785021f7dcd27c55aedcdc4a84b98ab57f2 [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);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002885 if (copy_to_user(priv_data.buf, &extra, len + 1))
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2888 "%s: failed to copy data to user buffer", __func__);
2889 ret = -EFAULT;
2890 goto exit;
2891 }
2892 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002893 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002894 {
2895 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2896 char extra[32];
2897 tANI_U8 len = 0;
2898
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002899 len = scnprintf(extra, sizeof(extra), "%s %d",
2900 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302901 len = VOS_MIN(priv_data.total_len, len + 1);
2902 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002903 {
2904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2905 "%s: failed to copy data to user buffer", __func__);
2906 ret = -EFAULT;
2907 goto exit;
2908 }
2909 }
2910 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2911 {
2912 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2913 char extra[32];
2914 tANI_U8 len = 0;
2915
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002916 len = scnprintf(extra, sizeof(extra), "%s %d",
2917 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302918 len = VOS_MIN(priv_data.total_len, len + 1);
2919 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002920 {
2921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2922 "%s: failed to copy data to user buffer", __func__);
2923 ret = -EFAULT;
2924 goto exit;
2925 }
2926 }
2927 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2928 {
2929 tANI_U8 *value = command;
2930 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2931
2932 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2933 value = value + 26;
2934 /* Convert the value from ascii to integer */
2935 ret = kstrtou8(value, 10, &minTime);
2936 if (ret < 0)
2937 {
2938 /* If the input value is greater than max value of datatype, then also
2939 kstrtou8 fails */
2940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2941 "%s: kstrtou8 failed range [%d - %d]", __func__,
2942 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2943 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2944 ret = -EINVAL;
2945 goto exit;
2946 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002947 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2948 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2949 {
2950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2951 "scan min channel time value %d is out of range"
2952 " (Min: %d Max: %d)", minTime,
2953 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2954 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2955 ret = -EINVAL;
2956 goto exit;
2957 }
2958
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302959 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2960 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2961 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2963 "%s: Received Command to change channel min time = %d", __func__, minTime);
2964
2965 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2966 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2967 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002968 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2969 {
2970 tANI_U8 *value = command;
2971 tANI_U8 channel = 0;
2972 tANI_U8 dwellTime = 0;
2973 tANI_U8 bufLen = 0;
2974 tANI_U8 *buf = NULL;
2975 tSirMacAddr targetApBssid;
2976 eHalStatus status = eHAL_STATUS_SUCCESS;
2977 struct ieee80211_channel chan;
2978 tANI_U8 finalLen = 0;
2979 tANI_U8 *finalBuf = NULL;
2980 tANI_U8 temp = 0;
2981 u64 cookie;
2982 hdd_station_ctx_t *pHddStaCtx = NULL;
2983 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2984
2985 /* if not associated, no need to send action frame */
2986 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2987 {
2988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2989 ret = -EINVAL;
2990 goto exit;
2991 }
2992
2993 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2994 &dwellTime, &buf, &bufLen);
2995 if (eHAL_STATUS_SUCCESS != status)
2996 {
2997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2998 "%s: Failed to parse send action frame data", __func__);
2999 ret = -EINVAL;
3000 goto exit;
3001 }
3002
3003 /* if the target bssid is different from currently associated AP,
3004 then no need to send action frame */
3005 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3006 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3007 {
3008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3009 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003010 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003011 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003012 goto exit;
3013 }
3014
3015 /* if the channel number is different from operating channel then
3016 no need to send action frame */
3017 if (channel != pHddStaCtx->conn_info.operationChannel)
3018 {
3019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3020 "%s: channel(%d) is different from operating channel(%d)",
3021 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3022 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003023 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003024 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003025 goto exit;
3026 }
3027 chan.center_freq = sme_ChnToFreq(channel);
3028
3029 finalLen = bufLen + 24;
3030 finalBuf = vos_mem_malloc(finalLen);
3031 if (NULL == finalBuf)
3032 {
3033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3034 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003035 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003036 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003037 goto exit;
3038 }
3039 vos_mem_zero(finalBuf, finalLen);
3040
3041 /* Fill subtype */
3042 temp = SIR_MAC_MGMT_ACTION << 4;
3043 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3044
3045 /* Fill type */
3046 temp = SIR_MAC_MGMT_FRAME;
3047 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3048
3049 /* Fill destination address (bssid of the AP) */
3050 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3051
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003052 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003053 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3054
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003055 /* Fill BSSID (AP mac address) */
3056 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003057
3058 /* Fill received buffer from 24th address */
3059 vos_mem_copy(finalBuf + 24, buf, bufLen);
3060
Jeff Johnson11c33152013-04-16 17:52:40 -07003061 /* done with the parsed buffer */
3062 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003063 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003064
DARAM SUDHA39eede62014-02-12 11:16:40 +05303065 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003066#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3067 &(pAdapter->wdev),
3068#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003069 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003070#endif
3071 &chan, 0,
3072#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3073 NL80211_CHAN_HT20, 1,
3074#endif
3075 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003076 1, &cookie );
3077 vos_mem_free(finalBuf);
3078 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003079 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3080 {
3081 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3082 char extra[32];
3083 tANI_U8 len = 0;
3084
3085 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003086 len = scnprintf(extra, sizeof(extra), "%s %d",
3087 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3089 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3090 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303091 len = VOS_MIN(priv_data.total_len, len + 1);
3092 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003093 {
3094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3095 "%s: failed to copy data to user buffer", __func__);
3096 ret = -EFAULT;
3097 goto exit;
3098 }
3099 }
3100 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3101 {
3102 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003103 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003104
3105 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3106 value = value + 19;
3107 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003108 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003109 if (ret < 0)
3110 {
3111 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003112 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003114 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003115 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3116 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3117 ret = -EINVAL;
3118 goto exit;
3119 }
3120
3121 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3122 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3123 {
3124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3125 "lfr mode value %d is out of range"
3126 " (Min: %d Max: %d)", maxTime,
3127 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3128 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3129 ret = -EINVAL;
3130 goto exit;
3131 }
3132
3133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3134 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3135
3136 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3137 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3138 }
3139 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3140 {
3141 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3142 char extra[32];
3143 tANI_U8 len = 0;
3144
3145 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003146 len = scnprintf(extra, sizeof(extra), "%s %d",
3147 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003148 if (copy_to_user(priv_data.buf, &extra, len + 1))
3149 {
3150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3151 "%s: failed to copy data to user buffer", __func__);
3152 ret = -EFAULT;
3153 goto exit;
3154 }
3155 }
3156 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3157 {
3158 tANI_U8 *value = command;
3159 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3160
3161 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3162 value = value + 16;
3163 /* Convert the value from ascii to integer */
3164 ret = kstrtou16(value, 10, &val);
3165 if (ret < 0)
3166 {
3167 /* If the input value is greater than max value of datatype, then also
3168 kstrtou16 fails */
3169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3170 "%s: kstrtou16 failed range [%d - %d]", __func__,
3171 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3172 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3173 ret = -EINVAL;
3174 goto exit;
3175 }
3176
3177 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3178 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3179 {
3180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3181 "scan home time value %d is out of range"
3182 " (Min: %d Max: %d)", val,
3183 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3184 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3185 ret = -EINVAL;
3186 goto exit;
3187 }
3188
3189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3190 "%s: Received Command to change scan home time = %d", __func__, val);
3191
3192 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3193 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3194 }
3195 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3196 {
3197 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3198 char extra[32];
3199 tANI_U8 len = 0;
3200
3201 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003202 len = scnprintf(extra, sizeof(extra), "%s %d",
3203 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003204 if (copy_to_user(priv_data.buf, &extra, len + 1))
3205 {
3206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3207 "%s: failed to copy data to user buffer", __func__);
3208 ret = -EFAULT;
3209 goto exit;
3210 }
3211 }
3212 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3213 {
3214 tANI_U8 *value = command;
3215 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3216
3217 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3218 value = value + 17;
3219 /* Convert the value from ascii to integer */
3220 ret = kstrtou8(value, 10, &val);
3221 if (ret < 0)
3222 {
3223 /* If the input value is greater than max value of datatype, then also
3224 kstrtou8 fails */
3225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3226 "%s: kstrtou8 failed range [%d - %d]", __func__,
3227 CFG_ROAM_INTRA_BAND_MIN,
3228 CFG_ROAM_INTRA_BAND_MAX);
3229 ret = -EINVAL;
3230 goto exit;
3231 }
3232
3233 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3234 (val > CFG_ROAM_INTRA_BAND_MAX))
3235 {
3236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3237 "intra band mode value %d is out of range"
3238 " (Min: %d Max: %d)", val,
3239 CFG_ROAM_INTRA_BAND_MIN,
3240 CFG_ROAM_INTRA_BAND_MAX);
3241 ret = -EINVAL;
3242 goto exit;
3243 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3245 "%s: Received Command to change intra band = %d", __func__, val);
3246
3247 pHddCtx->cfg_ini->nRoamIntraBand = val;
3248 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3249 }
3250 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3251 {
3252 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3253 char extra[32];
3254 tANI_U8 len = 0;
3255
3256 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003257 len = scnprintf(extra, sizeof(extra), "%s %d",
3258 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003259 if (copy_to_user(priv_data.buf, &extra, len + 1))
3260 {
3261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3262 "%s: failed to copy data to user buffer", __func__);
3263 ret = -EFAULT;
3264 goto exit;
3265 }
3266 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003267 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3268 {
3269 tANI_U8 *value = command;
3270 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3271
3272 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3273 value = value + 15;
3274 /* Convert the value from ascii to integer */
3275 ret = kstrtou8(value, 10, &nProbes);
3276 if (ret < 0)
3277 {
3278 /* If the input value is greater than max value of datatype, then also
3279 kstrtou8 fails */
3280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "%s: kstrtou8 failed range [%d - %d]", __func__,
3282 CFG_ROAM_SCAN_N_PROBES_MIN,
3283 CFG_ROAM_SCAN_N_PROBES_MAX);
3284 ret = -EINVAL;
3285 goto exit;
3286 }
3287
3288 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3289 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3290 {
3291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3292 "NProbes value %d is out of range"
3293 " (Min: %d Max: %d)", nProbes,
3294 CFG_ROAM_SCAN_N_PROBES_MIN,
3295 CFG_ROAM_SCAN_N_PROBES_MAX);
3296 ret = -EINVAL;
3297 goto exit;
3298 }
3299
3300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3301 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3302
3303 pHddCtx->cfg_ini->nProbes = nProbes;
3304 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3305 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303306 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003307 {
3308 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3309 char extra[32];
3310 tANI_U8 len = 0;
3311
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003312 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003313 if (copy_to_user(priv_data.buf, &extra, len + 1))
3314 {
3315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3316 "%s: failed to copy data to user buffer", __func__);
3317 ret = -EFAULT;
3318 goto exit;
3319 }
3320 }
3321 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3322 {
3323 tANI_U8 *value = command;
3324 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3325
3326 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3327 /* input value is in units of msec */
3328 value = value + 20;
3329 /* Convert the value from ascii to integer */
3330 ret = kstrtou16(value, 10, &homeAwayTime);
3331 if (ret < 0)
3332 {
3333 /* If the input value is greater than max value of datatype, then also
3334 kstrtou8 fails */
3335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3336 "%s: kstrtou8 failed range [%d - %d]", __func__,
3337 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3338 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3339 ret = -EINVAL;
3340 goto exit;
3341 }
3342
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003343 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3344 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3345 {
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3347 "homeAwayTime value %d is out of range"
3348 " (Min: %d Max: %d)", homeAwayTime,
3349 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3350 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3351 ret = -EINVAL;
3352 goto exit;
3353 }
3354
3355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3356 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003357 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3358 {
3359 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3360 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3361 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003362 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303363 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003364 {
3365 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3366 char extra[32];
3367 tANI_U8 len = 0;
3368
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003369 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003370 if (copy_to_user(priv_data.buf, &extra, len + 1))
3371 {
3372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3373 "%s: failed to copy data to user buffer", __func__);
3374 ret = -EFAULT;
3375 goto exit;
3376 }
3377 }
3378 else if (strncmp(command, "REASSOC", 7) == 0)
3379 {
3380 tANI_U8 *value = command;
3381 tANI_U8 channel = 0;
3382 tSirMacAddr targetApBssid;
3383 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003384#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3385 tCsrHandoffRequest handoffInfo;
3386#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003387 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003388 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3389
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003390 /* if not associated, no need to proceed with reassoc */
3391 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3392 {
3393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3394 ret = -EINVAL;
3395 goto exit;
3396 }
3397
3398 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3399 if (eHAL_STATUS_SUCCESS != status)
3400 {
3401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3402 "%s: Failed to parse reassoc command data", __func__);
3403 ret = -EINVAL;
3404 goto exit;
3405 }
3406
3407 /* if the target bssid is same as currently associated AP,
3408 then no need to proceed with reassoc */
3409 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3410 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3411 {
3412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3413 ret = -EINVAL;
3414 goto exit;
3415 }
3416
3417 /* Check channel number is a valid channel number */
3418 if(VOS_STATUS_SUCCESS !=
3419 wlan_hdd_validate_operation_channel(pAdapter, channel))
3420 {
3421 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003422 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003423 return -EINVAL;
3424 }
3425
3426 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003427#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3428 handoffInfo.channel = channel;
3429 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3430 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3431#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003432 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003433 else if (strncmp(command, "SETWESMODE", 10) == 0)
3434 {
3435 tANI_U8 *value = command;
3436 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3437
3438 /* Move pointer to ahead of SETWESMODE<delimiter> */
3439 value = value + 11;
3440 /* Convert the value from ascii to integer */
3441 ret = kstrtou8(value, 10, &wesMode);
3442 if (ret < 0)
3443 {
3444 /* If the input value is greater than max value of datatype, then also
3445 kstrtou8 fails */
3446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3447 "%s: kstrtou8 failed range [%d - %d]", __func__,
3448 CFG_ENABLE_WES_MODE_NAME_MIN,
3449 CFG_ENABLE_WES_MODE_NAME_MAX);
3450 ret = -EINVAL;
3451 goto exit;
3452 }
3453
3454 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3455 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3456 {
3457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3458 "WES Mode value %d is out of range"
3459 " (Min: %d Max: %d)", wesMode,
3460 CFG_ENABLE_WES_MODE_NAME_MIN,
3461 CFG_ENABLE_WES_MODE_NAME_MAX);
3462 ret = -EINVAL;
3463 goto exit;
3464 }
3465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3466 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3467
3468 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3469 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3470 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303471 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003472 {
3473 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3474 char extra[32];
3475 tANI_U8 len = 0;
3476
Arif Hussain826d9412013-11-12 16:44:54 -08003477 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003478 if (copy_to_user(priv_data.buf, &extra, len + 1))
3479 {
3480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3481 "%s: failed to copy data to user buffer", __func__);
3482 ret = -EFAULT;
3483 goto exit;
3484 }
3485 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003486#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003487#ifdef FEATURE_WLAN_LFR
3488 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3489 {
3490 tANI_U8 *value = command;
3491 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3492
3493 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3494 value = value + 12;
3495 /* Convert the value from ascii to integer */
3496 ret = kstrtou8(value, 10, &lfrMode);
3497 if (ret < 0)
3498 {
3499 /* If the input value is greater than max value of datatype, then also
3500 kstrtou8 fails */
3501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3502 "%s: kstrtou8 failed range [%d - %d]", __func__,
3503 CFG_LFR_FEATURE_ENABLED_MIN,
3504 CFG_LFR_FEATURE_ENABLED_MAX);
3505 ret = -EINVAL;
3506 goto exit;
3507 }
3508
3509 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3510 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3511 {
3512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3513 "lfr mode value %d is out of range"
3514 " (Min: %d Max: %d)", lfrMode,
3515 CFG_LFR_FEATURE_ENABLED_MIN,
3516 CFG_LFR_FEATURE_ENABLED_MAX);
3517 ret = -EINVAL;
3518 goto exit;
3519 }
3520
3521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3522 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3523
3524 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3525 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3526 }
3527#endif
3528#ifdef WLAN_FEATURE_VOWIFI_11R
3529 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3530 {
3531 tANI_U8 *value = command;
3532 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3533
3534 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3535 value = value + 18;
3536 /* Convert the value from ascii to integer */
3537 ret = kstrtou8(value, 10, &ft);
3538 if (ret < 0)
3539 {
3540 /* If the input value is greater than max value of datatype, then also
3541 kstrtou8 fails */
3542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3543 "%s: kstrtou8 failed range [%d - %d]", __func__,
3544 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3545 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3546 ret = -EINVAL;
3547 goto exit;
3548 }
3549
3550 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3551 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3552 {
3553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3554 "ft mode value %d is out of range"
3555 " (Min: %d Max: %d)", ft,
3556 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3557 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3558 ret = -EINVAL;
3559 goto exit;
3560 }
3561
3562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3563 "%s: Received Command to change ft mode = %d", __func__, ft);
3564
3565 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3566 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3567 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303568 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3569 {
3570 tANI_U8 *value = command;
3571 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303572
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303573 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3574 value = value + 15;
3575 /* Convert the value from ascii to integer */
3576 ret = kstrtou8(value, 10, &dfsScanMode);
3577 if (ret < 0)
3578 {
3579 /* If the input value is greater than max value of
3580 datatype, then also kstrtou8 fails
3581 */
3582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3583 "%s: kstrtou8 failed range [%d - %d]", __func__,
3584 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3585 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3586 ret = -EINVAL;
3587 goto exit;
3588 }
3589
3590 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3591 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3592 {
3593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3594 "dfsScanMode value %d is out of range"
3595 " (Min: %d Max: %d)", dfsScanMode,
3596 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3597 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3598 ret = -EINVAL;
3599 goto exit;
3600 }
3601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3602 "%s: Received Command to Set DFS Scan Mode = %d",
3603 __func__, dfsScanMode);
3604
3605 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3606 }
3607 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3608 {
3609 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3610 char extra[32];
3611 tANI_U8 len = 0;
3612
3613 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3614 if (copy_to_user(priv_data.buf, &extra, len + 1))
3615 {
3616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3617 "%s: failed to copy data to user buffer", __func__);
3618 ret = -EFAULT;
3619 goto exit;
3620 }
3621 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303622 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3623 {
3624 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303625 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303626 tSirMacAddr targetApBssid;
3627 tANI_U8 trigger = 0;
3628 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303629 tHalHandle hHal;
3630 v_U32_t roamId = 0;
3631 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303632 hdd_station_ctx_t *pHddStaCtx = NULL;
3633 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303634 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303635
3636 /* if not associated, no need to proceed with reassoc */
3637 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3638 {
3639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3640 ret = -EINVAL;
3641 goto exit;
3642 }
3643
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303644 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303645 if (eHAL_STATUS_SUCCESS != status)
3646 {
3647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3648 "%s: Failed to parse reassoc command data", __func__);
3649 ret = -EINVAL;
3650 goto exit;
3651 }
3652
3653 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303654 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303655 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3656 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3657 {
3658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3659 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3660 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303661 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3662 &modProfileFields);
3663 sme_RoamReassoc(hHal, pAdapter->sessionId,
3664 NULL, modProfileFields, &roamId, 1);
3665 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303666 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303667
3668 /* Check channel number is a valid channel number */
3669 if(VOS_STATUS_SUCCESS !=
3670 wlan_hdd_validate_operation_channel(pAdapter, channel))
3671 {
3672 hddLog(VOS_TRACE_LEVEL_ERROR,
3673 "%s: Invalid Channel [%d]", __func__, channel);
3674 return -EINVAL;
3675 }
3676
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303677 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303678
3679 /* Proceed with scan/roam */
3680 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3681 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303682 (tSmeFastRoamTrigger)(trigger),
3683 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303684 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003685#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003686#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003687 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3688 {
3689 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003690 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003691
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003692 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003693 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003694 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003695 hdd_is_okc_mode_enabled(pHddCtx) &&
3696 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3697 {
3698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003699 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003700 " hence this operation is not permitted!", __func__);
3701 ret = -EPERM;
3702 goto exit;
3703 }
3704
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003705 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3706 value = value + 11;
3707 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003708 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003709 if (ret < 0)
3710 {
3711 /* If the input value is greater than max value of datatype, then also
3712 kstrtou8 fails */
3713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3714 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003715 CFG_ESE_FEATURE_ENABLED_MIN,
3716 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003717 ret = -EINVAL;
3718 goto exit;
3719 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003720 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3721 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003722 {
3723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003724 "Ese mode value %d is out of range"
3725 " (Min: %d Max: %d)", eseMode,
3726 CFG_ESE_FEATURE_ENABLED_MIN,
3727 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003728 ret = -EINVAL;
3729 goto exit;
3730 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003732 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003733
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003734 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3735 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003736 }
3737#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003738 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3739 {
3740 tANI_U8 *value = command;
3741 tANI_BOOLEAN roamScanControl = 0;
3742
3743 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3744 value = value + 19;
3745 /* Convert the value from ascii to integer */
3746 ret = kstrtou8(value, 10, &roamScanControl);
3747 if (ret < 0)
3748 {
3749 /* If the input value is greater than max value of datatype, then also
3750 kstrtou8 fails */
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "%s: kstrtou8 failed ", __func__);
3753 ret = -EINVAL;
3754 goto exit;
3755 }
3756
3757 if (0 != roamScanControl)
3758 {
3759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3760 "roam scan control invalid value = %d",
3761 roamScanControl);
3762 ret = -EINVAL;
3763 goto exit;
3764 }
3765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3766 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3767
3768 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3769 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003770#ifdef FEATURE_WLAN_OKC
3771 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3772 {
3773 tANI_U8 *value = command;
3774 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3775
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003776 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003777 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003778 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003779 hdd_is_okc_mode_enabled(pHddCtx) &&
3780 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3781 {
3782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003783 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003784 " hence this operation is not permitted!", __func__);
3785 ret = -EPERM;
3786 goto exit;
3787 }
3788
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003789 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3790 value = value + 11;
3791 /* Convert the value from ascii to integer */
3792 ret = kstrtou8(value, 10, &okcMode);
3793 if (ret < 0)
3794 {
3795 /* If the input value is greater than max value of datatype, then also
3796 kstrtou8 fails */
3797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3798 "%s: kstrtou8 failed range [%d - %d]", __func__,
3799 CFG_OKC_FEATURE_ENABLED_MIN,
3800 CFG_OKC_FEATURE_ENABLED_MAX);
3801 ret = -EINVAL;
3802 goto exit;
3803 }
3804
3805 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3806 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3807 {
3808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3809 "Okc mode value %d is out of range"
3810 " (Min: %d Max: %d)", okcMode,
3811 CFG_OKC_FEATURE_ENABLED_MIN,
3812 CFG_OKC_FEATURE_ENABLED_MAX);
3813 ret = -EINVAL;
3814 goto exit;
3815 }
3816
3817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3818 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3819
3820 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3821 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003822#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303823 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003824 {
3825 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3826 char extra[32];
3827 tANI_U8 len = 0;
3828
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003829 len = scnprintf(extra, sizeof(extra), "%s %d",
3830 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003831 if (copy_to_user(priv_data.buf, &extra, len + 1))
3832 {
3833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3834 "%s: failed to copy data to user buffer", __func__);
3835 ret = -EFAULT;
3836 goto exit;
3837 }
3838 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303839#ifdef WLAN_FEATURE_PACKET_FILTERING
3840 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3841 {
3842 tANI_U8 filterType = 0;
3843 tANI_U8 *value = command;
3844
3845 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3846 value = value + 22;
3847
3848 /* Convert the value from ascii to integer */
3849 ret = kstrtou8(value, 10, &filterType);
3850 if (ret < 0)
3851 {
3852 /* If the input value is greater than max value of datatype,
3853 * then also kstrtou8 fails
3854 */
3855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3856 "%s: kstrtou8 failed range ", __func__);
3857 ret = -EINVAL;
3858 goto exit;
3859 }
3860
3861 if (filterType != 0 && filterType != 1)
3862 {
3863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3864 "%s: Accepted Values are 0 and 1 ", __func__);
3865 ret = -EINVAL;
3866 goto exit;
3867 }
3868 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3869 pAdapter->sessionId);
3870 }
3871#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303872 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3873 {
Kiet Lamad161252014-07-22 11:23:32 -07003874 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303875 int ret;
3876
Kiet Lamad161252014-07-22 11:23:32 -07003877 dhcpPhase = command + 11;
3878 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303879 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003881 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303882
3883 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003884
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303885 ret = wlan_hdd_scan_abort(pAdapter);
3886 if (ret < 0)
3887 {
3888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3889 FL("failed to abort existing scan %d"), ret);
3890 }
3891
Kiet Lamad161252014-07-22 11:23:32 -07003892 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3893 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303894 }
Kiet Lamad161252014-07-22 11:23:32 -07003895 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303896 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003898 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303899
3900 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003901
3902 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3903 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303904 }
3905 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003906 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3907 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3909 FL("making default scan to ACTIVE"));
3910 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003911 }
3912 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3913 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3915 FL("making default scan to PASSIVE"));
3916 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003917 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303918 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3919 {
3920 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3921 char extra[32];
3922 tANI_U8 len = 0;
3923
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303924 memset(extra, 0, sizeof(extra));
3925 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3926 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303927 {
3928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3929 "%s: failed to copy data to user buffer", __func__);
3930 ret = -EFAULT;
3931 goto exit;
3932 }
3933 ret = len;
3934 }
3935 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3936 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303937 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303938 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003939 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3940 {
3941 tANI_U8 filterType = 0;
3942 tANI_U8 *value;
3943 value = command + 9;
3944
3945 /* Convert the value from ascii to integer */
3946 ret = kstrtou8(value, 10, &filterType);
3947 if (ret < 0)
3948 {
3949 /* If the input value is greater than max value of datatype,
3950 * then also kstrtou8 fails
3951 */
3952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3953 "%s: kstrtou8 failed range ", __func__);
3954 ret = -EINVAL;
3955 goto exit;
3956 }
3957 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3958 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3959 {
3960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3961 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3962 " 2-Sink ", __func__);
3963 ret = -EINVAL;
3964 goto exit;
3965 }
3966 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3967 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303968 pScanInfo = &pHddCtx->scan_info;
3969 if (filterType && pScanInfo != NULL &&
3970 pHddCtx->scan_info.mScanPending)
3971 {
3972 /*Miracast Session started. Abort Scan */
3973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3974 "%s, Aborting Scan For Miracast",__func__);
3975 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3976 eCSR_SCAN_ABORT_DEFAULT);
3977 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003978 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303979 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003980 }
Leo Chang614d2072013-08-22 14:59:44 -07003981 else if (strncmp(command, "SETMCRATE", 9) == 0)
3982 {
Leo Chang614d2072013-08-22 14:59:44 -07003983 tANI_U8 *value = command;
3984 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003985 tSirRateUpdateInd *rateUpdate;
3986 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003987
3988 /* Only valid for SAP mode */
3989 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3990 {
3991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3992 "%s: SAP mode is not running", __func__);
3993 ret = -EFAULT;
3994 goto exit;
3995 }
3996
3997 /* Move pointer to ahead of SETMCRATE<delimiter> */
3998 /* input value is in units of hundred kbps */
3999 value = value + 10;
4000 /* Convert the value from ascii to integer, decimal base */
4001 ret = kstrtouint(value, 10, &targetRate);
4002
Leo Chang1f98cbd2013-10-17 15:03:52 -07004003 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4004 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004005 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004006 hddLog(VOS_TRACE_LEVEL_ERROR,
4007 "%s: SETMCRATE indication alloc fail", __func__);
4008 ret = -EFAULT;
4009 goto exit;
4010 }
4011 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4012
4013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4014 "MC Target rate %d", targetRate);
4015 /* Ignore unicast */
4016 rateUpdate->ucastDataRate = -1;
4017 rateUpdate->mcastDataRate24GHz = targetRate;
4018 rateUpdate->mcastDataRate5GHz = targetRate;
4019 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4020 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4021 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4022 if (eHAL_STATUS_SUCCESS != status)
4023 {
4024 hddLog(VOS_TRACE_LEVEL_ERROR,
4025 "%s: SET_MC_RATE failed", __func__);
4026 vos_mem_free(rateUpdate);
4027 ret = -EFAULT;
4028 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004029 }
4030 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304031#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004032 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304033 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004034 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304035 }
4036#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004037#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004038 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4039 {
4040 tANI_U8 *value = command;
4041 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4042 tANI_U8 numChannels = 0;
4043 eHalStatus status = eHAL_STATUS_SUCCESS;
4044
4045 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4046 if (eHAL_STATUS_SUCCESS != status)
4047 {
4048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4049 "%s: Failed to parse channel list information", __func__);
4050 ret = -EINVAL;
4051 goto exit;
4052 }
4053
4054 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4055 {
4056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4057 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4058 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4059 ret = -EINVAL;
4060 goto exit;
4061 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004062 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004063 ChannelList,
4064 numChannels);
4065 if (eHAL_STATUS_SUCCESS != status)
4066 {
4067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4068 "%s: Failed to update channel list information", __func__);
4069 ret = -EINVAL;
4070 goto exit;
4071 }
4072 }
4073 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4074 {
4075 tANI_U8 *value = command;
4076 char extra[128] = {0};
4077 int len = 0;
4078 tANI_U8 tid = 0;
4079 hdd_station_ctx_t *pHddStaCtx = NULL;
4080 tAniTrafStrmMetrics tsmMetrics;
4081 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4082
4083 /* if not associated, return error */
4084 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4085 {
4086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4087 ret = -EINVAL;
4088 goto exit;
4089 }
4090
4091 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4092 value = value + 12;
4093 /* Convert the value from ascii to integer */
4094 ret = kstrtou8(value, 10, &tid);
4095 if (ret < 0)
4096 {
4097 /* If the input value is greater than max value of datatype, then also
4098 kstrtou8 fails */
4099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4100 "%s: kstrtou8 failed range [%d - %d]", __func__,
4101 TID_MIN_VALUE,
4102 TID_MAX_VALUE);
4103 ret = -EINVAL;
4104 goto exit;
4105 }
4106
4107 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4108 {
4109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4110 "tid value %d is out of range"
4111 " (Min: %d Max: %d)", tid,
4112 TID_MIN_VALUE,
4113 TID_MAX_VALUE);
4114 ret = -EINVAL;
4115 goto exit;
4116 }
4117
4118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4119 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4120
4121 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4122 {
4123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4124 "%s: failed to get tsm stats", __func__);
4125 ret = -EFAULT;
4126 goto exit;
4127 }
4128
4129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4130 "UplinkPktQueueDly(%d)\n"
4131 "UplinkPktQueueDlyHist[0](%d)\n"
4132 "UplinkPktQueueDlyHist[1](%d)\n"
4133 "UplinkPktQueueDlyHist[2](%d)\n"
4134 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304135 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004136 "UplinkPktLoss(%d)\n"
4137 "UplinkPktCount(%d)\n"
4138 "RoamingCount(%d)\n"
4139 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4140 tsmMetrics.UplinkPktQueueDlyHist[0],
4141 tsmMetrics.UplinkPktQueueDlyHist[1],
4142 tsmMetrics.UplinkPktQueueDlyHist[2],
4143 tsmMetrics.UplinkPktQueueDlyHist[3],
4144 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4145 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4146
4147 /* Output TSM stats is of the format
4148 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4149 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004150 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004151 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4152 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4153 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4154 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4155 tsmMetrics.RoamingDly);
4156
4157 if (copy_to_user(priv_data.buf, &extra, len + 1))
4158 {
4159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4160 "%s: failed to copy data to user buffer", __func__);
4161 ret = -EFAULT;
4162 goto exit;
4163 }
4164 }
4165 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4166 {
4167 tANI_U8 *value = command;
4168 tANI_U8 *cckmIe = NULL;
4169 tANI_U8 cckmIeLen = 0;
4170 eHalStatus status = eHAL_STATUS_SUCCESS;
4171
4172 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4173 if (eHAL_STATUS_SUCCESS != status)
4174 {
4175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4176 "%s: Failed to parse cckm ie data", __func__);
4177 ret = -EINVAL;
4178 goto exit;
4179 }
4180
4181 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4182 {
4183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4184 "%s: CCKM Ie input length is more than max[%d]", __func__,
4185 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004186 vos_mem_free(cckmIe);
4187 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004188 ret = -EINVAL;
4189 goto exit;
4190 }
4191 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004192 vos_mem_free(cckmIe);
4193 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004194 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004195 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4196 {
4197 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004198 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004199 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004200
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004201 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004202 if (eHAL_STATUS_SUCCESS != status)
4203 {
4204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004205 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004206 ret = -EINVAL;
4207 goto exit;
4208 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004209 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4210 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4211 hdd_indicateEseBcnReportNoResults (pAdapter,
4212 eseBcnReq.bcnReq[0].measurementToken,
4213 0x02, //BIT(1) set for measurement done
4214 0); // no BSS
4215 goto exit;
4216 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004217
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004218 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4219 if (eHAL_STATUS_SUCCESS != status)
4220 {
4221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4222 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4223 ret = -EINVAL;
4224 goto exit;
4225 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004226 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004227#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304228 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4229 {
4230 eHalStatus status;
4231 char buf[32], len;
4232 long waitRet;
4233 bcnMissRateContext_t getBcnMissRateCtx;
4234
4235 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4236
4237 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4238 {
4239 hddLog(VOS_TRACE_LEVEL_WARN,
4240 FL("GETBCNMISSRATE: STA is not in connected state"));
4241 ret = -1;
4242 goto exit;
4243 }
4244
4245 init_completion(&(getBcnMissRateCtx.completion));
4246 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4247
4248 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4249 pAdapter->sessionId,
4250 (void *)getBcnMissRateCB,
4251 (void *)(&getBcnMissRateCtx));
4252 if( eHAL_STATUS_SUCCESS != status)
4253 {
4254 hddLog(VOS_TRACE_LEVEL_INFO,
4255 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4256 ret = -EINVAL;
4257 goto exit;
4258 }
4259
4260 waitRet = wait_for_completion_interruptible_timeout
4261 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4262 if(waitRet <= 0)
4263 {
4264 hddLog(VOS_TRACE_LEVEL_ERROR,
4265 FL("failed to wait on bcnMissRateComp %d"), ret);
4266
4267 //Make magic number to zero so that callback is not called.
4268 spin_lock(&hdd_context_lock);
4269 getBcnMissRateCtx.magic = 0x0;
4270 spin_unlock(&hdd_context_lock);
4271 ret = -EINVAL;
4272 goto exit;
4273 }
4274
4275 hddLog(VOS_TRACE_LEVEL_INFO,
4276 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4277
4278 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4279 if (copy_to_user(priv_data.buf, &buf, len + 1))
4280 {
4281 hddLog(VOS_TRACE_LEVEL_ERROR,
4282 "%s: failed to copy data to user buffer", __func__);
4283 ret = -EFAULT;
4284 goto exit;
4285 }
4286 ret = len;
4287 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304288#ifdef FEATURE_WLAN_TDLS
4289 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4290 tANI_U8 *value = command;
4291 int set_value;
4292 /* Move pointer to ahead of TDLSOFFCH*/
4293 value += 26;
4294 sscanf(value, "%d", &set_value);
4295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4296 "%s: Tdls offchannel offset:%d",
4297 __func__, set_value);
4298 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4299 if (ret < 0)
4300 {
4301 ret = -EINVAL;
4302 goto exit;
4303 }
4304
4305 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4306 tANI_U8 *value = command;
4307 int set_value;
4308 /* Move pointer to ahead of tdlsoffchnmode*/
4309 value += 18;
4310 sscanf(value, "%d", &set_value);
4311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4312 "%s: Tdls offchannel mode:%d",
4313 __func__, set_value);
4314 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4315 if (ret < 0)
4316 {
4317 ret = -EINVAL;
4318 goto exit;
4319 }
4320 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4321 tANI_U8 *value = command;
4322 int set_value;
4323 /* Move pointer to ahead of TDLSOFFCH*/
4324 value += 14;
4325 sscanf(value, "%d", &set_value);
4326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4327 "%s: Tdls offchannel num: %d",
4328 __func__, set_value);
4329 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4330 if (ret < 0)
4331 {
4332 ret = -EINVAL;
4333 goto exit;
4334 }
4335 }
4336#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304337 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4338 {
4339 eHalStatus status;
4340 char *buf = NULL;
4341 char len;
4342 long waitRet;
4343 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304344 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304345 tANI_U8 *ptr = command;
4346 int stats = *(ptr + 11) - '0';
4347
4348 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4349 if (!IS_FEATURE_FW_STATS_ENABLE)
4350 {
4351 hddLog(VOS_TRACE_LEVEL_INFO,
4352 FL("Get Firmware stats feature not supported"));
4353 ret = -EINVAL;
4354 goto exit;
4355 }
4356
4357 if (FW_STATS_MAX <= stats || 0 >= stats)
4358 {
4359 hddLog(VOS_TRACE_LEVEL_INFO,
4360 FL(" stats %d not supported"),stats);
4361 ret = -EINVAL;
4362 goto exit;
4363 }
4364
4365 init_completion(&(fwStatsCtx.completion));
4366 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4367 fwStatsCtx.pAdapter = pAdapter;
4368 fwStatsRsp->type = 0;
4369 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304370 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304371 if (eHAL_STATUS_SUCCESS != status)
4372 {
4373 hddLog(VOS_TRACE_LEVEL_ERROR,
4374 FL(" fail to post WDA cmd status = %d"), status);
4375 ret = -EINVAL;
4376 goto exit;
4377 }
4378 waitRet = wait_for_completion_timeout
4379 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4380 if (waitRet <= 0)
4381 {
4382 hddLog(VOS_TRACE_LEVEL_ERROR,
4383 FL("failed to wait on GwtFwstats"));
4384 //Make magic number to zero so that callback is not executed.
4385 spin_lock(&hdd_context_lock);
4386 fwStatsCtx.magic = 0x0;
4387 spin_unlock(&hdd_context_lock);
4388 ret = -EINVAL;
4389 goto exit;
4390 }
4391 if (fwStatsRsp->type)
4392 {
4393 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4394 if (!buf)
4395 {
4396 hddLog(VOS_TRACE_LEVEL_ERROR,
4397 FL(" failed to allocate memory"));
4398 ret = -ENOMEM;
4399 goto exit;
4400 }
4401 switch( fwStatsRsp->type )
4402 {
4403 case FW_UBSP_STATS:
4404 {
4405 len = snprintf(buf, FW_STATE_RSP_LEN,
4406 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304407 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4408 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304409 }
4410 break;
4411 default:
4412 {
4413 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4414 ret = -EFAULT;
4415 kfree(buf);
4416 goto exit;
4417 }
4418 }
4419 if (copy_to_user(priv_data.buf, buf, len + 1))
4420 {
4421 hddLog(VOS_TRACE_LEVEL_ERROR,
4422 FL(" failed to copy data to user buffer"));
4423 ret = -EFAULT;
4424 kfree(buf);
4425 goto exit;
4426 }
4427 ret = len;
4428 kfree(buf);
4429 }
4430 else
4431 {
4432 hddLog(VOS_TRACE_LEVEL_ERROR,
4433 FL("failed to fetch the stats"));
4434 ret = -EFAULT;
4435 goto exit;
4436 }
4437
4438 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304439 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4440 {
4441 /*
4442 * this command wld be called by user-space when it detects WLAN
4443 * ON after airplane mode is set. When APM is set, WLAN turns off.
4444 * But it can be turned back on. Otherwise; when APM is turned back
4445 * off, WLAN wld turn back on. So at that point the command is
4446 * expected to come down. 0 means disable, 1 means enable. The
4447 * constraint is removed when parameter 1 is set or different
4448 * country code is set
4449 */
4450 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4451 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004452 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4454 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4455 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304456 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4457 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004459 }
4460exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304461 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004462 if (command)
4463 {
4464 kfree(command);
4465 }
4466 return ret;
4467}
4468
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004469#ifdef CONFIG_COMPAT
4470static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4471{
4472 struct {
4473 compat_uptr_t buf;
4474 int used_len;
4475 int total_len;
4476 } compat_priv_data;
4477 hdd_priv_data_t priv_data;
4478 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004479
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004480 /*
4481 * Note that pAdapter and ifr have already been verified by caller,
4482 * and HDD context has also been validated
4483 */
4484 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4485 sizeof(compat_priv_data))) {
4486 ret = -EFAULT;
4487 goto exit;
4488 }
4489 priv_data.buf = compat_ptr(compat_priv_data.buf);
4490 priv_data.used_len = compat_priv_data.used_len;
4491 priv_data.total_len = compat_priv_data.total_len;
4492 ret = hdd_driver_command(pAdapter, &priv_data);
4493 exit:
4494 return ret;
4495}
4496#else /* CONFIG_COMPAT */
4497static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4498{
4499 /* will never be invoked */
4500 return 0;
4501}
4502#endif /* CONFIG_COMPAT */
4503
4504static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4505{
4506 hdd_priv_data_t priv_data;
4507 int ret = 0;
4508
4509 /*
4510 * Note that pAdapter and ifr have already been verified by caller,
4511 * and HDD context has also been validated
4512 */
4513 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4514 ret = -EFAULT;
4515 } else {
4516 ret = hdd_driver_command(pAdapter, &priv_data);
4517 }
4518 return ret;
4519}
4520
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304521int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004522{
4523 hdd_adapter_t *pAdapter;
4524 hdd_context_t *pHddCtx;
4525 int ret;
4526
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304527 ENTER();
4528
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004529 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4530 if (NULL == pAdapter) {
4531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4532 "%s: HDD adapter context is Null", __func__);
4533 ret = -ENODEV;
4534 goto exit;
4535 }
4536 if (dev != pAdapter->dev) {
4537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4538 "%s: HDD adapter/dev inconsistency", __func__);
4539 ret = -ENODEV;
4540 goto exit;
4541 }
4542
4543 if ((!ifr) || (!ifr->ifr_data)) {
4544 ret = -EINVAL;
4545 goto exit;
4546 }
4547
4548 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4549 ret = wlan_hdd_validate_context(pHddCtx);
4550 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004551 ret = -EBUSY;
4552 goto exit;
4553 }
4554
4555 switch (cmd) {
4556 case (SIOCDEVPRIVATE + 1):
4557 if (is_compat_task())
4558 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4559 else
4560 ret = hdd_driver_ioctl(pAdapter, ifr);
4561 break;
4562 default:
4563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4564 __func__, cmd);
4565 ret = -EINVAL;
4566 break;
4567 }
4568 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304569 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004570 return ret;
4571}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004572
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304573int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4574{
4575 int ret;
4576
4577 vos_ssr_protect(__func__);
4578 ret = __hdd_ioctl(dev, ifr, cmd);
4579 vos_ssr_unprotect(__func__);
4580
4581 return ret;
4582}
4583
Katya Nigame7b69a82015-04-28 15:24:06 +05304584int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4585{
4586 return 0;
4587}
4588
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004589#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004590/**---------------------------------------------------------------------------
4591
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004592 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004593
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004594 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004595 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4596 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4597 <space>Scan Mode N<space>Meas Duration N
4598 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4599 then take N.
4600 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4601 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4602 This function does not take care of removing duplicate channels from the list
4603
4604 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004605 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004606
4607 \return - 0 for success non-zero for failure
4608
4609 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004610static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4611 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004612{
4613 tANI_U8 *inPtr = pValue;
4614 int tempInt = 0;
4615 int j = 0, i = 0, v = 0;
4616 char buf[32];
4617
4618 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4619 /*no argument after the command*/
4620 if (NULL == inPtr)
4621 {
4622 return -EINVAL;
4623 }
4624 /*no space after the command*/
4625 else if (SPACE_ASCII_VALUE != *inPtr)
4626 {
4627 return -EINVAL;
4628 }
4629
4630 /*removing empty spaces*/
4631 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4632
4633 /*no argument followed by spaces*/
4634 if ('\0' == *inPtr) return -EINVAL;
4635
4636 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004637 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004638 if (1 != v) return -EINVAL;
4639
4640 v = kstrtos32(buf, 10, &tempInt);
4641 if ( v < 0) return -EINVAL;
4642
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004643 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004644
4645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004646 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004647
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004648 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004649 {
4650 for (i = 0; i < 4; i++)
4651 {
4652 /*inPtr pointing to the beginning of first space after number of ie fields*/
4653 inPtr = strpbrk( inPtr, " " );
4654 /*no ie data after the number of ie fields argument*/
4655 if (NULL == inPtr) return -EINVAL;
4656
4657 /*removing empty space*/
4658 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4659
4660 /*no ie data after the number of ie fields argument and spaces*/
4661 if ( '\0' == *inPtr ) return -EINVAL;
4662
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004663 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004664 if (1 != v) return -EINVAL;
4665
4666 v = kstrtos32(buf, 10, &tempInt);
4667 if (v < 0) return -EINVAL;
4668
4669 switch (i)
4670 {
4671 case 0: /* Measurement token */
4672 if (tempInt <= 0)
4673 {
4674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4675 "Invalid Measurement Token(%d)", tempInt);
4676 return -EINVAL;
4677 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004678 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004679 break;
4680
4681 case 1: /* Channel number */
4682 if ((tempInt <= 0) ||
4683 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4684 {
4685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4686 "Invalid Channel Number(%d)", tempInt);
4687 return -EINVAL;
4688 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004689 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004690 break;
4691
4692 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004693 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004694 {
4695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4696 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4697 return -EINVAL;
4698 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004699 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004700 break;
4701
4702 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004703 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4704 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004705 {
4706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4707 "Invalid Measurement Duration(%d)", tempInt);
4708 return -EINVAL;
4709 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004710 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004711 break;
4712 }
4713 }
4714 }
4715
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004716 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004717 {
4718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304719 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004720 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004721 pEseBcnReq->bcnReq[j].measurementToken,
4722 pEseBcnReq->bcnReq[j].channel,
4723 pEseBcnReq->bcnReq[j].scanMode,
4724 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004725 }
4726
4727 return VOS_STATUS_SUCCESS;
4728}
4729
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004730static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4731{
4732 struct statsContext *pStatsContext = NULL;
4733 hdd_adapter_t *pAdapter = NULL;
4734
4735 if (NULL == pContext)
4736 {
4737 hddLog(VOS_TRACE_LEVEL_ERROR,
4738 "%s: Bad param, pContext [%p]",
4739 __func__, pContext);
4740 return;
4741 }
4742
Jeff Johnson72a40512013-12-19 10:14:15 -08004743 /* there is a race condition that exists between this callback
4744 function and the caller since the caller could time out either
4745 before or while this code is executing. we use a spinlock to
4746 serialize these actions */
4747 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004748
4749 pStatsContext = pContext;
4750 pAdapter = pStatsContext->pAdapter;
4751 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4752 {
4753 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004754 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004755 hddLog(VOS_TRACE_LEVEL_WARN,
4756 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4757 __func__, pAdapter, pStatsContext->magic);
4758 return;
4759 }
4760
Jeff Johnson72a40512013-12-19 10:14:15 -08004761 /* context is valid so caller is still waiting */
4762
4763 /* paranoia: invalidate the magic */
4764 pStatsContext->magic = 0;
4765
4766 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004767 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4768 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4769 tsmMetrics.UplinkPktQueueDlyHist,
4770 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4771 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4772 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4773 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4774 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4775 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4776 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4777
Jeff Johnson72a40512013-12-19 10:14:15 -08004778 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004779 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004780
4781 /* serialization is complete */
4782 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004783}
4784
4785
4786
4787static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4788 tAniTrafStrmMetrics* pTsmMetrics)
4789{
4790 hdd_station_ctx_t *pHddStaCtx = NULL;
4791 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004792 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004793 long lrc;
4794 struct statsContext context;
4795 hdd_context_t *pHddCtx = NULL;
4796
4797 if (NULL == pAdapter)
4798 {
4799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4800 return VOS_STATUS_E_FAULT;
4801 }
4802
4803 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4804 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4805
4806 /* we are connected prepare our callback context */
4807 init_completion(&context.completion);
4808 context.pAdapter = pAdapter;
4809 context.magic = STATS_CONTEXT_MAGIC;
4810
4811 /* query tsm stats */
4812 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4813 pHddStaCtx->conn_info.staId[ 0 ],
4814 pHddStaCtx->conn_info.bssId,
4815 &context, pHddCtx->pvosContext, tid);
4816
4817 if (eHAL_STATUS_SUCCESS != hstatus)
4818 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4820 __func__);
4821 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004822 }
4823 else
4824 {
4825 /* request was sent -- wait for the response */
4826 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4827 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004828 if (lrc <= 0)
4829 {
4830 hddLog(VOS_TRACE_LEVEL_ERROR,
4831 "%s: SME %s while retrieving statistics",
4832 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004833 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004834 }
4835 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004836
Jeff Johnson72a40512013-12-19 10:14:15 -08004837 /* either we never sent a request, we sent a request and received a
4838 response or we sent a request and timed out. if we never sent a
4839 request or if we sent a request and got a response, we want to
4840 clear the magic out of paranoia. if we timed out there is a
4841 race condition such that the callback function could be
4842 executing at the same time we are. of primary concern is if the
4843 callback function had already verified the "magic" but had not
4844 yet set the completion variable when a timeout occurred. we
4845 serialize these activities by invalidating the magic while
4846 holding a shared spinlock which will cause us to block if the
4847 callback is currently executing */
4848 spin_lock(&hdd_context_lock);
4849 context.magic = 0;
4850 spin_unlock(&hdd_context_lock);
4851
4852 if (VOS_STATUS_SUCCESS == vstatus)
4853 {
4854 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4855 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4856 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4857 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4858 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4859 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4860 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4861 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4862 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4863 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4864 }
4865 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004866}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004867#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004868
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004869#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004870void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4871{
4872 eCsrBand band = -1;
4873 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4874 switch (band)
4875 {
4876 case eCSR_BAND_ALL:
4877 *pBand = WLAN_HDD_UI_BAND_AUTO;
4878 break;
4879
4880 case eCSR_BAND_24:
4881 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4882 break;
4883
4884 case eCSR_BAND_5G:
4885 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4886 break;
4887
4888 default:
4889 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4890 *pBand = -1;
4891 break;
4892 }
4893}
4894
4895/**---------------------------------------------------------------------------
4896
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004897 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4898
4899 This function parses the send action frame data passed in the format
4900 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4901
Srinivas Girigowda56076852013-08-20 14:00:50 -07004902 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004903 \param - pTargetApBssid Pointer to target Ap bssid
4904 \param - pChannel Pointer to the Target AP channel
4905 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4906 \param - pBuf Pointer to data
4907 \param - pBufLen Pointer to data length
4908
4909 \return - 0 for success non-zero for failure
4910
4911 --------------------------------------------------------------------------*/
4912VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4913 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4914{
4915 tANI_U8 *inPtr = pValue;
4916 tANI_U8 *dataEnd;
4917 int tempInt;
4918 int j = 0;
4919 int i = 0;
4920 int v = 0;
4921 tANI_U8 tempBuf[32];
4922 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004923 /* 12 hexa decimal digits, 5 ':' and '\0' */
4924 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004925
4926 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4927 /*no argument after the command*/
4928 if (NULL == inPtr)
4929 {
4930 return -EINVAL;
4931 }
4932
4933 /*no space after the command*/
4934 else if (SPACE_ASCII_VALUE != *inPtr)
4935 {
4936 return -EINVAL;
4937 }
4938
4939 /*removing empty spaces*/
4940 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4941
4942 /*no argument followed by spaces*/
4943 if ('\0' == *inPtr)
4944 {
4945 return -EINVAL;
4946 }
4947
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004948 v = sscanf(inPtr, "%17s", macAddress);
4949 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004950 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4952 "Invalid MAC address or All hex inputs are not read (%d)", v);
4953 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004954 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004955
4956 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4957 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4958 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4959 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4960 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4961 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004962
4963 /* point to the next argument */
4964 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4965 /*no argument after the command*/
4966 if (NULL == inPtr) return -EINVAL;
4967
4968 /*removing empty spaces*/
4969 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4970
4971 /*no argument followed by spaces*/
4972 if ('\0' == *inPtr)
4973 {
4974 return -EINVAL;
4975 }
4976
4977 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004978 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004979 if (1 != v) return -EINVAL;
4980
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004981 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304982 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304983 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004984
4985 *pChannel = tempInt;
4986
4987 /* point to the next argument */
4988 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4989 /*no argument after the command*/
4990 if (NULL == inPtr) return -EINVAL;
4991 /*removing empty spaces*/
4992 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4993
4994 /*no argument followed by spaces*/
4995 if ('\0' == *inPtr)
4996 {
4997 return -EINVAL;
4998 }
4999
5000 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005001 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005002 if (1 != v) return -EINVAL;
5003
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005004 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005005 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005006
5007 *pDwellTime = tempInt;
5008
5009 /* point to the next argument */
5010 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5011 /*no argument after the command*/
5012 if (NULL == inPtr) return -EINVAL;
5013 /*removing empty spaces*/
5014 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5015
5016 /*no argument followed by spaces*/
5017 if ('\0' == *inPtr)
5018 {
5019 return -EINVAL;
5020 }
5021
5022 /* find the length of data */
5023 dataEnd = inPtr;
5024 while(('\0' != *dataEnd) )
5025 {
5026 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005027 }
Kiet Lambe150c22013-11-21 16:30:32 +05305028 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005029 if ( *pBufLen <= 0) return -EINVAL;
5030
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005031 /* Allocate the number of bytes based on the number of input characters
5032 whether it is even or odd.
5033 if the number of input characters are even, then we need N/2 byte.
5034 if the number of input characters are odd, then we need do (N+1)/2 to
5035 compensate rounding off.
5036 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5037 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5038 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005039 if (NULL == *pBuf)
5040 {
5041 hddLog(VOS_TRACE_LEVEL_FATAL,
5042 "%s: vos_mem_alloc failed ", __func__);
5043 return -EINVAL;
5044 }
5045
5046 /* the buffer received from the upper layer is character buffer,
5047 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5048 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5049 and f0 in 3rd location */
5050 for (i = 0, j = 0; j < *pBufLen; j += 2)
5051 {
Kiet Lambe150c22013-11-21 16:30:32 +05305052 if( j+1 == *pBufLen)
5053 {
5054 tempByte = hdd_parse_hex(inPtr[j]);
5055 }
5056 else
5057 {
5058 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5059 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005060 (*pBuf)[i++] = tempByte;
5061 }
5062 *pBufLen = i;
5063 return VOS_STATUS_SUCCESS;
5064}
5065
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005066/**---------------------------------------------------------------------------
5067
Srinivas Girigowdade697412013-02-14 16:31:48 -08005068 \brief hdd_parse_channellist() - HDD Parse channel list
5069
5070 This function parses the channel list passed in the format
5071 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005072 if the Number of channels (N) does not match with the actual number of channels passed
5073 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5074 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5075 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5076 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005077
5078 \param - pValue Pointer to input channel list
5079 \param - ChannelList Pointer to local output array to record channel list
5080 \param - pNumChannels Pointer to number of roam scan channels
5081
5082 \return - 0 for success non-zero for failure
5083
5084 --------------------------------------------------------------------------*/
5085VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5086{
5087 tANI_U8 *inPtr = pValue;
5088 int tempInt;
5089 int j = 0;
5090 int v = 0;
5091 char buf[32];
5092
5093 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5094 /*no argument after the command*/
5095 if (NULL == inPtr)
5096 {
5097 return -EINVAL;
5098 }
5099
5100 /*no space after the command*/
5101 else if (SPACE_ASCII_VALUE != *inPtr)
5102 {
5103 return -EINVAL;
5104 }
5105
5106 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005107 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005108
5109 /*no argument followed by spaces*/
5110 if ('\0' == *inPtr)
5111 {
5112 return -EINVAL;
5113 }
5114
5115 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005116 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005117 if (1 != v) return -EINVAL;
5118
Srinivas Girigowdade697412013-02-14 16:31:48 -08005119 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005120 if ((v < 0) ||
5121 (tempInt <= 0) ||
5122 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5123 {
5124 return -EINVAL;
5125 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005126
5127 *pNumChannels = tempInt;
5128
5129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5130 "Number of channels are: %d", *pNumChannels);
5131
5132 for (j = 0; j < (*pNumChannels); j++)
5133 {
5134 /*inPtr pointing to the beginning of first space after number of channels*/
5135 inPtr = strpbrk( inPtr, " " );
5136 /*no channel list after the number of channels argument*/
5137 if (NULL == inPtr)
5138 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005139 if (0 != j)
5140 {
5141 *pNumChannels = j;
5142 return VOS_STATUS_SUCCESS;
5143 }
5144 else
5145 {
5146 return -EINVAL;
5147 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005148 }
5149
5150 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005151 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005152
5153 /*no channel list after the number of channels argument and spaces*/
5154 if ( '\0' == *inPtr )
5155 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005156 if (0 != j)
5157 {
5158 *pNumChannels = j;
5159 return VOS_STATUS_SUCCESS;
5160 }
5161 else
5162 {
5163 return -EINVAL;
5164 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005165 }
5166
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005167 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005168 if (1 != v) return -EINVAL;
5169
Srinivas Girigowdade697412013-02-14 16:31:48 -08005170 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005171 if ((v < 0) ||
5172 (tempInt <= 0) ||
5173 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5174 {
5175 return -EINVAL;
5176 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005177 pChannelList[j] = tempInt;
5178
5179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5180 "Channel %d added to preferred channel list",
5181 pChannelList[j] );
5182 }
5183
Srinivas Girigowdade697412013-02-14 16:31:48 -08005184 return VOS_STATUS_SUCCESS;
5185}
5186
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005187
5188/**---------------------------------------------------------------------------
5189
5190 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5191
5192 This function parses the reasoc command data passed in the format
5193 REASSOC<space><bssid><space><channel>
5194
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005195 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005196 \param - pTargetApBssid Pointer to target Ap bssid
5197 \param - pChannel Pointer to the Target AP channel
5198
5199 \return - 0 for success non-zero for failure
5200
5201 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005202VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5203 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005204{
5205 tANI_U8 *inPtr = pValue;
5206 int tempInt;
5207 int v = 0;
5208 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005209 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005210 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005211
5212 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5213 /*no argument after the command*/
5214 if (NULL == inPtr)
5215 {
5216 return -EINVAL;
5217 }
5218
5219 /*no space after the command*/
5220 else if (SPACE_ASCII_VALUE != *inPtr)
5221 {
5222 return -EINVAL;
5223 }
5224
5225 /*removing empty spaces*/
5226 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5227
5228 /*no argument followed by spaces*/
5229 if ('\0' == *inPtr)
5230 {
5231 return -EINVAL;
5232 }
5233
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005234 v = sscanf(inPtr, "%17s", macAddress);
5235 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005236 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5238 "Invalid MAC address or All hex inputs are not read (%d)", v);
5239 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005240 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005241
5242 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5243 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5244 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5245 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5246 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5247 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005248
5249 /* point to the next argument */
5250 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5251 /*no argument after the command*/
5252 if (NULL == inPtr) return -EINVAL;
5253
5254 /*removing empty spaces*/
5255 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5256
5257 /*no argument followed by spaces*/
5258 if ('\0' == *inPtr)
5259 {
5260 return -EINVAL;
5261 }
5262
5263 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005264 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005265 if (1 != v) return -EINVAL;
5266
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005267 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005268 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305269 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005270 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5271 {
5272 return -EINVAL;
5273 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005274
5275 *pChannel = tempInt;
5276 return VOS_STATUS_SUCCESS;
5277}
5278
5279#endif
5280
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005281#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005282/**---------------------------------------------------------------------------
5283
5284 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5285
5286 This function parses the SETCCKM IE command
5287 SETCCKMIE<space><ie data>
5288
5289 \param - pValue Pointer to input data
5290 \param - pCckmIe Pointer to output cckm Ie
5291 \param - pCckmIeLen Pointer to output cckm ie length
5292
5293 \return - 0 for success non-zero for failure
5294
5295 --------------------------------------------------------------------------*/
5296VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5297 tANI_U8 *pCckmIeLen)
5298{
5299 tANI_U8 *inPtr = pValue;
5300 tANI_U8 *dataEnd;
5301 int j = 0;
5302 int i = 0;
5303 tANI_U8 tempByte = 0;
5304
5305 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5306 /*no argument after the command*/
5307 if (NULL == inPtr)
5308 {
5309 return -EINVAL;
5310 }
5311
5312 /*no space after the command*/
5313 else if (SPACE_ASCII_VALUE != *inPtr)
5314 {
5315 return -EINVAL;
5316 }
5317
5318 /*removing empty spaces*/
5319 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5320
5321 /*no argument followed by spaces*/
5322 if ('\0' == *inPtr)
5323 {
5324 return -EINVAL;
5325 }
5326
5327 /* find the length of data */
5328 dataEnd = inPtr;
5329 while(('\0' != *dataEnd) )
5330 {
5331 dataEnd++;
5332 ++(*pCckmIeLen);
5333 }
5334 if ( *pCckmIeLen <= 0) return -EINVAL;
5335
5336 /* Allocate the number of bytes based on the number of input characters
5337 whether it is even or odd.
5338 if the number of input characters are even, then we need N/2 byte.
5339 if the number of input characters are odd, then we need do (N+1)/2 to
5340 compensate rounding off.
5341 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5342 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5343 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5344 if (NULL == *pCckmIe)
5345 {
5346 hddLog(VOS_TRACE_LEVEL_FATAL,
5347 "%s: vos_mem_alloc failed ", __func__);
5348 return -EINVAL;
5349 }
5350 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5351 /* the buffer received from the upper layer is character buffer,
5352 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5353 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5354 and f0 in 3rd location */
5355 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5356 {
5357 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5358 (*pCckmIe)[i++] = tempByte;
5359 }
5360 *pCckmIeLen = i;
5361
5362 return VOS_STATUS_SUCCESS;
5363}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005364#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005365
Jeff Johnson295189b2012-06-20 16:38:30 -07005366/**---------------------------------------------------------------------------
5367
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005368 \brief hdd_is_valid_mac_address() - Validate MAC address
5369
5370 This function validates whether the given MAC address is valid or not
5371 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5372 where X is the hexa decimal digit character and separated by ':'
5373 This algorithm works even if MAC address is not separated by ':'
5374
5375 This code checks given input string mac contains exactly 12 hexadecimal digits.
5376 and a separator colon : appears in the input string only after
5377 an even number of hex digits.
5378
5379 \param - pMacAddr pointer to the input MAC address
5380 \return - 1 for valid and 0 for invalid
5381
5382 --------------------------------------------------------------------------*/
5383
5384v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5385{
5386 int xdigit = 0;
5387 int separator = 0;
5388 while (*pMacAddr)
5389 {
5390 if (isxdigit(*pMacAddr))
5391 {
5392 xdigit++;
5393 }
5394 else if (':' == *pMacAddr)
5395 {
5396 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5397 break;
5398
5399 ++separator;
5400 }
5401 else
5402 {
5403 separator = -1;
5404 /* Invalid MAC found */
5405 return 0;
5406 }
5407 ++pMacAddr;
5408 }
5409 return (xdigit == 12 && (separator == 5 || separator == 0));
5410}
5411
5412/**---------------------------------------------------------------------------
5413
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305414 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005415
5416 \param - dev Pointer to net_device structure
5417
5418 \return - 0 for success non-zero for failure
5419
5420 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305421int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005422{
5423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5424 hdd_context_t *pHddCtx;
5425 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5426 VOS_STATUS status;
5427 v_BOOL_t in_standby = TRUE;
5428
5429 if (NULL == pAdapter)
5430 {
5431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305432 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 return -ENODEV;
5434 }
5435
5436 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305437 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5438 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 if (NULL == pHddCtx)
5440 {
5441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005442 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 return -ENODEV;
5444 }
5445
5446 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5447 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5448 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005449 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5450 {
5451 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305452 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005453 in_standby = FALSE;
5454 break;
5455 }
5456 else
5457 {
5458 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5459 pAdapterNode = pNext;
5460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 }
5462
5463 if (TRUE == in_standby)
5464 {
5465 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5466 {
5467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5468 "wlan out of power save", __func__);
5469 return -EINVAL;
5470 }
5471 }
5472
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005473 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5475 {
5476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005477 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305479 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005480 netif_tx_start_all_queues(dev);
5481 }
5482
5483 return 0;
5484}
5485
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305486/**---------------------------------------------------------------------------
5487
5488 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5489
5490 This is called in response to ifconfig up
5491
5492 \param - dev Pointer to net_device structure
5493
5494 \return - 0 for success non-zero for failure
5495
5496 --------------------------------------------------------------------------*/
5497int hdd_open(struct net_device *dev)
5498{
5499 int ret;
5500
5501 vos_ssr_protect(__func__);
5502 ret = __hdd_open(dev);
5503 vos_ssr_unprotect(__func__);
5504
5505 return ret;
5506}
5507
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305508int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005509{
5510 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5511
5512 if(pAdapter == NULL) {
5513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005514 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005515 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 }
5517
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 return 0;
5519}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305520
5521int hdd_mon_open (struct net_device *dev)
5522{
5523 int ret;
5524
5525 vos_ssr_protect(__func__);
5526 ret = __hdd_mon_open(dev);
5527 vos_ssr_unprotect(__func__);
5528
5529 return ret;
5530}
5531
Katya Nigame7b69a82015-04-28 15:24:06 +05305532int hdd_mon_stop(struct net_device *dev)
5533{
5534 return 0;
5535}
5536
Jeff Johnson295189b2012-06-20 16:38:30 -07005537/**---------------------------------------------------------------------------
5538
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305539 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005540
5541 \param - dev Pointer to net_device structure
5542
5543 \return - 0 for success non-zero for failure
5544
5545 --------------------------------------------------------------------------*/
5546
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305547int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005548{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305549 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5551 hdd_context_t *pHddCtx;
5552 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5553 VOS_STATUS status;
5554 v_BOOL_t enter_standby = TRUE;
5555
5556 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 if (NULL == pAdapter)
5558 {
5559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305560 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 return -ENODEV;
5562 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305563 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305564 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305565
5566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5567 ret = wlan_hdd_validate_context(pHddCtx);
5568 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305570 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005571 }
5572
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305573 /* Nothing to be done if the interface is not opened */
5574 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5575 {
5576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5577 "%s: NETDEV Interface is not OPENED", __func__);
5578 return -ENODEV;
5579 }
5580
5581 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005582 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305584
5585 /* Disable TX on the interface, after this hard_start_xmit() will not
5586 * be called on that interface
5587 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305590
5591 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 netif_carrier_off(pAdapter->dev);
5593
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305594 /* The interface is marked as down for outside world (aka kernel)
5595 * But the driver is pretty much alive inside. The driver needs to
5596 * tear down the existing connection on the netdev (session)
5597 * cleanup the data pipes and wait until the control plane is stabilized
5598 * for this interface. The call also needs to wait until the above
5599 * mentioned actions are completed before returning to the caller.
5600 * Notice that the hdd_stop_adapter is requested not to close the session
5601 * That is intentional to be able to scan if it is a STA/P2P interface
5602 */
5603 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305604#ifdef FEATURE_WLAN_TDLS
5605 mutex_lock(&pHddCtx->tdls_lock);
5606#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305607 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305608 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305609#ifdef FEATURE_WLAN_TDLS
5610 mutex_unlock(&pHddCtx->tdls_lock);
5611#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 /* SoftAP ifaces should never go in power save mode
5613 making sure same here. */
5614 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5615 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 )
5618 {
5619 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5621 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 EXIT();
5623 return 0;
5624 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305625 /* Find if any iface is up. If any iface is up then can't put device to
5626 * sleep/power save mode
5627 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5629 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5630 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005631 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5632 {
5633 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305634 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005635 enter_standby = FALSE;
5636 break;
5637 }
5638 else
5639 {
5640 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5641 pAdapterNode = pNext;
5642 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 }
5644
5645 if (TRUE == enter_standby)
5646 {
5647 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5648 "entering standby", __func__);
5649 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5650 {
5651 /*log and return success*/
5652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5653 "wlan in power save", __func__);
5654 }
5655 }
5656
5657 EXIT();
5658 return 0;
5659}
5660
5661/**---------------------------------------------------------------------------
5662
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305663 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005664
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305665 This is called in response to ifconfig down
5666
5667 \param - dev Pointer to net_device structure
5668
5669 \return - 0 for success non-zero for failure
5670-----------------------------------------------------------------------------*/
5671int hdd_stop (struct net_device *dev)
5672{
5673 int ret;
5674
5675 vos_ssr_protect(__func__);
5676 ret = __hdd_stop(dev);
5677 vos_ssr_unprotect(__func__);
5678
5679 return ret;
5680}
5681
5682/**---------------------------------------------------------------------------
5683
5684 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005685
5686 \param - dev Pointer to net_device structure
5687
5688 \return - void
5689
5690 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305691static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005692{
5693 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305694 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005695 ENTER();
5696
5697 do
5698 {
5699 if (NULL == pAdapter)
5700 {
5701 hddLog(VOS_TRACE_LEVEL_FATAL,
5702 "%s: NULL pAdapter", __func__);
5703 break;
5704 }
5705
5706 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5707 {
5708 hddLog(VOS_TRACE_LEVEL_FATAL,
5709 "%s: Invalid magic", __func__);
5710 break;
5711 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305712 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5713 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 {
5715 hddLog(VOS_TRACE_LEVEL_FATAL,
5716 "%s: NULL pHddCtx", __func__);
5717 break;
5718 }
5719
5720 if (dev != pAdapter->dev)
5721 {
5722 hddLog(VOS_TRACE_LEVEL_FATAL,
5723 "%s: Invalid device reference", __func__);
5724 /* we haven't validated all cases so let this go for now */
5725 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305726#ifdef FEATURE_WLAN_TDLS
5727 mutex_lock(&pHddCtx->tdls_lock);
5728#endif
c_hpothu002231a2015-02-05 14:58:51 +05305729 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305730#ifdef FEATURE_WLAN_TDLS
5731 mutex_unlock(&pHddCtx->tdls_lock);
5732#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005733
5734 /* after uninit our adapter structure will no longer be valid */
5735 pAdapter->dev = NULL;
5736 pAdapter->magic = 0;
5737 } while (0);
5738
5739 EXIT();
5740}
5741
5742/**---------------------------------------------------------------------------
5743
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305744 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5745
5746 This is called during the netdev unregister to uninitialize all data
5747associated with the device
5748
5749 \param - dev Pointer to net_device structure
5750
5751 \return - void
5752
5753 --------------------------------------------------------------------------*/
5754static void hdd_uninit (struct net_device *dev)
5755{
5756 vos_ssr_protect(__func__);
5757 __hdd_uninit(dev);
5758 vos_ssr_unprotect(__func__);
5759}
5760
5761/**---------------------------------------------------------------------------
5762
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 \brief hdd_release_firmware() -
5764
5765 This function calls the release firmware API to free the firmware buffer.
5766
5767 \param - pFileName Pointer to the File Name.
5768 pCtx - Pointer to the adapter .
5769
5770
5771 \return - 0 for success, non zero for failure
5772
5773 --------------------------------------------------------------------------*/
5774
5775VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5776{
5777 VOS_STATUS status = VOS_STATUS_SUCCESS;
5778 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5779 ENTER();
5780
5781
5782 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5783
5784 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5785
5786 if(pHddCtx->fw) {
5787 release_firmware(pHddCtx->fw);
5788 pHddCtx->fw = NULL;
5789 }
5790 else
5791 status = VOS_STATUS_E_FAILURE;
5792 }
5793 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5794 if(pHddCtx->nv) {
5795 release_firmware(pHddCtx->nv);
5796 pHddCtx->nv = NULL;
5797 }
5798 else
5799 status = VOS_STATUS_E_FAILURE;
5800
5801 }
5802
5803 EXIT();
5804 return status;
5805}
5806
5807/**---------------------------------------------------------------------------
5808
5809 \brief hdd_request_firmware() -
5810
5811 This function reads the firmware file using the request firmware
5812 API and returns the the firmware data and the firmware file size.
5813
5814 \param - pfileName - Pointer to the file name.
5815 - pCtx - Pointer to the adapter .
5816 - ppfw_data - Pointer to the pointer of the firmware data.
5817 - pSize - Pointer to the file size.
5818
5819 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5820
5821 --------------------------------------------------------------------------*/
5822
5823
5824VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5825{
5826 int status;
5827 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5828 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5829 ENTER();
5830
5831 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5832
5833 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5834
5835 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5836 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5837 __func__, pfileName);
5838 retval = VOS_STATUS_E_FAILURE;
5839 }
5840
5841 else {
5842 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5843 *pSize = pHddCtx->fw->size;
5844 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5845 __func__, *pSize);
5846 }
5847 }
5848 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5849
5850 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5851
5852 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5853 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5854 __func__, pfileName);
5855 retval = VOS_STATUS_E_FAILURE;
5856 }
5857
5858 else {
5859 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5860 *pSize = pHddCtx->nv->size;
5861 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5862 __func__, *pSize);
5863 }
5864 }
5865
5866 EXIT();
5867 return retval;
5868}
5869/**---------------------------------------------------------------------------
5870 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5871
5872 This is the function invoked by SME to inform the result of a full power
5873 request issued by HDD
5874
5875 \param - callbackcontext - Pointer to cookie
5876 status - result of request
5877
5878 \return - None
5879
5880--------------------------------------------------------------------------*/
5881void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5882{
5883 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5884
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005885 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 if(&pHddCtx->full_pwr_comp_var)
5887 {
5888 complete(&pHddCtx->full_pwr_comp_var);
5889 }
5890}
5891
5892/**---------------------------------------------------------------------------
5893
5894 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5895
5896 This is the function invoked by SME to inform the result of BMPS
5897 request issued by HDD
5898
5899 \param - callbackcontext - Pointer to cookie
5900 status - result of request
5901
5902 \return - None
5903
5904--------------------------------------------------------------------------*/
5905void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5906{
5907
5908 struct completion *completion_var = (struct completion*) callbackContext;
5909
Arif Hussain6d2a3322013-11-17 19:50:10 -08005910 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 if(completion_var != NULL)
5912 {
5913 complete(completion_var);
5914 }
5915}
5916
5917/**---------------------------------------------------------------------------
5918
5919 \brief hdd_get_cfg_file_size() -
5920
5921 This function reads the configuration file using the request firmware
5922 API and returns the configuration file size.
5923
5924 \param - pCtx - Pointer to the adapter .
5925 - pFileName - Pointer to the file name.
5926 - pBufSize - Pointer to the buffer size.
5927
5928 \return - 0 for success, non zero for failure
5929
5930 --------------------------------------------------------------------------*/
5931
5932VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5933{
5934 int status;
5935 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5936
5937 ENTER();
5938
5939 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5940
5941 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5942 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5943 status = VOS_STATUS_E_FAILURE;
5944 }
5945 else {
5946 *pBufSize = pHddCtx->fw->size;
5947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5948 release_firmware(pHddCtx->fw);
5949 pHddCtx->fw = NULL;
5950 }
5951
5952 EXIT();
5953 return VOS_STATUS_SUCCESS;
5954}
5955
5956/**---------------------------------------------------------------------------
5957
5958 \brief hdd_read_cfg_file() -
5959
5960 This function reads the configuration file using the request firmware
5961 API and returns the cfg data and the buffer size of the configuration file.
5962
5963 \param - pCtx - Pointer to the adapter .
5964 - pFileName - Pointer to the file name.
5965 - pBuffer - Pointer to the data buffer.
5966 - pBufSize - Pointer to the buffer size.
5967
5968 \return - 0 for success, non zero for failure
5969
5970 --------------------------------------------------------------------------*/
5971
5972VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5973 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5974{
5975 int status;
5976 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5977
5978 ENTER();
5979
5980 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5981
5982 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5983 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5984 return VOS_STATUS_E_FAILURE;
5985 }
5986 else {
5987 if(*pBufSize != pHddCtx->fw->size) {
5988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5989 "file size", __func__);
5990 release_firmware(pHddCtx->fw);
5991 pHddCtx->fw = NULL;
5992 return VOS_STATUS_E_FAILURE;
5993 }
5994 else {
5995 if(pBuffer) {
5996 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5997 }
5998 release_firmware(pHddCtx->fw);
5999 pHddCtx->fw = NULL;
6000 }
6001 }
6002
6003 EXIT();
6004
6005 return VOS_STATUS_SUCCESS;
6006}
6007
6008/**---------------------------------------------------------------------------
6009
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306010 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006011
6012 This function sets the user specified mac address using
6013 the command ifconfig wlanX hw ether <mac adress>.
6014
6015 \param - dev - Pointer to the net device.
6016 - addr - Pointer to the sockaddr.
6017 \return - 0 for success, non zero for failure
6018
6019 --------------------------------------------------------------------------*/
6020
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306021static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006022{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306023 hdd_adapter_t *pAdapter;
6024 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 struct sockaddr *psta_mac_addr = addr;
6026 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306027 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006028
6029 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306030 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6031 if (NULL == pAdapter)
6032 {
6033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6034 "%s: Adapter is NULL",__func__);
6035 return -EINVAL;
6036 }
6037 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6038 ret = wlan_hdd_validate_context(pHddCtx);
6039 if (0 != ret)
6040 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306041 return ret;
6042 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006043
6044 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6046
6047 EXIT();
6048 return halStatus;
6049}
6050
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306051/**---------------------------------------------------------------------------
6052
6053 \brief hdd_set_mac_address() -
6054
6055 Wrapper function to protect __hdd_set_mac_address() function from ssr
6056
6057 \param - dev - Pointer to the net device.
6058 - addr - Pointer to the sockaddr.
6059 \return - 0 for success, non zero for failure
6060
6061 --------------------------------------------------------------------------*/
6062static int hdd_set_mac_address(struct net_device *dev, void *addr)
6063{
6064 int ret;
6065
6066 vos_ssr_protect(__func__);
6067 ret = __hdd_set_mac_address(dev, addr);
6068 vos_ssr_unprotect(__func__);
6069
6070 return ret;
6071}
6072
Jeff Johnson295189b2012-06-20 16:38:30 -07006073tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6074{
6075 int i;
6076 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6077 {
Abhishek Singheb183782014-02-06 13:37:21 +05306078 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 break;
6080 }
6081
6082 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6083 return NULL;
6084
6085 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6086 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6087}
6088
6089void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6090{
6091 int i;
6092 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6093 {
6094 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6095 {
6096 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6097 break;
6098 }
6099 }
6100 return;
6101}
6102
6103#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6104 static struct net_device_ops wlan_drv_ops = {
6105 .ndo_open = hdd_open,
6106 .ndo_stop = hdd_stop,
6107 .ndo_uninit = hdd_uninit,
6108 .ndo_start_xmit = hdd_hard_start_xmit,
6109 .ndo_tx_timeout = hdd_tx_timeout,
6110 .ndo_get_stats = hdd_stats,
6111 .ndo_do_ioctl = hdd_ioctl,
6112 .ndo_set_mac_address = hdd_set_mac_address,
6113 .ndo_select_queue = hdd_select_queue,
6114#ifdef WLAN_FEATURE_PACKET_FILTERING
6115#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6116 .ndo_set_rx_mode = hdd_set_multicast_list,
6117#else
6118 .ndo_set_multicast_list = hdd_set_multicast_list,
6119#endif //LINUX_VERSION_CODE
6120#endif
6121 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 static struct net_device_ops wlan_mon_drv_ops = {
6123 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306124 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 .ndo_uninit = hdd_uninit,
6126 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6127 .ndo_tx_timeout = hdd_tx_timeout,
6128 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306129 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 .ndo_set_mac_address = hdd_set_mac_address,
6131 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306132
Jeff Johnson295189b2012-06-20 16:38:30 -07006133#endif
6134
6135void hdd_set_station_ops( struct net_device *pWlanDev )
6136{
6137#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 pWlanDev->netdev_ops = &wlan_drv_ops;
6139#else
6140 pWlanDev->open = hdd_open;
6141 pWlanDev->stop = hdd_stop;
6142 pWlanDev->uninit = hdd_uninit;
6143 pWlanDev->hard_start_xmit = NULL;
6144 pWlanDev->tx_timeout = hdd_tx_timeout;
6145 pWlanDev->get_stats = hdd_stats;
6146 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 pWlanDev->set_mac_address = hdd_set_mac_address;
6148#endif
6149}
6150
Katya Nigam1fd24402015-02-16 14:52:19 +05306151void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6152{
6153 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6154 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6155 #else
6156 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6157 #endif
6158}
6159
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006160static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006161{
6162 struct net_device *pWlanDev = NULL;
6163 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 /*
6165 * cfg80211 initialization and registration....
6166 */
6167 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6168
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 if(pWlanDev != NULL)
6170 {
6171
6172 //Save the pointer to the net_device in the HDD adapter
6173 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6174
Jeff Johnson295189b2012-06-20 16:38:30 -07006175 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6176
6177 pAdapter->dev = pWlanDev;
6178 pAdapter->pHddCtx = pHddCtx;
6179 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306180 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006181
6182 init_completion(&pAdapter->session_open_comp_var);
6183 init_completion(&pAdapter->session_close_comp_var);
6184 init_completion(&pAdapter->disconnect_comp_var);
6185 init_completion(&pAdapter->linkup_event_var);
6186 init_completion(&pAdapter->cancel_rem_on_chan_var);
6187 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306188 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006189#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6190 init_completion(&pAdapter->offchannel_tx_event);
6191#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006192 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006193#ifdef FEATURE_WLAN_TDLS
6194 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006195 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006196 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306197 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006198#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 init_completion(&pHddCtx->mc_sus_event_var);
6200 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306201 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006202 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006203 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006204
Rajeev79dbe4c2013-10-05 11:03:42 +05306205#ifdef FEATURE_WLAN_BATCH_SCAN
6206 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6207 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6208 pAdapter->pBatchScanRsp = NULL;
6209 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006210 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006211 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306212 mutex_init(&pAdapter->hdd_batch_scan_lock);
6213#endif
6214
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 pAdapter->isLinkUpSvcNeeded = FALSE;
6216 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6217 //Init the net_device structure
6218 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6219
6220 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6221 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6222 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6223 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6224
6225 hdd_set_station_ops( pAdapter->dev );
6226
6227 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6229 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6230 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 /* set pWlanDev's parent to underlying device */
6232 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006233
6234 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006235 }
6236
6237 return pAdapter;
6238}
6239
6240VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6241{
6242 struct net_device *pWlanDev = pAdapter->dev;
6243 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6244 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6245 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6246
6247 if( rtnl_lock_held )
6248 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006249 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6251 {
6252 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6253 return VOS_STATUS_E_FAILURE;
6254 }
6255 }
6256 if (register_netdevice(pWlanDev))
6257 {
6258 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6259 return VOS_STATUS_E_FAILURE;
6260 }
6261 }
6262 else
6263 {
6264 if(register_netdev(pWlanDev))
6265 {
6266 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6267 return VOS_STATUS_E_FAILURE;
6268 }
6269 }
6270 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6271
6272 return VOS_STATUS_SUCCESS;
6273}
6274
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006275static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006276{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006277 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006279 if (NULL == pAdapter)
6280 {
6281 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6282 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006284
6285 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6286 {
6287 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6288 return eHAL_STATUS_NOT_INITIALIZED;
6289 }
6290
6291 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6292
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006293#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006294 /* need to make sure all of our scheduled work has completed.
6295 * This callback is called from MC thread context, so it is safe to
6296 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006297 *
6298 * Even though this is called from MC thread context, if there is a faulty
6299 * work item in the system, that can hang this call forever. So flushing
6300 * this global work queue is not safe; and now we make sure that
6301 * individual work queues are stopped correctly. But the cancel work queue
6302 * is a GPL only API, so the proprietary version of the driver would still
6303 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006304 */
6305 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006306#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006307
6308 /* We can be blocked while waiting for scheduled work to be
6309 * flushed, and the adapter structure can potentially be freed, in
6310 * which case the magic will have been reset. So make sure the
6311 * magic is still good, and hence the adapter structure is still
6312 * valid, before signaling completion */
6313 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6314 {
6315 complete(&pAdapter->session_close_comp_var);
6316 }
6317
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 return eHAL_STATUS_SUCCESS;
6319}
6320
6321VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6322{
6323 struct net_device *pWlanDev = pAdapter->dev;
6324 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6325 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6326 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6327 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306328 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006329
Nirav Shah7e3c8132015-06-22 23:51:42 +05306330 spin_lock_init( &pAdapter->sta_hash_lock);
6331 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6332
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006334 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 //Open a SME session for future operation
6336 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006337 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6339 {
6340 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006341 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 halStatus, halStatus );
6343 status = VOS_STATUS_E_FAILURE;
6344 goto error_sme_open;
6345 }
6346
6347 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306348 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 &pAdapter->session_open_comp_var,
6350 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306351 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 {
6353 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306354 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 status = VOS_STATUS_E_FAILURE;
6356 goto error_sme_open;
6357 }
6358
6359 // Register wireless extensions
6360 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6361 {
6362 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006363 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 halStatus, halStatus );
6365 status = VOS_STATUS_E_FAILURE;
6366 goto error_register_wext;
6367 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306368
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306370 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6371 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6372 #else
6373 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6374 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006375
6376 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306377 hddLog(VOS_TRACE_LEVEL_INFO,
6378 "%s: Set HDD connState to eConnectionState_NotConnected",
6379 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6381
6382 //Set the default operation channel
6383 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6384
6385 /* Make the default Auth Type as OPEN*/
6386 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6387
6388 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6389 {
6390 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006391 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 status, status );
6393 goto error_init_txrx;
6394 }
6395
6396 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6397
6398 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6399 {
6400 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006401 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 status, status );
6403 goto error_wmm_init;
6404 }
6405
6406 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6407
6408 return VOS_STATUS_SUCCESS;
6409
6410error_wmm_init:
6411 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6412 hdd_deinit_tx_rx(pAdapter);
6413error_init_txrx:
6414 hdd_UnregisterWext(pWlanDev);
6415error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006416 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 {
6418 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006419 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306420 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006421 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306423 unsigned long rc;
6424
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306426 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006428 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306429 if (rc <= 0)
6430 hddLog(VOS_TRACE_LEVEL_ERROR,
6431 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 }
6433}
6434error_sme_open:
6435 return status;
6436}
6437
Jeff Johnson295189b2012-06-20 16:38:30 -07006438void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6439{
6440 hdd_cfg80211_state_t *cfgState;
6441
6442 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6443
6444 if( NULL != cfgState->buf )
6445 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306446 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6448 rc = wait_for_completion_interruptible_timeout(
6449 &pAdapter->tx_action_cnf_event,
6450 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306451 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306454 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6455 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 }
6457 }
6458 return;
6459}
Jeff Johnson295189b2012-06-20 16:38:30 -07006460
c_hpothu002231a2015-02-05 14:58:51 +05306461void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006462{
6463 ENTER();
6464 switch ( pAdapter->device_mode )
6465 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306466 case WLAN_HDD_IBSS:
6467 {
6468 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6469 {
6470 hdd_ibss_deinit_tx_rx( pAdapter );
6471 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6472 }
6473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 case WLAN_HDD_INFRA_STATION:
6475 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006476 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 {
6478 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6479 {
6480 hdd_deinit_tx_rx( pAdapter );
6481 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6482 }
6483
6484 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6485 {
6486 hdd_wmm_adapter_close( pAdapter );
6487 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6488 }
6489
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 break;
6492 }
6493
6494 case WLAN_HDD_SOFTAP:
6495 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306497
6498 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6499 {
6500 hdd_wmm_adapter_close( pAdapter );
6501 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6502 }
6503
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006505
c_hpothu002231a2015-02-05 14:58:51 +05306506 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006508 break;
6509 }
6510
6511 case WLAN_HDD_MONITOR:
6512 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006513 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6514 {
6515 hdd_deinit_tx_rx( pAdapter );
6516 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 break;
6519 }
6520
6521
6522 default:
6523 break;
6524 }
6525
6526 EXIT();
6527}
6528
6529void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6530{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006531 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306532
6533 ENTER();
6534 if (NULL == pAdapter)
6535 {
6536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6537 "%s: HDD adapter is Null", __func__);
6538 return;
6539 }
6540
6541 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006542
Rajeev79dbe4c2013-10-05 11:03:42 +05306543#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306544 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6545 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006546 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306547 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6548 )
6549 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006550 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306551 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006552 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6553 {
6554 hdd_deinit_batch_scan(pAdapter);
6555 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306556 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006557 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306558#endif
6559
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6561 if( rtnl_held )
6562 {
6563 unregister_netdevice(pWlanDev);
6564 }
6565 else
6566 {
6567 unregister_netdev(pWlanDev);
6568 }
6569 // note that the pAdapter is no longer valid at this point
6570 // since the memory has been reclaimed
6571 }
6572
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306573 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006574}
6575
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006576void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6577{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306578 VOS_STATUS status;
6579 hdd_adapter_t *pAdapter = NULL;
6580 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006581
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306582 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006583
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306584 /*loop through all adapters.*/
6585 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006586 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306587 pAdapter = pAdapterNode->pAdapter;
6588 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6589 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006590
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306591 { // we skip this registration for modes other than STA and P2P client modes.
6592 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6593 pAdapterNode = pNext;
6594 continue;
6595 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006596
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306597 //Apply Dynamic DTIM For P2P
6598 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6599 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6600 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6601 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6602 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6603 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6604 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6605 (eConnectionState_Associated ==
6606 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6607 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6608 {
6609 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006610
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306611 powerRequest.uIgnoreDTIM = 1;
6612 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6613
6614 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6615 {
6616 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6617 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6618 }
6619 else
6620 {
6621 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6622 }
6623
6624 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6625 * specified during Enter/Exit BMPS when LCD off*/
6626 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6627 NULL, eANI_BOOLEAN_FALSE);
6628 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6629 NULL, eANI_BOOLEAN_FALSE);
6630
6631 /* switch to the DTIM specified in cfg.ini */
6632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6633 "Switch to DTIM %d", powerRequest.uListenInterval);
6634 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6635 break;
6636
6637 }
6638
6639 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6640 pAdapterNode = pNext;
6641 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006642}
6643
6644void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6645{
6646 /*Switch back to DTIM 1*/
6647 tSirSetPowerParamsReq powerRequest = { 0 };
6648
6649 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6650 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006651 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006652
6653 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6654 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6655 NULL, eANI_BOOLEAN_FALSE);
6656 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6657 NULL, eANI_BOOLEAN_FALSE);
6658
6659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6660 "Switch to DTIM%d",powerRequest.uListenInterval);
6661 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6662
6663}
6664
Jeff Johnson295189b2012-06-20 16:38:30 -07006665VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6666{
6667 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306668 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6669 {
6670 hddLog( LOGE, FL("Wlan Unload in progress"));
6671 return VOS_STATUS_E_PERM;
6672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6674 {
6675 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6676 }
6677
6678 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6679 {
6680 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6681 }
6682
6683 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6684 {
6685 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6686 }
6687
6688 return status;
6689}
6690
6691VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6692{
6693 hdd_adapter_t *pAdapter = NULL;
6694 eHalStatus halStatus;
6695 VOS_STATUS status = VOS_STATUS_E_INVAL;
6696 v_BOOL_t disableBmps = FALSE;
6697 v_BOOL_t disableImps = FALSE;
6698
6699 switch(session_type)
6700 {
6701 case WLAN_HDD_INFRA_STATION:
6702 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006703 case WLAN_HDD_P2P_CLIENT:
6704 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 //Exit BMPS -> Is Sta/P2P Client is already connected
6706 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6707 if((NULL != pAdapter)&&
6708 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6709 {
6710 disableBmps = TRUE;
6711 }
6712
6713 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6714 if((NULL != pAdapter)&&
6715 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6716 {
6717 disableBmps = TRUE;
6718 }
6719
6720 //Exit both Bmps and Imps incase of Go/SAP Mode
6721 if((WLAN_HDD_SOFTAP == session_type) ||
6722 (WLAN_HDD_P2P_GO == session_type))
6723 {
6724 disableBmps = TRUE;
6725 disableImps = TRUE;
6726 }
6727
6728 if(TRUE == disableImps)
6729 {
6730 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6731 {
6732 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6733 }
6734 }
6735
6736 if(TRUE == disableBmps)
6737 {
6738 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6739 {
6740 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6741
6742 if(eHAL_STATUS_SUCCESS != halStatus)
6743 {
6744 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006745 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 VOS_ASSERT(0);
6747 return status;
6748 }
6749 }
6750
6751 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6752 {
6753 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6754
6755 if(eHAL_STATUS_SUCCESS != halStatus)
6756 {
6757 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006758 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 VOS_ASSERT(0);
6760 return status;
6761 }
6762 }
6763 }
6764
6765 if((TRUE == disableBmps) ||
6766 (TRUE == disableImps))
6767 {
6768 /* Now, get the chip into Full Power now */
6769 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6770 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6771 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6772
6773 if(halStatus != eHAL_STATUS_SUCCESS)
6774 {
6775 if(halStatus == eHAL_STATUS_PMC_PENDING)
6776 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306777 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306779 ret = wait_for_completion_interruptible_timeout(
6780 &pHddCtx->full_pwr_comp_var,
6781 msecs_to_jiffies(1000));
6782 if (ret <= 0)
6783 {
6784 hddLog(VOS_TRACE_LEVEL_ERROR,
6785 "%s: wait on full_pwr_comp_var failed %ld",
6786 __func__, ret);
6787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 }
6789 else
6790 {
6791 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006792 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 VOS_ASSERT(0);
6794 return status;
6795 }
6796 }
6797
6798 status = VOS_STATUS_SUCCESS;
6799 }
6800
6801 break;
6802 }
6803 return status;
6804}
Katya Nigame7b69a82015-04-28 15:24:06 +05306805void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6806 {
6807 hdd_mon_ctx_t *pMonCtx = NULL;
6808 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6809
6810 pMonCtx->state = 0;
6811 pMonCtx->ChannelNo = 1;
6812 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306813 pMonCtx->crcCheckEnabled = 1;
6814 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6815 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306816 pMonCtx->numOfMacFilters = 0;
6817 }
6818
Jeff Johnson295189b2012-06-20 16:38:30 -07006819
6820hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006821 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 tANI_U8 rtnl_held )
6823{
6824 hdd_adapter_t *pAdapter = NULL;
6825 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6826 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6827 VOS_STATUS exitbmpsStatus;
6828
Arif Hussain6d2a3322013-11-17 19:50:10 -08006829 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006830
Nirav Shah436658f2014-02-28 17:05:45 +05306831 if(macAddr == NULL)
6832 {
6833 /* Not received valid macAddr */
6834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6835 "%s:Unable to add virtual intf: Not able to get"
6836 "valid mac address",__func__);
6837 return NULL;
6838 }
6839
Jeff Johnson295189b2012-06-20 16:38:30 -07006840 //Disable BMPS incase of Concurrency
6841 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6842
6843 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6844 {
6845 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306846 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 VOS_ASSERT(0);
6848 return NULL;
6849 }
6850
6851 switch(session_type)
6852 {
6853 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006855 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 {
6857 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6858
6859 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306860 {
6861 hddLog(VOS_TRACE_LEVEL_FATAL,
6862 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006863 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006865
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306866#ifdef FEATURE_WLAN_TDLS
6867 /* A Mutex Lock is introduced while changing/initializing the mode to
6868 * protect the concurrent access for the Adapters by TDLS module.
6869 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306870 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306871#endif
6872
Jeff Johnsone7245742012-09-05 17:12:55 -07006873 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6874 NL80211_IFTYPE_P2P_CLIENT:
6875 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006876
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306878#ifdef FEATURE_WLAN_TDLS
6879 mutex_unlock(&pHddCtx->tdls_lock);
6880#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306881
6882 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 if( VOS_STATUS_SUCCESS != status )
6884 goto err_free_netdev;
6885
6886 status = hdd_register_interface( pAdapter, rtnl_held );
6887 if( VOS_STATUS_SUCCESS != status )
6888 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306889#ifdef FEATURE_WLAN_TDLS
6890 mutex_lock(&pHddCtx->tdls_lock);
6891#endif
c_hpothu002231a2015-02-05 14:58:51 +05306892 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306893#ifdef FEATURE_WLAN_TDLS
6894 mutex_unlock(&pHddCtx->tdls_lock);
6895#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 goto err_free_netdev;
6897 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306898
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306899 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306900 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306901
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306902#ifdef WLAN_NS_OFFLOAD
6903 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306904 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306905#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006906 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306907 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006908 netif_tx_disable(pAdapter->dev);
6909 //netif_tx_disable(pWlanDev);
6910 netif_carrier_off(pAdapter->dev);
6911
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306912 if (WLAN_HDD_P2P_CLIENT == session_type ||
6913 WLAN_HDD_P2P_DEVICE == session_type)
6914 {
6915 /* Initialize the work queue to defer the
6916 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306917 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306918 hdd_p2p_roc_work_queue);
6919 }
6920
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 break;
6922 }
6923
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006925 case WLAN_HDD_SOFTAP:
6926 {
6927 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6928 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306929 {
6930 hddLog(VOS_TRACE_LEVEL_FATAL,
6931 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306933 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006934
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6936 NL80211_IFTYPE_AP:
6937 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 pAdapter->device_mode = session_type;
6939
6940 status = hdd_init_ap_mode(pAdapter);
6941 if( VOS_STATUS_SUCCESS != status )
6942 goto err_free_netdev;
6943
Nirav Shah7e3c8132015-06-22 23:51:42 +05306944 status = hdd_sta_id_hash_attach(pAdapter);
6945 if (VOS_STATUS_SUCCESS != status)
6946 {
6947 hddLog(VOS_TRACE_LEVEL_FATAL,
6948 FL("failed to attach hash for session %d"), session_type);
6949 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6950 goto err_free_netdev;
6951 }
6952
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 status = hdd_register_hostapd( pAdapter, rtnl_held );
6954 if( VOS_STATUS_SUCCESS != status )
6955 {
c_hpothu002231a2015-02-05 14:58:51 +05306956 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 goto err_free_netdev;
6958 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306959 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 netif_tx_disable(pAdapter->dev);
6961 netif_carrier_off(pAdapter->dev);
6962
6963 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306964
6965 if (WLAN_HDD_P2P_GO == session_type)
6966 {
6967 /* Initialize the work queue to
6968 * defer the back to back RoC request */
6969 INIT_DELAYED_WORK(&pAdapter->roc_work,
6970 hdd_p2p_roc_work_queue);
6971 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 break;
6973 }
6974 case WLAN_HDD_MONITOR:
6975 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6977 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306978 {
6979 hddLog(VOS_TRACE_LEVEL_FATAL,
6980 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006983
Katya Nigame7b69a82015-04-28 15:24:06 +05306984 // Register wireless extensions
6985 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6986 {
6987 hddLog(VOS_TRACE_LEVEL_FATAL,
6988 "hdd_register_wext() failed with status code %08d [x%08x]",
6989 status, status );
6990 status = VOS_STATUS_E_FAILURE;
6991 }
6992
Jeff Johnson295189b2012-06-20 16:38:30 -07006993 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6994 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006995#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6996 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6997#else
6998 pAdapter->dev->open = hdd_mon_open;
6999 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307000 pAdapter->dev->stop = hdd_mon_stop;
7001 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007002#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307003 status = hdd_register_interface( pAdapter, rtnl_held );
7004 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 hdd_init_tx_rx( pAdapter );
7006 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307007 //Stop the Interface TX queue.
7008 netif_tx_disable(pAdapter->dev);
7009 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007010 }
7011 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007012 case WLAN_HDD_FTM:
7013 {
7014 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7015
7016 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307017 {
7018 hddLog(VOS_TRACE_LEVEL_FATAL,
7019 FL("failed to allocate adapter for session %d"), session_type);
7020 return NULL;
7021 }
7022
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7024 * message while loading driver in FTM mode. */
7025 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7026 pAdapter->device_mode = session_type;
7027 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307028
7029 hdd_init_tx_rx( pAdapter );
7030
7031 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307032 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307033 netif_tx_disable(pAdapter->dev);
7034 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 }
7036 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 default:
7038 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307039 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7040 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007041 VOS_ASSERT(0);
7042 return NULL;
7043 }
7044 }
7045
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 if( VOS_STATUS_SUCCESS == status )
7047 {
7048 //Add it to the hdd's session list.
7049 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7050 if( NULL == pHddAdapterNode )
7051 {
7052 status = VOS_STATUS_E_NOMEM;
7053 }
7054 else
7055 {
7056 pHddAdapterNode->pAdapter = pAdapter;
7057 status = hdd_add_adapter_back ( pHddCtx,
7058 pHddAdapterNode );
7059 }
7060 }
7061
7062 if( VOS_STATUS_SUCCESS != status )
7063 {
7064 if( NULL != pAdapter )
7065 {
7066 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7067 pAdapter = NULL;
7068 }
7069 if( NULL != pHddAdapterNode )
7070 {
7071 vos_mem_free( pHddAdapterNode );
7072 }
7073
7074 goto resume_bmps;
7075 }
7076
7077 if(VOS_STATUS_SUCCESS == status)
7078 {
7079 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7080
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007081 //Initialize the WoWL service
7082 if(!hdd_init_wowl(pAdapter))
7083 {
7084 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7085 goto err_free_netdev;
7086 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 return pAdapter;
7089
7090err_free_netdev:
7091 free_netdev(pAdapter->dev);
7092 wlan_hdd_release_intf_addr( pHddCtx,
7093 pAdapter->macAddressCurrent.bytes );
7094
7095resume_bmps:
7096 //If bmps disabled enable it
7097 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7098 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307099 if (pHddCtx->hdd_wlan_suspended)
7100 {
7101 hdd_set_pwrparams(pHddCtx);
7102 }
7103 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 }
7105 return NULL;
7106}
7107
7108VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7109 tANI_U8 rtnl_held )
7110{
7111 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7112 VOS_STATUS status;
7113
7114 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7115 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307116 {
7117 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7118 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007121
7122 while ( pCurrent->pAdapter != pAdapter )
7123 {
7124 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7125 if( VOS_STATUS_SUCCESS != status )
7126 break;
7127
7128 pCurrent = pNext;
7129 }
7130 pAdapterNode = pCurrent;
7131 if( VOS_STATUS_SUCCESS == status )
7132 {
7133 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7134 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307135
7136#ifdef FEATURE_WLAN_TDLS
7137
7138 /* A Mutex Lock is introduced while changing/initializing the mode to
7139 * protect the concurrent access for the Adapters by TDLS module.
7140 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307141 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307142#endif
7143
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 hdd_remove_adapter( pHddCtx, pAdapterNode );
7145 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007146 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007147
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307148#ifdef FEATURE_WLAN_TDLS
7149 mutex_unlock(&pHddCtx->tdls_lock);
7150#endif
7151
Jeff Johnson295189b2012-06-20 16:38:30 -07007152
7153 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307154 if ((!vos_concurrent_open_sessions_running()) &&
7155 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7156 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007157 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307158 if (pHddCtx->hdd_wlan_suspended)
7159 {
7160 hdd_set_pwrparams(pHddCtx);
7161 }
7162 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 }
7164
7165 return VOS_STATUS_SUCCESS;
7166 }
7167
7168 return VOS_STATUS_E_FAILURE;
7169}
7170
7171VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7172{
7173 hdd_adapter_list_node_t *pHddAdapterNode;
7174 VOS_STATUS status;
7175
7176 ENTER();
7177
7178 do
7179 {
7180 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7181 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7182 {
7183 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7184 vos_mem_free( pHddAdapterNode );
7185 }
7186 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7187
7188 EXIT();
7189
7190 return VOS_STATUS_SUCCESS;
7191}
7192
7193void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7194{
7195 v_U8_t addIE[1] = {0};
7196
7197 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7198 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7199 eANI_BOOLEAN_FALSE) )
7200 {
7201 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007202 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 }
7204
7205 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7206 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7207 eANI_BOOLEAN_FALSE) )
7208 {
7209 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007210 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007211 }
7212
7213 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7214 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7215 eANI_BOOLEAN_FALSE) )
7216 {
7217 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007218 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 }
7220}
7221
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307222VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7223 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007224{
7225 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7226 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307227 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007228 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307229 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307230 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307231 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007232
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307233 if (pHddCtx->isLogpInProgress) {
7234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7235 "%s:LOGP in Progress. Ignore!!!",__func__);
7236 return VOS_STATUS_E_FAILURE;
7237 }
7238
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307240
Nirav Shah7e3c8132015-06-22 23:51:42 +05307241 status = hdd_sta_id_hash_detach(pAdapter);
7242 if (status != VOS_STATUS_SUCCESS)
7243 hddLog(VOS_TRACE_LEVEL_ERROR,
7244 FL("sta id hash detach failed"));
7245
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307246 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007247 switch(pAdapter->device_mode)
7248 {
7249 case WLAN_HDD_INFRA_STATION:
7250 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007251 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307252 {
7253 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307254#ifdef FEATURE_WLAN_TDLS
7255 mutex_lock(&pHddCtx->tdls_lock);
7256 wlan_hdd_tdls_exit(pAdapter, TRUE);
7257 mutex_unlock(&pHddCtx->tdls_lock);
7258#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307259 if( hdd_connIsConnected(pstation) ||
7260 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 {
7262 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7263 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7264 pAdapter->sessionId,
7265 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7266 else
7267 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7268 pAdapter->sessionId,
7269 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7270 //success implies disconnect command got queued up successfully
7271 if(halStatus == eHAL_STATUS_SUCCESS)
7272 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307273 ret = wait_for_completion_interruptible_timeout(
7274 &pAdapter->disconnect_comp_var,
7275 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7276 if (ret <= 0)
7277 {
7278 hddLog(VOS_TRACE_LEVEL_ERROR,
7279 "%s: wait on disconnect_comp_var failed %ld",
7280 __func__, ret);
7281 }
7282 }
7283 else
7284 {
7285 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7286 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 }
7288 memset(&wrqu, '\0', sizeof(wrqu));
7289 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7290 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7291 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7292 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307293 else if(pstation->conn_info.connState ==
7294 eConnectionState_Disconnecting)
7295 {
7296 ret = wait_for_completion_interruptible_timeout(
7297 &pAdapter->disconnect_comp_var,
7298 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7299 if (ret <= 0)
7300 {
7301 hddLog(VOS_TRACE_LEVEL_ERROR,
7302 FL("wait on disconnect_comp_var failed %ld"), ret);
7303 }
7304 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307305 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307307 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307308 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307310 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7311 {
7312 while (pAdapter->is_roc_inprogress)
7313 {
7314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7315 "%s: ROC in progress for session %d!!!",
7316 __func__, pAdapter->sessionId);
7317 // waiting for ROC to expire
7318 msleep(500);
7319 /* In GO present case , if retry exceeds 3,
7320 it means something went wrong. */
7321 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7322 {
7323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7324 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307325 if (eHAL_STATUS_SUCCESS !=
7326 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7327 pAdapter->sessionId ))
7328 {
7329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7330 FL("Failed to Cancel Remain on Channel"));
7331 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307332 wait_for_completion_interruptible_timeout(
7333 &pAdapter->cancel_rem_on_chan_var,
7334 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7335 break;
7336 }
7337 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307338 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307339 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307340#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307341 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307342#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307343
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307344 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307345
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307346 /* It is possible that the caller of this function does not
7347 * wish to close the session
7348 */
7349 if (VOS_TRUE == bCloseSession &&
7350 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 {
7352 INIT_COMPLETION(pAdapter->session_close_comp_var);
7353 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307354 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307355 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007356 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307357 unsigned long ret;
7358
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307360 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307361 &pAdapter->session_close_comp_var,
7362 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307363 if ( 0 >= ret)
7364 {
7365 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307366 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307367 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007368 }
7369 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 break;
7372
7373 case WLAN_HDD_SOFTAP:
7374 case WLAN_HDD_P2P_GO:
7375 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307376 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7377 while (pAdapter->is_roc_inprogress) {
7378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7379 "%s: ROC in progress for session %d!!!",
7380 __func__, pAdapter->sessionId);
7381 msleep(500);
7382 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7384 "%s: ROC completion is not received.!!!", __func__);
7385 WLANSAP_CancelRemainOnChannel(
7386 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7387 wait_for_completion_interruptible_timeout(
7388 &pAdapter->cancel_rem_on_chan_var,
7389 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7390 break;
7391 }
7392 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307393
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307394 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007396 mutex_lock(&pHddCtx->sap_lock);
7397 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7398 {
7399 VOS_STATUS status;
7400 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7401
7402 //Stop Bss.
7403 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7404 if (VOS_IS_STATUS_SUCCESS(status))
7405 {
7406 hdd_hostapd_state_t *pHostapdState =
7407 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7408
7409 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7410
7411 if (!VOS_IS_STATUS_SUCCESS(status))
7412 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307413 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7414 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 }
7416 }
7417 else
7418 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007419 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007420 }
7421 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307422 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007423
7424 if (eHAL_STATUS_FAILURE ==
7425 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7426 0, NULL, eANI_BOOLEAN_FALSE))
7427 {
7428 hddLog(LOGE,
7429 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007430 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 }
7432
7433 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7434 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7435 eANI_BOOLEAN_FALSE) )
7436 {
7437 hddLog(LOGE,
7438 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7439 }
7440
7441 // Reset WNI_CFG_PROBE_RSP Flags
7442 wlan_hdd_reset_prob_rspies(pAdapter);
7443 kfree(pAdapter->sessionCtx.ap.beacon);
7444 pAdapter->sessionCtx.ap.beacon = NULL;
7445 }
7446 mutex_unlock(&pHddCtx->sap_lock);
7447 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007448
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 case WLAN_HDD_MONITOR:
7450 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007451
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 default:
7453 break;
7454 }
7455
7456 EXIT();
7457 return VOS_STATUS_SUCCESS;
7458}
7459
7460VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7461{
7462 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7463 VOS_STATUS status;
7464 hdd_adapter_t *pAdapter;
7465
7466 ENTER();
7467
7468 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7469
7470 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7471 {
7472 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007473
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307474 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007475
7476 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7477 pAdapterNode = pNext;
7478 }
7479
7480 EXIT();
7481
7482 return VOS_STATUS_SUCCESS;
7483}
7484
Rajeev Kumarf999e582014-01-09 17:33:29 -08007485
7486#ifdef FEATURE_WLAN_BATCH_SCAN
7487/**---------------------------------------------------------------------------
7488
7489 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7490 structures
7491
7492 \param - pAdapter Pointer to HDD adapter
7493
7494 \return - None
7495
7496 --------------------------------------------------------------------------*/
7497void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7498{
7499 tHddBatchScanRsp *pNode;
7500 tHddBatchScanRsp *pPrev;
7501
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307502 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007503 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307504 hddLog(VOS_TRACE_LEVEL_ERROR,
7505 "%s: Adapter context is Null", __func__);
7506 return;
7507 }
7508
7509 pNode = pAdapter->pBatchScanRsp;
7510 while (pNode)
7511 {
7512 pPrev = pNode;
7513 pNode = pNode->pNext;
7514 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007515 }
7516
7517 pAdapter->pBatchScanRsp = NULL;
7518 pAdapter->numScanList = 0;
7519 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7520 pAdapter->prev_batch_id = 0;
7521
7522 return;
7523}
7524#endif
7525
7526
Jeff Johnson295189b2012-06-20 16:38:30 -07007527VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7528{
7529 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7530 VOS_STATUS status;
7531 hdd_adapter_t *pAdapter;
7532
7533 ENTER();
7534
7535 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7536
7537 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7538 {
7539 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307540 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 netif_tx_disable(pAdapter->dev);
7542 netif_carrier_off(pAdapter->dev);
7543
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007544 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7545
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307547
Katya Nigam1fd24402015-02-16 14:52:19 +05307548 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7549 hdd_ibss_deinit_tx_rx(pAdapter);
7550
Nirav Shah7e3c8132015-06-22 23:51:42 +05307551 status = hdd_sta_id_hash_detach(pAdapter);
7552 if (status != VOS_STATUS_SUCCESS)
7553 hddLog(VOS_TRACE_LEVEL_ERROR,
7554 FL("sta id hash detach failed for session id %d"),
7555 pAdapter->sessionId);
7556
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307557 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7558
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307559 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7560 {
7561 hdd_wmm_adapter_close( pAdapter );
7562 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007564
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307565 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7566 {
7567 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7568 }
7569
Rajeev Kumarf999e582014-01-09 17:33:29 -08007570#ifdef FEATURE_WLAN_BATCH_SCAN
7571 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7572 {
7573 hdd_deinit_batch_scan(pAdapter);
7574 }
7575#endif
7576
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307577#ifdef FEATURE_WLAN_TDLS
7578 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307579 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307580 mutex_unlock(&pHddCtx->tdls_lock);
7581#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007582 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7583 pAdapterNode = pNext;
7584 }
7585
7586 EXIT();
7587
7588 return VOS_STATUS_SUCCESS;
7589}
7590
7591VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7592{
7593 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7594 VOS_STATUS status;
7595 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307596 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007597
7598 ENTER();
7599
7600 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7601
7602 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7603 {
7604 pAdapter = pAdapterNode->pAdapter;
7605
Kumar Anand82c009f2014-05-29 00:29:42 -07007606 hdd_wmm_init( pAdapter );
7607
Jeff Johnson295189b2012-06-20 16:38:30 -07007608 switch(pAdapter->device_mode)
7609 {
7610 case WLAN_HDD_INFRA_STATION:
7611 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007612 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307613
7614 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7615
Jeff Johnson295189b2012-06-20 16:38:30 -07007616 hdd_init_station_mode(pAdapter);
7617 /* Open the gates for HDD to receive Wext commands */
7618 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007619 pHddCtx->scan_info.mScanPending = FALSE;
7620 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007621
7622 //Trigger the initial scan
7623 hdd_wlan_initial_scan(pAdapter);
7624
7625 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307626 if (eConnectionState_Associated == connState ||
7627 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007628 {
7629 union iwreq_data wrqu;
7630 memset(&wrqu, '\0', sizeof(wrqu));
7631 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7632 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7633 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007634 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007635
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 /* indicate disconnected event to nl80211 */
7637 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7638 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307640 else if (eConnectionState_Connecting == connState)
7641 {
7642 /*
7643 * Indicate connect failure to supplicant if we were in the
7644 * process of connecting
7645 */
7646 cfg80211_connect_result(pAdapter->dev, NULL,
7647 NULL, 0, NULL, 0,
7648 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7649 GFP_KERNEL);
7650 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 break;
7652
7653 case WLAN_HDD_SOFTAP:
7654 /* softAP can handle SSR */
7655 break;
7656
7657 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007660 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007661 break;
7662
7663 case WLAN_HDD_MONITOR:
7664 /* monitor interface start */
7665 break;
7666 default:
7667 break;
7668 }
7669
7670 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7671 pAdapterNode = pNext;
7672 }
7673
7674 EXIT();
7675
7676 return VOS_STATUS_SUCCESS;
7677}
7678
7679VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7680{
7681 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7682 hdd_adapter_t *pAdapter;
7683 VOS_STATUS status;
7684 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307685 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007686
7687 ENTER();
7688
7689 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7690
7691 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7692 {
7693 pAdapter = pAdapterNode->pAdapter;
7694
7695 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7696 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7697 {
7698 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7699 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7700
Abhishek Singhf4669da2014-05-26 15:07:49 +05307701 hddLog(VOS_TRACE_LEVEL_INFO,
7702 "%s: Set HDD connState to eConnectionState_NotConnected",
7703 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007704 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7705 init_completion(&pAdapter->disconnect_comp_var);
7706 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7707 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7708
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307709 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 &pAdapter->disconnect_comp_var,
7711 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307712 if (0 >= ret)
7713 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7714 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007715
7716 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7717 pHddCtx->isAmpAllowed = VOS_FALSE;
7718 sme_RoamConnect(pHddCtx->hHal,
7719 pAdapter->sessionId, &(pWextState->roamProfile),
7720 &roamId);
7721 }
7722
7723 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7724 pAdapterNode = pNext;
7725 }
7726
7727 EXIT();
7728
7729 return VOS_STATUS_SUCCESS;
7730}
7731
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007732void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7733{
7734 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7735 VOS_STATUS status;
7736 hdd_adapter_t *pAdapter;
7737 hdd_station_ctx_t *pHddStaCtx;
7738 hdd_ap_ctx_t *pHddApCtx;
7739 hdd_hostapd_state_t * pHostapdState;
7740 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7741 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7742 const char *p2pMode = "DEV";
7743 const char *ccMode = "Standalone";
7744 int n;
7745
7746 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7747 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7748 {
7749 pAdapter = pAdapterNode->pAdapter;
7750 switch (pAdapter->device_mode) {
7751 case WLAN_HDD_INFRA_STATION:
7752 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7753 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7754 staChannel = pHddStaCtx->conn_info.operationChannel;
7755 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7756 }
7757 break;
7758 case WLAN_HDD_P2P_CLIENT:
7759 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7760 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7761 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7762 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7763 p2pMode = "CLI";
7764 }
7765 break;
7766 case WLAN_HDD_P2P_GO:
7767 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7768 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7769 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7770 p2pChannel = pHddApCtx->operatingChannel;
7771 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7772 }
7773 p2pMode = "GO";
7774 break;
7775 case WLAN_HDD_SOFTAP:
7776 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7777 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7778 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7779 apChannel = pHddApCtx->operatingChannel;
7780 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7781 }
7782 break;
7783 default:
7784 break;
7785 }
7786 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7787 pAdapterNode = pNext;
7788 }
7789 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7790 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7791 }
7792 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7793 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7794 if (p2pChannel > 0) {
7795 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7796 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7797 }
7798 if (apChannel > 0) {
7799 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7800 apChannel, MAC_ADDR_ARRAY(apBssid));
7801 }
7802
7803 if (p2pChannel > 0 && apChannel > 0) {
7804 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7805 }
7806}
7807
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007808bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007809{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007810 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007811}
7812
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007813/* Once SSR is disabled then it cannot be set. */
7814void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007815{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007816 if (HDD_SSR_DISABLED == isSsrRequired)
7817 return;
7818
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 isSsrRequired = value;
7820}
7821
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307822void hdd_set_pre_close( hdd_context_t *pHddCtx)
7823{
7824 sme_PreClose(pHddCtx->hHal);
7825}
7826
Jeff Johnson295189b2012-06-20 16:38:30 -07007827VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7828 hdd_adapter_list_node_t** ppAdapterNode)
7829{
7830 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307831 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007832 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7833 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307834 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 return status;
7836}
7837
7838VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7839 hdd_adapter_list_node_t* pAdapterNode,
7840 hdd_adapter_list_node_t** pNextAdapterNode)
7841{
7842 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307843 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7845 (hdd_list_node_t*) pAdapterNode,
7846 (hdd_list_node_t**)pNextAdapterNode );
7847
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307848 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007849 return status;
7850}
7851
7852VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7853 hdd_adapter_list_node_t* pAdapterNode)
7854{
7855 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307856 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7858 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307859 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 return status;
7861}
7862
7863VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7864 hdd_adapter_list_node_t** ppAdapterNode)
7865{
7866 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307867 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7869 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307870 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 return status;
7872}
7873
7874VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7875 hdd_adapter_list_node_t* pAdapterNode)
7876{
7877 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307878 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7880 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307881 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 return status;
7883}
7884
7885VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7886 hdd_adapter_list_node_t* pAdapterNode)
7887{
7888 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307889 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7891 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307892 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007893 return status;
7894}
7895
7896hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7897 tSirMacAddr macAddr )
7898{
7899 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7900 hdd_adapter_t *pAdapter;
7901 VOS_STATUS status;
7902
7903 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7904
7905 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7906 {
7907 pAdapter = pAdapterNode->pAdapter;
7908
7909 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7910 macAddr, sizeof(tSirMacAddr) ) )
7911 {
7912 return pAdapter;
7913 }
7914 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7915 pAdapterNode = pNext;
7916 }
7917
7918 return NULL;
7919
7920}
7921
7922hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7923{
7924 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7925 hdd_adapter_t *pAdapter;
7926 VOS_STATUS status;
7927
7928 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7929
7930 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7931 {
7932 pAdapter = pAdapterNode->pAdapter;
7933
7934 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7935 IFNAMSIZ ) )
7936 {
7937 return pAdapter;
7938 }
7939 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7940 pAdapterNode = pNext;
7941 }
7942
7943 return NULL;
7944
7945}
7946
7947hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7948{
7949 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7950 hdd_adapter_t *pAdapter;
7951 VOS_STATUS status;
7952
7953 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7954
7955 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7956 {
7957 pAdapter = pAdapterNode->pAdapter;
7958
7959 if( pAdapter && (mode == pAdapter->device_mode) )
7960 {
7961 return pAdapter;
7962 }
7963 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7964 pAdapterNode = pNext;
7965 }
7966
7967 return NULL;
7968
7969}
7970
7971//Remove this function later
7972hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7973{
7974 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7975 hdd_adapter_t *pAdapter;
7976 VOS_STATUS status;
7977
7978 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7979
7980 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7981 {
7982 pAdapter = pAdapterNode->pAdapter;
7983
7984 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7985 {
7986 return pAdapter;
7987 }
7988
7989 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7990 pAdapterNode = pNext;
7991 }
7992
7993 return NULL;
7994
7995}
7996
Jeff Johnson295189b2012-06-20 16:38:30 -07007997/**---------------------------------------------------------------------------
7998
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307999 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008000
8001 This API returns the operating channel of the requested device mode
8002
8003 \param - pHddCtx - Pointer to the HDD context.
8004 - mode - Device mode for which operating channel is required
8005 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8006 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8007 \return - channel number. "0" id the requested device is not found OR it is not connected.
8008 --------------------------------------------------------------------------*/
8009v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8010{
8011 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8012 VOS_STATUS status;
8013 hdd_adapter_t *pAdapter;
8014 v_U8_t operatingChannel = 0;
8015
8016 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8017
8018 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8019 {
8020 pAdapter = pAdapterNode->pAdapter;
8021
8022 if( mode == pAdapter->device_mode )
8023 {
8024 switch(pAdapter->device_mode)
8025 {
8026 case WLAN_HDD_INFRA_STATION:
8027 case WLAN_HDD_P2P_CLIENT:
8028 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8029 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8030 break;
8031 case WLAN_HDD_SOFTAP:
8032 case WLAN_HDD_P2P_GO:
8033 /*softap connection info */
8034 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8035 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8036 break;
8037 default:
8038 break;
8039 }
8040
8041 break; //Found the device of interest. break the loop
8042 }
8043
8044 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8045 pAdapterNode = pNext;
8046 }
8047 return operatingChannel;
8048}
8049
8050#ifdef WLAN_FEATURE_PACKET_FILTERING
8051/**---------------------------------------------------------------------------
8052
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308053 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008054
8055 This used to set the multicast address list.
8056
8057 \param - dev - Pointer to the WLAN device.
8058 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308059 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008060
8061 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308062static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008063{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308064 hdd_adapter_t *pAdapter;
8065 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308067 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308069
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308070 ENTER();
8071
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308072 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308073 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 {
8075 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308076 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 return;
8078 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308079 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8080 ret = wlan_hdd_validate_context(pHddCtx);
8081 if (0 != ret)
8082 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308083 return;
8084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 if (dev->flags & IFF_ALLMULTI)
8086 {
8087 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008088 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308089 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308091 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 {
8093 mc_count = netdev_mc_count(dev);
8094 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008095 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8097 {
8098 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008099 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308100 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008101 return;
8102 }
8103
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308104 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008105
8106 netdev_for_each_mc_addr(ha, dev) {
8107 if (i == mc_count)
8108 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308109 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8110 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308112 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308113 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 i++;
8115 }
8116 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308117
8118 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008119 return;
8120}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308121
8122static void hdd_set_multicast_list(struct net_device *dev)
8123{
8124 vos_ssr_protect(__func__);
8125 __hdd_set_multicast_list(dev);
8126 vos_ssr_unprotect(__func__);
8127}
Jeff Johnson295189b2012-06-20 16:38:30 -07008128#endif
8129
8130/**---------------------------------------------------------------------------
8131
8132 \brief hdd_select_queue() -
8133
8134 This function is registered with the Linux OS for network
8135 core to decide which queue to use first.
8136
8137 \param - dev - Pointer to the WLAN device.
8138 - skb - Pointer to OS packet (sk_buff).
8139 \return - ac, Queue Index/access category corresponding to UP in IP header
8140
8141 --------------------------------------------------------------------------*/
8142v_U16_t hdd_select_queue(struct net_device *dev,
8143 struct sk_buff *skb)
8144{
8145 return hdd_wmm_select_queue(dev, skb);
8146}
8147
8148
8149/**---------------------------------------------------------------------------
8150
8151 \brief hdd_wlan_initial_scan() -
8152
8153 This function triggers the initial scan
8154
8155 \param - pAdapter - Pointer to the HDD adapter.
8156
8157 --------------------------------------------------------------------------*/
8158void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8159{
8160 tCsrScanRequest scanReq;
8161 tCsrChannelInfo channelInfo;
8162 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008163 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8165
8166 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8167 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8168 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8169
8170 if(sme_Is11dSupported(pHddCtx->hHal))
8171 {
8172 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8173 if ( HAL_STATUS_SUCCESS( halStatus ) )
8174 {
8175 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8176 if( !scanReq.ChannelInfo.ChannelList )
8177 {
8178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8179 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008180 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008181 return;
8182 }
8183 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8184 channelInfo.numOfChannels);
8185 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8186 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008187 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008188 }
8189
8190 scanReq.scanType = eSIR_PASSIVE_SCAN;
8191 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8192 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8193 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8194 }
8195 else
8196 {
8197 scanReq.scanType = eSIR_ACTIVE_SCAN;
8198 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8199 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8200 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8201 }
8202
8203 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8204 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8205 {
8206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8207 __func__, halStatus );
8208 }
8209
8210 if(sme_Is11dSupported(pHddCtx->hHal))
8211 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8212}
8213
mukul sharmabab477d2015-06-11 17:14:55 +05308214void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8215{
8216 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8217 VOS_STATUS status;
8218 hdd_adapter_t *pAdapter;
8219
8220 ENTER();
8221
8222 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8223
8224 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8225 {
8226 pAdapter = pAdapterNode->pAdapter;
8227
8228 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8229 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8230 pAdapterNode = pNext;
8231 }
8232
8233 EXIT();
8234}
Jeff Johnson295189b2012-06-20 16:38:30 -07008235/**---------------------------------------------------------------------------
8236
8237 \brief hdd_full_power_callback() - HDD full power callback function
8238
8239 This is the function invoked by SME to inform the result of a full power
8240 request issued by HDD
8241
8242 \param - callbackcontext - Pointer to cookie
8243 \param - status - result of request
8244
8245 \return - None
8246
8247 --------------------------------------------------------------------------*/
8248static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8249{
Jeff Johnson72a40512013-12-19 10:14:15 -08008250 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008251
8252 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308253 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008254
8255 if (NULL == callbackContext)
8256 {
8257 hddLog(VOS_TRACE_LEVEL_ERROR,
8258 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008259 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 return;
8261 }
8262
Jeff Johnson72a40512013-12-19 10:14:15 -08008263 /* there is a race condition that exists between this callback
8264 function and the caller since the caller could time out either
8265 before or while this code is executing. we use a spinlock to
8266 serialize these actions */
8267 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268
8269 if (POWER_CONTEXT_MAGIC != pContext->magic)
8270 {
8271 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008272 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 hddLog(VOS_TRACE_LEVEL_WARN,
8274 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008275 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 return;
8277 }
8278
Jeff Johnson72a40512013-12-19 10:14:15 -08008279 /* context is valid so caller is still waiting */
8280
8281 /* paranoia: invalidate the magic */
8282 pContext->magic = 0;
8283
8284 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008286
8287 /* serialization is complete */
8288 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008289}
8290
Katya Nigamf0511f62015-05-05 16:40:57 +05308291void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8292{
8293 pMonCtx->typeSubtypeBitmap = 0;
8294 if( type%10 ) /* Management Packets */
8295 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8296 type/=10;
8297 if( type%10 ) /* Control Packets */
8298 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8299 type/=10;
8300 if( type%10 ) /* Data Packets */
8301 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8302}
8303
8304VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8305{
8306 vos_msg_t monMsg;
8307
8308 monMsg.type = WDA_MON_START_REQ;
8309 monMsg.reserved = 0;
8310 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8311 monMsg.bodyval = 0;
8312
8313 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8314 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8315 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8316 return VOS_STATUS_E_FAILURE;
8317 }
8318
8319 return VOS_STATUS_SUCCESS;
8320}
8321
8322void wlan_hdd_mon_poststopmsg(void)
8323{
8324 vos_msg_t monMsg;
8325
8326 monMsg.type = WDA_MON_STOP_REQ;
8327 monMsg.reserved = 0;
8328 monMsg.bodyptr = NULL;
8329 monMsg.bodyval = 0;
8330
8331 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8332 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8333 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8334 }
8335}
8336
Katya Nigame7b69a82015-04-28 15:24:06 +05308337void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8338{
8339 VOS_STATUS vosStatus;
8340 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8341 struct wiphy *wiphy = pHddCtx->wiphy;
8342
8343 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8344 if(pAdapter == NULL || pVosContext == NULL)
8345 {
8346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8347 return ;
8348 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308349
8350 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308351 hdd_UnregisterWext(pAdapter->dev);
8352
8353 vos_mon_stop( pVosContext );
8354
8355 vosStatus = vos_sched_close( pVosContext );
8356 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8357 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8358 "%s: Failed to close VOSS Scheduler",__func__);
8359 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8360 }
8361
8362 vosStatus = vos_nv_close();
8363 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8364 {
8365 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8366 "%s: Failed to close NV", __func__);
8367 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8368 }
8369
8370 vos_close(pVosContext);
8371
8372 #ifdef WLAN_KD_READY_NOTIFIER
8373 nl_srv_exit(pHddCtx->ptt_pid);
8374 #else
8375 nl_srv_exit();
8376 #endif
8377
8378 if (pHddCtx->cfg_ini)
8379 {
8380 kfree(pHddCtx->cfg_ini);
8381 pHddCtx->cfg_ini= NULL;
8382 }
8383 hdd_close_all_adapters( pHddCtx );
8384
8385 wiphy_free(wiphy) ;
8386
8387}
Jeff Johnson295189b2012-06-20 16:38:30 -07008388/**---------------------------------------------------------------------------
8389
8390 \brief hdd_wlan_exit() - HDD WLAN exit function
8391
8392 This is the driver exit point (invoked during rmmod)
8393
8394 \param - pHddCtx - Pointer to the HDD Context
8395
8396 \return - None
8397
8398 --------------------------------------------------------------------------*/
8399void hdd_wlan_exit(hdd_context_t *pHddCtx)
8400{
8401 eHalStatus halStatus;
8402 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8403 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308404 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008405 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008406 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008407 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308408 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008409
8410 ENTER();
8411
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308412
Katya Nigame7b69a82015-04-28 15:24:06 +05308413 if (VOS_MONITOR_MODE == hdd_get_conparam())
8414 {
8415 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8416 wlan_hdd_mon_close(pHddCtx);
8417 return;
8418 }
8419 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008420 {
8421 // Unloading, restart logic is no more required.
8422 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008423
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308424#ifdef FEATURE_WLAN_TDLS
8425 /* At the time of driver unloading; if tdls connection is present;
8426 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8427 * wlan_hdd_tdls_find_peer always checks for valid context;
8428 * as load/unload in progress there can be a race condition.
8429 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8430 * when tdls state is enabled.
8431 * As soon as driver set load/unload flag; tdls flag also needs
8432 * to be disabled so that hdd_rx_packet_cbk won't call
8433 * wlan_hdd_tdls_find_peer.
8434 */
8435 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8436#endif
8437
c_hpothu5ab05e92014-06-13 17:34:05 +05308438 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8439 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308441 pAdapter = pAdapterNode->pAdapter;
8442 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308444 /* Disable TX on the interface, after this hard_start_xmit() will
8445 * not be called on that interface
8446 */
8447 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8448 netif_tx_disable(pAdapter->dev);
8449
8450 /* Mark the interface status as "down" for outside world */
8451 netif_carrier_off(pAdapter->dev);
8452
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308453 /* DeInit the adapter. This ensures that all data packets
8454 * are freed.
8455 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308456#ifdef FEATURE_WLAN_TDLS
8457 mutex_lock(&pHddCtx->tdls_lock);
8458#endif
c_hpothu002231a2015-02-05 14:58:51 +05308459 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308460#ifdef FEATURE_WLAN_TDLS
8461 mutex_unlock(&pHddCtx->tdls_lock);
8462#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308463
c_hpothu5ab05e92014-06-13 17:34:05 +05308464 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8465 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8466 {
8467 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8468 hdd_UnregisterWext(pAdapter->dev);
8469 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308470
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308472 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8473 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 }
mukul sharmabab477d2015-06-11 17:14:55 +05308475
8476 //Purge all sme cmd's for all interface
8477 hdd_purge_cmd_list_all_adapters(pHddCtx);
8478
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308479 // Cancel any outstanding scan requests. We are about to close all
8480 // of our adapters, but an adapter structure is what SME passes back
8481 // to our callback function. Hence if there are any outstanding scan
8482 // requests then there is a race condition between when the adapter
8483 // is closed and when the callback is invoked.We try to resolve that
8484 // race condition here by canceling any outstanding scans before we
8485 // close the adapters.
8486 // Note that the scans may be cancelled in an asynchronous manner,
8487 // so ideally there needs to be some kind of synchronization. Rather
8488 // than introduce a new synchronization here, we will utilize the
8489 // fact that we are about to Request Full Power, and since that is
8490 // synchronized, the expectation is that by the time Request Full
8491 // Power has completed all scans will be cancelled.
8492 if (pHddCtx->scan_info.mScanPending)
8493 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308494 if(NULL != pAdapter)
8495 {
8496 hddLog(VOS_TRACE_LEVEL_INFO,
8497 FL("abort scan mode: %d sessionId: %d"),
8498 pAdapter->device_mode,
8499 pAdapter->sessionId);
8500 }
8501 hdd_abort_mac_scan(pHddCtx,
8502 pHddCtx->scan_info.sessionId,
8503 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308504 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308506 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008507 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308508 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308509 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8510 {
8511 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8513 "%s: in middle of FTM START", __func__);
8514 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8515 msecs_to_jiffies(20000));
8516 if(!lrc)
8517 {
8518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8519 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8520 }
8521 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008522 wlan_hdd_ftm_close(pHddCtx);
8523 goto free_hdd_ctx;
8524 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308525
Jeff Johnson295189b2012-06-20 16:38:30 -07008526 /* DeRegister with platform driver as client for Suspend/Resume */
8527 vosStatus = hddDeregisterPmOps(pHddCtx);
8528 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8529 {
8530 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8531 VOS_ASSERT(0);
8532 }
8533
8534 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8535 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8536 {
8537 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8538 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008539
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008540 //Stop the traffic monitor timer
8541 if ( VOS_TIMER_STATE_RUNNING ==
8542 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8543 {
8544 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8545 }
8546
8547 // Destroy the traffic monitor timer
8548 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8549 &pHddCtx->tx_rx_trafficTmr)))
8550 {
8551 hddLog(VOS_TRACE_LEVEL_ERROR,
8552 "%s: Cannot deallocate Traffic monitor timer", __func__);
8553 }
8554
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 //Disable IMPS/BMPS as we do not want the device to enter any power
8556 //save mode during shutdown
8557 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8558 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8559 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8560
8561 //Ensure that device is in full power as we will touch H/W during vos_Stop
8562 init_completion(&powerContext.completion);
8563 powerContext.magic = POWER_CONTEXT_MAGIC;
8564
8565 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8566 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8567
8568 if (eHAL_STATUS_SUCCESS != halStatus)
8569 {
8570 if (eHAL_STATUS_PMC_PENDING == halStatus)
8571 {
8572 /* request was sent -- wait for the response */
8573 lrc = wait_for_completion_interruptible_timeout(
8574 &powerContext.completion,
8575 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 if (lrc <= 0)
8577 {
8578 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008579 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 }
8581 }
8582 else
8583 {
8584 hddLog(VOS_TRACE_LEVEL_ERROR,
8585 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008586 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008587 /* continue -- need to clean up as much as possible */
8588 }
8589 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308590 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8591 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8592 {
8593 /* This will issue a dump command which will clean up
8594 BTQM queues and unblock MC thread */
8595 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8596 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008597
Jeff Johnson72a40512013-12-19 10:14:15 -08008598 /* either we never sent a request, we sent a request and received a
8599 response or we sent a request and timed out. if we never sent a
8600 request or if we sent a request and got a response, we want to
8601 clear the magic out of paranoia. if we timed out there is a
8602 race condition such that the callback function could be
8603 executing at the same time we are. of primary concern is if the
8604 callback function had already verified the "magic" but had not
8605 yet set the completion variable when a timeout occurred. we
8606 serialize these activities by invalidating the magic while
8607 holding a shared spinlock which will cause us to block if the
8608 callback is currently executing */
8609 spin_lock(&hdd_context_lock);
8610 powerContext.magic = 0;
8611 spin_unlock(&hdd_context_lock);
8612
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308613 /* If Device is shutdown, no point for SME to wait for responses
8614 from device. Pre Close SME */
8615 if(wcnss_device_is_shutdown())
8616 {
8617 sme_PreClose(pHddCtx->hHal);
8618 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008619 hdd_debugfs_exit(pHddCtx);
8620
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308621#ifdef WLAN_NS_OFFLOAD
8622 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8623 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8624#endif
8625 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8626 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8627
Jeff Johnson295189b2012-06-20 16:38:30 -07008628 // Unregister the Net Device Notifier
8629 unregister_netdevice_notifier(&hdd_netdev_notifier);
8630
Jeff Johnson295189b2012-06-20 16:38:30 -07008631 hdd_stop_all_adapters( pHddCtx );
8632
Jeff Johnson295189b2012-06-20 16:38:30 -07008633#ifdef WLAN_BTAMP_FEATURE
8634 vosStatus = WLANBAP_Stop(pVosContext);
8635 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8636 {
8637 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8638 "%s: Failed to stop BAP",__func__);
8639 }
8640#endif //WLAN_BTAMP_FEATURE
8641
8642 //Stop all the modules
8643 vosStatus = vos_stop( pVosContext );
8644 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8645 {
8646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8647 "%s: Failed to stop VOSS",__func__);
8648 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8649 }
8650
Jeff Johnson295189b2012-06-20 16:38:30 -07008651 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008653
8654 //Close the scheduler before calling vos_close to make sure no thread is
8655 // scheduled after the each module close is called i.e after all the data
8656 // structures are freed.
8657 vosStatus = vos_sched_close( pVosContext );
8658 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8659 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8660 "%s: Failed to close VOSS Scheduler",__func__);
8661 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8662 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008663#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8664 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308665 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008666#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008667 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308668 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008669
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308670#ifdef CONFIG_ENABLE_LINUX_REG
8671 vosStatus = vos_nv_close();
8672 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8673 {
8674 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8675 "%s: Failed to close NV", __func__);
8676 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8677 }
8678#endif
8679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 //Close VOSS
8681 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8682 vos_close(pVosContext);
8683
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 //Close Watchdog
8685 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8686 vos_watchdog_close(pVosContext);
8687
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308688 //Clean up HDD Nlink Service
8689 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308690
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308691#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308692 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308693 {
8694 wlan_logging_sock_deactivate_svc();
8695 }
8696#endif
8697
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308698#ifdef WLAN_KD_READY_NOTIFIER
8699 nl_srv_exit(pHddCtx->ptt_pid);
8700#else
8701 nl_srv_exit();
8702#endif /* WLAN_KD_READY_NOTIFIER */
8703
8704
Jeff Johnson295189b2012-06-20 16:38:30 -07008705 hdd_close_all_adapters( pHddCtx );
8706
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 /* free the power on lock from platform driver */
8708 if (free_riva_power_on_lock("wlan"))
8709 {
8710 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8711 __func__);
8712 }
8713
Jeff Johnson88ba7742013-02-27 14:36:02 -08008714free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308715
8716 //Free up dynamically allocated members inside HDD Adapter
8717 if (pHddCtx->cfg_ini)
8718 {
8719 kfree(pHddCtx->cfg_ini);
8720 pHddCtx->cfg_ini= NULL;
8721 }
8722
Leo Changf04ddad2013-09-18 13:46:38 -07008723 /* FTM mode, WIPHY did not registered
8724 If un-register here, system crash will happen */
8725 if (VOS_FTM_MODE != hdd_get_conparam())
8726 {
8727 wiphy_unregister(wiphy) ;
8728 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 if (hdd_is_ssr_required())
8731 {
8732 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008733 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 msleep(5000);
8735 }
8736 hdd_set_ssr_required (VOS_FALSE);
8737}
8738
8739
8740/**---------------------------------------------------------------------------
8741
8742 \brief hdd_update_config_from_nv() - Function to update the contents of
8743 the running configuration with parameters taken from NV storage
8744
8745 \param - pHddCtx - Pointer to the HDD global context
8746
8747 \return - VOS_STATUS_SUCCESS if successful
8748
8749 --------------------------------------------------------------------------*/
8750static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8751{
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 v_BOOL_t itemIsValid = VOS_FALSE;
8753 VOS_STATUS status;
8754 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8755 v_U8_t macLoop;
8756
8757 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8758 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8759 if(status != VOS_STATUS_SUCCESS)
8760 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008761 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 return VOS_STATUS_E_FAILURE;
8763 }
8764
8765 if (itemIsValid == VOS_TRUE)
8766 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008767 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8769 VOS_MAX_CONCURRENCY_PERSONA);
8770 if(status != VOS_STATUS_SUCCESS)
8771 {
8772 /* Get MAC from NV fail, not update CFG info
8773 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008774 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 return VOS_STATUS_E_FAILURE;
8776 }
8777
8778 /* If first MAC is not valid, treat all others are not valid
8779 * Then all MACs will be got from ini file */
8780 if(vos_is_macaddr_zero(&macFromNV[0]))
8781 {
8782 /* MAC address in NV file is not configured yet */
8783 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8784 return VOS_STATUS_E_INVAL;
8785 }
8786
8787 /* Get MAC address from NV, update CFG info */
8788 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8789 {
8790 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8791 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308792 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008793 /* This MAC is not valid, skip it
8794 * This MAC will be got from ini file */
8795 }
8796 else
8797 {
8798 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8799 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8800 VOS_MAC_ADDR_SIZE);
8801 }
8802 }
8803 }
8804 else
8805 {
8806 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8807 return VOS_STATUS_E_FAILURE;
8808 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008809
Jeff Johnson295189b2012-06-20 16:38:30 -07008810
8811 return VOS_STATUS_SUCCESS;
8812}
8813
8814/**---------------------------------------------------------------------------
8815
8816 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8817
8818 \param - pAdapter - Pointer to the HDD
8819
8820 \return - None
8821
8822 --------------------------------------------------------------------------*/
8823VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8824{
8825 eHalStatus halStatus;
8826 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308827 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008828
Jeff Johnson295189b2012-06-20 16:38:30 -07008829
8830 // Send ready indication to the HDD. This will kick off the MAC
8831 // into a 'running' state and should kick off an initial scan.
8832 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8833 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8834 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 "code %08d [x%08x]",__func__, halStatus, halStatus );
8837 return VOS_STATUS_E_FAILURE;
8838 }
8839
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308840 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8842 // And RIVA will crash
8843 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8844 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308845 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8846 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8847
8848
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 return VOS_STATUS_SUCCESS;
8850}
8851
Jeff Johnson295189b2012-06-20 16:38:30 -07008852/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308853void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008854{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308855
8856 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8857
Jeff Johnson295189b2012-06-20 16:38:30 -07008858}
8859
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308860void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008861{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308862
8863 vos_wake_lock_release(&wlan_wake_lock, reason);
8864
Jeff Johnson295189b2012-06-20 16:38:30 -07008865}
8866
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308867void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008868{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308869
8870 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8871 reason);
8872
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008873}
8874
Jeff Johnson295189b2012-06-20 16:38:30 -07008875/**---------------------------------------------------------------------------
8876
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008877 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8878 information between Host and Riva
8879
8880 This function gets reported version of FW
8881 It also finds the version of Riva headers used to compile the host
8882 It compares the above two and prints a warning if they are different
8883 It gets the SW and HW version string
8884 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8885 indicating the features they support through a bitmap
8886
8887 \param - pHddCtx - Pointer to HDD context
8888
8889 \return - void
8890
8891 --------------------------------------------------------------------------*/
8892
8893void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8894{
8895
8896 tSirVersionType versionCompiled;
8897 tSirVersionType versionReported;
8898 tSirVersionString versionString;
8899 tANI_U8 fwFeatCapsMsgSupported = 0;
8900 VOS_STATUS vstatus;
8901
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008902 memset(&versionCompiled, 0, sizeof(versionCompiled));
8903 memset(&versionReported, 0, sizeof(versionReported));
8904
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008905 /* retrieve and display WCNSS version information */
8906 do {
8907
8908 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8909 &versionCompiled);
8910 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8911 {
8912 hddLog(VOS_TRACE_LEVEL_FATAL,
8913 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008914 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008915 break;
8916 }
8917
8918 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8919 &versionReported);
8920 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8921 {
8922 hddLog(VOS_TRACE_LEVEL_FATAL,
8923 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008924 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008925 break;
8926 }
8927
8928 if ((versionCompiled.major != versionReported.major) ||
8929 (versionCompiled.minor != versionReported.minor) ||
8930 (versionCompiled.version != versionReported.version) ||
8931 (versionCompiled.revision != versionReported.revision))
8932 {
8933 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8934 "Host expected %u.%u.%u.%u\n",
8935 WLAN_MODULE_NAME,
8936 (int)versionReported.major,
8937 (int)versionReported.minor,
8938 (int)versionReported.version,
8939 (int)versionReported.revision,
8940 (int)versionCompiled.major,
8941 (int)versionCompiled.minor,
8942 (int)versionCompiled.version,
8943 (int)versionCompiled.revision);
8944 }
8945 else
8946 {
8947 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8948 WLAN_MODULE_NAME,
8949 (int)versionReported.major,
8950 (int)versionReported.minor,
8951 (int)versionReported.version,
8952 (int)versionReported.revision);
8953 }
8954
8955 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8956 versionString,
8957 sizeof(versionString));
8958 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8959 {
8960 hddLog(VOS_TRACE_LEVEL_FATAL,
8961 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008962 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008963 break;
8964 }
8965
8966 pr_info("%s: WCNSS software version %s\n",
8967 WLAN_MODULE_NAME, versionString);
8968
8969 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8970 versionString,
8971 sizeof(versionString));
8972 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8973 {
8974 hddLog(VOS_TRACE_LEVEL_FATAL,
8975 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008976 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008977 break;
8978 }
8979
8980 pr_info("%s: WCNSS hardware version %s\n",
8981 WLAN_MODULE_NAME, versionString);
8982
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008983 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8984 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008985 send the message only if it the riva is 1.1
8986 minor numbers for different riva branches:
8987 0 -> (1.0)Mainline Build
8988 1 -> (1.1)Mainline Build
8989 2->(1.04) Stability Build
8990 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008991 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008992 ((versionReported.minor>=1) && (versionReported.version>=1)))
8993 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8994 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008995
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008996 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008997 {
8998#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8999 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9000 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9001#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009002 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9003 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9004 {
9005 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9006 }
9007
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009008 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009009 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009010
9011 } while (0);
9012
9013}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309014void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9015{
9016 struct sk_buff *skb;
9017 struct nlmsghdr *nlh;
9018 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309019 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309020
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309021 if (in_interrupt() || irqs_disabled() || in_atomic())
9022 flags = GFP_ATOMIC;
9023
9024 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309025
9026 if(skb == NULL) {
9027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9028 "%s: alloc_skb failed", __func__);
9029 return;
9030 }
9031
9032 nlh = (struct nlmsghdr *)skb->data;
9033 nlh->nlmsg_pid = 0; /* from kernel */
9034 nlh->nlmsg_flags = 0;
9035 nlh->nlmsg_seq = 0;
9036 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9037
9038 ani_hdr = NLMSG_DATA(nlh);
9039 ani_hdr->type = type;
9040
9041 switch(type) {
9042 case WLAN_SVC_SAP_RESTART_IND:
9043 ani_hdr->length = 0;
9044 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9045 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9046 break;
9047 default:
9048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9049 "Attempt to send unknown nlink message %d", type);
9050 kfree_skb(skb);
9051 return;
9052 }
9053
9054 nl_srv_bcast(skb);
9055
9056 return;
9057}
9058
9059
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009060
9061/**---------------------------------------------------------------------------
9062
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309063 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9064
9065 \param - pHddCtx - Pointer to the hdd context
9066
9067 \return - true if hardware supports 5GHz
9068
9069 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309070boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309071{
9072 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9073 * then hardware support 5Ghz.
9074 */
9075 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9076 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309078 return true;
9079 }
9080 else
9081 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309083 __func__);
9084 return false;
9085 }
9086}
9087
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309088/**---------------------------------------------------------------------------
9089
9090 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9091 generate function
9092
9093 This is generate the random mac address for WLAN interface
9094
9095 \param - pHddCtx - Pointer to HDD context
9096 idx - Start interface index to get auto
9097 generated mac addr.
9098 mac_addr - Mac address
9099
9100 \return - 0 for success, < 0 for failure
9101
9102 --------------------------------------------------------------------------*/
9103
9104static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9105 int idx, v_MACADDR_t mac_addr)
9106{
9107 int i;
9108 unsigned int serialno;
9109 serialno = wcnss_get_serial_number();
9110
9111 if (0 != serialno)
9112 {
9113 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9114 bytes of the serial number that can be used to generate
9115 the other 3 bytes of the MAC address. Mask off all but
9116 the lower 3 bytes (this will also make sure we don't
9117 overflow in the next step) */
9118 serialno &= 0x00FFFFFF;
9119
9120 /* we need a unique address for each session */
9121 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9122
9123 /* autogen other Mac addresses */
9124 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9125 {
9126 /* start with the entire default address */
9127 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9128 /* then replace the lower 3 bytes */
9129 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9130 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9131 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9132
9133 serialno++;
9134 hddLog(VOS_TRACE_LEVEL_ERROR,
9135 "%s: Derived Mac Addr: "
9136 MAC_ADDRESS_STR, __func__,
9137 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9138 }
9139
9140 }
9141 else
9142 {
9143 hddLog(LOGE, FL("Failed to Get Serial NO"));
9144 return -1;
9145 }
9146 return 0;
9147}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309148
Katya Nigame7b69a82015-04-28 15:24:06 +05309149int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9150{
9151 VOS_STATUS status;
9152 v_CONTEXT_t pVosContext= NULL;
9153 hdd_adapter_t *pAdapter= NULL;
9154
9155 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9156
9157 if (NULL == pVosContext)
9158 {
9159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9160 "%s: Trying to open VOSS without a PreOpen", __func__);
9161 VOS_ASSERT(0);
9162 return VOS_STATUS_E_FAILURE;
9163 }
9164
9165 status = vos_nv_open();
9166 if (!VOS_IS_STATUS_SUCCESS(status))
9167 {
9168 /* NV module cannot be initialized */
9169 hddLog( VOS_TRACE_LEVEL_FATAL,
9170 "%s: vos_nv_open failed", __func__);
9171 return VOS_STATUS_E_FAILURE;
9172 }
9173
9174 status = vos_init_wiphy_from_nv_bin();
9175 if (!VOS_IS_STATUS_SUCCESS(status))
9176 {
9177 /* NV module cannot be initialized */
9178 hddLog( VOS_TRACE_LEVEL_FATAL,
9179 "%s: vos_init_wiphy failed", __func__);
9180 goto err_vos_nv_close;
9181 }
9182
9183 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9184 if ( !VOS_IS_STATUS_SUCCESS( status ))
9185 {
9186 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9187 goto err_vos_nv_close;
9188 }
9189
9190 status = vos_mon_start( pVosContext );
9191 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9192 {
9193 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9194 goto err_vosclose;
9195 }
9196
9197 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9198 WDA_featureCapsExchange(pVosContext);
9199 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9200
9201 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9202 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9203 if( pAdapter == NULL )
9204 {
9205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9206 goto err_close_adapter;
9207 }
9208
9209 //Initialize the nlink service
9210 if(nl_srv_init() != 0)
9211 {
9212 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9213 goto err_close_adapter;
9214 }
9215 return VOS_STATUS_SUCCESS;
9216
9217err_close_adapter:
9218 hdd_close_all_adapters( pHddCtx );
9219 vos_mon_stop( pVosContext );
9220err_vosclose:
9221 status = vos_sched_close( pVosContext );
9222 if (!VOS_IS_STATUS_SUCCESS(status)) {
9223 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9224 "%s: Failed to close VOSS Scheduler", __func__);
9225 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9226 }
9227 vos_close(pVosContext );
9228
9229err_vos_nv_close:
9230 vos_nv_close();
9231
9232return status;
9233}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309234/**---------------------------------------------------------------------------
9235
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309236 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9237 completed to flush out the scan results
9238
9239 11d scan is done during driver load and is a passive scan on all
9240 channels supported by the device, 11d scans may find some APs on
9241 frequencies which are forbidden to be used in the regulatory domain
9242 the device is operating in. If these APs are notified to the supplicant
9243 it may try to connect to these APs, thus flush out all the scan results
9244 which are present in SME after 11d scan is done.
9245
9246 \return - eHalStatus
9247
9248 --------------------------------------------------------------------------*/
9249static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9250 tANI_U32 scanId, eCsrScanStatus status)
9251{
9252 ENTER();
9253
9254 sme_ScanFlushResult(halHandle, 0);
9255
9256 EXIT();
9257
9258 return eHAL_STATUS_SUCCESS;
9259}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309260/**---------------------------------------------------------------------------
9261
9262 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9263 logging is completed successfully.
9264
9265 \return - None
9266
9267 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309268void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309269{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309270 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309271
9272 if (NULL == pHddCtx)
9273 {
9274 hddLog(VOS_TRACE_LEVEL_ERROR,
9275 "%s: HDD context is NULL",__func__);
9276 return;
9277 }
9278
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309279 if ((VOS_STATUS_SUCCESS == status) &&
9280 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309281 {
9282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9283 pHddCtx->mgmt_frame_logging = TRUE;
9284 }
9285 else
9286 {
9287 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9288 pHddCtx->mgmt_frame_logging = FALSE;
9289 }
9290
9291 return;
9292}
9293/**---------------------------------------------------------------------------
9294
9295 \brief hdd_init_frame_logging - function to initialize frame logging.
9296 Currently only Mgmt Frames are logged in both TX
9297 and Rx direction and are sent to userspace
9298 application using logger thread when queried.
9299
9300 \return - None
9301
9302 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309303void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309304{
9305 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309306 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309307
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309308 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9309 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309310 {
9311 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9312 return;
9313 }
9314
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309315 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9316 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309317 {
9318 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9319 return;
9320 }
9321
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309322 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309323
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309324 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9325 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9326 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9327 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309328
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309329 if (pHddCtx->cfg_ini->enableFWLogging ||
9330 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309331 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309332 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309333 }
9334
Sushant Kaushik46804902015-07-08 14:46:03 +05309335 if (pHddCtx->cfg_ini->enableMgmtLogging)
9336 {
9337 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9338 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309339 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9340 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309341 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309342 }
9343
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309344 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9345 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9346 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9347 wlanFWLoggingInitParam->continuousFrameLogging =
9348 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309349
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309350 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309351
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309352 wlanFWLoggingInitParam->minLogBufferSize =
9353 pHddCtx->cfg_ini->minLoggingBufferSize;
9354 wlanFWLoggingInitParam->maxLogBufferSize =
9355 pHddCtx->cfg_ini->maxLoggingBufferSize;
9356 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9357 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309358
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309359 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309360
9361 if (eHAL_STATUS_SUCCESS != halStatus)
9362 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309363 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309364 }
9365
9366 return;
9367}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309368
9369/**---------------------------------------------------------------------------
9370
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 \brief hdd_wlan_startup() - HDD init function
9372
9373 This is the driver startup code executed once a WLAN device has been detected
9374
9375 \param - dev - Pointer to the underlying device
9376
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009377 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009378
9379 --------------------------------------------------------------------------*/
9380
9381int hdd_wlan_startup(struct device *dev )
9382{
9383 VOS_STATUS status;
9384 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009385 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 hdd_context_t *pHddCtx = NULL;
9387 v_CONTEXT_t pVosContext= NULL;
9388#ifdef WLAN_BTAMP_FEATURE
9389 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9390 WLANBAP_ConfigType btAmpConfig;
9391 hdd_config_t *pConfig;
9392#endif
9393 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309395 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009396
9397 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 /*
9399 * cfg80211: wiphy allocation
9400 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309401 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009402
9403 if(wiphy == NULL)
9404 {
9405 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009406 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 pHddCtx = wiphy_priv(wiphy);
9409
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 //Initialize the adapter context to zeros.
9411 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9412
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309414 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309415 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009416
9417 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9418
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309419 /* register for riva power on lock to platform driver
9420 * Locking power early to ensure FW doesn't reset by kernel while
9421 * host driver is busy initializing itself */
9422 if (req_riva_power_on_lock("wlan"))
9423 {
9424 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9425 __func__);
9426 goto err_free_hdd_context;
9427 }
9428
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 /*Get vos context here bcoz vos_open requires it*/
9430 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9431
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009432 if(pVosContext == NULL)
9433 {
9434 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9435 goto err_free_hdd_context;
9436 }
9437
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 //Save the Global VOSS context in adapter context for future.
9439 pHddCtx->pvosContext = pVosContext;
9440
9441 //Save the adapter context in global context for future.
9442 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9443
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 pHddCtx->parent_dev = dev;
9445
9446 init_completion(&pHddCtx->full_pwr_comp_var);
9447 init_completion(&pHddCtx->standby_comp_var);
9448 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009449 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009450 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309451 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309452 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009453
9454#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009455 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009456#else
9457 init_completion(&pHddCtx->driver_crda_req);
9458#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009459
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309460 spin_lock_init(&pHddCtx->schedScan_lock);
9461
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9463
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309464#ifdef FEATURE_WLAN_TDLS
9465 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9466 * invoked by other instances also) to protect the concurrent
9467 * access for the Adapters by TDLS module.
9468 */
9469 mutex_init(&pHddCtx->tdls_lock);
9470#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309471 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309472 mutex_init(&pHddCtx->wmmLock);
9473
Agarwal Ashish1f422872014-07-22 00:11:55 +05309474 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309475
Agarwal Ashish1f422872014-07-22 00:11:55 +05309476 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009477 // Load all config first as TL config is needed during vos_open
9478 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9479 if(pHddCtx->cfg_ini == NULL)
9480 {
9481 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9482 goto err_free_hdd_context;
9483 }
9484
9485 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9486
9487 // Read and parse the qcom_cfg.ini file
9488 status = hdd_parse_config_ini( pHddCtx );
9489 if ( VOS_STATUS_SUCCESS != status )
9490 {
9491 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9492 __func__, WLAN_INI_FILE);
9493 goto err_config;
9494 }
Arif Hussaind5218912013-12-05 01:10:55 -08009495#ifdef MEMORY_DEBUG
9496 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9497 vos_mem_init();
9498
9499 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9500 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9501#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009502
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309503 /* INI has been read, initialise the configuredMcastBcastFilter with
9504 * INI value as this will serve as the default value
9505 */
9506 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9507 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9508 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309509
9510 if (false == hdd_is_5g_supported(pHddCtx))
9511 {
9512 //5Ghz is not supported.
9513 if (1 != pHddCtx->cfg_ini->nBandCapability)
9514 {
9515 hddLog(VOS_TRACE_LEVEL_INFO,
9516 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9517 pHddCtx->cfg_ini->nBandCapability = 1;
9518 }
9519 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309520
9521 /* If SNR Monitoring is enabled, FW has to parse all beacons
9522 * for calcaluting and storing the average SNR, so set Nth beacon
9523 * filter to 1 to enable FW to parse all the beaocons
9524 */
9525 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9526 {
9527 /* The log level is deliberately set to WARN as overriding
9528 * nthBeaconFilter to 1 will increase power cosumption and this
9529 * might just prove helpful to detect the power issue.
9530 */
9531 hddLog(VOS_TRACE_LEVEL_WARN,
9532 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9533 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309536 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009538 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009540 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9541 {
9542 hddLog(VOS_TRACE_LEVEL_FATAL,
9543 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9544 goto err_config;
9545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009547
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009548 // Update VOS trace levels based upon the cfg.ini
9549 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9550 pHddCtx->cfg_ini->vosTraceEnableBAP);
9551 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9552 pHddCtx->cfg_ini->vosTraceEnableTL);
9553 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9554 pHddCtx->cfg_ini->vosTraceEnableWDI);
9555 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9556 pHddCtx->cfg_ini->vosTraceEnableHDD);
9557 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9558 pHddCtx->cfg_ini->vosTraceEnableSME);
9559 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9560 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309561 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9562 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009563 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9564 pHddCtx->cfg_ini->vosTraceEnableWDA);
9565 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9566 pHddCtx->cfg_ini->vosTraceEnableSYS);
9567 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9568 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009569 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9570 pHddCtx->cfg_ini->vosTraceEnableSAP);
9571 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9572 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009573
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 // Update WDI trace levels based upon the cfg.ini
9575 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9576 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9577 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9578 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9579 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9580 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9581 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9582 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009583
Jeff Johnson88ba7742013-02-27 14:36:02 -08009584 if (VOS_FTM_MODE == hdd_get_conparam())
9585 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9587 {
9588 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9589 goto err_free_hdd_context;
9590 }
9591 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309592 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309593 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009595 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009596
Katya Nigame7b69a82015-04-28 15:24:06 +05309597 if( VOS_MONITOR_MODE == hdd_get_conparam())
9598 {
9599 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9600 {
9601 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9602 goto err_free_hdd_context;
9603 }
9604 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9605 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9606 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9607 return VOS_STATUS_SUCCESS;
9608 }
9609
Jeff Johnson88ba7742013-02-27 14:36:02 -08009610 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9612 {
9613 status = vos_watchdog_open(pVosContext,
9614 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9615
9616 if(!VOS_IS_STATUS_SUCCESS( status ))
9617 {
9618 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309619 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 }
9621 }
9622
9623 pHddCtx->isLogpInProgress = FALSE;
9624 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9625
Amar Singhala49cbc52013-10-08 18:37:44 -07009626#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009627 /* initialize the NV module. This is required so that
9628 we can initialize the channel information in wiphy
9629 from the NV.bin data. The channel information in
9630 wiphy needs to be initialized before wiphy registration */
9631
9632 status = vos_nv_open();
9633 if (!VOS_IS_STATUS_SUCCESS(status))
9634 {
9635 /* NV module cannot be initialized */
9636 hddLog( VOS_TRACE_LEVEL_FATAL,
9637 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309638 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009639 }
9640
9641 status = vos_init_wiphy_from_nv_bin();
9642 if (!VOS_IS_STATUS_SUCCESS(status))
9643 {
9644 /* NV module cannot be initialized */
9645 hddLog( VOS_TRACE_LEVEL_FATAL,
9646 "%s: vos_init_wiphy failed", __func__);
9647 goto err_vos_nv_close;
9648 }
9649
Amar Singhala49cbc52013-10-08 18:37:44 -07009650#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309651 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309652 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 if ( !VOS_IS_STATUS_SUCCESS( status ))
9654 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009655 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309656 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 }
9658
Jeff Johnson295189b2012-06-20 16:38:30 -07009659 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9660
9661 if ( NULL == pHddCtx->hHal )
9662 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009663 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 goto err_vosclose;
9665 }
9666
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009667 status = vos_preStart( pHddCtx->pvosContext );
9668 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9669 {
9670 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309671 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009672 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009673
Arif Hussaineaf68602013-12-30 23:10:44 -08009674 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9675 {
9676 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9678 __func__, enable_dfs_chan_scan);
9679 }
9680 if (0 == enable_11d || 1 == enable_11d)
9681 {
9682 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9684 __func__, enable_11d);
9685 }
9686
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009687 /* Note that the vos_preStart() sequence triggers the cfg download.
9688 The cfg download must occur before we update the SME config
9689 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 status = hdd_set_sme_config( pHddCtx );
9691
9692 if ( VOS_STATUS_SUCCESS != status )
9693 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009694 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309695 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009696 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009697
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 /* In the integrated architecture we update the configuration from
9699 the INI file and from NV before vOSS has been started so that
9700 the final contents are available to send down to the cCPU */
9701
9702 // Apply the cfg.ini to cfg.dat
9703 if (FALSE == hdd_update_config_dat(pHddCtx))
9704 {
9705 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309706 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 }
9708
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309709 // Get mac addr from platform driver
9710 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9711
9712 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009713 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309714 /* Store the mac addr for first interface */
9715 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9716
9717 hddLog(VOS_TRACE_LEVEL_ERROR,
9718 "%s: WLAN Mac Addr: "
9719 MAC_ADDRESS_STR, __func__,
9720 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9721
9722 /* Here, passing Arg2 as 1 because we do not want to change the
9723 last 3 bytes (means non OUI bytes) of first interface mac
9724 addr.
9725 */
9726 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9727 {
9728 hddLog(VOS_TRACE_LEVEL_ERROR,
9729 "%s: Failed to generate wlan interface mac addr "
9730 "using MAC from ini file ", __func__);
9731 }
9732 }
9733 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9734 {
9735 // Apply the NV to cfg.dat
9736 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009737#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9738 /* There was not a valid set of MAC Addresses in NV. See if the
9739 default addresses were modified by the cfg.ini settings. If so,
9740 we'll use them, but if not, we'll autogenerate a set of MAC
9741 addresses based upon the device serial number */
9742
9743 static const v_MACADDR_t default_address =
9744 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009745
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309746 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9747 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009748 {
9749 /* cfg.ini has the default address, invoke autogen logic */
9750
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309751 /* Here, passing Arg2 as 0 because we want to change the
9752 last 3 bytes (means non OUI bytes) of all the interfaces
9753 mac addr.
9754 */
9755 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9756 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309758 hddLog(VOS_TRACE_LEVEL_ERROR,
9759 "%s: Failed to generate wlan interface mac addr "
9760 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9761 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 }
9764 else
9765#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9766 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009767 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 "%s: Invalid MAC address in NV, using MAC from ini file "
9769 MAC_ADDRESS_STR, __func__,
9770 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9771 }
9772 }
9773 {
9774 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309775
9776 /* Set the MAC Address Currently this is used by HAL to
9777 * add self sta. Remove this once self sta is added as
9778 * part of session open.
9779 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009780 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9781 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9782 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309783
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 if (!HAL_STATUS_SUCCESS( halStatus ))
9785 {
9786 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9787 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309788 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 }
9790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009791
9792 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9793 Note: Firmware image will be read and downloaded inside vos_start API */
9794 status = vos_start( pHddCtx->pvosContext );
9795 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9796 {
9797 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309798 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 }
9800
Leo Chang6cec3e22014-01-21 15:33:49 -08009801#ifdef FEATURE_WLAN_CH_AVOID
9802 /* Plug in avoid channel notification callback
9803 * This should happen before ADD_SELF_STA
9804 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309805
9806 /* check the Channel Avoidance is enabled */
9807 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9808 {
9809 sme_AddChAvoidCallback(pHddCtx->hHal,
9810 hdd_hostapd_ch_avoid_cb);
9811 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009812#endif /* FEATURE_WLAN_CH_AVOID */
9813
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009814 /* Exchange capability info between Host and FW and also get versioning info from FW */
9815 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009816
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309817#ifdef CONFIG_ENABLE_LINUX_REG
9818 status = wlan_hdd_init_channels(pHddCtx);
9819 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9820 {
9821 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9822 __func__);
9823 goto err_vosstop;
9824 }
9825#endif
9826
Jeff Johnson295189b2012-06-20 16:38:30 -07009827 status = hdd_post_voss_start_config( pHddCtx );
9828 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9829 {
9830 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9831 __func__);
9832 goto err_vosstop;
9833 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009834
9835#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309836 wlan_hdd_cfg80211_update_reg_info( wiphy );
9837
9838 /* registration of wiphy dev with cfg80211 */
9839 if (0 > wlan_hdd_cfg80211_register(wiphy))
9840 {
9841 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9842 goto err_vosstop;
9843 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009844#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009845
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309846#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309847 /* registration of wiphy dev with cfg80211 */
9848 if (0 > wlan_hdd_cfg80211_register(wiphy))
9849 {
9850 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9851 goto err_vosstop;
9852 }
9853
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309854 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309855 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9856 {
9857 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9858 __func__);
9859 goto err_unregister_wiphy;
9860 }
9861#endif
9862
c_hpothu4a298be2014-12-22 21:12:51 +05309863 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9864
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9866 {
9867 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9868 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9869 }
9870 else
9871 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9873 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9874 if (pAdapter != NULL)
9875 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309876 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309878 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9879 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9880 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009881
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309882 /* Generate the P2P Device Address. This consists of the device's
9883 * primary MAC address with the locally administered bit set.
9884 */
9885 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009886 }
9887 else
9888 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309889 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9890 if (p2p_dev_addr != NULL)
9891 {
9892 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9893 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9894 }
9895 else
9896 {
9897 hddLog(VOS_TRACE_LEVEL_FATAL,
9898 "%s: Failed to allocate mac_address for p2p_device",
9899 __func__);
9900 goto err_close_adapter;
9901 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009903
9904 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9905 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9906 if ( NULL == pP2pAdapter )
9907 {
9908 hddLog(VOS_TRACE_LEVEL_FATAL,
9909 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009910 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009911 goto err_close_adapter;
9912 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009913 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009915
9916 if( pAdapter == NULL )
9917 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9919 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009921
Arif Hussain66559122013-11-21 10:11:40 -08009922 if (country_code)
9923 {
9924 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009925 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009926 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9927#ifndef CONFIG_ENABLE_LINUX_REG
9928 hdd_checkandupdate_phymode(pAdapter, country_code);
9929#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009930 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9931 (void *)(tSmeChangeCountryCallback)
9932 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009933 country_code,
9934 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309935 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009936 if (eHAL_STATUS_SUCCESS == ret)
9937 {
Arif Hussaincb607082013-12-20 11:57:42 -08009938 ret = wait_for_completion_interruptible_timeout(
9939 &pAdapter->change_country_code,
9940 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9941
9942 if (0 >= ret)
9943 {
9944 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9945 "%s: SME while setting country code timed out", __func__);
9946 }
Arif Hussain66559122013-11-21 10:11:40 -08009947 }
9948 else
9949 {
Arif Hussaincb607082013-12-20 11:57:42 -08009950 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9951 "%s: SME Change Country code from module param fail ret=%d",
9952 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009953 }
9954 }
9955
Jeff Johnson295189b2012-06-20 16:38:30 -07009956#ifdef WLAN_BTAMP_FEATURE
9957 vStatus = WLANBAP_Open(pVosContext);
9958 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9959 {
9960 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9961 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009962 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 }
9964
9965 vStatus = BSL_Init(pVosContext);
9966 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9967 {
9968 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9969 "%s: Failed to Init BSL",__func__);
9970 goto err_bap_close;
9971 }
9972 vStatus = WLANBAP_Start(pVosContext);
9973 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9974 {
9975 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9976 "%s: Failed to start TL",__func__);
9977 goto err_bap_close;
9978 }
9979
9980 pConfig = pHddCtx->cfg_ini;
9981 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9982 status = WLANBAP_SetConfig(&btAmpConfig);
9983
9984#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009985
Mihir Shete9c238772014-10-15 14:35:16 +05309986 /*
9987 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9988 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9989 * which is greater than 0xf. So the below check is safe to make
9990 * sure that there is no entry for UapsdMask in the ini
9991 */
9992 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9993 {
9994 if(IS_DYNAMIC_WMM_PS_ENABLED)
9995 {
9996 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9997 __func__);
9998 pHddCtx->cfg_ini->UapsdMask =
9999 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10000 }
10001 else
10002 {
10003 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10004 __func__);
10005 pHddCtx->cfg_ini->UapsdMask =
10006 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10007 }
10008 }
10009
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010010#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10011 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10012 {
10013 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10014 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10015 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10016 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10017 }
10018#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010019
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010020 wlan_hdd_tdls_init(pHddCtx);
10021
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010022 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10023
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 /* Register with platform driver as client for Suspend/Resume */
10025 status = hddRegisterPmOps(pHddCtx);
10026 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10027 {
10028 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10029#ifdef WLAN_BTAMP_FEATURE
10030 goto err_bap_stop;
10031#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010032 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010033#endif //WLAN_BTAMP_FEATURE
10034 }
10035
Yue Ma0d4891e2013-08-06 17:01:45 -070010036 /* Open debugfs interface */
10037 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10038 {
10039 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10040 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010041 }
10042
Jeff Johnson295189b2012-06-20 16:38:30 -070010043 /* Register TM level change handler function to the platform */
10044 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10045 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10046 {
10047 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10048 goto err_unregister_pmops;
10049 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010050
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 // register net device notifier for device change notification
10052 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10053
10054 if(ret < 0)
10055 {
10056 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010057 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010058 }
10059
10060 //Initialize the nlink service
10061 if(nl_srv_init() != 0)
10062 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010063 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 goto err_reg_netdev;
10065 }
10066
Leo Chang4ce1cc52013-10-21 18:27:15 -070010067#ifdef WLAN_KD_READY_NOTIFIER
10068 pHddCtx->kd_nl_init = 1;
10069#endif /* WLAN_KD_READY_NOTIFIER */
10070
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 //Initialize the BTC service
10072 if(btc_activate_service(pHddCtx) != 0)
10073 {
10074 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10075 goto err_nl_srv;
10076 }
10077
10078#ifdef PTT_SOCK_SVC_ENABLE
10079 //Initialize the PTT service
10080 if(ptt_sock_activate_svc(pHddCtx) != 0)
10081 {
10082 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10083 goto err_nl_srv;
10084 }
10085#endif
10086
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010087#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10088 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10089 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010090 if(wlan_logging_sock_activate_svc(
10091 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10092 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10093 {
10094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10095 " failed", __func__);
10096 goto err_nl_srv;
10097 }
10098 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10099 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010100 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10101 pHddCtx->cfg_ini->gEnableDebugLog =
10102 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010103 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010104
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010105 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10106 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010107 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010108 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010109 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010110 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010111 }
10112 else
10113 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010114 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010115 }
10116
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010117#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010118
10119
Sushant Kaushik215778f2015-05-21 14:05:36 +053010120 if (vos_is_multicast_logging())
10121 wlan_logging_set_log_level();
10122
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010126 /* Action frame registered in one adapter which will
10127 * applicable to all interfaces
10128 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010129 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010131
10132 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010133 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010134
Jeff Johnsone7245742012-09-05 17:12:55 -070010135#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10136 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010137 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010138 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010139
Jeff Johnsone7245742012-09-05 17:12:55 -070010140#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010141 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010142 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010143 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010144
Jeff Johnsone7245742012-09-05 17:12:55 -070010145
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010146 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10147 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010148
Katya Nigam5c306ea2014-06-19 15:39:54 +053010149 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010151 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010152
10153#ifdef FEATURE_WLAN_SCAN_PNO
10154 /*SME must send channel update configuration to RIVA*/
10155 sme_UpdateChannelConfig(pHddCtx->hHal);
10156#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010157 /* Send the update default channel list to the FW*/
10158 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010159
10160 /* Fwr capabilities received, Set the Dot11 mode */
10161 sme_SetDefDot11Mode(pHddCtx->hHal);
10162
Abhishek Singha306a442013-11-07 18:39:01 +053010163#ifndef CONFIG_ENABLE_LINUX_REG
10164 /*updating wiphy so that regulatory user hints can be processed*/
10165 if (wiphy)
10166 {
10167 regulatory_hint(wiphy, "00");
10168 }
10169#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010170 // Initialize the restart logic
10171 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010172
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010173 //Register the traffic monitor timer now
10174 if ( pHddCtx->cfg_ini->dynSplitscan)
10175 {
10176 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10177 VOS_TIMER_TYPE_SW,
10178 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10179 (void *)pHddCtx);
10180 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010181 wlan_hdd_cfg80211_nan_init(pHddCtx);
10182
Dino Mycle6fb96c12014-06-10 11:52:40 +053010183#ifdef WLAN_FEATURE_EXTSCAN
10184 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10185 wlan_hdd_cfg80211_extscan_callback,
10186 pHddCtx);
10187#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010188
10189#ifdef WLAN_NS_OFFLOAD
10190 // Register IPv6 notifier to notify if any change in IP
10191 // So that we can reconfigure the offload parameters
10192 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10193 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10194 if (ret)
10195 {
10196 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10197 }
10198 else
10199 {
10200 hddLog(LOGE, FL("Registered IPv6 notifier"));
10201 }
10202#endif
10203
10204 // Register IPv4 notifier to notify if any change in IP
10205 // So that we can reconfigure the offload parameters
10206 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10207 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10208 if (ret)
10209 {
10210 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10211 }
10212 else
10213 {
10214 hddLog(LOGE, FL("Registered IPv4 notifier"));
10215 }
10216
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 goto success;
10218
10219err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010220#ifdef WLAN_KD_READY_NOTIFIER
10221 nl_srv_exit(pHddCtx->ptt_pid);
10222#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010223 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010224#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010225err_reg_netdev:
10226 unregister_netdevice_notifier(&hdd_netdev_notifier);
10227
Jeff Johnson295189b2012-06-20 16:38:30 -070010228err_unregister_pmops:
10229 hddDevTmUnregisterNotifyCallback(pHddCtx);
10230 hddDeregisterPmOps(pHddCtx);
10231
Yue Ma0d4891e2013-08-06 17:01:45 -070010232 hdd_debugfs_exit(pHddCtx);
10233
Jeff Johnson295189b2012-06-20 16:38:30 -070010234#ifdef WLAN_BTAMP_FEATURE
10235err_bap_stop:
10236 WLANBAP_Stop(pVosContext);
10237#endif
10238
10239#ifdef WLAN_BTAMP_FEATURE
10240err_bap_close:
10241 WLANBAP_Close(pVosContext);
10242#endif
10243
Jeff Johnson295189b2012-06-20 16:38:30 -070010244err_close_adapter:
10245 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010246#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010247err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010248#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010249 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010250err_vosstop:
10251 vos_stop(pVosContext);
10252
Amar Singhala49cbc52013-10-08 18:37:44 -070010253err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 status = vos_sched_close( pVosContext );
10255 if (!VOS_IS_STATUS_SUCCESS(status)) {
10256 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10257 "%s: Failed to close VOSS Scheduler", __func__);
10258 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10259 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010260 vos_close(pVosContext );
10261
Amar Singhal0a402232013-10-11 20:57:16 -070010262err_vos_nv_close:
10263
c_hpothue6a36282014-03-19 12:27:38 +053010264#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010265 vos_nv_close();
10266
c_hpothu70f8d812014-03-22 22:59:23 +053010267#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010268
10269err_wdclose:
10270 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10271 vos_watchdog_close(pVosContext);
10272
Jeff Johnson295189b2012-06-20 16:38:30 -070010273err_config:
10274 kfree(pHddCtx->cfg_ini);
10275 pHddCtx->cfg_ini= NULL;
10276
10277err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010278 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010279 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 wiphy_free(wiphy) ;
10281 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 VOS_BUG(1);
10283
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010284 if (hdd_is_ssr_required())
10285 {
10286 /* WDI timeout had happened during load, so SSR is needed here */
10287 subsystem_restart("wcnss");
10288 msleep(5000);
10289 }
10290 hdd_set_ssr_required (VOS_FALSE);
10291
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010292 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010293
10294success:
10295 EXIT();
10296 return 0;
10297}
10298
10299/**---------------------------------------------------------------------------
10300
Jeff Johnson32d95a32012-09-10 13:15:23 -070010301 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010302
Jeff Johnson32d95a32012-09-10 13:15:23 -070010303 This is the driver entry point - called in different timeline depending
10304 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010305
10306 \param - None
10307
10308 \return - 0 for success, non zero for failure
10309
10310 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010311static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010312{
10313 VOS_STATUS status;
10314 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 struct device *dev = NULL;
10316 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010317#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10318 int max_retries = 0;
10319#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010320#ifdef HAVE_CBC_DONE
10321 int max_cbc_retries = 0;
10322#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010323
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010324#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10325 wlan_logging_sock_init_svc();
10326#endif
10327
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 ENTER();
10329
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010330 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010331
10332 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10333 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10334
Jeff Johnson295189b2012-06-20 16:38:30 -070010335#ifdef ANI_BUS_TYPE_PCI
10336
10337 dev = wcnss_wlan_get_device();
10338
10339#endif // ANI_BUS_TYPE_PCI
10340
10341#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010342
10343#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10344 /* wait until WCNSS driver downloads NV */
10345 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10346 msleep(1000);
10347 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010348
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010349 if (max_retries >= 5) {
10350 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010351 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010352#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10353 wlan_logging_sock_deinit_svc();
10354#endif
10355
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010356 return -ENODEV;
10357 }
10358#endif
10359
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010360#ifdef HAVE_CBC_DONE
10361 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10362 msleep(1000);
10363 }
10364 if (max_cbc_retries >= 10) {
10365 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10366 }
10367#endif
10368
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 dev = wcnss_wlan_get_device();
10370#endif // ANI_BUS_TYPE_PLATFORM
10371
10372
10373 do {
10374 if (NULL == dev) {
10375 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10376 ret_status = -1;
10377 break;
10378 }
10379
Jeff Johnson295189b2012-06-20 16:38:30 -070010380#ifdef TIMER_MANAGER
10381 vos_timer_manager_init();
10382#endif
10383
10384 /* Preopen VOSS so that it is ready to start at least SAL */
10385 status = vos_preOpen(&pVosContext);
10386
10387 if (!VOS_IS_STATUS_SUCCESS(status))
10388 {
10389 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10390 ret_status = -1;
10391 break;
10392 }
10393
Sushant Kaushik02beb352015-06-04 15:15:01 +053010394 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010395#ifndef MODULE
10396 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10397 */
10398 hdd_set_conparam((v_UINT_t)con_mode);
10399#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010400
10401 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010402 if (hdd_wlan_startup(dev))
10403 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010405 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 vos_preClose( &pVosContext );
10407 ret_status = -1;
10408 break;
10409 }
10410
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 } while (0);
10412
10413 if (0 != ret_status)
10414 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010415#ifdef TIMER_MANAGER
10416 vos_timer_exit();
10417#endif
10418#ifdef MEMORY_DEBUG
10419 vos_mem_exit();
10420#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010421 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010422#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10423 wlan_logging_sock_deinit_svc();
10424#endif
10425
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10427 }
10428 else
10429 {
10430 //Send WLAN UP indication to Nlink Service
10431 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10432
10433 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010434 }
10435
10436 EXIT();
10437
10438 return ret_status;
10439}
10440
Jeff Johnson32d95a32012-09-10 13:15:23 -070010441/**---------------------------------------------------------------------------
10442
10443 \brief hdd_module_init() - Init Function
10444
10445 This is the driver entry point (invoked when module is loaded using insmod)
10446
10447 \param - None
10448
10449 \return - 0 for success, non zero for failure
10450
10451 --------------------------------------------------------------------------*/
10452#ifdef MODULE
10453static int __init hdd_module_init ( void)
10454{
10455 return hdd_driver_init();
10456}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010457#else /* #ifdef MODULE */
10458static int __init hdd_module_init ( void)
10459{
10460 /* Driver initialization is delayed to fwpath_changed_handler */
10461 return 0;
10462}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010463#endif /* #ifdef MODULE */
10464
Jeff Johnson295189b2012-06-20 16:38:30 -070010465
10466/**---------------------------------------------------------------------------
10467
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010468 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010469
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010470 This is the driver exit point (invoked when module is unloaded using rmmod
10471 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010472
10473 \param - None
10474
10475 \return - None
10476
10477 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010478static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010479{
10480 hdd_context_t *pHddCtx = NULL;
10481 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010482 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010483 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010484
10485 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10486
10487 //Get the global vos context
10488 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10489
10490 if(!pVosContext)
10491 {
10492 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10493 goto done;
10494 }
10495
10496 //Get the HDD context.
10497 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10498
10499 if(!pHddCtx)
10500 {
10501 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10502 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010503 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10504 {
10505 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10506 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10507 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10508 hdd_wlan_exit(pHddCtx);
10509 vos_preClose( &pVosContext );
10510 goto done;
10511 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 else
10513 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010514 /* We wait for active entry threads to exit from driver
10515 * by waiting until rtnl_lock is available.
10516 */
10517 rtnl_lock();
10518 rtnl_unlock();
10519
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010520 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10521 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10522 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10523 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010525 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010526 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10527 msecs_to_jiffies(30000));
10528 if(!rc)
10529 {
10530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10531 "%s:SSR timedout, fatal error", __func__);
10532 VOS_BUG(0);
10533 }
10534 }
10535
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010536 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10537 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010538
c_hpothu8adb97b2014-12-08 19:38:20 +053010539 /* Driver Need to send country code 00 in below condition
10540 * 1) If gCountryCodePriority is set to 1; and last country
10541 * code set is through 11d. This needs to be done in case
10542 * when NV country code is 00.
10543 * This Needs to be done as when kernel store last country
10544 * code and if stored country code is not through 11d,
10545 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10546 * in next load/unload as soon as we get any country through
10547 * 11d. In sme_HandleChangeCountryCodeByUser
10548 * pMsg->countryCode will be last countryCode and
10549 * pMac->scan.countryCode11d will be country through 11d so
10550 * due to mismatch driver will disable 11d.
10551 *
10552 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010553
c_hpothu8adb97b2014-12-08 19:38:20 +053010554 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010555 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010556 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010557 {
10558 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010559 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010560 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10561 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010562
c_hpothu8adb97b2014-12-08 19:38:20 +053010563 //Do all the cleanup before deregistering the driver
10564 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 }
10566
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 vos_preClose( &pVosContext );
10568
10569#ifdef TIMER_MANAGER
10570 vos_timer_exit();
10571#endif
10572#ifdef MEMORY_DEBUG
10573 vos_mem_exit();
10574#endif
10575
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010576#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10577 wlan_logging_sock_deinit_svc();
10578#endif
10579
Jeff Johnson295189b2012-06-20 16:38:30 -070010580done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010581 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010582
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10584}
10585
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010586/**---------------------------------------------------------------------------
10587
10588 \brief hdd_module_exit() - Exit function
10589
10590 This is the driver exit point (invoked when module is unloaded using rmmod)
10591
10592 \param - None
10593
10594 \return - None
10595
10596 --------------------------------------------------------------------------*/
10597static void __exit hdd_module_exit(void)
10598{
10599 hdd_driver_exit();
10600}
10601
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010602#ifdef MODULE
10603static int fwpath_changed_handler(const char *kmessage,
10604 struct kernel_param *kp)
10605{
Jeff Johnson76052702013-04-16 13:55:05 -070010606 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010607}
10608
10609static int con_mode_handler(const char *kmessage,
10610 struct kernel_param *kp)
10611{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010612 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010613}
10614#else /* #ifdef MODULE */
10615/**---------------------------------------------------------------------------
10616
Jeff Johnson76052702013-04-16 13:55:05 -070010617 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010618
Jeff Johnson76052702013-04-16 13:55:05 -070010619 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010620 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010621 - invoked when module parameter fwpath is modified from userspace to signal
10622 initializing the WLAN driver or when con_mode is modified from userspace
10623 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010624
10625 \return - 0 for success, non zero for failure
10626
10627 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010628static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010629{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010630 int ret_status;
10631
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010632 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010633 ret_status = hdd_driver_init();
10634 wlan_hdd_inited = ret_status ? 0 : 1;
10635 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010636 }
10637
10638 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010639
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010640 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010641
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010642 ret_status = hdd_driver_init();
10643 wlan_hdd_inited = ret_status ? 0 : 1;
10644 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010645}
10646
Jeff Johnson295189b2012-06-20 16:38:30 -070010647/**---------------------------------------------------------------------------
10648
Jeff Johnson76052702013-04-16 13:55:05 -070010649 \brief fwpath_changed_handler() - Handler Function
10650
10651 Handle changes to the fwpath parameter
10652
10653 \return - 0 for success, non zero for failure
10654
10655 --------------------------------------------------------------------------*/
10656static int fwpath_changed_handler(const char *kmessage,
10657 struct kernel_param *kp)
10658{
10659 int ret;
10660
10661 ret = param_set_copystring(kmessage, kp);
10662 if (0 == ret)
10663 ret = kickstart_driver();
10664 return ret;
10665}
10666
10667/**---------------------------------------------------------------------------
10668
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010669 \brief con_mode_handler() -
10670
10671 Handler function for module param con_mode when it is changed by userspace
10672 Dynamically linked - do nothing
10673 Statically linked - exit and init driver, as in rmmod and insmod
10674
Jeff Johnson76052702013-04-16 13:55:05 -070010675 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010676
Jeff Johnson76052702013-04-16 13:55:05 -070010677 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010678
10679 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010680static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010681{
Jeff Johnson76052702013-04-16 13:55:05 -070010682 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010683
Jeff Johnson76052702013-04-16 13:55:05 -070010684 ret = param_set_int(kmessage, kp);
10685 if (0 == ret)
10686 ret = kickstart_driver();
10687 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010688}
10689#endif /* #ifdef MODULE */
10690
10691/**---------------------------------------------------------------------------
10692
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 \brief hdd_get_conparam() -
10694
10695 This is the driver exit point (invoked when module is unloaded using rmmod)
10696
10697 \param - None
10698
10699 \return - tVOS_CON_MODE
10700
10701 --------------------------------------------------------------------------*/
10702tVOS_CON_MODE hdd_get_conparam ( void )
10703{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010704#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010706#else
10707 return (tVOS_CON_MODE)curr_con_mode;
10708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010709}
10710void hdd_set_conparam ( v_UINT_t newParam )
10711{
10712 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010713#ifndef MODULE
10714 curr_con_mode = con_mode;
10715#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010716}
10717/**---------------------------------------------------------------------------
10718
10719 \brief hdd_softap_sta_deauth() - function
10720
10721 This to take counter measure to handle deauth req from HDD
10722
10723 \param - pAdapter - Pointer to the HDD
10724
10725 \param - enable - boolean value
10726
10727 \return - None
10728
10729 --------------------------------------------------------------------------*/
10730
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010731VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10732 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010733{
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010735 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010736
10737 ENTER();
10738
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010739 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10740 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010741
10742 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010743 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010744 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010745
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010746 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010747
10748 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010749 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010750}
10751
10752/**---------------------------------------------------------------------------
10753
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010754 \brief hdd_del_all_sta() - function
10755
10756 This function removes all the stations associated on stopping AP/P2P GO.
10757
10758 \param - pAdapter - Pointer to the HDD
10759
10760 \return - None
10761
10762 --------------------------------------------------------------------------*/
10763
10764int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10765{
10766 v_U16_t i;
10767 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010768 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10769 ptSapContext pSapCtx = NULL;
10770 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10771 if(pSapCtx == NULL){
10772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10773 FL("psapCtx is NULL"));
10774 return 1;
10775 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010776 ENTER();
10777
10778 hddLog(VOS_TRACE_LEVEL_INFO,
10779 "%s: Delete all STAs associated.",__func__);
10780 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10781 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10782 )
10783 {
10784 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10785 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010786 if ((pSapCtx->aStaInfo[i].isUsed) &&
10787 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010788 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010789 struct tagCsrDelStaParams delStaParams;
10790
10791 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010792 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010793 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10794 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010795 &delStaParams);
10796 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010797 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010798 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010799 }
10800 }
10801 }
10802
10803 EXIT();
10804 return 0;
10805}
10806
10807/**---------------------------------------------------------------------------
10808
Jeff Johnson295189b2012-06-20 16:38:30 -070010809 \brief hdd_softap_sta_disassoc() - function
10810
10811 This to take counter measure to handle deauth req from HDD
10812
10813 \param - pAdapter - Pointer to the HDD
10814
10815 \param - enable - boolean value
10816
10817 \return - None
10818
10819 --------------------------------------------------------------------------*/
10820
10821void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10822{
10823 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10824
10825 ENTER();
10826
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010827 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010828
10829 //Ignore request to disassoc bcmc station
10830 if( pDestMacAddress[0] & 0x1 )
10831 return;
10832
10833 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10834}
10835
10836void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10837{
10838 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10839
10840 ENTER();
10841
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010842 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010843
10844 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10845}
10846
Jeff Johnson295189b2012-06-20 16:38:30 -070010847/**---------------------------------------------------------------------------
10848 *
10849 * \brief hdd_get__concurrency_mode() -
10850 *
10851 *
10852 * \param - None
10853 *
10854 * \return - CONCURRENCY MODE
10855 *
10856 * --------------------------------------------------------------------------*/
10857tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10858{
10859 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10860 hdd_context_t *pHddCtx;
10861
10862 if (NULL != pVosContext)
10863 {
10864 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10865 if (NULL != pHddCtx)
10866 {
10867 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10868 }
10869 }
10870
10871 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010872 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010873 return VOS_STA;
10874}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010875v_BOOL_t
10876wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10877{
10878 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010879
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010880 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10881 if (pAdapter == NULL)
10882 {
10883 hddLog(VOS_TRACE_LEVEL_INFO,
10884 FL("GO doesn't exist"));
10885 return TRUE;
10886 }
10887 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10888 {
10889 hddLog(VOS_TRACE_LEVEL_INFO,
10890 FL("GO started"));
10891 return TRUE;
10892 }
10893 else
10894 /* wait till GO changes its interface to p2p device */
10895 hddLog(VOS_TRACE_LEVEL_INFO,
10896 FL("Del_bss called, avoid apps suspend"));
10897 return FALSE;
10898
10899}
Jeff Johnson295189b2012-06-20 16:38:30 -070010900/* Decide whether to allow/not the apps power collapse.
10901 * Allow apps power collapse if we are in connected state.
10902 * if not, allow only if we are in IMPS */
10903v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10904{
10905 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010906 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010907 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10909 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10910 hdd_adapter_t *pAdapter = NULL;
10911 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010912 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010913
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10915 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010916
Yathish9f22e662012-12-10 14:21:35 -080010917 concurrent_state = hdd_get_concurrency_mode();
10918
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010919 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10920 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10921 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010922#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010923
Yathish9f22e662012-12-10 14:21:35 -080010924 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010925 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010926 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10927 return TRUE;
10928#endif
10929
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 /*loop through all adapters. TBD fix for Concurrency */
10931 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10932 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10933 {
10934 pAdapter = pAdapterNode->pAdapter;
10935 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10936 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10937 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010938 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010939 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010940 && pmcState != STOPPED && pmcState != STANDBY &&
10941 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010942 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10943 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010944 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010945 if(pmcState == FULL_POWER &&
10946 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10947 {
10948 /*
10949 * When SCO indication comes from Coex module , host will
10950 * enter in to full power mode, but this should not prevent
10951 * apps processor power collapse.
10952 */
10953 hddLog(LOG1,
10954 FL("Allow apps power collapse"
10955 "even when sco indication is set"));
10956 return TRUE;
10957 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010958 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010959 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10960 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010961 return FALSE;
10962 }
10963 }
10964 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10965 pAdapterNode = pNext;
10966 }
10967 return TRUE;
10968}
10969
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010970/* Decides whether to send suspend notification to Riva
10971 * if any adapter is in BMPS; then it is required */
10972v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10973{
10974 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10975 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10976
10977 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10978 {
10979 return TRUE;
10980 }
10981 return FALSE;
10982}
10983
Jeff Johnson295189b2012-06-20 16:38:30 -070010984void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10985{
10986 switch(mode)
10987 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010988 case VOS_STA_MODE:
10989 case VOS_P2P_CLIENT_MODE:
10990 case VOS_P2P_GO_MODE:
10991 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010992 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010993 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 break;
10995 default:
10996 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010998 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10999 "Number of open sessions for mode %d = %d"),
11000 pHddCtx->concurrency_mode, mode,
11001 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011002}
11003
11004
11005void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11006{
11007 switch(mode)
11008 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011009 case VOS_STA_MODE:
11010 case VOS_P2P_CLIENT_MODE:
11011 case VOS_P2P_GO_MODE:
11012 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011013 pHddCtx->no_of_open_sessions[mode]--;
11014 if (!(pHddCtx->no_of_open_sessions[mode]))
11015 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 break;
11017 default:
11018 break;
11019 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011020 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11021 "Number of open sessions for mode %d = %d"),
11022 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11023
11024}
11025/**---------------------------------------------------------------------------
11026 *
11027 * \brief wlan_hdd_incr_active_session()
11028 *
11029 * This function increments the number of active sessions
11030 * maintained per device mode
11031 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11032 * Incase of SAP/P2P GO upon bss start it is incremented
11033 *
11034 * \param pHddCtx - HDD Context
11035 * \param mode - device mode
11036 *
11037 * \return - None
11038 *
11039 * --------------------------------------------------------------------------*/
11040void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11041{
11042 switch (mode) {
11043 case VOS_STA_MODE:
11044 case VOS_P2P_CLIENT_MODE:
11045 case VOS_P2P_GO_MODE:
11046 case VOS_STA_SAP_MODE:
11047 pHddCtx->no_of_active_sessions[mode]++;
11048 break;
11049 default:
11050 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11051 break;
11052 }
11053 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11054 mode,
11055 pHddCtx->no_of_active_sessions[mode]);
11056}
11057
11058/**---------------------------------------------------------------------------
11059 *
11060 * \brief wlan_hdd_decr_active_session()
11061 *
11062 * This function decrements the number of active sessions
11063 * maintained per device mode
11064 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11065 * Incase of SAP/P2P GO upon bss stop it is decremented
11066 *
11067 * \param pHddCtx - HDD Context
11068 * \param mode - device mode
11069 *
11070 * \return - None
11071 *
11072 * --------------------------------------------------------------------------*/
11073void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11074{
11075 switch (mode) {
11076 case VOS_STA_MODE:
11077 case VOS_P2P_CLIENT_MODE:
11078 case VOS_P2P_GO_MODE:
11079 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011080 if (pHddCtx->no_of_active_sessions[mode] > 0)
11081 pHddCtx->no_of_active_sessions[mode]--;
11082 else
11083 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11084 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011085 break;
11086 default:
11087 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11088 break;
11089 }
11090 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11091 mode,
11092 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011093}
11094
Jeff Johnsone7245742012-09-05 17:12:55 -070011095/**---------------------------------------------------------------------------
11096 *
11097 * \brief wlan_hdd_restart_init
11098 *
11099 * This function initalizes restart timer/flag. An internal function.
11100 *
11101 * \param - pHddCtx
11102 *
11103 * \return - None
11104 *
11105 * --------------------------------------------------------------------------*/
11106
11107static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11108{
11109 /* Initialize */
11110 pHddCtx->hdd_restart_retries = 0;
11111 atomic_set(&pHddCtx->isRestartInProgress, 0);
11112 vos_timer_init(&pHddCtx->hdd_restart_timer,
11113 VOS_TIMER_TYPE_SW,
11114 wlan_hdd_restart_timer_cb,
11115 pHddCtx);
11116}
11117/**---------------------------------------------------------------------------
11118 *
11119 * \brief wlan_hdd_restart_deinit
11120 *
11121 * This function cleans up the resources used. An internal function.
11122 *
11123 * \param - pHddCtx
11124 *
11125 * \return - None
11126 *
11127 * --------------------------------------------------------------------------*/
11128
11129static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11130{
11131
11132 VOS_STATUS vos_status;
11133 /* Block any further calls */
11134 atomic_set(&pHddCtx->isRestartInProgress, 1);
11135 /* Cleanup */
11136 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11137 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011138 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011139 vos_status = vos_timer_destroy(&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 destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011142
11143}
11144
11145/**---------------------------------------------------------------------------
11146 *
11147 * \brief wlan_hdd_framework_restart
11148 *
11149 * This function uses a cfg80211 API to start a framework initiated WLAN
11150 * driver module unload/load.
11151 *
11152 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11153 *
11154 *
11155 * \param - pHddCtx
11156 *
11157 * \return - VOS_STATUS_SUCCESS: Success
11158 * VOS_STATUS_E_EMPTY: Adapter is Empty
11159 * VOS_STATUS_E_NOMEM: No memory
11160
11161 * --------------------------------------------------------------------------*/
11162
11163static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11164{
11165 VOS_STATUS status = VOS_STATUS_SUCCESS;
11166 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011167 int len = (sizeof (struct ieee80211_mgmt));
11168 struct ieee80211_mgmt *mgmt = NULL;
11169
11170 /* Prepare the DEAUTH managment frame with reason code */
11171 mgmt = kzalloc(len, GFP_KERNEL);
11172 if(mgmt == NULL)
11173 {
11174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11175 "%s: memory allocation failed (%d bytes)", __func__, len);
11176 return VOS_STATUS_E_NOMEM;
11177 }
11178 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011179
11180 /* Iterate over all adapters/devices */
11181 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011182 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11183 {
11184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11185 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11186 goto end;
11187 }
11188
Jeff Johnsone7245742012-09-05 17:12:55 -070011189 do
11190 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011191 if(pAdapterNode->pAdapter &&
11192 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011193 {
11194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11195 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11196 pAdapterNode->pAdapter->dev->name,
11197 pAdapterNode->pAdapter->device_mode,
11198 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011199 /*
11200 * CFG80211 event to restart the driver
11201 *
11202 * 'cfg80211_send_unprot_deauth' sends a
11203 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11204 * of SME(Linux Kernel) state machine.
11205 *
11206 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11207 * the driver.
11208 *
11209 */
11210
11211 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011212 }
11213 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11214 pAdapterNode = pNext;
11215 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11216
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011217 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011218 /* Free the allocated management frame */
11219 kfree(mgmt);
11220
Jeff Johnsone7245742012-09-05 17:12:55 -070011221 /* Retry until we unload or reach max count */
11222 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11223 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11224
11225 return status;
11226
11227}
11228/**---------------------------------------------------------------------------
11229 *
11230 * \brief wlan_hdd_restart_timer_cb
11231 *
11232 * Restart timer callback. An internal function.
11233 *
11234 * \param - User data:
11235 *
11236 * \return - None
11237 *
11238 * --------------------------------------------------------------------------*/
11239
11240void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11241{
11242 hdd_context_t *pHddCtx = usrDataForCallback;
11243 wlan_hdd_framework_restart(pHddCtx);
11244 return;
11245
11246}
11247
11248
11249/**---------------------------------------------------------------------------
11250 *
11251 * \brief wlan_hdd_restart_driver
11252 *
11253 * This function sends an event to supplicant to restart the WLAN driver.
11254 *
11255 * This function is called from vos_wlanRestart.
11256 *
11257 * \param - pHddCtx
11258 *
11259 * \return - VOS_STATUS_SUCCESS: Success
11260 * VOS_STATUS_E_EMPTY: Adapter is Empty
11261 * VOS_STATUS_E_ALREADY: Request already in progress
11262
11263 * --------------------------------------------------------------------------*/
11264VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11265{
11266 VOS_STATUS status = VOS_STATUS_SUCCESS;
11267
11268 /* A tight check to make sure reentrancy */
11269 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11270 {
Mihir Shetefd528652014-06-23 19:07:50 +053011271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011272 "%s: WLAN restart is already in progress", __func__);
11273
11274 return VOS_STATUS_E_ALREADY;
11275 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011276 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011277#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011278 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011279#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011280
Jeff Johnsone7245742012-09-05 17:12:55 -070011281 return status;
11282}
11283
Mihir Shetee1093ba2014-01-21 20:13:32 +053011284/**---------------------------------------------------------------------------
11285 *
11286 * \brief wlan_hdd_init_channels
11287 *
11288 * This function is used to initialize the channel list in CSR
11289 *
11290 * This function is called from hdd_wlan_startup
11291 *
11292 * \param - pHddCtx: HDD context
11293 *
11294 * \return - VOS_STATUS_SUCCESS: Success
11295 * VOS_STATUS_E_FAULT: Failure reported by SME
11296
11297 * --------------------------------------------------------------------------*/
11298static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11299{
11300 eHalStatus status;
11301
11302 status = sme_InitChannels(pHddCtx->hHal);
11303 if (HAL_STATUS_SUCCESS(status))
11304 {
11305 return VOS_STATUS_SUCCESS;
11306 }
11307 else
11308 {
11309 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11310 __func__, status);
11311 return VOS_STATUS_E_FAULT;
11312 }
11313}
11314
Mihir Shete04206452014-11-20 17:50:58 +053011315#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011316VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011317{
11318 eHalStatus status;
11319
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011320 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011321 if (HAL_STATUS_SUCCESS(status))
11322 {
11323 return VOS_STATUS_SUCCESS;
11324 }
11325 else
11326 {
11327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11328 __func__, status);
11329 return VOS_STATUS_E_FAULT;
11330 }
11331}
Mihir Shete04206452014-11-20 17:50:58 +053011332#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011333/*
11334 * API to find if there is any STA or P2P-Client is connected
11335 */
11336VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11337{
11338 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11339}
Jeff Johnsone7245742012-09-05 17:12:55 -070011340
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011341
11342/*
11343 * API to find if the firmware will send logs using DXE channel
11344 */
11345v_U8_t hdd_is_fw_logging_enabled(void)
11346{
11347 hdd_context_t *pHddCtx;
11348
11349 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11350 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11351
Sachin Ahuja084313e2015-05-21 17:57:10 +053011352 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011353}
11354
Agarwal Ashish57e84372014-12-05 18:26:53 +053011355/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011356 * API to find if the firmware will send trace logs using DXE channel
11357 */
11358v_U8_t hdd_is_fw_ev_logging_enabled(void)
11359{
11360 hdd_context_t *pHddCtx;
11361
11362 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11363 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11364
11365 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11366}
11367/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011368 * API to find if there is any session connected
11369 */
11370VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11371{
11372 return sme_is_any_session_connected(pHddCtx->hHal);
11373}
11374
11375
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011376int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11377{
11378 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11379 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011380 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011381 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011382
11383 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011384 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011385 if (pScanInfo->mScanPending)
11386 {
c_hpothua3d45d52015-01-05 14:11:17 +053011387 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11388 eCSR_SCAN_ABORT_DEFAULT);
11389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11390 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011391
c_hpothua3d45d52015-01-05 14:11:17 +053011392 /* If there is active scan command lets wait for the completion else
11393 * there is no need to wait as scan command might be in the SME pending
11394 * command list.
11395 */
11396 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11397 {
c_hpothua3d45d52015-01-05 14:11:17 +053011398 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011399 &pScanInfo->abortscan_event_var,
11400 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011401 if (0 >= status)
11402 {
11403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011404 "%s: Timeout or Interrupt occurred while waiting for abort"
11405 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011406 return -ETIMEDOUT;
11407 }
11408 }
11409 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11410 {
11411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11412 FL("hdd_abort_mac_scan failed"));
11413 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011414 }
11415 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011416 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011417}
11418
c_hpothu225aa7c2014-10-22 17:45:13 +053011419VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11420{
11421 hdd_adapter_t *pAdapter;
11422 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11423 VOS_STATUS vosStatus;
11424
11425 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11426 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11427 {
11428 pAdapter = pAdapterNode->pAdapter;
11429 if (NULL != pAdapter)
11430 {
11431 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11432 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11433 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11434 {
11435 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11436 pAdapter->device_mode);
11437 if (VOS_STATUS_SUCCESS !=
11438 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11439 {
11440 hddLog(LOGE, FL("failed to abort ROC"));
11441 return VOS_STATUS_E_FAILURE;
11442 }
11443 }
11444 }
11445 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11446 pAdapterNode = pNext;
11447 }
11448 return VOS_STATUS_SUCCESS;
11449}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011450
Mihir Shete0be28772015-02-17 18:42:14 +053011451hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11452{
11453 hdd_adapter_t *pAdapter;
11454 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11455 hdd_cfg80211_state_t *cfgState;
11456 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11457 VOS_STATUS vosStatus;
11458
11459 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11460 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11461 {
11462 pAdapter = pAdapterNode->pAdapter;
11463 if (NULL != pAdapter)
11464 {
11465 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11466 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11467 if (pRemainChanCtx)
11468 break;
11469 }
11470 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11471 pAdapterNode = pNext;
11472 }
11473 return pRemainChanCtx;
11474}
11475
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011476/**
11477 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11478 *
11479 * @pHddCtx: HDD context within host driver
11480 * @dfsScanMode: dfsScanMode passed from ioctl
11481 *
11482 */
11483
11484VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11485 tANI_U8 dfsScanMode)
11486{
11487 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11488 hdd_adapter_t *pAdapter;
11489 VOS_STATUS vosStatus;
11490 hdd_station_ctx_t *pHddStaCtx;
11491 eHalStatus status = eHAL_STATUS_SUCCESS;
11492
11493 if(!pHddCtx)
11494 {
11495 hddLog(LOGE, FL("HDD context is Null"));
11496 return eHAL_STATUS_FAILURE;
11497 }
11498
11499 if (pHddCtx->scan_info.mScanPending)
11500 {
11501 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11502 pHddCtx->scan_info.sessionId);
11503 hdd_abort_mac_scan(pHddCtx,
11504 pHddCtx->scan_info.sessionId,
11505 eCSR_SCAN_ABORT_DEFAULT);
11506 }
11507
11508 if (!dfsScanMode)
11509 {
11510 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11511 while ((NULL != pAdapterNode) &&
11512 (VOS_STATUS_SUCCESS == vosStatus))
11513 {
11514 pAdapter = pAdapterNode->pAdapter;
11515
11516 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11517 {
11518 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11519
11520 if(!pHddStaCtx)
11521 {
11522 hddLog(LOGE, FL("HDD STA context is Null"));
11523 return eHAL_STATUS_FAILURE;
11524 }
11525
11526 /* if STA is already connected on DFS channel,
11527 disconnect immediately*/
11528 if (hdd_connIsConnected(pHddStaCtx) &&
11529 (NV_CHANNEL_DFS ==
11530 vos_nv_getChannelEnabledState(
11531 pHddStaCtx->conn_info.operationChannel)))
11532 {
11533 status = sme_RoamDisconnect(pHddCtx->hHal,
11534 pAdapter->sessionId,
11535 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11536 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11537 "sme_RoamDisconnect returned with status: %d"
11538 "for sessionid: %d"), pHddStaCtx->conn_info.
11539 operationChannel, status, pAdapter->sessionId);
11540 }
11541 }
11542
11543 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11544 &pNext);
11545 pAdapterNode = pNext;
11546 }
11547 }
11548
11549 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11550 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11551 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11552
11553 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11554 if (!HAL_STATUS_SUCCESS(status))
11555 {
11556 hddLog(LOGE,
11557 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11558 return status;
11559 }
11560
11561 return status;
11562}
11563
Nirav Shah7e3c8132015-06-22 23:51:42 +053011564static int hdd_log2_ceil(unsigned value)
11565{
11566 /* need to switch to unsigned math so that negative values
11567 * will right-shift towards 0 instead of -1
11568 */
11569 unsigned tmp = value;
11570 int log2 = -1;
11571
11572 if (value == 0)
11573 return 0;
11574
11575 while (tmp) {
11576 log2++;
11577 tmp >>= 1;
11578 }
11579 if (1U << log2 != value)
11580 log2++;
11581
11582 return log2;
11583}
11584
11585/**
11586 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11587 * @pAdapter: adapter handle
11588 *
11589 * Return: vos status
11590 */
11591VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11592{
11593 int hash_elem, log2, i;
11594
11595 spin_lock_bh( &pAdapter->sta_hash_lock);
11596 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11597 spin_unlock_bh( &pAdapter->sta_hash_lock);
11598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11599 "%s: hash already attached for session id %d",
11600 __func__, pAdapter->sessionId);
11601 return VOS_STATUS_SUCCESS;
11602 }
11603 spin_unlock_bh( &pAdapter->sta_hash_lock);
11604
11605 hash_elem = WLAN_MAX_STA_COUNT;
11606 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11607 log2 = hdd_log2_ceil(hash_elem);
11608 hash_elem = 1 << log2;
11609
11610 pAdapter->sta_id_hash.mask = hash_elem - 1;
11611 pAdapter->sta_id_hash.idx_bits = log2;
11612 pAdapter->sta_id_hash.bins =
11613 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11614 if (!pAdapter->sta_id_hash.bins) {
11615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11616 "%s: malloc failed for session %d",
11617 __func__, pAdapter->sessionId);
11618 return VOS_STATUS_E_NOMEM;
11619 }
11620
11621 for (i = 0; i < hash_elem; i++)
11622 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11623
11624 spin_lock_bh( &pAdapter->sta_hash_lock);
11625 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11626 spin_unlock_bh( &pAdapter->sta_hash_lock);
11627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11628 "%s: Station ID Hash attached for session id %d",
11629 __func__, pAdapter->sessionId);
11630
11631 return VOS_STATUS_SUCCESS;
11632}
11633
11634/**
11635 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11636 * @pAdapter: adapter handle
11637 *
11638 * Return: vos status
11639 */
11640VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11641{
11642 int hash_elem, i;
11643 v_SIZE_t size;
11644
11645 spin_lock_bh( &pAdapter->sta_hash_lock);
11646 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11647 spin_unlock_bh( &pAdapter->sta_hash_lock);
11648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11649 "%s: hash not initialized for session id %d",
11650 __func__, pAdapter->sessionId);
11651 return VOS_STATUS_SUCCESS;
11652 }
11653
11654 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11655 spin_unlock_bh( &pAdapter->sta_hash_lock);
11656
11657 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11658
11659 /* free all station info*/
11660 for (i = 0; i < hash_elem; i++) {
11661 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11662 if (size != 0) {
11663 VOS_STATUS status;
11664 hdd_staid_hash_node_t *sta_info_node = NULL;
11665 hdd_staid_hash_node_t *next_node = NULL;
11666 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11667 (hdd_list_node_t**) &sta_info_node );
11668
11669 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11670 {
11671 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11672 &sta_info_node->node);
11673 vos_mem_free(sta_info_node);
11674
11675 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11676 (hdd_list_node_t*)sta_info_node,
11677 (hdd_list_node_t**)&next_node);
11678 sta_info_node = next_node;
11679 }
11680 }
11681 }
11682
11683 vos_mem_free(pAdapter->sta_id_hash.bins);
11684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11685 "%s: Station ID Hash detached for session id %d",
11686 __func__, pAdapter->sessionId);
11687 return VOS_STATUS_SUCCESS;
11688}
11689
11690/**
11691 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11692 * @pAdapter: adapter handle
11693 * @mac_addr_in: input mac address
11694 *
11695 * Return: index derived from mac address
11696 */
11697int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11698 v_MACADDR_t *mac_addr_in)
11699{
11700 uint16 index;
11701 struct hdd_align_mac_addr_t * mac_addr =
11702 (struct hdd_align_mac_addr_t *)mac_addr_in;
11703
11704 index = mac_addr->bytes_ab ^
11705 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11706 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11707 index &= pAdapter->sta_id_hash.mask;
11708 return index;
11709}
11710
11711/**
11712 * hdd_sta_id_hash_add_entry() - add entry in hash
11713 * @pAdapter: adapter handle
11714 * @sta_id: station id
11715 * @mac_addr: mac address
11716 *
11717 * Return: vos status
11718 */
11719VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11720 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11721{
11722 uint16 index;
11723 hdd_staid_hash_node_t *sta_info_node = NULL;
11724
11725 spin_lock_bh( &pAdapter->sta_hash_lock);
11726 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11727 spin_unlock_bh( &pAdapter->sta_hash_lock);
11728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11729 "%s: hash is not initialized for session id %d",
11730 __func__, pAdapter->sessionId);
11731 return VOS_STATUS_E_FAILURE;
11732 }
11733
11734 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11735 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11736 if (!sta_info_node) {
11737 spin_unlock_bh( &pAdapter->sta_hash_lock);
11738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11739 "%s: malloc failed", __func__);
11740 return VOS_STATUS_E_NOMEM;
11741 }
11742
11743 sta_info_node->sta_id = sta_id;
11744 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11745
11746 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11747 (hdd_list_node_t*) sta_info_node );
11748 spin_unlock_bh( &pAdapter->sta_hash_lock);
11749 return VOS_STATUS_SUCCESS;
11750}
11751
11752/**
11753 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11754 * @pAdapter: adapter handle
11755 * @sta_id: station id
11756 * @mac_addr: mac address
11757 *
11758 * Return: vos status
11759 */
11760VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11761 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11762{
11763 uint16 index;
11764 VOS_STATUS status;
11765 hdd_staid_hash_node_t *sta_info_node = NULL;
11766 hdd_staid_hash_node_t *next_node = NULL;
11767
11768 spin_lock_bh( &pAdapter->sta_hash_lock);
11769 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11770 spin_unlock_bh( &pAdapter->sta_hash_lock);
11771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11772 "%s: hash is not initialized for session id %d",
11773 __func__, pAdapter->sessionId);
11774 return VOS_STATUS_E_FAILURE;
11775 }
11776
11777 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11778 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11779 (hdd_list_node_t**) &sta_info_node );
11780
11781 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11782 {
11783 if (sta_info_node->sta_id == sta_id) {
11784 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11785 &sta_info_node->node);
11786 vos_mem_free(sta_info_node);
11787 break;
11788 }
11789 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11790 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11791 sta_info_node = next_node;
11792 }
11793 spin_unlock_bh( &pAdapter->sta_hash_lock);
11794 return status;
11795}
11796
11797/**
11798 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11799 * @pAdapter: adapter handle
11800 * @mac_addr_in: mac address
11801 *
11802 * Return: station id
11803 */
11804int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11805 v_MACADDR_t *mac_addr_in)
11806{
11807 uint8 is_found = 0;
11808 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11809 uint16 index;
11810 VOS_STATUS status;
11811 hdd_staid_hash_node_t *sta_info_node = NULL;
11812 hdd_staid_hash_node_t *next_node = NULL;
11813
11814 spin_lock_bh( &pAdapter->sta_hash_lock);
11815 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11816 spin_unlock_bh( &pAdapter->sta_hash_lock);
11817 hddLog(VOS_TRACE_LEVEL_ERROR,
11818 FL("hash is not initialized for session id %d"),
11819 pAdapter->sessionId);
11820 return HDD_WLAN_INVALID_STA_ID;
11821 }
11822
11823 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11824 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11825 (hdd_list_node_t**) &sta_info_node );
11826
11827 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11828 {
11829 if (vos_mem_compare(&sta_info_node->mac_addr,
11830 mac_addr_in, sizeof(v_MACADDR_t))) {
11831 is_found = 1;
11832 sta_id = sta_info_node->sta_id;
11833 break;
11834 }
11835 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11836 (hdd_list_node_t*)sta_info_node,
11837 (hdd_list_node_t**)&next_node);
11838 sta_info_node = next_node;
11839 }
11840 spin_unlock_bh( &pAdapter->sta_hash_lock);
11841 return sta_id;
11842}
11843
Jeff Johnson295189b2012-06-20 16:38:30 -070011844//Register the module init/exit functions
11845module_init(hdd_module_init);
11846module_exit(hdd_module_exit);
11847
11848MODULE_LICENSE("Dual BSD/GPL");
11849MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11850MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11851
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011852module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11853 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011854
Jeff Johnson76052702013-04-16 13:55:05 -070011855module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011856 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011857
11858module_param(enable_dfs_chan_scan, int,
11859 S_IRUSR | S_IRGRP | S_IROTH);
11860
11861module_param(enable_11d, int,
11862 S_IRUSR | S_IRGRP | S_IROTH);
11863
11864module_param(country_code, charp,
11865 S_IRUSR | S_IRGRP | S_IROTH);