blob: cd7775512e8929ef9e6aeb408fd8cbbc5257d6c3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
210 struct sk_buff *skb);
211
212#ifdef WLAN_FEATURE_PACKET_FILTERING
213static void hdd_set_multicast_list(struct net_device *dev);
214#endif
215
216void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
217
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800218#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800219void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
220static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700221static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
222 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
223 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700224static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
225 tANI_U8 *pTargetApBssid,
226 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800227#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530228
229/* Store WLAN driver info in a global variable such that crash debugger
230 can extract it from driver debug symbol and crashdump for post processing */
231tANI_U8 g_wlan_driver[ ] = "pronto_driver";
232
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530238const char * hdd_device_modetoString(v_U8_t device_mode)
239{
240 switch(device_mode)
241 {
242 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
243 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
246 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
247 CASE_RETURN_STRING( WLAN_HDD_FTM );
248 CASE_RETURN_STRING( WLAN_HDD_IBSS );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
250 default:
251 return "device_mode Unknown";
252 }
253}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530254
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530255static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700256 unsigned long state,
257 void *ndev)
258{
259 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#ifdef WLAN_BTAMP_FEATURE
263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530265 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
267 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700269 (strncmp(dev->name, "p2p", 3)))
270 return NOTIFY_DONE;
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 VOS_ASSERT(0);
279 return NOTIFY_DONE;
280 }
281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
283 if (NULL == pHddCtx)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
286 VOS_ASSERT(0);
287 return NOTIFY_DONE;
288 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800289 if (pHddCtx->isLogpInProgress)
290 return NOTIFY_DONE;
291
Jeff Johnson27cee452013-03-27 11:10:24 -0700292
293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
294 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 switch (state) {
297 case NETDEV_REGISTER:
298 break;
299
300 case NETDEV_UNREGISTER:
301 break;
302
303 case NETDEV_UP:
304 break;
305
306 case NETDEV_DOWN:
307 break;
308
309 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700310 if(TRUE == pAdapter->isLinkUpSvcNeeded)
311 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 break;
313
314 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530316 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
319 "%s: Timeout occurred while waiting for abortscan %ld",
320 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 }
322 else
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530325 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 status = WLANBAP_StopAmp();
330 if(VOS_STATUS_SUCCESS != status )
331 {
332 pHddCtx->isAmpAllowed = VOS_TRUE;
333 hddLog(VOS_TRACE_LEVEL_FATAL,
334 "%s: Failed to stop AMP", __func__);
335 }
336 else
337 {
338 //a state m/c implementation in PAL is TBD to avoid this delay
339 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700340 if ( pHddCtx->isAmpAllowed )
341 {
342 WLANBAP_DeregisterFromHCI();
343 pHddCtx->isAmpAllowed = VOS_FALSE;
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346#endif //WLAN_BTAMP_FEATURE
347 break;
348
349 default:
350 break;
351 }
352
353 return NOTIFY_DONE;
354}
355
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530356static int hdd_netdev_notifier_call(struct notifier_block * nb,
357 unsigned long state,
358 void *ndev)
359{
360 int ret;
361 vos_ssr_protect(__func__);
362 ret = __hdd_netdev_notifier_call( nb, state, ndev);
363 vos_ssr_unprotect(__func__);
364 return ret;
365}
366
Jeff Johnson295189b2012-06-20 16:38:30 -0700367struct notifier_block hdd_netdev_notifier = {
368 .notifier_call = hdd_netdev_notifier_call,
369};
370
371/*---------------------------------------------------------------------------
372 * Function definitions
373 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700374void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
375void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700377static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700378#ifndef MODULE
379/* current con_mode - used only for statically linked driver
380 * con_mode is changed by userspace to indicate a mode change which will
381 * result in calling the module exit and init functions. The module
382 * exit function will clean up based on the value of con_mode prior to it
383 * being changed by userspace. So curr_con_mode records the current con_mode
384 * for exit when con_mode becomes the next mode for init
385 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700386static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700387#endif
388
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800389/**---------------------------------------------------------------------------
390
391 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
392
393 Called immediately after the cfg.ini is read in order to configure
394 the desired trace levels.
395
396 \param - moduleId - module whose trace level is being configured
397 \param - bitmask - bitmask of log levels to be enabled
398
399 \return - void
400
401 --------------------------------------------------------------------------*/
402static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
403{
404 wpt_tracelevel level;
405
406 /* if the bitmask is the default value, then a bitmask was not
407 specified in cfg.ini, so leave the logging level alone (it
408 will remain at the "compiled in" default value) */
409 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
410 {
411 return;
412 }
413
414 /* a mask was specified. start by disabling all logging */
415 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
416
417 /* now cycle through the bitmask until all "set" bits are serviced */
418 level = VOS_TRACE_LEVEL_FATAL;
419 while (0 != bitmask)
420 {
421 if (bitmask & 1)
422 {
423 vos_trace_setValue(moduleId, level, 1);
424 }
425 level++;
426 bitmask >>= 1;
427 }
428}
429
430
Jeff Johnson295189b2012-06-20 16:38:30 -0700431/**---------------------------------------------------------------------------
432
433 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
434
435 Called immediately after the cfg.ini is read in order to configure
436 the desired trace levels in the WDI.
437
438 \param - moduleId - module whose trace level is being configured
439 \param - bitmask - bitmask of log levels to be enabled
440
441 \return - void
442
443 --------------------------------------------------------------------------*/
444static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
445{
446 wpt_tracelevel level;
447
448 /* if the bitmask is the default value, then a bitmask was not
449 specified in cfg.ini, so leave the logging level alone (it
450 will remain at the "compiled in" default value) */
451 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
452 {
453 return;
454 }
455
456 /* a mask was specified. start by disabling all logging */
457 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
458
459 /* now cycle through the bitmask until all "set" bits are serviced */
460 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
461 while (0 != bitmask)
462 {
463 if (bitmask & 1)
464 {
465 wpalTraceSetLevel(moduleId, level, 1);
466 }
467 level++;
468 bitmask >>= 1;
469 }
470}
Jeff Johnson295189b2012-06-20 16:38:30 -0700471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530472/*
473 * FUNCTION: wlan_hdd_validate_context
474 * This function is used to check the HDD context
475 */
476int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
477{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478
479 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
480 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 "%s: HDD context is Null", __func__);
483 return -ENODEV;
484 }
485
486 if (pHddCtx->isLogpInProgress)
487 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530489 "%s: LOGP %s. Ignore!!", __func__,
490 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
491 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 return -EAGAIN;
493 }
494
Mihir Shete18156292014-03-11 15:38:30 +0530495 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530498 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
499 return -EAGAIN;
500 }
501 return 0;
502}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700503#ifdef CONFIG_ENABLE_LINUX_REG
504void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
505{
506 hdd_adapter_t *pAdapter = NULL;
507 hdd_station_ctx_t *pHddStaCtx = NULL;
508 eCsrPhyMode phyMode;
509 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530510
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700511 if (NULL == pHddCtx)
512 {
513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
514 "HDD Context is null !!");
515 return ;
516 }
517
518 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
519 if (NULL == pAdapter)
520 {
521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
522 "pAdapter is null !!");
523 return ;
524 }
525
526 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
527 if (NULL == pHddStaCtx)
528 {
529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
530 "pHddStaCtx is null !!");
531 return ;
532 }
533
534 cfg_param = pHddCtx->cfg_ini;
535 if (NULL == cfg_param)
536 {
537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
538 "cfg_params not available !!");
539 return ;
540 }
541
542 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
543
544 if (!pHddCtx->isVHT80Allowed)
545 {
546 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
547 (eCSR_DOT11_MODE_11ac == phyMode) ||
548 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
549 {
550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
551 "Setting phymode to 11n!!");
552 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
553 }
554 }
555 else
556 {
557 /*New country Supports 11ac as well resetting value back from .ini*/
558 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
559 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
560 return ;
561 }
562
563 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
564 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
565 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
566 {
567 VOS_STATUS vosStatus;
568
569 // need to issue a disconnect to CSR.
570 INIT_COMPLETION(pAdapter->disconnect_comp_var);
571 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
572 pAdapter->sessionId,
573 eCSR_DISCONNECT_REASON_UNSPECIFIED );
574
575 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530576 {
577 long ret;
578
579 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700580 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 if (0 >= ret)
582 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
583 ret);
584 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700585
586 }
587}
588#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
590{
591 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
592 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
593 hdd_config_t *cfg_param;
594 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530595 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530596
597 if (NULL == pHddCtx)
598 {
599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
600 "HDD Context is null !!");
601 return ;
602 }
603
604 cfg_param = pHddCtx->cfg_ini;
605
606 if (NULL == cfg_param)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
609 "cfg_params not available !!");
610 return ;
611 }
612
613 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
614
615 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
616 {
617 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
618 (eCSR_DOT11_MODE_11ac == phyMode) ||
619 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
620 {
621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
622 "Setting phymode to 11n!!");
623 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
624 }
625 }
626 else
627 {
628 /*New country Supports 11ac as well resetting value back from .ini*/
629 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
630 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
631 return ;
632 }
633
634 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
635 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
636 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
637 {
638 VOS_STATUS vosStatus;
639
640 // need to issue a disconnect to CSR.
641 INIT_COMPLETION(pAdapter->disconnect_comp_var);
642 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
643 pAdapter->sessionId,
644 eCSR_DISCONNECT_REASON_UNSPECIFIED );
645
646 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530647 {
648 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530650 if (ret <= 0)
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
653 "wait on disconnect_comp_var is failed %ld", ret);
654 }
655 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
657 }
658}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700659#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530660
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700661void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
662{
663 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
664 hdd_config_t *cfg_param;
665
666 if (NULL == pHddCtx)
667 {
668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
669 "HDD Context is null !!");
670 return ;
671 }
672
673 cfg_param = pHddCtx->cfg_ini;
674
675 if (NULL == cfg_param)
676 {
677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
678 "cfg_params not available !!");
679 return ;
680 }
681
Agarwal Ashish738843c2014-09-25 12:27:56 +0530682 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
683 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700684 {
685 /*New country doesn't support DFS */
686 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
687 }
688 else
689 {
690 /*New country Supports DFS as well resetting value back from .ini*/
691 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
692 }
693
694}
695
Rajeev79dbe4c2013-10-05 11:03:42 +0530696#ifdef FEATURE_WLAN_BATCH_SCAN
697
698/**---------------------------------------------------------------------------
699
700 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
701 input string
702
703 This function extracts assigned integer from string in below format:
704 "STRING=10" : extracts integer 10 from this string
705
706 \param - pInPtr Pointer to input string
707 \param - base Base for string to int conversion(10 for decimal 16 for hex)
708 \param - pOutPtr Pointer to variable in which extracted integer needs to be
709 assigned
710 \param - pLastArg to tell whether it is last arguement in input string or
711 not
712
713 \return - NULL for failure cases
714 pointer to next arguement in input string for success cases
715 --------------------------------------------------------------------------*/
716static tANI_U8 *
717hdd_extract_assigned_int_from_str
718(
719 tANI_U8 *pInPtr,
720 tANI_U8 base,
721 tANI_U32 *pOutPtr,
722 tANI_U8 *pLastArg
723)
724{
725 int tempInt;
726 int v = 0;
727 char buf[32];
728 int val = 0;
729 *pLastArg = FALSE;
730
731 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
732 if (NULL == pInPtr)
733 {
734 return NULL;
735 }
736
737 pInPtr++;
738
739 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
740
741 val = sscanf(pInPtr, "%32s ", buf);
742 if (val < 0 && val > strlen(pInPtr))
743 {
744 return NULL;
745 }
746 pInPtr += val;
747 v = kstrtos32(buf, base, &tempInt);
748 if (v < 0)
749 {
750 return NULL;
751 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800752 if (tempInt < 0)
753 {
754 tempInt = 0;
755 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530756 *pOutPtr = tempInt;
757
758 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
759 if (NULL == pInPtr)
760 {
761 *pLastArg = TRUE;
762 return NULL;
763 }
764 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
765
766 return pInPtr;
767}
768
769/**---------------------------------------------------------------------------
770
771 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
772 input string
773
774 This function extracts assigned character from string in below format:
775 "STRING=A" : extracts char 'A' from this string
776
777 \param - pInPtr Pointer to input string
778 \param - pOutPtr Pointer to variable in which extracted char needs to be
779 assigned
780 \param - pLastArg to tell whether it is last arguement in input string or
781 not
782
783 \return - NULL for failure cases
784 pointer to next arguement in input string for success cases
785 --------------------------------------------------------------------------*/
786static tANI_U8 *
787hdd_extract_assigned_char_from_str
788(
789 tANI_U8 *pInPtr,
790 tANI_U8 *pOutPtr,
791 tANI_U8 *pLastArg
792)
793{
794 *pLastArg = FALSE;
795
796 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
797 if (NULL == pInPtr)
798 {
799 return NULL;
800 }
801
802 pInPtr++;
803
804 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
805
806 *pOutPtr = *pInPtr;
807
808 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
809 if (NULL == pInPtr)
810 {
811 *pLastArg = TRUE;
812 return NULL;
813 }
814 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
815
816 return pInPtr;
817}
818
819
820/**---------------------------------------------------------------------------
821
822 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
823
824 This function parses set batch scan command in below format:
825 WLS_BATCHING_SET <space> followed by below arguements
826 "SCANFREQ=XX" : Optional defaults to 30 sec
827 "MSCAN=XX" : Required number of scans to attempt to batch
828 "BESTN=XX" : Best Network (RSSI) defaults to 16
829 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
830 A. implies only 5 GHz , B. implies only 2.4GHz
831 "RTT=X" : optional defaults to 0
832 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
833 error
834
835 For example input commands:
836 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
837 translated into set batch scan with following parameters:
838 a) Frequence 60 seconds
839 b) Batch 10 scans together
840 c) Best RSSI to be 20
841 d) 5GHz band only
842 e) RTT is equal to 0
843
844 \param - pValue Pointer to input channel list
845 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
846
847 \return - 0 for success non-zero for failure
848
849 --------------------------------------------------------------------------*/
850static int
851hdd_parse_set_batchscan_command
852(
853 tANI_U8 *pValue,
854 tSirSetBatchScanReq *pHddSetBatchScanReq
855)
856{
857 tANI_U8 *inPtr = pValue;
858 tANI_U8 val = 0;
859 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 tANI_U32 nScanFreq;
861 tANI_U32 nMscan;
862 tANI_U32 nBestN;
863 tANI_U8 ucRfBand;
864 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800865 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530866
867 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800868 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
869 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
870 nRtt = 0;
871 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530872
873 /*go to space after WLS_BATCHING_SET command*/
874 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
875 /*no argument after the command*/
876 if (NULL == inPtr)
877 {
878 return -EINVAL;
879 }
880
881 /*no space after the command*/
882 else if (SPACE_ASCII_VALUE != *inPtr)
883 {
884 return -EINVAL;
885 }
886
887 /*removing empty spaces*/
888 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
889
890 /*no argument followed by spaces*/
891 if ('\0' == *inPtr)
892 {
893 return -EINVAL;
894 }
895
896 /*check and parse SCANFREQ*/
897 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
898 {
899 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901
Rajeev Kumarc933d982013-11-18 20:04:20 -0800902 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800904 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800905 }
906
Rajeev79dbe4c2013-10-05 11:03:42 +0530907 if ( (NULL == inPtr) || (TRUE == lastArg))
908 {
909 return -EINVAL;
910 }
911 }
912
913 /*check and parse MSCAN*/
914 if ((strncmp(inPtr, "MSCAN", 5) == 0))
915 {
916 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800917 &nMscan, &lastArg);
918
919 if (0 == nMscan)
920 {
921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
922 "invalid MSCAN=%d", nMscan);
923 return -EINVAL;
924 }
925
Rajeev79dbe4c2013-10-05 11:03:42 +0530926 if (TRUE == lastArg)
927 {
928 goto done;
929 }
930 else if (NULL == inPtr)
931 {
932 return -EINVAL;
933 }
934 }
935 else
936 {
937 return -EINVAL;
938 }
939
940 /*check and parse BESTN*/
941 if ((strncmp(inPtr, "BESTN", 5) == 0))
942 {
943 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945
Rajeev Kumarc933d982013-11-18 20:04:20 -0800946 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800947 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800948 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800949 }
950
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 if (TRUE == lastArg)
952 {
953 goto done;
954 }
955 else if (NULL == inPtr)
956 {
957 return -EINVAL;
958 }
959 }
960
961 /*check and parse CHANNEL*/
962 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
963 {
964 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800965
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 if (('A' == val) || ('a' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else if (('B' == val) || ('b' == val))
971 {
c_hpothuebf89732014-02-25 13:00:24 +0530972 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 }
974 else
975 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800976 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
977 }
978
979 if (TRUE == lastArg)
980 {
981 goto done;
982 }
983 else if (NULL == inPtr)
984 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530985 return -EINVAL;
986 }
987 }
988
989 /*check and parse RTT*/
990 if ((strncmp(inPtr, "RTT", 3) == 0))
991 {
992 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530994 if (TRUE == lastArg)
995 {
996 goto done;
997 }
998 if (NULL == inPtr)
999 {
1000 return -EINVAL;
1001 }
1002 }
1003
1004
1005done:
1006
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001007 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1008 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1009 pHddSetBatchScanReq->bestNetwork = nBestN;
1010 pHddSetBatchScanReq->rfBand = ucRfBand;
1011 pHddSetBatchScanReq->rtt = nRtt;
1012
Rajeev79dbe4c2013-10-05 11:03:42 +05301013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1014 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1015 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1016 pHddSetBatchScanReq->scanFrequency,
1017 pHddSetBatchScanReq->numberOfScansToBatch,
1018 pHddSetBatchScanReq->bestNetwork,
1019 pHddSetBatchScanReq->rfBand,
1020 pHddSetBatchScanReq->rtt);
1021
1022 return 0;
1023}/*End of hdd_parse_set_batchscan_command*/
1024
1025/**---------------------------------------------------------------------------
1026
1027 \brief hdd_set_batch_scan_req_callback () - This function is called after
1028 receiving set batch scan response from FW and it saves set batch scan
1029 response data FW to HDD context and sets the completion event on
1030 which hdd_ioctl is waiting
1031
1032 \param - callbackContext Pointer to HDD adapter
1033 \param - pRsp Pointer to set batch scan response data received from FW
1034
1035 \return - nothing
1036
1037 --------------------------------------------------------------------------*/
1038static void hdd_set_batch_scan_req_callback
1039(
1040 void *callbackContext,
1041 tSirSetBatchScanRsp *pRsp
1042)
1043{
1044 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1045 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1046
1047 /*sanity check*/
1048 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1049 {
1050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1051 "%s: Invalid pAdapter magic", __func__);
1052 VOS_ASSERT(0);
1053 return;
1054 }
1055 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1056
1057 /*save set batch scan response*/
1058 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1059
1060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1061 "Received set batch scan rsp from FW with nScansToBatch=%d",
1062 pHddSetBatchScanRsp->nScansToBatch);
1063
1064 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1065 complete(&pAdapter->hdd_set_batch_scan_req_var);
1066
1067 return;
1068}/*End of hdd_set_batch_scan_req_callback*/
1069
1070
1071/**---------------------------------------------------------------------------
1072
1073 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1074 info in hdd batch scan response queue
1075
1076 \param - pAdapter Pointer to hdd adapter
1077 \param - pAPMetaInfo Pointer to access point meta info
1078 \param - scanId scan ID of batch scan response
1079 \param - isLastAp tells whether AP is last AP in batch scan response or not
1080
1081 \return - nothing
1082
1083 --------------------------------------------------------------------------*/
1084static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1085 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1086{
1087 tHddBatchScanRsp *pHead;
1088 tHddBatchScanRsp *pNode;
1089 tHddBatchScanRsp *pPrev;
1090 tHddBatchScanRsp *pTemp;
1091 tANI_U8 ssidLen;
1092
1093 /*head of hdd batch scan response queue*/
1094 pHead = pAdapter->pBatchScanRsp;
1095
1096 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1097 if (NULL == pNode)
1098 {
1099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1100 "%s: Could not allocate memory", __func__);
1101 VOS_ASSERT(0);
1102 return;
1103 }
1104
1105 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1106 sizeof(pNode->ApInfo.bssid));
1107 ssidLen = strlen(pApMetaInfo->ssid);
1108 if (SIR_MAX_SSID_SIZE < ssidLen)
1109 {
1110 /*invalid scan result*/
1111 vos_mem_free(pNode);
1112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1113 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1114 return;
1115 }
1116 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1117 /*null terminate ssid*/
1118 pNode->ApInfo.ssid[ssidLen] = '\0';
1119 pNode->ApInfo.ch = pApMetaInfo->ch;
1120 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1121 pNode->ApInfo.age = pApMetaInfo->timestamp;
1122 pNode->ApInfo.batchId = scanId;
1123 pNode->ApInfo.isLastAp = isLastAp;
1124
1125 pNode->pNext = NULL;
1126 if (NULL == pHead)
1127 {
1128 pAdapter->pBatchScanRsp = pNode;
1129 }
1130 else
1131 {
1132 pTemp = pHead;
1133 while (NULL != pTemp)
1134 {
1135 pPrev = pTemp;
1136 pTemp = pTemp->pNext;
1137 }
1138 pPrev->pNext = pNode;
1139 }
1140
1141 return;
1142}/*End of hdd_populate_batch_scan_rsp_queue*/
1143
1144/**---------------------------------------------------------------------------
1145
1146 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1147 receiving batch scan response indication from FW. It saves get batch scan
1148 response data in HDD batch scan response queue. This callback sets the
1149 completion event on which hdd_ioctl is waiting only after getting complete
1150 batch scan response data from FW
1151
1152 \param - callbackContext Pointer to HDD adapter
1153 \param - pRsp Pointer to get batch scan response data received from FW
1154
1155 \return - nothing
1156
1157 --------------------------------------------------------------------------*/
1158static void hdd_batch_scan_result_ind_callback
1159(
1160 void *callbackContext,
1161 void *pRsp
1162)
1163{
1164 v_BOOL_t isLastAp;
1165 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001166 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301167 tANI_U32 numberScanList;
1168 tANI_U32 nextScanListOffset;
1169 tANI_U32 nextApMetaInfoOffset;
1170 hdd_adapter_t* pAdapter;
1171 tpSirBatchScanList pScanList;
1172 tpSirBatchScanNetworkInfo pApMetaInfo;
1173 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1174 tSirSetBatchScanReq *pReq;
1175
1176 pAdapter = (hdd_adapter_t *)callbackContext;
1177 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001178 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301179 {
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1181 "%s: Invalid pAdapter magic", __func__);
1182 VOS_ASSERT(0);
1183 return;
1184 }
1185
1186 /*initialize locals*/
1187 pReq = &pAdapter->hddSetBatchScanReq;
1188 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1189 isLastAp = FALSE;
1190 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001191 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301192 numberScanList = 0;
1193 nextScanListOffset = 0;
1194 nextApMetaInfoOffset = 0;
1195 pScanList = NULL;
1196 pApMetaInfo = NULL;
1197
1198 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1202 isLastAp = TRUE;
1203 goto done;
1204 }
1205
1206 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1208 "Batch scan rsp: numberScalList %d", numberScanList);
1209
1210 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1211 {
1212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1213 "%s: numberScanList %d", __func__, numberScanList);
1214 isLastAp = TRUE;
1215 goto done;
1216 }
1217
1218 while (numberScanList)
1219 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001220 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301221 nextScanListOffset);
1222 if (NULL == pScanList)
1223 {
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1225 "%s: pScanList is %p", __func__, pScanList);
1226 isLastAp = TRUE;
1227 goto done;
1228 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001229 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001231 "Batch scan rsp: numApMetaInfo %d scanId %d",
1232 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301233
1234 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1235 {
1236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1237 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1238 isLastAp = TRUE;
1239 goto done;
1240 }
1241
Rajeev Kumarce651e42013-10-21 18:57:15 -07001242 /*Initialize next AP meta info offset for next scan list*/
1243 nextApMetaInfoOffset = 0;
1244
Rajeev79dbe4c2013-10-05 11:03:42 +05301245 while (numApMetaInfo)
1246 {
1247 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1248 nextApMetaInfoOffset);
1249 if (NULL == pApMetaInfo)
1250 {
1251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1252 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1253 isLastAp = TRUE;
1254 goto done;
1255 }
1256 /*calculate AP age*/
1257 pApMetaInfo->timestamp =
1258 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1259
1260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001261 "%s: bssId "MAC_ADDRESS_STR
1262 " ch %d rssi %d timestamp %d", __func__,
1263 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1264 pApMetaInfo->ch, pApMetaInfo->rssi,
1265 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301266
1267 /*mark last AP in batch scan response*/
1268 if ((TRUE == pBatchScanRsp->isLastResult) &&
1269 (1 == numberScanList) && (1 == numApMetaInfo))
1270 {
1271 isLastAp = TRUE;
1272 }
1273
1274 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1275 /*store batch scan repsonse in hdd queue*/
1276 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1277 pScanList->scanId, isLastAp);
1278 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1279
1280 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1281 numApMetaInfo--;
1282 }
1283
Rajeev Kumarce651e42013-10-21 18:57:15 -07001284 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1285 + (sizeof(tSirBatchScanNetworkInfo)
1286 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301287 numberScanList--;
1288 }
1289
1290done:
1291
1292 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1293 requested from hdd_ioctl*/
1294 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1295 (TRUE == isLastAp))
1296 {
1297 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1298 complete(&pAdapter->hdd_get_batch_scan_req_var);
1299 }
1300
1301 return;
1302}/*End of hdd_batch_scan_result_ind_callback*/
1303
1304/**---------------------------------------------------------------------------
1305
1306 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1307 response as per batch scan FR request format by putting proper markers
1308
1309 \param - pDest pointer to destination buffer
1310 \param - cur_len current length
1311 \param - tot_len total remaining size which can be written to user space
1312 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1313 \param - pAdapter Pointer to HDD adapter
1314
1315 \return - ret no of characters written
1316
1317 --------------------------------------------------------------------------*/
1318static tANI_U32
1319hdd_format_batch_scan_rsp
1320(
1321 tANI_U8 *pDest,
1322 tANI_U32 cur_len,
1323 tANI_U32 tot_len,
1324 tHddBatchScanRsp *pApMetaInfo,
1325 hdd_adapter_t* pAdapter
1326)
1327{
1328 tANI_U32 ret = 0;
1329 tANI_U32 rem_len = 0;
1330 tANI_U8 temp_len = 0;
1331 tANI_U8 temp_total_len = 0;
1332 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1333 tANI_U8 *pTemp = temp;
1334
1335 /*Batch scan reponse needs to be returned to user space in
1336 following format:
1337 "scancount=X\n" where X is the number of scans in current batch
1338 batch
1339 "trunc\n" optional present if current scan truncated
1340 "bssid=XX:XX:XX:XX:XX:XX\n"
1341 "ssid=XXXX\n"
1342 "freq=X\n" frequency in Mhz
1343 "level=XX\n"
1344 "age=X\n" ms
1345 "dist=X\n" cm (-1 if not available)
1346 "errror=X\n" (-1if not available)
1347 "====\n" (end of ap marker)
1348 "####\n" (end of scan marker)
1349 "----\n" (end of results)*/
1350 /*send scan result in above format to user space based on
1351 available length*/
1352 /*The GET response may have more data than the driver can return in its
1353 buffer. In that case the buffer should be filled to the nearest complete
1354 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1355 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1356 The final buffer should end with "----\n"*/
1357
1358 /*sanity*/
1359 if (cur_len > tot_len)
1360 {
1361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1362 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1363 return 0;
1364 }
1365 else
1366 {
1367 rem_len = (tot_len - cur_len);
1368 }
1369
1370 /*end scan marker*/
1371 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1372 {
1373 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1374 pTemp += temp_len;
1375 temp_total_len += temp_len;
1376 }
1377
1378 /*bssid*/
1379 temp_len = snprintf(pTemp, sizeof(temp),
1380 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1381 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1382 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1383 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1384 pTemp += temp_len;
1385 temp_total_len += temp_len;
1386
1387 /*ssid*/
1388 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1389 pApMetaInfo->ApInfo.ssid);
1390 pTemp += temp_len;
1391 temp_total_len += temp_len;
1392
1393 /*freq*/
1394 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001395 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*level*/
1400 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1401 pApMetaInfo->ApInfo.rssi);
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404
1405 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001406 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301407 pApMetaInfo->ApInfo.age);
1408 pTemp += temp_len;
1409 temp_total_len += temp_len;
1410
1411 /*dist*/
1412 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1413 pTemp += temp_len;
1414 temp_total_len += temp_len;
1415
1416 /*error*/
1417 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1418 pTemp += temp_len;
1419 temp_total_len += temp_len;
1420
1421 /*end AP marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*last AP in batch scan response*/
1427 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1428 {
1429 /*end scan marker*/
1430 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1431 pTemp += temp_len;
1432 temp_total_len += temp_len;
1433
1434 /*end batch scan result marker*/
1435 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1436 pTemp += temp_len;
1437 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001438
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
1440
1441 if (temp_total_len < rem_len)
1442 {
1443 ret = temp_total_len + 1;
1444 strlcpy(pDest, temp, ret);
1445 pAdapter->isTruncated = FALSE;
1446 }
1447 else
1448 {
1449 pAdapter->isTruncated = TRUE;
1450 if (rem_len >= strlen("%%%%"))
1451 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001452 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301453 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001454 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301455 {
1456 ret = 0;
1457 }
1458 }
1459
1460 return ret;
1461
1462}/*End of hdd_format_batch_scan_rsp*/
1463
1464/**---------------------------------------------------------------------------
1465
1466 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1467 buffer starting with head of hdd batch scan response queue
1468
1469 \param - pAdapter Pointer to HDD adapter
1470 \param - pDest Pointer to user data buffer
1471 \param - cur_len current offset in user buffer
1472 \param - rem_len remaining no of bytes in user buffer
1473
1474 \return - number of bytes written in user buffer
1475
1476 --------------------------------------------------------------------------*/
1477
1478tANI_U32 hdd_populate_user_batch_scan_rsp
1479(
1480 hdd_adapter_t* pAdapter,
1481 tANI_U8 *pDest,
1482 tANI_U32 cur_len,
1483 tANI_U32 rem_len
1484)
1485{
1486 tHddBatchScanRsp *pHead;
1487 tHddBatchScanRsp *pPrev;
1488 tANI_U32 len;
1489
Rajeev79dbe4c2013-10-05 11:03:42 +05301490 pAdapter->isTruncated = FALSE;
1491
1492 /*head of hdd batch scan response queue*/
1493 pHead = pAdapter->pBatchScanRsp;
1494 while (pHead)
1495 {
1496 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1497 pAdapter);
1498 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001499 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301500 cur_len += len;
1501 if(TRUE == pAdapter->isTruncated)
1502 {
1503 /*result is truncated return rest of scan rsp in next req*/
1504 cur_len = rem_len;
1505 break;
1506 }
1507 pPrev = pHead;
1508 pHead = pHead->pNext;
1509 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001510 if (TRUE == pPrev->ApInfo.isLastAp)
1511 {
1512 pAdapter->prev_batch_id = 0;
1513 }
1514 else
1515 {
1516 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1517 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301518 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001519 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 }
1521
1522 return cur_len;
1523}/*End of hdd_populate_user_batch_scan_rsp*/
1524
1525/**---------------------------------------------------------------------------
1526
1527 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1528 scan response data from HDD queue to user space
1529 It does following in detail:
1530 a) if HDD has enough data in its queue then it 1st copies data to user
1531 space and then send get batch scan indication message to FW. In this
1532 case it does not wait on any event and batch scan response data will
1533 be populated in HDD response queue in MC thread context after receiving
1534 indication from FW
1535 b) else send get batch scan indication message to FW and wait on an event
1536 which will be set once HDD receives complete batch scan response from
1537 FW and then this function returns batch scan response to user space
1538
1539 \param - pAdapter Pointer to HDD adapter
1540 \param - pPrivData Pointer to priv_data
1541
1542 \return - 0 for success -EFAULT for failure
1543
1544 --------------------------------------------------------------------------*/
1545
1546int hdd_return_batch_scan_rsp_to_user
1547(
1548 hdd_adapter_t* pAdapter,
1549 hdd_priv_data_t *pPrivData,
1550 tANI_U8 *command
1551)
1552{
1553 tANI_U8 *pDest;
1554 tANI_U32 count = 0;
1555 tANI_U32 len = 0;
1556 tANI_U32 cur_len = 0;
1557 tANI_U32 rem_len = 0;
1558 eHalStatus halStatus;
1559 unsigned long rc;
1560 tSirTriggerBatchScanResultInd *pReq;
1561
1562 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1563 pReq->param = 0;/*batch scan client*/
1564 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1565 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1566
1567 cur_len = pPrivData->used_len;
1568 if (pPrivData->total_len > pPrivData->used_len)
1569 {
1570 rem_len = pPrivData->total_len - pPrivData->used_len;
1571 }
1572 else
1573 {
1574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1575 "%s: Invalid user data buffer total_len %d used_len %d",
1576 __func__, pPrivData->total_len, pPrivData->used_len);
1577 return -EFAULT;
1578 }
1579
1580 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1581 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1582 cur_len, rem_len);
1583 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1584
1585 /*enough scan result available in cache to return to user space or
1586 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001587 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301588 {
1589 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1590 halStatus = sme_TriggerBatchScanResultInd(
1591 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1592 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1593 pAdapter);
1594 if ( eHAL_STATUS_SUCCESS == halStatus )
1595 {
1596 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1597 {
1598 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1599 rc = wait_for_completion_timeout(
1600 &pAdapter->hdd_get_batch_scan_req_var,
1601 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1602 if (0 == rc)
1603 {
1604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1605 "%s: Timeout waiting to fetch batch scan rsp from fw",
1606 __func__);
1607 return -EFAULT;
1608 }
1609 }
1610
1611 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001612 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301613 pDest += len;
1614 cur_len += len;
1615
1616 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1617 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1618 cur_len, rem_len);
1619 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1620
1621 count = 0;
1622 len = (len - pPrivData->used_len);
1623 pDest = (command + pPrivData->used_len);
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001625 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301626 while(count < len)
1627 {
1628 printk("%c", *(pDest + count));
1629 count++;
1630 }
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: copy %d data to user buffer", __func__, len);
1633 if (copy_to_user(pPrivData->buf, pDest, len))
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "%s: failed to copy data to user buffer", __func__);
1637 return -EFAULT;
1638 }
1639 }
1640 else
1641 {
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1643 "sme_GetBatchScanScan returned failure halStatus %d",
1644 halStatus);
1645 return -EINVAL;
1646 }
1647 }
1648 else
1649 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301650 count = 0;
1651 len = (len - pPrivData->used_len);
1652 pDest = (command + pPrivData->used_len);
1653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001654 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 while(count < len)
1656 {
1657 printk("%c", *(pDest + count));
1658 count++;
1659 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301662 if (copy_to_user(pPrivData->buf, pDest, len))
1663 {
1664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 "%s: failed to copy data to user buffer", __func__);
1666 return -EFAULT;
1667 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301668 }
1669
1670 return 0;
1671} /*End of hdd_return_batch_scan_rsp_to_user*/
1672
Rajeev Kumar8b373292014-01-08 20:36:55 -08001673
1674/**---------------------------------------------------------------------------
1675
1676 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1677 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1678 WLS_BATCHING VERSION
1679 WLS_BATCHING SET
1680 WLS_BATCHING GET
1681 WLS_BATCHING STOP
1682
1683 \param - pAdapter Pointer to HDD adapter
1684 \param - pPrivdata Pointer to priv_data
1685 \param - command Pointer to command
1686
1687 \return - 0 for success -EFAULT for failure
1688
1689 --------------------------------------------------------------------------*/
1690
1691int hdd_handle_batch_scan_ioctl
1692(
1693 hdd_adapter_t *pAdapter,
1694 hdd_priv_data_t *pPrivdata,
1695 tANI_U8 *command
1696)
1697{
1698 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001699 hdd_context_t *pHddCtx;
1700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301701 ENTER();
1702
Yue Mae36e3552014-03-05 17:06:20 -08001703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1704 ret = wlan_hdd_validate_context(pHddCtx);
1705 if (ret)
1706 {
Yue Mae36e3552014-03-05 17:06:20 -08001707 goto exit;
1708 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001709
1710 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1711 {
1712 char extra[32];
1713 tANI_U8 len = 0;
1714 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1715
1716 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1717 {
1718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1719 "%s: Batch scan feature is not supported by FW", __func__);
1720 ret = -EINVAL;
1721 goto exit;
1722 }
1723
1724 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1725 version);
1726 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1727 {
1728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1729 "%s: failed to copy data to user buffer", __func__);
1730 ret = -EFAULT;
1731 goto exit;
1732 }
1733 ret = HDD_BATCH_SCAN_VERSION;
1734 }
1735 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1736 {
1737 int status;
1738 tANI_U8 *value = (command + 16);
1739 eHalStatus halStatus;
1740 unsigned long rc;
1741 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1742 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1743
1744 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1745 {
1746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1747 "%s: Batch scan feature is not supported by FW", __func__);
1748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1753 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1754 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1755 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1756 {
1757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301758 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001759 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301760 hdd_device_modetoString(pAdapter->device_mode),
1761 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001762 ret = -EINVAL;
1763 goto exit;
1764 }
1765
1766 status = hdd_parse_set_batchscan_command(value, pReq);
1767 if (status)
1768 {
1769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "Invalid WLS_BATCHING SET command");
1771 ret = -EINVAL;
1772 goto exit;
1773 }
1774
1775
1776 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1777 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1778 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1779 pAdapter);
1780
1781 if ( eHAL_STATUS_SUCCESS == halStatus )
1782 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301783 char extra[32];
1784 tANI_U8 len = 0;
1785 tANI_U8 mScan = 0;
1786
Rajeev Kumar8b373292014-01-08 20:36:55 -08001787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1788 "sme_SetBatchScanReq returned success halStatus %d",
1789 halStatus);
1790 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1791 {
1792 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1793 rc = wait_for_completion_timeout(
1794 &pAdapter->hdd_set_batch_scan_req_var,
1795 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1796 if (0 == rc)
1797 {
1798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: Timeout waiting for set batch scan to complete",
1800 __func__);
1801 ret = -EINVAL;
1802 goto exit;
1803 }
1804 }
1805 if ( !pRsp->nScansToBatch )
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1808 "%s: Received set batch scan failure response from FW",
1809 __func__);
1810 ret = -EINVAL;
1811 goto exit;
1812 }
1813 /*As per the Batch Scan Framework API we should return the MIN of
1814 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301815 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816
1817 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1818
1819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301821 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1822 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1823 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: failed to copy MSCAN value to user buffer", __func__);
1827 ret = -EFAULT;
1828 goto exit;
1829 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001830 }
1831 else
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "sme_SetBatchScanReq returned failure halStatus %d",
1835 halStatus);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839 }
1840 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1841 {
1842 eHalStatus halStatus;
1843 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1844 pInd->param = 0;
1845
1846 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "%s: Batch scan feature is not supported by FW", __func__);
1850 ret = -EINVAL;
1851 goto exit;
1852 }
1853
1854 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1855 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001857 "Batch scan is not yet enabled batch scan state %d",
1858 pAdapter->batchScanState);
1859 ret = -EINVAL;
1860 goto exit;
1861 }
1862
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 hdd_deinit_batch_scan(pAdapter);
1865 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1866
Rajeev Kumar8b373292014-01-08 20:36:55 -08001867 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1868
1869 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1870 pAdapter->sessionId);
1871 if ( eHAL_STATUS_SUCCESS == halStatus )
1872 {
1873 ret = 0;
1874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1875 "sme_StopBatchScanInd returned success halStatus %d",
1876 halStatus);
1877 }
1878 else
1879 {
1880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1881 "sme_StopBatchScanInd returned failure halStatus %d",
1882 halStatus);
1883 ret = -EINVAL;
1884 goto exit;
1885 }
1886 }
1887 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1888 {
1889 tANI_U32 remain_len;
1890
1891 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "%s: Batch scan feature is not supported by FW", __func__);
1895 ret = -EINVAL;
1896 goto exit;
1897 }
1898
1899 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1900 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001902 "Batch scan is not yet enabled could not return results"
1903 "Batch Scan state %d",
1904 pAdapter->batchScanState);
1905 ret = -EINVAL;
1906 goto exit;
1907 }
1908
1909 pPrivdata->used_len = 16;
1910 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1911 if (remain_len < pPrivdata->total_len)
1912 {
1913 /*Clear previous batch scan response data if any*/
1914 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1915 }
1916 else
1917 {
1918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1919 "Invalid total length from user space can't fetch batch"
1920 " scan response total_len %d used_len %d remain len %d",
1921 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1922 ret = -EINVAL;
1923 goto exit;
1924 }
1925 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1926 }
1927
1928exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301929 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001930 return ret;
1931}
1932
1933
Rajeev79dbe4c2013-10-05 11:03:42 +05301934#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1935
c_hpothu92367912014-05-01 15:18:17 +05301936static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1937{
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 bcnMissRateContext_t *pCBCtx;
1939
1940 if (NULL == data)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1943 return;
1944 }
c_hpothu92367912014-05-01 15:18:17 +05301945
1946 /* there is a race condition that exists between this callback
1947 function and the caller since the caller could time out either
1948 before or while this code is executing. we use a spinlock to
1949 serialize these actions */
1950 spin_lock(&hdd_context_lock);
1951
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301953 gbcnMissRate = -1;
1954
c_hpothu39eb1e32014-06-26 16:31:50 +05301955 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301958 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301959 spin_unlock(&hdd_context_lock);
1960 return ;
1961 }
1962
1963 if (VOS_STATUS_SUCCESS == status)
1964 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301965 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301966 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301967 else
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1970 }
1971
c_hpothu92367912014-05-01 15:18:17 +05301972 complete(&(pCBCtx->completion));
1973 spin_unlock(&hdd_context_lock);
1974
1975 return;
1976}
1977
Abhishek Singh08aa7762014-12-16 13:59:03 +05301978void hdd_FWStatisCB( VOS_STATUS status,
1979 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301980{
1981 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301982 hdd_adapter_t *pAdapter;
1983
1984 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1985
Abhishek Singh08aa7762014-12-16 13:59:03 +05301986 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1989 return;
1990 }
1991 /* there is a race condition that exists between this callback
1992 function and the caller since the caller could time out either
1993 before or while this code is executing. we use a spinlock to
1994 serialize these actions */
1995 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301996 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301997 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_ERROR,
2000 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2001 spin_unlock(&hdd_context_lock);
2002 return;
2003 }
2004 pAdapter = fwStatsCtx->pAdapter;
2005 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("pAdapter returned is NULL or invalid"));
2009 spin_unlock(&hdd_context_lock);
2010 return;
2011 }
2012 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302013 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302014 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302015 switch( fwStatsResult->type )
2016 {
2017 case FW_UBSP_STATS:
2018 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302019 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 hddLog(VOS_TRACE_LEVEL_INFO,
2021 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302022 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2023 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302024 }
2025 break;
2026 default:
2027 {
2028 hddLog(VOS_TRACE_LEVEL_ERROR,
2029 FL(" No handling for stats type %d"),fwStatsResult->type);
2030 }
2031 }
2032 }
2033 complete(&(fwStatsCtx->completion));
2034 spin_unlock(&hdd_context_lock);
2035 return;
2036}
2037
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302038static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2039{
2040 int ret = 0;
2041
2042 if (!pCfg || !command || !extra || !len)
2043 {
2044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2045 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2046 ret = -EINVAL;
2047 return ret;
2048 }
2049
2050 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2051 {
2052 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2053 (int)pCfg->nActiveMaxChnTime);
2054 return ret;
2055 }
2056 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2057 {
2058 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2059 (int)pCfg->nActiveMinChnTime);
2060 return ret;
2061 }
2062 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2063 {
2064 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2065 (int)pCfg->nPassiveMaxChnTime);
2066 return ret;
2067 }
2068 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2069 {
2070 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2071 (int)pCfg->nPassiveMinChnTime);
2072 return ret;
2073 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302074 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2075 {
2076 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2077 (int)pCfg->nActiveMaxChnTime);
2078 return ret;
2079 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080 else
2081 {
2082 ret = -EINVAL;
2083 }
2084
2085 return ret;
2086}
2087
2088static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2089{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091 hdd_config_t *pCfg;
2092 tANI_U8 *value = command;
2093 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302094 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302095
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302096 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2097 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302098 {
2099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2100 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2101 ret = -EINVAL;
2102 return ret;
2103 }
2104
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302105 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2106 sme_GetConfigParam(hHal, &smeConfig);
2107
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302108 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2109 {
2110 value = value + 24;
2111 temp = kstrtou32(value, 10, &val);
2112 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2113 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2114 {
2115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2116 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2117 ret = -EFAULT;
2118 return ret;
2119 }
2120 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302121 smeConfig.csrConfig.nActiveMaxChnTime = val;
2122 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302123 }
2124 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2125 {
2126 value = value + 24;
2127 temp = kstrtou32(value, 10, &val);
2128 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2129 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2130 {
2131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2132 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2133 ret = -EFAULT;
2134 return ret;
2135 }
2136 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302137 smeConfig.csrConfig.nActiveMinChnTime = val;
2138 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302139 }
2140 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2141 {
2142 value = value + 25;
2143 temp = kstrtou32(value, 10, &val);
2144 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2145 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2146 {
2147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2148 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2149 ret = -EFAULT;
2150 return ret;
2151 }
2152 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302153 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2154 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302155 }
2156 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2157 {
2158 value = value + 25;
2159 temp = kstrtou32(value, 10, &val);
2160 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2161 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2165 ret = -EFAULT;
2166 return ret;
2167 }
2168 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302169 smeConfig.csrConfig.nPassiveMinChnTime = val;
2170 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302171 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302172 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2173 {
2174 value = value + 13;
2175 temp = kstrtou32(value, 10, &val);
2176 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2177 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2178 {
2179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2180 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2181 ret = -EFAULT;
2182 return ret;
2183 }
2184 pCfg->nActiveMaxChnTime = val;
2185 smeConfig.csrConfig.nActiveMaxChnTime = val;
2186 sme_UpdateConfig(hHal, &smeConfig);
2187 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302188 else
2189 {
2190 ret = -EINVAL;
2191 }
2192
2193 return ret;
2194}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302195static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2196 tANI_U8 cmd_len)
2197{
2198 tANI_U8 *value;
2199 tANI_U8 fcc_constraint;
2200
2201 eHalStatus status;
2202 int ret = 0;
2203 value = cmd + cmd_len + 1;
2204
2205 ret = kstrtou8(value, 10, &fcc_constraint);
2206 if ((ret < 0) || (fcc_constraint > 1)) {
2207 /*
2208 * If the input value is greater than max value of datatype,
2209 * then also it is a failure
2210 */
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 "%s: value out of range", __func__);
2213 return -EINVAL;
2214 }
2215
2216 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2217 if (status != eHAL_STATUS_SUCCESS)
2218 ret = -EPERM;
2219
2220 return ret;
2221}
2222
2223
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302224
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002225static int hdd_driver_command(hdd_adapter_t *pAdapter,
2226 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002227{
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 hdd_priv_data_t priv_data;
2229 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302230 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2231 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002232 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302233 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302234
2235 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002236 /*
2237 * Note that valid pointers are provided by caller
2238 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002239
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002240 /* copy to local struct to avoid numerous changes to legacy code */
2241 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002242
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002243 if (priv_data.total_len <= 0 ||
2244 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002245 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002246 hddLog(VOS_TRACE_LEVEL_WARN,
2247 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2248 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002249 ret = -EINVAL;
2250 goto exit;
2251 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302252 status = wlan_hdd_validate_context(pHddCtx);
2253 if (0 != status)
2254 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302255 ret = -EINVAL;
2256 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302257 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002258 /* Allocate +1 for '\0' */
2259 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 if (!command)
2261 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002264 ret = -ENOMEM;
2265 goto exit;
2266 }
2267
2268 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2269 {
2270 ret = -EFAULT;
2271 goto exit;
2272 }
2273
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002274 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002275 command[priv_data.total_len] = '\0';
2276
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002277 /* at one time the following block of code was conditional. braces
2278 * have been retained to avoid re-indenting the legacy code
2279 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 {
2281 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2282
2283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002284 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002285
2286 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2287 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2289 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2290 pAdapter->sessionId, (unsigned)
2291 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2292 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2293 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2294 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2296 sizeof(tSirMacAddr)))
2297 {
2298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002299 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 ret = -EFAULT;
2301 }
2302 }
Amar Singhal0974e402013-02-12 14:27:46 -08002303 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002304 {
Amar Singhal0974e402013-02-12 14:27:46 -08002305 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002306
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002308
2309 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002312 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Anand N Sunkad27354cf2015-07-13 14:39:11 +05302313 if(VOS_FTM_MODE != hdd_get_conparam())
2314 {
2315 /* Change band request received */
2316 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2317 if(ret < 0)
2318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2319 "%s: failed to set band ret=%d", __func__, ret);
2320 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002321 }
Kiet Lamf040f472013-11-20 21:15:23 +05302322 else if(strncmp(command, "SETWMMPS", 8) == 0)
2323 {
2324 tANI_U8 *ptr = command;
2325 ret = hdd_wmmps_helper(pAdapter, ptr);
2326 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302327
2328 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2329 {
2330 tANI_U8 *ptr = command;
2331 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2332 }
2333
Jeff Johnson32d95a32012-09-10 13:15:23 -07002334 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2335 {
2336 char *country_code;
2337
2338 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002339
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002340 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002341 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002342#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302343 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002344#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002345 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2346 (void *)(tSmeChangeCountryCallback)
2347 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302348 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002349 if (eHAL_STATUS_SUCCESS == ret)
2350 {
2351 ret = wait_for_completion_interruptible_timeout(
2352 &pAdapter->change_country_code,
2353 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2354 if (0 >= ret)
2355 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302357 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002358 }
2359 }
2360 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002361 {
2362 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002363 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002364 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002365 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002366
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002367 }
2368 /*
2369 command should be a string having format
2370 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2371 */
Amar Singhal0974e402013-02-12 14:27:46 -08002372 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002373 {
Amar Singhal0974e402013-02-12 14:27:46 -08002374 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002375
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002377 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002378
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002379 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002380 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002381 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2382 {
2383 int suspend = 0;
2384 tANI_U8 *ptr = (tANI_U8*)command + 15;
2385
2386 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2388 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2389 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002390 hdd_set_wlan_suspend_mode(suspend);
2391 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002392#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2393 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2394 {
2395 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002396 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002397 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2398 eHalStatus status = eHAL_STATUS_SUCCESS;
2399
2400 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2401 value = value + 15;
2402
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002403 /* Convert the value from ascii to integer */
2404 ret = kstrtos8(value, 10, &rssi);
2405 if (ret < 0)
2406 {
2407 /* If the input value is greater than max value of datatype, then also
2408 kstrtou8 fails */
2409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002411 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002412 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2413 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2414 ret = -EINVAL;
2415 goto exit;
2416 }
2417
Srinivas Girigowdade697412013-02-14 16:31:48 -08002418 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002419
Srinivas Girigowdade697412013-02-14 16:31:48 -08002420 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2421 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2422 {
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2424 "Neighbor lookup threshold value %d is out of range"
2425 " (Min: %d Max: %d)", lookUpThreshold,
2426 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2427 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2428 ret = -EINVAL;
2429 goto exit;
2430 }
2431
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302432 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2433 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2434 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2436 "%s: Received Command to Set Roam trigger"
2437 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2438
2439 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2440 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2441 if (eHAL_STATUS_SUCCESS != status)
2442 {
2443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2444 "%s: Failed to set roam trigger, try again", __func__);
2445 ret = -EPERM;
2446 goto exit;
2447 }
2448
2449 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302450 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002451 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2452 }
2453 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2454 {
2455 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2456 int rssi = (-1) * lookUpThreshold;
2457 char extra[32];
2458 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2461 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002462 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302463 len = VOS_MIN(priv_data.total_len, len + 1);
2464 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002465 {
2466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2467 "%s: failed to copy data to user buffer", __func__);
2468 ret = -EFAULT;
2469 goto exit;
2470 }
2471 }
2472 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2473 {
2474 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002475 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002476 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478 /* input refresh period is in terms of seconds */
2479 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2480 value = value + 18;
2481 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002482 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002483 if (ret < 0)
2484 {
2485 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002486 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002488 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002489 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002490 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2491 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002492 ret = -EINVAL;
2493 goto exit;
2494 }
2495
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2497 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500 "Roam scan period value %d is out of range"
2501 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002502 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2503 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002504 ret = -EINVAL;
2505 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302506 }
2507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2508 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2509 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002511
2512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2513 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002514 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002516 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2517 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002518 }
2519 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2520 {
2521 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2522 char extra[32];
2523 tANI_U8 len = 0;
2524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2526 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2527 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002528 len = scnprintf(extra, sizeof(extra), "%s %d",
2529 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002530 /* Returned value is in units of seconds */
2531 if (copy_to_user(priv_data.buf, &extra, len + 1))
2532 {
2533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2534 "%s: failed to copy data to user buffer", __func__);
2535 ret = -EFAULT;
2536 goto exit;
2537 }
2538 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002539 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2540 {
2541 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 /* input refresh period is in terms of seconds */
2546 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2547 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002548
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002549 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002550 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002551 if (ret < 0)
2552 {
2553 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002554 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002556 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002557 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002558 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2559 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2560 ret = -EINVAL;
2561 goto exit;
2562 }
2563
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002564 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2565 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2566 {
2567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2568 "Neighbor scan results refresh period value %d is out of range"
2569 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2570 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2571 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2572 ret = -EINVAL;
2573 goto exit;
2574 }
2575 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2576
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2578 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002579 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002580
2581 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2582 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2583 }
2584 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2585 {
2586 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2587 char extra[32];
2588 tANI_U8 len = 0;
2589
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002590 len = scnprintf(extra, sizeof(extra), "%s %d",
2591 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002592 /* Returned value is in units of seconds */
2593 if (copy_to_user(priv_data.buf, &extra, len + 1))
2594 {
2595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2596 "%s: failed to copy data to user buffer", __func__);
2597 ret = -EFAULT;
2598 goto exit;
2599 }
2600 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002601#ifdef FEATURE_WLAN_LFR
2602 /* SETROAMMODE */
2603 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2604 {
2605 tANI_U8 *value = command;
2606 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2607
2608 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2609 value = value + SIZE_OF_SETROAMMODE + 1;
2610
2611 /* Convert the value from ascii to integer */
2612 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2613 if (ret < 0)
2614 {
2615 /* If the input value is greater than max value of datatype, then also
2616 kstrtou8 fails */
2617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2618 "%s: kstrtou8 failed range [%d - %d]", __func__,
2619 CFG_LFR_FEATURE_ENABLED_MIN,
2620 CFG_LFR_FEATURE_ENABLED_MAX);
2621 ret = -EINVAL;
2622 goto exit;
2623 }
2624 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2625 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2626 {
2627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2628 "Roam Mode value %d is out of range"
2629 " (Min: %d Max: %d)", roamMode,
2630 CFG_LFR_FEATURE_ENABLED_MIN,
2631 CFG_LFR_FEATURE_ENABLED_MAX);
2632 ret = -EINVAL;
2633 goto exit;
2634 }
2635
2636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2637 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2638 /*
2639 * Note that
2640 * SETROAMMODE 0 is to enable LFR while
2641 * SETROAMMODE 1 is to disable LFR, but
2642 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2643 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2644 */
2645 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2646 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2647 else
2648 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2649
2650 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2651 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2652 }
2653 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302654 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002655 {
2656 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2657 char extra[32];
2658 tANI_U8 len = 0;
2659
2660 /*
2661 * roamMode value shall be inverted because the sementics is different.
2662 */
2663 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2664 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2665 else
2666 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2667
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002668 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002669 if (copy_to_user(priv_data.buf, &extra, len + 1))
2670 {
2671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2672 "%s: failed to copy data to user buffer", __func__);
2673 ret = -EFAULT;
2674 goto exit;
2675 }
2676 }
2677#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002678#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002679#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2681 {
2682 tANI_U8 *value = command;
2683 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2684
2685 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2686 value = value + 13;
2687 /* Convert the value from ascii to integer */
2688 ret = kstrtou8(value, 10, &roamRssiDiff);
2689 if (ret < 0)
2690 {
2691 /* If the input value is greater than max value of datatype, then also
2692 kstrtou8 fails */
2693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2694 "%s: kstrtou8 failed range [%d - %d]", __func__,
2695 CFG_ROAM_RSSI_DIFF_MIN,
2696 CFG_ROAM_RSSI_DIFF_MAX);
2697 ret = -EINVAL;
2698 goto exit;
2699 }
2700
2701 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2702 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2703 {
2704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2705 "Roam rssi diff value %d is out of range"
2706 " (Min: %d Max: %d)", roamRssiDiff,
2707 CFG_ROAM_RSSI_DIFF_MIN,
2708 CFG_ROAM_RSSI_DIFF_MAX);
2709 ret = -EINVAL;
2710 goto exit;
2711 }
2712
2713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2714 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2715
2716 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2717 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2718 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302719 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002720 {
2721 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2722 char extra[32];
2723 tANI_U8 len = 0;
2724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2726 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2727 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002728 len = scnprintf(extra, sizeof(extra), "%s %d",
2729 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 if (copy_to_user(priv_data.buf, &extra, len + 1))
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: failed to copy data to user buffer", __func__);
2734 ret = -EFAULT;
2735 goto exit;
2736 }
2737 }
2738#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002739#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002740 else if (strncmp(command, "GETBAND", 7) == 0)
2741 {
2742 int band = -1;
2743 char extra[32];
2744 tANI_U8 len = 0;
2745 hdd_getBand_helper(pHddCtx, &band);
2746
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2748 TRACE_CODE_HDD_GETBAND_IOCTL,
2749 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002750 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002751 if (copy_to_user(priv_data.buf, &extra, len + 1))
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: failed to copy data to user buffer", __func__);
2755 ret = -EFAULT;
2756 goto exit;
2757 }
2758 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002759 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 *value = command;
2762 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2763 tANI_U8 numChannels = 0;
2764 eHalStatus status = eHAL_STATUS_SUCCESS;
2765
2766 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2767 if (eHAL_STATUS_SUCCESS != status)
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: Failed to parse channel list information", __func__);
2771 ret = -EINVAL;
2772 goto exit;
2773 }
2774
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2782 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2783 ret = -EINVAL;
2784 goto exit;
2785 }
2786 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2787 numChannels);
2788 if (eHAL_STATUS_SUCCESS != status)
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: Failed to update channel list information", __func__);
2792 ret = -EINVAL;
2793 goto exit;
2794 }
2795 }
2796 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2797 {
2798 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2799 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002800 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002801 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002802 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002803
2804 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2805 ChannelList, &numChannels ))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2808 "%s: failed to get roam scan channel list", __func__);
2809 ret = -EFAULT;
2810 goto exit;
2811 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2813 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2814 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 /* output channel list is of the format
2816 [Number of roam scan channels][Channel1][Channel2]... */
2817 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002818 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002819 for (j = 0; (j < numChannels); j++)
2820 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002821 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2822 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002823 }
2824
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05302825 len = VOS_MIN(priv_data.total_len, len + 1);
2826 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002827 {
2828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2829 "%s: failed to copy data to user buffer", __func__);
2830 ret = -EFAULT;
2831 goto exit;
2832 }
2833 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002834 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2835 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002836 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002837 char extra[32];
2838 tANI_U8 len = 0;
2839
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002840 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002841 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002842 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002843 hdd_is_okc_mode_enabled(pHddCtx) &&
2844 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2845 {
2846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002847 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002848 " hence this operation is not permitted!", __func__);
2849 ret = -EPERM;
2850 goto exit;
2851 }
2852
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002853 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002854 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05302855 len = VOS_MIN(priv_data.total_len, len + 1);
2856 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002857 {
2858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2859 "%s: failed to copy data to user buffer", __func__);
2860 ret = -EFAULT;
2861 goto exit;
2862 }
2863 }
2864 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2865 {
2866 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2867 char extra[32];
2868 tANI_U8 len = 0;
2869
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002870 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002871 then this operation is not permitted (return FAILURE) */
2872 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002873 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002874 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2875 {
2876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002877 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002878 " hence this operation is not permitted!", __func__);
2879 ret = -EPERM;
2880 goto exit;
2881 }
2882
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002883 len = scnprintf(extra, sizeof(extra), "%s %d",
2884 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05302885 len = VOS_MIN(priv_data.total_len, len + 1);
2886 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002887 {
2888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2889 "%s: failed to copy data to user buffer", __func__);
2890 ret = -EFAULT;
2891 goto exit;
2892 }
2893 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002894 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002895 {
2896 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2897 char extra[32];
2898 tANI_U8 len = 0;
2899
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002900 len = scnprintf(extra, sizeof(extra), "%s %d",
2901 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302902 len = VOS_MIN(priv_data.total_len, len + 1);
2903 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002904 {
2905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2906 "%s: failed to copy data to user buffer", __func__);
2907 ret = -EFAULT;
2908 goto exit;
2909 }
2910 }
2911 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2912 {
2913 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2914 char extra[32];
2915 tANI_U8 len = 0;
2916
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002917 len = scnprintf(extra, sizeof(extra), "%s %d",
2918 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302919 len = VOS_MIN(priv_data.total_len, len + 1);
2920 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002921 {
2922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2923 "%s: failed to copy data to user buffer", __func__);
2924 ret = -EFAULT;
2925 goto exit;
2926 }
2927 }
2928 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2929 {
2930 tANI_U8 *value = command;
2931 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2932
2933 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2934 value = value + 26;
2935 /* Convert the value from ascii to integer */
2936 ret = kstrtou8(value, 10, &minTime);
2937 if (ret < 0)
2938 {
2939 /* If the input value is greater than max value of datatype, then also
2940 kstrtou8 fails */
2941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2942 "%s: kstrtou8 failed range [%d - %d]", __func__,
2943 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2944 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2945 ret = -EINVAL;
2946 goto exit;
2947 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002948 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2949 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2950 {
2951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2952 "scan min channel time value %d is out of range"
2953 " (Min: %d Max: %d)", minTime,
2954 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2955 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2956 ret = -EINVAL;
2957 goto exit;
2958 }
2959
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2961 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2962 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2964 "%s: Received Command to change channel min time = %d", __func__, minTime);
2965
2966 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2967 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2968 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002969 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2970 {
2971 tANI_U8 *value = command;
2972 tANI_U8 channel = 0;
2973 tANI_U8 dwellTime = 0;
2974 tANI_U8 bufLen = 0;
2975 tANI_U8 *buf = NULL;
2976 tSirMacAddr targetApBssid;
2977 eHalStatus status = eHAL_STATUS_SUCCESS;
2978 struct ieee80211_channel chan;
2979 tANI_U8 finalLen = 0;
2980 tANI_U8 *finalBuf = NULL;
2981 tANI_U8 temp = 0;
2982 u64 cookie;
2983 hdd_station_ctx_t *pHddStaCtx = NULL;
2984 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2985
2986 /* if not associated, no need to send action frame */
2987 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2988 {
2989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2990 ret = -EINVAL;
2991 goto exit;
2992 }
2993
2994 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2995 &dwellTime, &buf, &bufLen);
2996 if (eHAL_STATUS_SUCCESS != status)
2997 {
2998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2999 "%s: Failed to parse send action frame data", __func__);
3000 ret = -EINVAL;
3001 goto exit;
3002 }
3003
3004 /* if the target bssid is different from currently associated AP,
3005 then no need to send action frame */
3006 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3007 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3008 {
3009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3010 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003011 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003012 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003013 goto exit;
3014 }
3015
3016 /* if the channel number is different from operating channel then
3017 no need to send action frame */
3018 if (channel != pHddStaCtx->conn_info.operationChannel)
3019 {
3020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3021 "%s: channel(%d) is different from operating channel(%d)",
3022 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3023 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003024 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003025 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003026 goto exit;
3027 }
3028 chan.center_freq = sme_ChnToFreq(channel);
3029
3030 finalLen = bufLen + 24;
3031 finalBuf = vos_mem_malloc(finalLen);
3032 if (NULL == finalBuf)
3033 {
3034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3035 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003036 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003037 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003038 goto exit;
3039 }
3040 vos_mem_zero(finalBuf, finalLen);
3041
3042 /* Fill subtype */
3043 temp = SIR_MAC_MGMT_ACTION << 4;
3044 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3045
3046 /* Fill type */
3047 temp = SIR_MAC_MGMT_FRAME;
3048 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3049
3050 /* Fill destination address (bssid of the AP) */
3051 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3052
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003053 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003054 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3055
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003056 /* Fill BSSID (AP mac address) */
3057 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003058
3059 /* Fill received buffer from 24th address */
3060 vos_mem_copy(finalBuf + 24, buf, bufLen);
3061
Jeff Johnson11c33152013-04-16 17:52:40 -07003062 /* done with the parsed buffer */
3063 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003064 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003065
DARAM SUDHA39eede62014-02-12 11:16:40 +05303066 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3068 &(pAdapter->wdev),
3069#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003070 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003071#endif
3072 &chan, 0,
3073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3074 NL80211_CHAN_HT20, 1,
3075#endif
3076 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003077 1, &cookie );
3078 vos_mem_free(finalBuf);
3079 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003080 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3081 {
3082 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3083 char extra[32];
3084 tANI_U8 len = 0;
3085
3086 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003087 len = scnprintf(extra, sizeof(extra), "%s %d",
3088 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303089 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3090 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3091 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303092 len = VOS_MIN(priv_data.total_len, len + 1);
3093 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003094 {
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3096 "%s: failed to copy data to user buffer", __func__);
3097 ret = -EFAULT;
3098 goto exit;
3099 }
3100 }
3101 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3102 {
3103 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003104 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003105
3106 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3107 value = value + 19;
3108 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003109 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003110 if (ret < 0)
3111 {
3112 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003113 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003115 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003116 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3117 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3118 ret = -EINVAL;
3119 goto exit;
3120 }
3121
3122 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3123 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3124 {
3125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3126 "lfr mode value %d is out of range"
3127 " (Min: %d Max: %d)", maxTime,
3128 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3129 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3130 ret = -EINVAL;
3131 goto exit;
3132 }
3133
3134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3135 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3136
3137 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3138 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3139 }
3140 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3141 {
3142 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3143 char extra[32];
3144 tANI_U8 len = 0;
3145
3146 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003147 len = scnprintf(extra, sizeof(extra), "%s %d",
3148 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003149 if (copy_to_user(priv_data.buf, &extra, len + 1))
3150 {
3151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3152 "%s: failed to copy data to user buffer", __func__);
3153 ret = -EFAULT;
3154 goto exit;
3155 }
3156 }
3157 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3158 {
3159 tANI_U8 *value = command;
3160 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3161
3162 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3163 value = value + 16;
3164 /* Convert the value from ascii to integer */
3165 ret = kstrtou16(value, 10, &val);
3166 if (ret < 0)
3167 {
3168 /* If the input value is greater than max value of datatype, then also
3169 kstrtou16 fails */
3170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3171 "%s: kstrtou16 failed range [%d - %d]", __func__,
3172 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3173 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3174 ret = -EINVAL;
3175 goto exit;
3176 }
3177
3178 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3179 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3180 {
3181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3182 "scan home time value %d is out of range"
3183 " (Min: %d Max: %d)", val,
3184 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3185 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3186 ret = -EINVAL;
3187 goto exit;
3188 }
3189
3190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3191 "%s: Received Command to change scan home time = %d", __func__, val);
3192
3193 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3194 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3195 }
3196 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3197 {
3198 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3199 char extra[32];
3200 tANI_U8 len = 0;
3201
3202 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003203 len = scnprintf(extra, sizeof(extra), "%s %d",
3204 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003205 if (copy_to_user(priv_data.buf, &extra, len + 1))
3206 {
3207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3208 "%s: failed to copy data to user buffer", __func__);
3209 ret = -EFAULT;
3210 goto exit;
3211 }
3212 }
3213 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3214 {
3215 tANI_U8 *value = command;
3216 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3217
3218 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3219 value = value + 17;
3220 /* Convert the value from ascii to integer */
3221 ret = kstrtou8(value, 10, &val);
3222 if (ret < 0)
3223 {
3224 /* If the input value is greater than max value of datatype, then also
3225 kstrtou8 fails */
3226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3227 "%s: kstrtou8 failed range [%d - %d]", __func__,
3228 CFG_ROAM_INTRA_BAND_MIN,
3229 CFG_ROAM_INTRA_BAND_MAX);
3230 ret = -EINVAL;
3231 goto exit;
3232 }
3233
3234 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3235 (val > CFG_ROAM_INTRA_BAND_MAX))
3236 {
3237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3238 "intra band mode value %d is out of range"
3239 " (Min: %d Max: %d)", val,
3240 CFG_ROAM_INTRA_BAND_MIN,
3241 CFG_ROAM_INTRA_BAND_MAX);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3246 "%s: Received Command to change intra band = %d", __func__, val);
3247
3248 pHddCtx->cfg_ini->nRoamIntraBand = val;
3249 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3250 }
3251 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3252 {
3253 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3254 char extra[32];
3255 tANI_U8 len = 0;
3256
3257 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003258 len = scnprintf(extra, sizeof(extra), "%s %d",
3259 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003260 if (copy_to_user(priv_data.buf, &extra, len + 1))
3261 {
3262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3263 "%s: failed to copy data to user buffer", __func__);
3264 ret = -EFAULT;
3265 goto exit;
3266 }
3267 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003268 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3269 {
3270 tANI_U8 *value = command;
3271 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3272
3273 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3274 value = value + 15;
3275 /* Convert the value from ascii to integer */
3276 ret = kstrtou8(value, 10, &nProbes);
3277 if (ret < 0)
3278 {
3279 /* If the input value is greater than max value of datatype, then also
3280 kstrtou8 fails */
3281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3282 "%s: kstrtou8 failed range [%d - %d]", __func__,
3283 CFG_ROAM_SCAN_N_PROBES_MIN,
3284 CFG_ROAM_SCAN_N_PROBES_MAX);
3285 ret = -EINVAL;
3286 goto exit;
3287 }
3288
3289 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3290 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3291 {
3292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3293 "NProbes value %d is out of range"
3294 " (Min: %d Max: %d)", nProbes,
3295 CFG_ROAM_SCAN_N_PROBES_MIN,
3296 CFG_ROAM_SCAN_N_PROBES_MAX);
3297 ret = -EINVAL;
3298 goto exit;
3299 }
3300
3301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3302 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3303
3304 pHddCtx->cfg_ini->nProbes = nProbes;
3305 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3306 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303307 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003308 {
3309 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3310 char extra[32];
3311 tANI_U8 len = 0;
3312
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003313 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003314 if (copy_to_user(priv_data.buf, &extra, len + 1))
3315 {
3316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3317 "%s: failed to copy data to user buffer", __func__);
3318 ret = -EFAULT;
3319 goto exit;
3320 }
3321 }
3322 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3323 {
3324 tANI_U8 *value = command;
3325 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3326
3327 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3328 /* input value is in units of msec */
3329 value = value + 20;
3330 /* Convert the value from ascii to integer */
3331 ret = kstrtou16(value, 10, &homeAwayTime);
3332 if (ret < 0)
3333 {
3334 /* If the input value is greater than max value of datatype, then also
3335 kstrtou8 fails */
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3337 "%s: kstrtou8 failed range [%d - %d]", __func__,
3338 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3339 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3340 ret = -EINVAL;
3341 goto exit;
3342 }
3343
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003344 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3345 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3346 {
3347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3348 "homeAwayTime value %d is out of range"
3349 " (Min: %d Max: %d)", homeAwayTime,
3350 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3351 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3352 ret = -EINVAL;
3353 goto exit;
3354 }
3355
3356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3357 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003358 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3359 {
3360 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3361 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3362 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003363 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303364 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003365 {
3366 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3367 char extra[32];
3368 tANI_U8 len = 0;
3369
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003370 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003371 if (copy_to_user(priv_data.buf, &extra, len + 1))
3372 {
3373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3374 "%s: failed to copy data to user buffer", __func__);
3375 ret = -EFAULT;
3376 goto exit;
3377 }
3378 }
3379 else if (strncmp(command, "REASSOC", 7) == 0)
3380 {
3381 tANI_U8 *value = command;
3382 tANI_U8 channel = 0;
3383 tSirMacAddr targetApBssid;
3384 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003385#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3386 tCsrHandoffRequest handoffInfo;
3387#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003388 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003389 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3390
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003391 /* if not associated, no need to proceed with reassoc */
3392 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3393 {
3394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3395 ret = -EINVAL;
3396 goto exit;
3397 }
3398
3399 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3400 if (eHAL_STATUS_SUCCESS != status)
3401 {
3402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3403 "%s: Failed to parse reassoc command data", __func__);
3404 ret = -EINVAL;
3405 goto exit;
3406 }
3407
3408 /* if the target bssid is same as currently associated AP,
3409 then no need to proceed with reassoc */
3410 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3411 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3412 {
3413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3414 ret = -EINVAL;
3415 goto exit;
3416 }
3417
3418 /* Check channel number is a valid channel number */
3419 if(VOS_STATUS_SUCCESS !=
3420 wlan_hdd_validate_operation_channel(pAdapter, channel))
3421 {
3422 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003423 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003424 return -EINVAL;
3425 }
3426
3427 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003428#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3429 handoffInfo.channel = channel;
3430 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3431 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3432#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003433 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003434 else if (strncmp(command, "SETWESMODE", 10) == 0)
3435 {
3436 tANI_U8 *value = command;
3437 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3438
3439 /* Move pointer to ahead of SETWESMODE<delimiter> */
3440 value = value + 11;
3441 /* Convert the value from ascii to integer */
3442 ret = kstrtou8(value, 10, &wesMode);
3443 if (ret < 0)
3444 {
3445 /* If the input value is greater than max value of datatype, then also
3446 kstrtou8 fails */
3447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3448 "%s: kstrtou8 failed range [%d - %d]", __func__,
3449 CFG_ENABLE_WES_MODE_NAME_MIN,
3450 CFG_ENABLE_WES_MODE_NAME_MAX);
3451 ret = -EINVAL;
3452 goto exit;
3453 }
3454
3455 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3456 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3457 {
3458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3459 "WES Mode value %d is out of range"
3460 " (Min: %d Max: %d)", wesMode,
3461 CFG_ENABLE_WES_MODE_NAME_MIN,
3462 CFG_ENABLE_WES_MODE_NAME_MAX);
3463 ret = -EINVAL;
3464 goto exit;
3465 }
3466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3467 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3468
3469 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3470 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3471 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303472 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003473 {
3474 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3475 char extra[32];
3476 tANI_U8 len = 0;
3477
Arif Hussain826d9412013-11-12 16:44:54 -08003478 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003479 if (copy_to_user(priv_data.buf, &extra, len + 1))
3480 {
3481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3482 "%s: failed to copy data to user buffer", __func__);
3483 ret = -EFAULT;
3484 goto exit;
3485 }
3486 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003487#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003488#ifdef FEATURE_WLAN_LFR
3489 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3490 {
3491 tANI_U8 *value = command;
3492 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3493
3494 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3495 value = value + 12;
3496 /* Convert the value from ascii to integer */
3497 ret = kstrtou8(value, 10, &lfrMode);
3498 if (ret < 0)
3499 {
3500 /* If the input value is greater than max value of datatype, then also
3501 kstrtou8 fails */
3502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3503 "%s: kstrtou8 failed range [%d - %d]", __func__,
3504 CFG_LFR_FEATURE_ENABLED_MIN,
3505 CFG_LFR_FEATURE_ENABLED_MAX);
3506 ret = -EINVAL;
3507 goto exit;
3508 }
3509
3510 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3511 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3512 {
3513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3514 "lfr mode value %d is out of range"
3515 " (Min: %d Max: %d)", lfrMode,
3516 CFG_LFR_FEATURE_ENABLED_MIN,
3517 CFG_LFR_FEATURE_ENABLED_MAX);
3518 ret = -EINVAL;
3519 goto exit;
3520 }
3521
3522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3523 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3524
3525 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3526 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3527 }
3528#endif
3529#ifdef WLAN_FEATURE_VOWIFI_11R
3530 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3531 {
3532 tANI_U8 *value = command;
3533 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3534
3535 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3536 value = value + 18;
3537 /* Convert the value from ascii to integer */
3538 ret = kstrtou8(value, 10, &ft);
3539 if (ret < 0)
3540 {
3541 /* If the input value is greater than max value of datatype, then also
3542 kstrtou8 fails */
3543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3544 "%s: kstrtou8 failed range [%d - %d]", __func__,
3545 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3546 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3547 ret = -EINVAL;
3548 goto exit;
3549 }
3550
3551 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3552 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3553 {
3554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3555 "ft mode value %d is out of range"
3556 " (Min: %d Max: %d)", ft,
3557 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3558 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3559 ret = -EINVAL;
3560 goto exit;
3561 }
3562
3563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3564 "%s: Received Command to change ft mode = %d", __func__, ft);
3565
3566 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3567 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3568 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303569 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3570 {
3571 tANI_U8 *value = command;
3572 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303573
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303574 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3575 value = value + 15;
3576 /* Convert the value from ascii to integer */
3577 ret = kstrtou8(value, 10, &dfsScanMode);
3578 if (ret < 0)
3579 {
3580 /* If the input value is greater than max value of
3581 datatype, then also kstrtou8 fails
3582 */
3583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3584 "%s: kstrtou8 failed range [%d - %d]", __func__,
3585 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3586 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3587 ret = -EINVAL;
3588 goto exit;
3589 }
3590
3591 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3592 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3593 {
3594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3595 "dfsScanMode value %d is out of range"
3596 " (Min: %d Max: %d)", dfsScanMode,
3597 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3598 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3599 ret = -EINVAL;
3600 goto exit;
3601 }
3602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3603 "%s: Received Command to Set DFS Scan Mode = %d",
3604 __func__, dfsScanMode);
3605
3606 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3607 }
3608 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3609 {
3610 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3611 char extra[32];
3612 tANI_U8 len = 0;
3613
3614 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3615 if (copy_to_user(priv_data.buf, &extra, len + 1))
3616 {
3617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3618 "%s: failed to copy data to user buffer", __func__);
3619 ret = -EFAULT;
3620 goto exit;
3621 }
3622 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303623 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3624 {
3625 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303626 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303627 tSirMacAddr targetApBssid;
3628 tANI_U8 trigger = 0;
3629 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303630 tHalHandle hHal;
3631 v_U32_t roamId = 0;
3632 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303633 hdd_station_ctx_t *pHddStaCtx = NULL;
3634 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303635 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303636
3637 /* if not associated, no need to proceed with reassoc */
3638 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3639 {
3640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3641 ret = -EINVAL;
3642 goto exit;
3643 }
3644
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303645 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303646 if (eHAL_STATUS_SUCCESS != status)
3647 {
3648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3649 "%s: Failed to parse reassoc command data", __func__);
3650 ret = -EINVAL;
3651 goto exit;
3652 }
3653
3654 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303655 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303656 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3657 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3658 {
3659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3660 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3661 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303662 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3663 &modProfileFields);
3664 sme_RoamReassoc(hHal, pAdapter->sessionId,
3665 NULL, modProfileFields, &roamId, 1);
3666 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303667 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303668
3669 /* Check channel number is a valid channel number */
3670 if(VOS_STATUS_SUCCESS !=
3671 wlan_hdd_validate_operation_channel(pAdapter, channel))
3672 {
3673 hddLog(VOS_TRACE_LEVEL_ERROR,
3674 "%s: Invalid Channel [%d]", __func__, channel);
3675 return -EINVAL;
3676 }
3677
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303678 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303679
3680 /* Proceed with scan/roam */
3681 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3682 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303683 (tSmeFastRoamTrigger)(trigger),
3684 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303685 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003686#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003687#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003688 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3689 {
3690 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003691 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003692
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003693 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003694 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003695 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003696 hdd_is_okc_mode_enabled(pHddCtx) &&
3697 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3698 {
3699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003700 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003701 " hence this operation is not permitted!", __func__);
3702 ret = -EPERM;
3703 goto exit;
3704 }
3705
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003706 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3707 value = value + 11;
3708 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003709 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003710 if (ret < 0)
3711 {
3712 /* If the input value is greater than max value of datatype, then also
3713 kstrtou8 fails */
3714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3715 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003716 CFG_ESE_FEATURE_ENABLED_MIN,
3717 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003718 ret = -EINVAL;
3719 goto exit;
3720 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003721 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3722 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003723 {
3724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003725 "Ese mode value %d is out of range"
3726 " (Min: %d Max: %d)", eseMode,
3727 CFG_ESE_FEATURE_ENABLED_MIN,
3728 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003729 ret = -EINVAL;
3730 goto exit;
3731 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003733 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003734
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003735 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3736 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003737 }
3738#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003739 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3740 {
3741 tANI_U8 *value = command;
3742 tANI_BOOLEAN roamScanControl = 0;
3743
3744 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3745 value = value + 19;
3746 /* Convert the value from ascii to integer */
3747 ret = kstrtou8(value, 10, &roamScanControl);
3748 if (ret < 0)
3749 {
3750 /* If the input value is greater than max value of datatype, then also
3751 kstrtou8 fails */
3752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3753 "%s: kstrtou8 failed ", __func__);
3754 ret = -EINVAL;
3755 goto exit;
3756 }
3757
3758 if (0 != roamScanControl)
3759 {
3760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3761 "roam scan control invalid value = %d",
3762 roamScanControl);
3763 ret = -EINVAL;
3764 goto exit;
3765 }
3766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3767 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3768
3769 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3770 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003771#ifdef FEATURE_WLAN_OKC
3772 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3773 {
3774 tANI_U8 *value = command;
3775 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3776
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003777 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003778 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003779 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003780 hdd_is_okc_mode_enabled(pHddCtx) &&
3781 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3782 {
3783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003784 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003785 " hence this operation is not permitted!", __func__);
3786 ret = -EPERM;
3787 goto exit;
3788 }
3789
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003790 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3791 value = value + 11;
3792 /* Convert the value from ascii to integer */
3793 ret = kstrtou8(value, 10, &okcMode);
3794 if (ret < 0)
3795 {
3796 /* If the input value is greater than max value of datatype, then also
3797 kstrtou8 fails */
3798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3799 "%s: kstrtou8 failed range [%d - %d]", __func__,
3800 CFG_OKC_FEATURE_ENABLED_MIN,
3801 CFG_OKC_FEATURE_ENABLED_MAX);
3802 ret = -EINVAL;
3803 goto exit;
3804 }
3805
3806 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3807 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3808 {
3809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3810 "Okc mode value %d is out of range"
3811 " (Min: %d Max: %d)", okcMode,
3812 CFG_OKC_FEATURE_ENABLED_MIN,
3813 CFG_OKC_FEATURE_ENABLED_MAX);
3814 ret = -EINVAL;
3815 goto exit;
3816 }
3817
3818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3819 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3820
3821 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3822 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003823#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303824 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003825 {
3826 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3827 char extra[32];
3828 tANI_U8 len = 0;
3829
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003830 len = scnprintf(extra, sizeof(extra), "%s %d",
3831 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003832 if (copy_to_user(priv_data.buf, &extra, len + 1))
3833 {
3834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3835 "%s: failed to copy data to user buffer", __func__);
3836 ret = -EFAULT;
3837 goto exit;
3838 }
3839 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303840#ifdef WLAN_FEATURE_PACKET_FILTERING
3841 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3842 {
3843 tANI_U8 filterType = 0;
3844 tANI_U8 *value = command;
3845
3846 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3847 value = value + 22;
3848
3849 /* Convert the value from ascii to integer */
3850 ret = kstrtou8(value, 10, &filterType);
3851 if (ret < 0)
3852 {
3853 /* If the input value is greater than max value of datatype,
3854 * then also kstrtou8 fails
3855 */
3856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3857 "%s: kstrtou8 failed range ", __func__);
3858 ret = -EINVAL;
3859 goto exit;
3860 }
3861
3862 if (filterType != 0 && filterType != 1)
3863 {
3864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3865 "%s: Accepted Values are 0 and 1 ", __func__);
3866 ret = -EINVAL;
3867 goto exit;
3868 }
3869 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3870 pAdapter->sessionId);
3871 }
3872#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303873 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3874 {
Kiet Lamad161252014-07-22 11:23:32 -07003875 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303876 int ret;
3877
Kiet Lamad161252014-07-22 11:23:32 -07003878 dhcpPhase = command + 11;
3879 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303880 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003882 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303883
3884 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003885
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303886 ret = wlan_hdd_scan_abort(pAdapter);
3887 if (ret < 0)
3888 {
3889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3890 FL("failed to abort existing scan %d"), ret);
3891 }
3892
Kiet Lamad161252014-07-22 11:23:32 -07003893 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3894 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303895 }
Kiet Lamad161252014-07-22 11:23:32 -07003896 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303897 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003899 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303900
3901 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003902
3903 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3904 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303905 }
3906 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003907 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3908 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3910 FL("making default scan to ACTIVE"));
3911 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003912 }
3913 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3914 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3916 FL("making default scan to PASSIVE"));
3917 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003918 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303919 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3920 {
3921 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3922 char extra[32];
3923 tANI_U8 len = 0;
3924
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303925 memset(extra, 0, sizeof(extra));
3926 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3927 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303928 {
3929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3930 "%s: failed to copy data to user buffer", __func__);
3931 ret = -EFAULT;
3932 goto exit;
3933 }
3934 ret = len;
3935 }
3936 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3937 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303938 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303939 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003940 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3941 {
3942 tANI_U8 filterType = 0;
3943 tANI_U8 *value;
3944 value = command + 9;
3945
3946 /* Convert the value from ascii to integer */
3947 ret = kstrtou8(value, 10, &filterType);
3948 if (ret < 0)
3949 {
3950 /* If the input value is greater than max value of datatype,
3951 * then also kstrtou8 fails
3952 */
3953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3954 "%s: kstrtou8 failed range ", __func__);
3955 ret = -EINVAL;
3956 goto exit;
3957 }
3958 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3959 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3963 " 2-Sink ", __func__);
3964 ret = -EINVAL;
3965 goto exit;
3966 }
3967 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3968 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303969 pScanInfo = &pHddCtx->scan_info;
3970 if (filterType && pScanInfo != NULL &&
3971 pHddCtx->scan_info.mScanPending)
3972 {
3973 /*Miracast Session started. Abort Scan */
3974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3975 "%s, Aborting Scan For Miracast",__func__);
3976 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3977 eCSR_SCAN_ABORT_DEFAULT);
3978 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003979 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303980 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003981 }
Leo Chang614d2072013-08-22 14:59:44 -07003982 else if (strncmp(command, "SETMCRATE", 9) == 0)
3983 {
Leo Chang614d2072013-08-22 14:59:44 -07003984 tANI_U8 *value = command;
3985 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003986 tSirRateUpdateInd *rateUpdate;
3987 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003988
3989 /* Only valid for SAP mode */
3990 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3991 {
3992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3993 "%s: SAP mode is not running", __func__);
3994 ret = -EFAULT;
3995 goto exit;
3996 }
3997
3998 /* Move pointer to ahead of SETMCRATE<delimiter> */
3999 /* input value is in units of hundred kbps */
4000 value = value + 10;
4001 /* Convert the value from ascii to integer, decimal base */
4002 ret = kstrtouint(value, 10, &targetRate);
4003
Leo Chang1f98cbd2013-10-17 15:03:52 -07004004 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4005 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004006 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004007 hddLog(VOS_TRACE_LEVEL_ERROR,
4008 "%s: SETMCRATE indication alloc fail", __func__);
4009 ret = -EFAULT;
4010 goto exit;
4011 }
4012 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4013
4014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4015 "MC Target rate %d", targetRate);
4016 /* Ignore unicast */
4017 rateUpdate->ucastDataRate = -1;
4018 rateUpdate->mcastDataRate24GHz = targetRate;
4019 rateUpdate->mcastDataRate5GHz = targetRate;
4020 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4021 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4022 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4023 if (eHAL_STATUS_SUCCESS != status)
4024 {
4025 hddLog(VOS_TRACE_LEVEL_ERROR,
4026 "%s: SET_MC_RATE failed", __func__);
4027 vos_mem_free(rateUpdate);
4028 ret = -EFAULT;
4029 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004030 }
4031 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304032#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004033 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304034 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004035 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304036 }
4037#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004038#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004039 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4040 {
4041 tANI_U8 *value = command;
4042 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4043 tANI_U8 numChannels = 0;
4044 eHalStatus status = eHAL_STATUS_SUCCESS;
4045
4046 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4047 if (eHAL_STATUS_SUCCESS != status)
4048 {
4049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4050 "%s: Failed to parse channel list information", __func__);
4051 ret = -EINVAL;
4052 goto exit;
4053 }
4054
4055 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4056 {
4057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4058 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4059 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4060 ret = -EINVAL;
4061 goto exit;
4062 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004063 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004064 ChannelList,
4065 numChannels);
4066 if (eHAL_STATUS_SUCCESS != status)
4067 {
4068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4069 "%s: Failed to update channel list information", __func__);
4070 ret = -EINVAL;
4071 goto exit;
4072 }
4073 }
4074 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4075 {
4076 tANI_U8 *value = command;
4077 char extra[128] = {0};
4078 int len = 0;
4079 tANI_U8 tid = 0;
4080 hdd_station_ctx_t *pHddStaCtx = NULL;
4081 tAniTrafStrmMetrics tsmMetrics;
4082 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4083
4084 /* if not associated, return error */
4085 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4086 {
4087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4088 ret = -EINVAL;
4089 goto exit;
4090 }
4091
4092 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4093 value = value + 12;
4094 /* Convert the value from ascii to integer */
4095 ret = kstrtou8(value, 10, &tid);
4096 if (ret < 0)
4097 {
4098 /* If the input value is greater than max value of datatype, then also
4099 kstrtou8 fails */
4100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4101 "%s: kstrtou8 failed range [%d - %d]", __func__,
4102 TID_MIN_VALUE,
4103 TID_MAX_VALUE);
4104 ret = -EINVAL;
4105 goto exit;
4106 }
4107
4108 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4109 {
4110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4111 "tid value %d is out of range"
4112 " (Min: %d Max: %d)", tid,
4113 TID_MIN_VALUE,
4114 TID_MAX_VALUE);
4115 ret = -EINVAL;
4116 goto exit;
4117 }
4118
4119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4120 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4121
4122 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4123 {
4124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4125 "%s: failed to get tsm stats", __func__);
4126 ret = -EFAULT;
4127 goto exit;
4128 }
4129
4130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4131 "UplinkPktQueueDly(%d)\n"
4132 "UplinkPktQueueDlyHist[0](%d)\n"
4133 "UplinkPktQueueDlyHist[1](%d)\n"
4134 "UplinkPktQueueDlyHist[2](%d)\n"
4135 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304136 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004137 "UplinkPktLoss(%d)\n"
4138 "UplinkPktCount(%d)\n"
4139 "RoamingCount(%d)\n"
4140 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4141 tsmMetrics.UplinkPktQueueDlyHist[0],
4142 tsmMetrics.UplinkPktQueueDlyHist[1],
4143 tsmMetrics.UplinkPktQueueDlyHist[2],
4144 tsmMetrics.UplinkPktQueueDlyHist[3],
4145 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4146 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4147
4148 /* Output TSM stats is of the format
4149 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4150 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004151 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004152 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4153 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4154 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4155 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4156 tsmMetrics.RoamingDly);
4157
4158 if (copy_to_user(priv_data.buf, &extra, len + 1))
4159 {
4160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4161 "%s: failed to copy data to user buffer", __func__);
4162 ret = -EFAULT;
4163 goto exit;
4164 }
4165 }
4166 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4167 {
4168 tANI_U8 *value = command;
4169 tANI_U8 *cckmIe = NULL;
4170 tANI_U8 cckmIeLen = 0;
4171 eHalStatus status = eHAL_STATUS_SUCCESS;
4172
4173 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4174 if (eHAL_STATUS_SUCCESS != status)
4175 {
4176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4177 "%s: Failed to parse cckm ie data", __func__);
4178 ret = -EINVAL;
4179 goto exit;
4180 }
4181
4182 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4183 {
4184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4185 "%s: CCKM Ie input length is more than max[%d]", __func__,
4186 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004187 vos_mem_free(cckmIe);
4188 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004189 ret = -EINVAL;
4190 goto exit;
4191 }
4192 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004193 vos_mem_free(cckmIe);
4194 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004195 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004196 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4197 {
4198 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004199 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004200 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004201
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004202 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004203 if (eHAL_STATUS_SUCCESS != status)
4204 {
4205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004206 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004207 ret = -EINVAL;
4208 goto exit;
4209 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004210 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4211 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4212 hdd_indicateEseBcnReportNoResults (pAdapter,
4213 eseBcnReq.bcnReq[0].measurementToken,
4214 0x02, //BIT(1) set for measurement done
4215 0); // no BSS
4216 goto exit;
4217 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004218
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004219 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4220 if (eHAL_STATUS_SUCCESS != status)
4221 {
4222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4223 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4224 ret = -EINVAL;
4225 goto exit;
4226 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004227 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004228#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304229 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4230 {
4231 eHalStatus status;
4232 char buf[32], len;
4233 long waitRet;
4234 bcnMissRateContext_t getBcnMissRateCtx;
4235
4236 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4237
4238 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4239 {
4240 hddLog(VOS_TRACE_LEVEL_WARN,
4241 FL("GETBCNMISSRATE: STA is not in connected state"));
4242 ret = -1;
4243 goto exit;
4244 }
4245
4246 init_completion(&(getBcnMissRateCtx.completion));
4247 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4248
4249 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4250 pAdapter->sessionId,
4251 (void *)getBcnMissRateCB,
4252 (void *)(&getBcnMissRateCtx));
4253 if( eHAL_STATUS_SUCCESS != status)
4254 {
4255 hddLog(VOS_TRACE_LEVEL_INFO,
4256 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4257 ret = -EINVAL;
4258 goto exit;
4259 }
4260
4261 waitRet = wait_for_completion_interruptible_timeout
4262 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4263 if(waitRet <= 0)
4264 {
4265 hddLog(VOS_TRACE_LEVEL_ERROR,
4266 FL("failed to wait on bcnMissRateComp %d"), ret);
4267
4268 //Make magic number to zero so that callback is not called.
4269 spin_lock(&hdd_context_lock);
4270 getBcnMissRateCtx.magic = 0x0;
4271 spin_unlock(&hdd_context_lock);
4272 ret = -EINVAL;
4273 goto exit;
4274 }
4275
4276 hddLog(VOS_TRACE_LEVEL_INFO,
4277 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4278
4279 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4280 if (copy_to_user(priv_data.buf, &buf, len + 1))
4281 {
4282 hddLog(VOS_TRACE_LEVEL_ERROR,
4283 "%s: failed to copy data to user buffer", __func__);
4284 ret = -EFAULT;
4285 goto exit;
4286 }
4287 ret = len;
4288 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304289#ifdef FEATURE_WLAN_TDLS
4290 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4291 tANI_U8 *value = command;
4292 int set_value;
4293 /* Move pointer to ahead of TDLSOFFCH*/
4294 value += 26;
4295 sscanf(value, "%d", &set_value);
4296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4297 "%s: Tdls offchannel offset:%d",
4298 __func__, set_value);
4299 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4300 if (ret < 0)
4301 {
4302 ret = -EINVAL;
4303 goto exit;
4304 }
4305
4306 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4307 tANI_U8 *value = command;
4308 int set_value;
4309 /* Move pointer to ahead of tdlsoffchnmode*/
4310 value += 18;
4311 sscanf(value, "%d", &set_value);
4312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4313 "%s: Tdls offchannel mode:%d",
4314 __func__, set_value);
4315 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4316 if (ret < 0)
4317 {
4318 ret = -EINVAL;
4319 goto exit;
4320 }
4321 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4322 tANI_U8 *value = command;
4323 int set_value;
4324 /* Move pointer to ahead of TDLSOFFCH*/
4325 value += 14;
4326 sscanf(value, "%d", &set_value);
4327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4328 "%s: Tdls offchannel num: %d",
4329 __func__, set_value);
4330 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4331 if (ret < 0)
4332 {
4333 ret = -EINVAL;
4334 goto exit;
4335 }
4336 }
4337#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304338 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4339 {
4340 eHalStatus status;
4341 char *buf = NULL;
4342 char len;
4343 long waitRet;
4344 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304345 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304346 tANI_U8 *ptr = command;
4347 int stats = *(ptr + 11) - '0';
4348
4349 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4350 if (!IS_FEATURE_FW_STATS_ENABLE)
4351 {
4352 hddLog(VOS_TRACE_LEVEL_INFO,
4353 FL("Get Firmware stats feature not supported"));
4354 ret = -EINVAL;
4355 goto exit;
4356 }
4357
4358 if (FW_STATS_MAX <= stats || 0 >= stats)
4359 {
4360 hddLog(VOS_TRACE_LEVEL_INFO,
4361 FL(" stats %d not supported"),stats);
4362 ret = -EINVAL;
4363 goto exit;
4364 }
4365
4366 init_completion(&(fwStatsCtx.completion));
4367 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4368 fwStatsCtx.pAdapter = pAdapter;
4369 fwStatsRsp->type = 0;
4370 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304371 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304372 if (eHAL_STATUS_SUCCESS != status)
4373 {
4374 hddLog(VOS_TRACE_LEVEL_ERROR,
4375 FL(" fail to post WDA cmd status = %d"), status);
4376 ret = -EINVAL;
4377 goto exit;
4378 }
4379 waitRet = wait_for_completion_timeout
4380 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4381 if (waitRet <= 0)
4382 {
4383 hddLog(VOS_TRACE_LEVEL_ERROR,
4384 FL("failed to wait on GwtFwstats"));
4385 //Make magic number to zero so that callback is not executed.
4386 spin_lock(&hdd_context_lock);
4387 fwStatsCtx.magic = 0x0;
4388 spin_unlock(&hdd_context_lock);
4389 ret = -EINVAL;
4390 goto exit;
4391 }
4392 if (fwStatsRsp->type)
4393 {
4394 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4395 if (!buf)
4396 {
4397 hddLog(VOS_TRACE_LEVEL_ERROR,
4398 FL(" failed to allocate memory"));
4399 ret = -ENOMEM;
4400 goto exit;
4401 }
4402 switch( fwStatsRsp->type )
4403 {
4404 case FW_UBSP_STATS:
4405 {
4406 len = snprintf(buf, FW_STATE_RSP_LEN,
4407 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304408 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4409 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304410 }
4411 break;
4412 default:
4413 {
4414 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4415 ret = -EFAULT;
4416 kfree(buf);
4417 goto exit;
4418 }
4419 }
4420 if (copy_to_user(priv_data.buf, buf, len + 1))
4421 {
4422 hddLog(VOS_TRACE_LEVEL_ERROR,
4423 FL(" failed to copy data to user buffer"));
4424 ret = -EFAULT;
4425 kfree(buf);
4426 goto exit;
4427 }
4428 ret = len;
4429 kfree(buf);
4430 }
4431 else
4432 {
4433 hddLog(VOS_TRACE_LEVEL_ERROR,
4434 FL("failed to fetch the stats"));
4435 ret = -EFAULT;
4436 goto exit;
4437 }
4438
4439 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304440 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4441 {
4442 /*
4443 * this command wld be called by user-space when it detects WLAN
4444 * ON after airplane mode is set. When APM is set, WLAN turns off.
4445 * But it can be turned back on. Otherwise; when APM is turned back
4446 * off, WLAN wld turn back on. So at that point the command is
4447 * expected to come down. 0 means disable, 1 means enable. The
4448 * constraint is removed when parameter 1 is set or different
4449 * country code is set
4450 */
4451 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4452 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004453 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304454 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4455 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4456 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304457 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4458 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004460 }
4461exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304462 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004463 if (command)
4464 {
4465 kfree(command);
4466 }
4467 return ret;
4468}
4469
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004470#ifdef CONFIG_COMPAT
4471static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4472{
4473 struct {
4474 compat_uptr_t buf;
4475 int used_len;
4476 int total_len;
4477 } compat_priv_data;
4478 hdd_priv_data_t priv_data;
4479 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004480
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004481 /*
4482 * Note that pAdapter and ifr have already been verified by caller,
4483 * and HDD context has also been validated
4484 */
4485 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4486 sizeof(compat_priv_data))) {
4487 ret = -EFAULT;
4488 goto exit;
4489 }
4490 priv_data.buf = compat_ptr(compat_priv_data.buf);
4491 priv_data.used_len = compat_priv_data.used_len;
4492 priv_data.total_len = compat_priv_data.total_len;
4493 ret = hdd_driver_command(pAdapter, &priv_data);
4494 exit:
4495 return ret;
4496}
4497#else /* CONFIG_COMPAT */
4498static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4499{
4500 /* will never be invoked */
4501 return 0;
4502}
4503#endif /* CONFIG_COMPAT */
4504
4505static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4506{
4507 hdd_priv_data_t priv_data;
4508 int ret = 0;
4509
4510 /*
4511 * Note that pAdapter and ifr have already been verified by caller,
4512 * and HDD context has also been validated
4513 */
4514 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4515 ret = -EFAULT;
4516 } else {
4517 ret = hdd_driver_command(pAdapter, &priv_data);
4518 }
4519 return ret;
4520}
4521
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304522int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004523{
4524 hdd_adapter_t *pAdapter;
4525 hdd_context_t *pHddCtx;
4526 int ret;
4527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304528 ENTER();
4529
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004530 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4531 if (NULL == pAdapter) {
4532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4533 "%s: HDD adapter context is Null", __func__);
4534 ret = -ENODEV;
4535 goto exit;
4536 }
4537 if (dev != pAdapter->dev) {
4538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4539 "%s: HDD adapter/dev inconsistency", __func__);
4540 ret = -ENODEV;
4541 goto exit;
4542 }
4543
4544 if ((!ifr) || (!ifr->ifr_data)) {
4545 ret = -EINVAL;
4546 goto exit;
4547 }
4548
4549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4550 ret = wlan_hdd_validate_context(pHddCtx);
4551 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004552 ret = -EBUSY;
4553 goto exit;
4554 }
4555
4556 switch (cmd) {
4557 case (SIOCDEVPRIVATE + 1):
4558 if (is_compat_task())
4559 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4560 else
4561 ret = hdd_driver_ioctl(pAdapter, ifr);
4562 break;
4563 default:
4564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4565 __func__, cmd);
4566 ret = -EINVAL;
4567 break;
4568 }
4569 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304570 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004571 return ret;
4572}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004573
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304574int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4575{
4576 int ret;
4577
4578 vos_ssr_protect(__func__);
4579 ret = __hdd_ioctl(dev, ifr, cmd);
4580 vos_ssr_unprotect(__func__);
4581
4582 return ret;
4583}
4584
Katya Nigame7b69a82015-04-28 15:24:06 +05304585int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4586{
4587 return 0;
4588}
4589
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004590#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004591/**---------------------------------------------------------------------------
4592
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004593 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004594
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004595 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004596 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4597 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4598 <space>Scan Mode N<space>Meas Duration N
4599 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4600 then take N.
4601 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4602 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4603 This function does not take care of removing duplicate channels from the list
4604
4605 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004606 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004607
4608 \return - 0 for success non-zero for failure
4609
4610 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004611static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4612 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004613{
4614 tANI_U8 *inPtr = pValue;
4615 int tempInt = 0;
4616 int j = 0, i = 0, v = 0;
4617 char buf[32];
4618
4619 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4620 /*no argument after the command*/
4621 if (NULL == inPtr)
4622 {
4623 return -EINVAL;
4624 }
4625 /*no space after the command*/
4626 else if (SPACE_ASCII_VALUE != *inPtr)
4627 {
4628 return -EINVAL;
4629 }
4630
4631 /*removing empty spaces*/
4632 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4633
4634 /*no argument followed by spaces*/
4635 if ('\0' == *inPtr) return -EINVAL;
4636
4637 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004638 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004639 if (1 != v) return -EINVAL;
4640
4641 v = kstrtos32(buf, 10, &tempInt);
4642 if ( v < 0) return -EINVAL;
4643
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004644 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004645
4646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004647 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004648
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004649 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004650 {
4651 for (i = 0; i < 4; i++)
4652 {
4653 /*inPtr pointing to the beginning of first space after number of ie fields*/
4654 inPtr = strpbrk( inPtr, " " );
4655 /*no ie data after the number of ie fields argument*/
4656 if (NULL == inPtr) return -EINVAL;
4657
4658 /*removing empty space*/
4659 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4660
4661 /*no ie data after the number of ie fields argument and spaces*/
4662 if ( '\0' == *inPtr ) return -EINVAL;
4663
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004664 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004665 if (1 != v) return -EINVAL;
4666
4667 v = kstrtos32(buf, 10, &tempInt);
4668 if (v < 0) return -EINVAL;
4669
4670 switch (i)
4671 {
4672 case 0: /* Measurement token */
4673 if (tempInt <= 0)
4674 {
4675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4676 "Invalid Measurement Token(%d)", tempInt);
4677 return -EINVAL;
4678 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004679 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004680 break;
4681
4682 case 1: /* Channel number */
4683 if ((tempInt <= 0) ||
4684 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4685 {
4686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4687 "Invalid Channel Number(%d)", tempInt);
4688 return -EINVAL;
4689 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004690 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004691 break;
4692
4693 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004694 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004695 {
4696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4697 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4698 return -EINVAL;
4699 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004700 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004701 break;
4702
4703 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004704 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4705 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004706 {
4707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4708 "Invalid Measurement Duration(%d)", tempInt);
4709 return -EINVAL;
4710 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004711 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004712 break;
4713 }
4714 }
4715 }
4716
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004717 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004718 {
4719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304720 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004721 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004722 pEseBcnReq->bcnReq[j].measurementToken,
4723 pEseBcnReq->bcnReq[j].channel,
4724 pEseBcnReq->bcnReq[j].scanMode,
4725 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004726 }
4727
4728 return VOS_STATUS_SUCCESS;
4729}
4730
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004731static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4732{
4733 struct statsContext *pStatsContext = NULL;
4734 hdd_adapter_t *pAdapter = NULL;
4735
4736 if (NULL == pContext)
4737 {
4738 hddLog(VOS_TRACE_LEVEL_ERROR,
4739 "%s: Bad param, pContext [%p]",
4740 __func__, pContext);
4741 return;
4742 }
4743
Jeff Johnson72a40512013-12-19 10:14:15 -08004744 /* there is a race condition that exists between this callback
4745 function and the caller since the caller could time out either
4746 before or while this code is executing. we use a spinlock to
4747 serialize these actions */
4748 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004749
4750 pStatsContext = pContext;
4751 pAdapter = pStatsContext->pAdapter;
4752 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4753 {
4754 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004755 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004756 hddLog(VOS_TRACE_LEVEL_WARN,
4757 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4758 __func__, pAdapter, pStatsContext->magic);
4759 return;
4760 }
4761
Jeff Johnson72a40512013-12-19 10:14:15 -08004762 /* context is valid so caller is still waiting */
4763
4764 /* paranoia: invalidate the magic */
4765 pStatsContext->magic = 0;
4766
4767 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004768 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4769 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4770 tsmMetrics.UplinkPktQueueDlyHist,
4771 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4772 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4773 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4774 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4775 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4776 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4777 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4778
Jeff Johnson72a40512013-12-19 10:14:15 -08004779 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004780 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004781
4782 /* serialization is complete */
4783 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004784}
4785
4786
4787
4788static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4789 tAniTrafStrmMetrics* pTsmMetrics)
4790{
4791 hdd_station_ctx_t *pHddStaCtx = NULL;
4792 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004793 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004794 long lrc;
4795 struct statsContext context;
4796 hdd_context_t *pHddCtx = NULL;
4797
4798 if (NULL == pAdapter)
4799 {
4800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4801 return VOS_STATUS_E_FAULT;
4802 }
4803
4804 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4805 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4806
4807 /* we are connected prepare our callback context */
4808 init_completion(&context.completion);
4809 context.pAdapter = pAdapter;
4810 context.magic = STATS_CONTEXT_MAGIC;
4811
4812 /* query tsm stats */
4813 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4814 pHddStaCtx->conn_info.staId[ 0 ],
4815 pHddStaCtx->conn_info.bssId,
4816 &context, pHddCtx->pvosContext, tid);
4817
4818 if (eHAL_STATUS_SUCCESS != hstatus)
4819 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4821 __func__);
4822 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004823 }
4824 else
4825 {
4826 /* request was sent -- wait for the response */
4827 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4828 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004829 if (lrc <= 0)
4830 {
4831 hddLog(VOS_TRACE_LEVEL_ERROR,
4832 "%s: SME %s while retrieving statistics",
4833 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004834 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004835 }
4836 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004837
Jeff Johnson72a40512013-12-19 10:14:15 -08004838 /* either we never sent a request, we sent a request and received a
4839 response or we sent a request and timed out. if we never sent a
4840 request or if we sent a request and got a response, we want to
4841 clear the magic out of paranoia. if we timed out there is a
4842 race condition such that the callback function could be
4843 executing at the same time we are. of primary concern is if the
4844 callback function had already verified the "magic" but had not
4845 yet set the completion variable when a timeout occurred. we
4846 serialize these activities by invalidating the magic while
4847 holding a shared spinlock which will cause us to block if the
4848 callback is currently executing */
4849 spin_lock(&hdd_context_lock);
4850 context.magic = 0;
4851 spin_unlock(&hdd_context_lock);
4852
4853 if (VOS_STATUS_SUCCESS == vstatus)
4854 {
4855 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4856 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4857 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4858 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4859 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4860 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4861 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4862 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4863 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4864 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4865 }
4866 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004867}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004868#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004869
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004870#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004871void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4872{
4873 eCsrBand band = -1;
4874 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4875 switch (band)
4876 {
4877 case eCSR_BAND_ALL:
4878 *pBand = WLAN_HDD_UI_BAND_AUTO;
4879 break;
4880
4881 case eCSR_BAND_24:
4882 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4883 break;
4884
4885 case eCSR_BAND_5G:
4886 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4887 break;
4888
4889 default:
4890 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4891 *pBand = -1;
4892 break;
4893 }
4894}
4895
4896/**---------------------------------------------------------------------------
4897
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004898 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4899
4900 This function parses the send action frame data passed in the format
4901 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4902
Srinivas Girigowda56076852013-08-20 14:00:50 -07004903 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004904 \param - pTargetApBssid Pointer to target Ap bssid
4905 \param - pChannel Pointer to the Target AP channel
4906 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4907 \param - pBuf Pointer to data
4908 \param - pBufLen Pointer to data length
4909
4910 \return - 0 for success non-zero for failure
4911
4912 --------------------------------------------------------------------------*/
4913VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4914 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4915{
4916 tANI_U8 *inPtr = pValue;
4917 tANI_U8 *dataEnd;
4918 int tempInt;
4919 int j = 0;
4920 int i = 0;
4921 int v = 0;
4922 tANI_U8 tempBuf[32];
4923 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004924 /* 12 hexa decimal digits, 5 ':' and '\0' */
4925 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004926
4927 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4928 /*no argument after the command*/
4929 if (NULL == inPtr)
4930 {
4931 return -EINVAL;
4932 }
4933
4934 /*no space after the command*/
4935 else if (SPACE_ASCII_VALUE != *inPtr)
4936 {
4937 return -EINVAL;
4938 }
4939
4940 /*removing empty spaces*/
4941 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4942
4943 /*no argument followed by spaces*/
4944 if ('\0' == *inPtr)
4945 {
4946 return -EINVAL;
4947 }
4948
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004949 v = sscanf(inPtr, "%17s", macAddress);
4950 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004951 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4953 "Invalid MAC address or All hex inputs are not read (%d)", v);
4954 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004955 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004956
4957 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4958 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4959 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4960 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4961 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4962 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004963
4964 /* point to the next argument */
4965 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4966 /*no argument after the command*/
4967 if (NULL == inPtr) return -EINVAL;
4968
4969 /*removing empty spaces*/
4970 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4971
4972 /*no argument followed by spaces*/
4973 if ('\0' == *inPtr)
4974 {
4975 return -EINVAL;
4976 }
4977
4978 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004979 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004980 if (1 != v) return -EINVAL;
4981
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004982 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304983 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304984 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004985
4986 *pChannel = tempInt;
4987
4988 /* point to the next argument */
4989 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4990 /*no argument after the command*/
4991 if (NULL == inPtr) return -EINVAL;
4992 /*removing empty spaces*/
4993 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4994
4995 /*no argument followed by spaces*/
4996 if ('\0' == *inPtr)
4997 {
4998 return -EINVAL;
4999 }
5000
5001 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005002 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005003 if (1 != v) return -EINVAL;
5004
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005005 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005006 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005007
5008 *pDwellTime = tempInt;
5009
5010 /* point to the next argument */
5011 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5012 /*no argument after the command*/
5013 if (NULL == inPtr) return -EINVAL;
5014 /*removing empty spaces*/
5015 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5016
5017 /*no argument followed by spaces*/
5018 if ('\0' == *inPtr)
5019 {
5020 return -EINVAL;
5021 }
5022
5023 /* find the length of data */
5024 dataEnd = inPtr;
5025 while(('\0' != *dataEnd) )
5026 {
5027 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005028 }
Kiet Lambe150c22013-11-21 16:30:32 +05305029 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005030 if ( *pBufLen <= 0) return -EINVAL;
5031
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005032 /* Allocate the number of bytes based on the number of input characters
5033 whether it is even or odd.
5034 if the number of input characters are even, then we need N/2 byte.
5035 if the number of input characters are odd, then we need do (N+1)/2 to
5036 compensate rounding off.
5037 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5038 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5039 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005040 if (NULL == *pBuf)
5041 {
5042 hddLog(VOS_TRACE_LEVEL_FATAL,
5043 "%s: vos_mem_alloc failed ", __func__);
5044 return -EINVAL;
5045 }
5046
5047 /* the buffer received from the upper layer is character buffer,
5048 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5049 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5050 and f0 in 3rd location */
5051 for (i = 0, j = 0; j < *pBufLen; j += 2)
5052 {
Kiet Lambe150c22013-11-21 16:30:32 +05305053 if( j+1 == *pBufLen)
5054 {
5055 tempByte = hdd_parse_hex(inPtr[j]);
5056 }
5057 else
5058 {
5059 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5060 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005061 (*pBuf)[i++] = tempByte;
5062 }
5063 *pBufLen = i;
5064 return VOS_STATUS_SUCCESS;
5065}
5066
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005067/**---------------------------------------------------------------------------
5068
Srinivas Girigowdade697412013-02-14 16:31:48 -08005069 \brief hdd_parse_channellist() - HDD Parse channel list
5070
5071 This function parses the channel list passed in the format
5072 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005073 if the Number of channels (N) does not match with the actual number of channels passed
5074 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5075 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5076 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5077 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005078
5079 \param - pValue Pointer to input channel list
5080 \param - ChannelList Pointer to local output array to record channel list
5081 \param - pNumChannels Pointer to number of roam scan channels
5082
5083 \return - 0 for success non-zero for failure
5084
5085 --------------------------------------------------------------------------*/
5086VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5087{
5088 tANI_U8 *inPtr = pValue;
5089 int tempInt;
5090 int j = 0;
5091 int v = 0;
5092 char buf[32];
5093
5094 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5095 /*no argument after the command*/
5096 if (NULL == inPtr)
5097 {
5098 return -EINVAL;
5099 }
5100
5101 /*no space after the command*/
5102 else if (SPACE_ASCII_VALUE != *inPtr)
5103 {
5104 return -EINVAL;
5105 }
5106
5107 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005108 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005109
5110 /*no argument followed by spaces*/
5111 if ('\0' == *inPtr)
5112 {
5113 return -EINVAL;
5114 }
5115
5116 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005117 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005118 if (1 != v) return -EINVAL;
5119
Srinivas Girigowdade697412013-02-14 16:31:48 -08005120 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005121 if ((v < 0) ||
5122 (tempInt <= 0) ||
5123 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5124 {
5125 return -EINVAL;
5126 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005127
5128 *pNumChannels = tempInt;
5129
5130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5131 "Number of channels are: %d", *pNumChannels);
5132
5133 for (j = 0; j < (*pNumChannels); j++)
5134 {
5135 /*inPtr pointing to the beginning of first space after number of channels*/
5136 inPtr = strpbrk( inPtr, " " );
5137 /*no channel list after the number of channels argument*/
5138 if (NULL == inPtr)
5139 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005140 if (0 != j)
5141 {
5142 *pNumChannels = j;
5143 return VOS_STATUS_SUCCESS;
5144 }
5145 else
5146 {
5147 return -EINVAL;
5148 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005149 }
5150
5151 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005152 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005153
5154 /*no channel list after the number of channels argument and spaces*/
5155 if ( '\0' == *inPtr )
5156 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005157 if (0 != j)
5158 {
5159 *pNumChannels = j;
5160 return VOS_STATUS_SUCCESS;
5161 }
5162 else
5163 {
5164 return -EINVAL;
5165 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005166 }
5167
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005168 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005169 if (1 != v) return -EINVAL;
5170
Srinivas Girigowdade697412013-02-14 16:31:48 -08005171 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005172 if ((v < 0) ||
5173 (tempInt <= 0) ||
5174 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5175 {
5176 return -EINVAL;
5177 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005178 pChannelList[j] = tempInt;
5179
5180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5181 "Channel %d added to preferred channel list",
5182 pChannelList[j] );
5183 }
5184
Srinivas Girigowdade697412013-02-14 16:31:48 -08005185 return VOS_STATUS_SUCCESS;
5186}
5187
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005188
5189/**---------------------------------------------------------------------------
5190
5191 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5192
5193 This function parses the reasoc command data passed in the format
5194 REASSOC<space><bssid><space><channel>
5195
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005196 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005197 \param - pTargetApBssid Pointer to target Ap bssid
5198 \param - pChannel Pointer to the Target AP channel
5199
5200 \return - 0 for success non-zero for failure
5201
5202 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005203VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5204 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005205{
5206 tANI_U8 *inPtr = pValue;
5207 int tempInt;
5208 int v = 0;
5209 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005210 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005211 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005212
5213 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5214 /*no argument after the command*/
5215 if (NULL == inPtr)
5216 {
5217 return -EINVAL;
5218 }
5219
5220 /*no space after the command*/
5221 else if (SPACE_ASCII_VALUE != *inPtr)
5222 {
5223 return -EINVAL;
5224 }
5225
5226 /*removing empty spaces*/
5227 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5228
5229 /*no argument followed by spaces*/
5230 if ('\0' == *inPtr)
5231 {
5232 return -EINVAL;
5233 }
5234
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005235 v = sscanf(inPtr, "%17s", macAddress);
5236 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005237 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5239 "Invalid MAC address or All hex inputs are not read (%d)", v);
5240 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005241 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005242
5243 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5244 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5245 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5246 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5247 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5248 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005249
5250 /* point to the next argument */
5251 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5252 /*no argument after the command*/
5253 if (NULL == inPtr) return -EINVAL;
5254
5255 /*removing empty spaces*/
5256 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5257
5258 /*no argument followed by spaces*/
5259 if ('\0' == *inPtr)
5260 {
5261 return -EINVAL;
5262 }
5263
5264 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005265 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005266 if (1 != v) return -EINVAL;
5267
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005268 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005269 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305270 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005271 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5272 {
5273 return -EINVAL;
5274 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005275
5276 *pChannel = tempInt;
5277 return VOS_STATUS_SUCCESS;
5278}
5279
5280#endif
5281
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005282#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005283/**---------------------------------------------------------------------------
5284
5285 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5286
5287 This function parses the SETCCKM IE command
5288 SETCCKMIE<space><ie data>
5289
5290 \param - pValue Pointer to input data
5291 \param - pCckmIe Pointer to output cckm Ie
5292 \param - pCckmIeLen Pointer to output cckm ie length
5293
5294 \return - 0 for success non-zero for failure
5295
5296 --------------------------------------------------------------------------*/
5297VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5298 tANI_U8 *pCckmIeLen)
5299{
5300 tANI_U8 *inPtr = pValue;
5301 tANI_U8 *dataEnd;
5302 int j = 0;
5303 int i = 0;
5304 tANI_U8 tempByte = 0;
5305
5306 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5307 /*no argument after the command*/
5308 if (NULL == inPtr)
5309 {
5310 return -EINVAL;
5311 }
5312
5313 /*no space after the command*/
5314 else if (SPACE_ASCII_VALUE != *inPtr)
5315 {
5316 return -EINVAL;
5317 }
5318
5319 /*removing empty spaces*/
5320 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5321
5322 /*no argument followed by spaces*/
5323 if ('\0' == *inPtr)
5324 {
5325 return -EINVAL;
5326 }
5327
5328 /* find the length of data */
5329 dataEnd = inPtr;
5330 while(('\0' != *dataEnd) )
5331 {
5332 dataEnd++;
5333 ++(*pCckmIeLen);
5334 }
5335 if ( *pCckmIeLen <= 0) return -EINVAL;
5336
5337 /* Allocate the number of bytes based on the number of input characters
5338 whether it is even or odd.
5339 if the number of input characters are even, then we need N/2 byte.
5340 if the number of input characters are odd, then we need do (N+1)/2 to
5341 compensate rounding off.
5342 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5343 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5344 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5345 if (NULL == *pCckmIe)
5346 {
5347 hddLog(VOS_TRACE_LEVEL_FATAL,
5348 "%s: vos_mem_alloc failed ", __func__);
5349 return -EINVAL;
5350 }
5351 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5352 /* the buffer received from the upper layer is character buffer,
5353 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5354 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5355 and f0 in 3rd location */
5356 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5357 {
5358 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5359 (*pCckmIe)[i++] = tempByte;
5360 }
5361 *pCckmIeLen = i;
5362
5363 return VOS_STATUS_SUCCESS;
5364}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005365#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005366
Jeff Johnson295189b2012-06-20 16:38:30 -07005367/**---------------------------------------------------------------------------
5368
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005369 \brief hdd_is_valid_mac_address() - Validate MAC address
5370
5371 This function validates whether the given MAC address is valid or not
5372 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5373 where X is the hexa decimal digit character and separated by ':'
5374 This algorithm works even if MAC address is not separated by ':'
5375
5376 This code checks given input string mac contains exactly 12 hexadecimal digits.
5377 and a separator colon : appears in the input string only after
5378 an even number of hex digits.
5379
5380 \param - pMacAddr pointer to the input MAC address
5381 \return - 1 for valid and 0 for invalid
5382
5383 --------------------------------------------------------------------------*/
5384
5385v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5386{
5387 int xdigit = 0;
5388 int separator = 0;
5389 while (*pMacAddr)
5390 {
5391 if (isxdigit(*pMacAddr))
5392 {
5393 xdigit++;
5394 }
5395 else if (':' == *pMacAddr)
5396 {
5397 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5398 break;
5399
5400 ++separator;
5401 }
5402 else
5403 {
5404 separator = -1;
5405 /* Invalid MAC found */
5406 return 0;
5407 }
5408 ++pMacAddr;
5409 }
5410 return (xdigit == 12 && (separator == 5 || separator == 0));
5411}
5412
5413/**---------------------------------------------------------------------------
5414
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305415 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005416
5417 \param - dev Pointer to net_device structure
5418
5419 \return - 0 for success non-zero for failure
5420
5421 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305422int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005423{
5424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5425 hdd_context_t *pHddCtx;
5426 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5427 VOS_STATUS status;
5428 v_BOOL_t in_standby = TRUE;
5429
5430 if (NULL == pAdapter)
5431 {
5432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305433 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 return -ENODEV;
5435 }
5436
5437 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305438 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5439 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 if (NULL == pHddCtx)
5441 {
5442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005443 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 return -ENODEV;
5445 }
5446
5447 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5448 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5449 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005450 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5451 {
5452 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305453 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005454 in_standby = FALSE;
5455 break;
5456 }
5457 else
5458 {
5459 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5460 pAdapterNode = pNext;
5461 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 }
5463
5464 if (TRUE == in_standby)
5465 {
5466 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5467 {
5468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5469 "wlan out of power save", __func__);
5470 return -EINVAL;
5471 }
5472 }
5473
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005474 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5476 {
5477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005478 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305480 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005481 netif_tx_start_all_queues(dev);
5482 }
5483
5484 return 0;
5485}
5486
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305487/**---------------------------------------------------------------------------
5488
5489 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5490
5491 This is called in response to ifconfig up
5492
5493 \param - dev Pointer to net_device structure
5494
5495 \return - 0 for success non-zero for failure
5496
5497 --------------------------------------------------------------------------*/
5498int hdd_open(struct net_device *dev)
5499{
5500 int ret;
5501
5502 vos_ssr_protect(__func__);
5503 ret = __hdd_open(dev);
5504 vos_ssr_unprotect(__func__);
5505
5506 return ret;
5507}
5508
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305509int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005510{
5511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5512
5513 if(pAdapter == NULL) {
5514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005515 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005516 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 }
5518
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 return 0;
5520}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305521
5522int hdd_mon_open (struct net_device *dev)
5523{
5524 int ret;
5525
5526 vos_ssr_protect(__func__);
5527 ret = __hdd_mon_open(dev);
5528 vos_ssr_unprotect(__func__);
5529
5530 return ret;
5531}
5532
Katya Nigame7b69a82015-04-28 15:24:06 +05305533int hdd_mon_stop(struct net_device *dev)
5534{
5535 return 0;
5536}
5537
Jeff Johnson295189b2012-06-20 16:38:30 -07005538/**---------------------------------------------------------------------------
5539
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305540 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005541
5542 \param - dev Pointer to net_device structure
5543
5544 \return - 0 for success non-zero for failure
5545
5546 --------------------------------------------------------------------------*/
5547
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305548int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005549{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305550 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5552 hdd_context_t *pHddCtx;
5553 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5554 VOS_STATUS status;
5555 v_BOOL_t enter_standby = TRUE;
5556
5557 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 if (NULL == pAdapter)
5559 {
5560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305561 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 return -ENODEV;
5563 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305564 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305565 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305566
5567 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5568 ret = wlan_hdd_validate_context(pHddCtx);
5569 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305571 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 }
5573
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305574 /* Nothing to be done if the interface is not opened */
5575 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5576 {
5577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5578 "%s: NETDEV Interface is not OPENED", __func__);
5579 return -ENODEV;
5580 }
5581
5582 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005583 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305585
5586 /* Disable TX on the interface, after this hard_start_xmit() will not
5587 * be called on that interface
5588 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305591
5592 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 netif_carrier_off(pAdapter->dev);
5594
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305595 /* The interface is marked as down for outside world (aka kernel)
5596 * But the driver is pretty much alive inside. The driver needs to
5597 * tear down the existing connection on the netdev (session)
5598 * cleanup the data pipes and wait until the control plane is stabilized
5599 * for this interface. The call also needs to wait until the above
5600 * mentioned actions are completed before returning to the caller.
5601 * Notice that the hdd_stop_adapter is requested not to close the session
5602 * That is intentional to be able to scan if it is a STA/P2P interface
5603 */
5604 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305605#ifdef FEATURE_WLAN_TDLS
5606 mutex_lock(&pHddCtx->tdls_lock);
5607#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305608 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305609 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305610#ifdef FEATURE_WLAN_TDLS
5611 mutex_unlock(&pHddCtx->tdls_lock);
5612#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005613 /* SoftAP ifaces should never go in power save mode
5614 making sure same here. */
5615 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5616 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 )
5619 {
5620 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5622 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 EXIT();
5624 return 0;
5625 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305626 /* Find if any iface is up. If any iface is up then can't put device to
5627 * sleep/power save mode
5628 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5630 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5631 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005632 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5633 {
5634 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305635 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005636 enter_standby = FALSE;
5637 break;
5638 }
5639 else
5640 {
5641 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5642 pAdapterNode = pNext;
5643 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 }
5645
5646 if (TRUE == enter_standby)
5647 {
5648 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5649 "entering standby", __func__);
5650 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5651 {
5652 /*log and return success*/
5653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5654 "wlan in power save", __func__);
5655 }
5656 }
5657
5658 EXIT();
5659 return 0;
5660}
5661
5662/**---------------------------------------------------------------------------
5663
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305664 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005665
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305666 This is called in response to ifconfig down
5667
5668 \param - dev Pointer to net_device structure
5669
5670 \return - 0 for success non-zero for failure
5671-----------------------------------------------------------------------------*/
5672int hdd_stop (struct net_device *dev)
5673{
5674 int ret;
5675
5676 vos_ssr_protect(__func__);
5677 ret = __hdd_stop(dev);
5678 vos_ssr_unprotect(__func__);
5679
5680 return ret;
5681}
5682
5683/**---------------------------------------------------------------------------
5684
5685 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005686
5687 \param - dev Pointer to net_device structure
5688
5689 \return - void
5690
5691 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305692static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005693{
5694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305695 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 ENTER();
5697
5698 do
5699 {
5700 if (NULL == pAdapter)
5701 {
5702 hddLog(VOS_TRACE_LEVEL_FATAL,
5703 "%s: NULL pAdapter", __func__);
5704 break;
5705 }
5706
5707 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5708 {
5709 hddLog(VOS_TRACE_LEVEL_FATAL,
5710 "%s: Invalid magic", __func__);
5711 break;
5712 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305713 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5714 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005715 {
5716 hddLog(VOS_TRACE_LEVEL_FATAL,
5717 "%s: NULL pHddCtx", __func__);
5718 break;
5719 }
5720
5721 if (dev != pAdapter->dev)
5722 {
5723 hddLog(VOS_TRACE_LEVEL_FATAL,
5724 "%s: Invalid device reference", __func__);
5725 /* we haven't validated all cases so let this go for now */
5726 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305727#ifdef FEATURE_WLAN_TDLS
5728 mutex_lock(&pHddCtx->tdls_lock);
5729#endif
c_hpothu002231a2015-02-05 14:58:51 +05305730 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305731#ifdef FEATURE_WLAN_TDLS
5732 mutex_unlock(&pHddCtx->tdls_lock);
5733#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005734
5735 /* after uninit our adapter structure will no longer be valid */
5736 pAdapter->dev = NULL;
5737 pAdapter->magic = 0;
5738 } while (0);
5739
5740 EXIT();
5741}
5742
5743/**---------------------------------------------------------------------------
5744
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305745 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5746
5747 This is called during the netdev unregister to uninitialize all data
5748associated with the device
5749
5750 \param - dev Pointer to net_device structure
5751
5752 \return - void
5753
5754 --------------------------------------------------------------------------*/
5755static void hdd_uninit (struct net_device *dev)
5756{
5757 vos_ssr_protect(__func__);
5758 __hdd_uninit(dev);
5759 vos_ssr_unprotect(__func__);
5760}
5761
5762/**---------------------------------------------------------------------------
5763
Jeff Johnson295189b2012-06-20 16:38:30 -07005764 \brief hdd_release_firmware() -
5765
5766 This function calls the release firmware API to free the firmware buffer.
5767
5768 \param - pFileName Pointer to the File Name.
5769 pCtx - Pointer to the adapter .
5770
5771
5772 \return - 0 for success, non zero for failure
5773
5774 --------------------------------------------------------------------------*/
5775
5776VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5777{
5778 VOS_STATUS status = VOS_STATUS_SUCCESS;
5779 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5780 ENTER();
5781
5782
5783 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5784
5785 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5786
5787 if(pHddCtx->fw) {
5788 release_firmware(pHddCtx->fw);
5789 pHddCtx->fw = NULL;
5790 }
5791 else
5792 status = VOS_STATUS_E_FAILURE;
5793 }
5794 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5795 if(pHddCtx->nv) {
5796 release_firmware(pHddCtx->nv);
5797 pHddCtx->nv = NULL;
5798 }
5799 else
5800 status = VOS_STATUS_E_FAILURE;
5801
5802 }
5803
5804 EXIT();
5805 return status;
5806}
5807
5808/**---------------------------------------------------------------------------
5809
5810 \brief hdd_request_firmware() -
5811
5812 This function reads the firmware file using the request firmware
5813 API and returns the the firmware data and the firmware file size.
5814
5815 \param - pfileName - Pointer to the file name.
5816 - pCtx - Pointer to the adapter .
5817 - ppfw_data - Pointer to the pointer of the firmware data.
5818 - pSize - Pointer to the file size.
5819
5820 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5821
5822 --------------------------------------------------------------------------*/
5823
5824
5825VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5826{
5827 int status;
5828 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5829 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5830 ENTER();
5831
5832 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5833
5834 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5835
5836 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5837 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5838 __func__, pfileName);
5839 retval = VOS_STATUS_E_FAILURE;
5840 }
5841
5842 else {
5843 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5844 *pSize = pHddCtx->fw->size;
5845 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5846 __func__, *pSize);
5847 }
5848 }
5849 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5850
5851 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5852
5853 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5854 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5855 __func__, pfileName);
5856 retval = VOS_STATUS_E_FAILURE;
5857 }
5858
5859 else {
5860 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5861 *pSize = pHddCtx->nv->size;
5862 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5863 __func__, *pSize);
5864 }
5865 }
5866
5867 EXIT();
5868 return retval;
5869}
5870/**---------------------------------------------------------------------------
5871 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5872
5873 This is the function invoked by SME to inform the result of a full power
5874 request issued by HDD
5875
5876 \param - callbackcontext - Pointer to cookie
5877 status - result of request
5878
5879 \return - None
5880
5881--------------------------------------------------------------------------*/
5882void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5883{
5884 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5885
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005886 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 if(&pHddCtx->full_pwr_comp_var)
5888 {
5889 complete(&pHddCtx->full_pwr_comp_var);
5890 }
5891}
5892
5893/**---------------------------------------------------------------------------
5894
5895 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5896
5897 This is the function invoked by SME to inform the result of BMPS
5898 request issued by HDD
5899
5900 \param - callbackcontext - Pointer to cookie
5901 status - result of request
5902
5903 \return - None
5904
5905--------------------------------------------------------------------------*/
5906void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5907{
5908
5909 struct completion *completion_var = (struct completion*) callbackContext;
5910
Arif Hussain6d2a3322013-11-17 19:50:10 -08005911 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 if(completion_var != NULL)
5913 {
5914 complete(completion_var);
5915 }
5916}
5917
5918/**---------------------------------------------------------------------------
5919
5920 \brief hdd_get_cfg_file_size() -
5921
5922 This function reads the configuration file using the request firmware
5923 API and returns the configuration file size.
5924
5925 \param - pCtx - Pointer to the adapter .
5926 - pFileName - Pointer to the file name.
5927 - pBufSize - Pointer to the buffer size.
5928
5929 \return - 0 for success, non zero for failure
5930
5931 --------------------------------------------------------------------------*/
5932
5933VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5934{
5935 int status;
5936 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5937
5938 ENTER();
5939
5940 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5941
5942 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5943 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5944 status = VOS_STATUS_E_FAILURE;
5945 }
5946 else {
5947 *pBufSize = pHddCtx->fw->size;
5948 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5949 release_firmware(pHddCtx->fw);
5950 pHddCtx->fw = NULL;
5951 }
5952
5953 EXIT();
5954 return VOS_STATUS_SUCCESS;
5955}
5956
5957/**---------------------------------------------------------------------------
5958
5959 \brief hdd_read_cfg_file() -
5960
5961 This function reads the configuration file using the request firmware
5962 API and returns the cfg data and the buffer size of the configuration file.
5963
5964 \param - pCtx - Pointer to the adapter .
5965 - pFileName - Pointer to the file name.
5966 - pBuffer - Pointer to the data buffer.
5967 - pBufSize - Pointer to the buffer size.
5968
5969 \return - 0 for success, non zero for failure
5970
5971 --------------------------------------------------------------------------*/
5972
5973VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5974 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5975{
5976 int status;
5977 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5978
5979 ENTER();
5980
5981 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5982
5983 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5984 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5985 return VOS_STATUS_E_FAILURE;
5986 }
5987 else {
5988 if(*pBufSize != pHddCtx->fw->size) {
5989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5990 "file size", __func__);
5991 release_firmware(pHddCtx->fw);
5992 pHddCtx->fw = NULL;
5993 return VOS_STATUS_E_FAILURE;
5994 }
5995 else {
5996 if(pBuffer) {
5997 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5998 }
5999 release_firmware(pHddCtx->fw);
6000 pHddCtx->fw = NULL;
6001 }
6002 }
6003
6004 EXIT();
6005
6006 return VOS_STATUS_SUCCESS;
6007}
6008
6009/**---------------------------------------------------------------------------
6010
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306011 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006012
6013 This function sets the user specified mac address using
6014 the command ifconfig wlanX hw ether <mac adress>.
6015
6016 \param - dev - Pointer to the net device.
6017 - addr - Pointer to the sockaddr.
6018 \return - 0 for success, non zero for failure
6019
6020 --------------------------------------------------------------------------*/
6021
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306022static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006023{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306024 hdd_adapter_t *pAdapter;
6025 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 struct sockaddr *psta_mac_addr = addr;
6027 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306028 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006029
6030 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306031 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6032 if (NULL == pAdapter)
6033 {
6034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6035 "%s: Adapter is NULL",__func__);
6036 return -EINVAL;
6037 }
6038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6039 ret = wlan_hdd_validate_context(pHddCtx);
6040 if (0 != ret)
6041 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306042 return ret;
6043 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006044
6045 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006046 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6047
6048 EXIT();
6049 return halStatus;
6050}
6051
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306052/**---------------------------------------------------------------------------
6053
6054 \brief hdd_set_mac_address() -
6055
6056 Wrapper function to protect __hdd_set_mac_address() function from ssr
6057
6058 \param - dev - Pointer to the net device.
6059 - addr - Pointer to the sockaddr.
6060 \return - 0 for success, non zero for failure
6061
6062 --------------------------------------------------------------------------*/
6063static int hdd_set_mac_address(struct net_device *dev, void *addr)
6064{
6065 int ret;
6066
6067 vos_ssr_protect(__func__);
6068 ret = __hdd_set_mac_address(dev, addr);
6069 vos_ssr_unprotect(__func__);
6070
6071 return ret;
6072}
6073
Jeff Johnson295189b2012-06-20 16:38:30 -07006074tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6075{
6076 int i;
6077 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6078 {
Abhishek Singheb183782014-02-06 13:37:21 +05306079 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 break;
6081 }
6082
6083 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6084 return NULL;
6085
6086 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6087 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6088}
6089
6090void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6091{
6092 int i;
6093 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6094 {
6095 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6096 {
6097 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6098 break;
6099 }
6100 }
6101 return;
6102}
6103
6104#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6105 static struct net_device_ops wlan_drv_ops = {
6106 .ndo_open = hdd_open,
6107 .ndo_stop = hdd_stop,
6108 .ndo_uninit = hdd_uninit,
6109 .ndo_start_xmit = hdd_hard_start_xmit,
6110 .ndo_tx_timeout = hdd_tx_timeout,
6111 .ndo_get_stats = hdd_stats,
6112 .ndo_do_ioctl = hdd_ioctl,
6113 .ndo_set_mac_address = hdd_set_mac_address,
6114 .ndo_select_queue = hdd_select_queue,
6115#ifdef WLAN_FEATURE_PACKET_FILTERING
6116#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6117 .ndo_set_rx_mode = hdd_set_multicast_list,
6118#else
6119 .ndo_set_multicast_list = hdd_set_multicast_list,
6120#endif //LINUX_VERSION_CODE
6121#endif
6122 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006123 static struct net_device_ops wlan_mon_drv_ops = {
6124 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306125 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 .ndo_uninit = hdd_uninit,
6127 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6128 .ndo_tx_timeout = hdd_tx_timeout,
6129 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306130 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 .ndo_set_mac_address = hdd_set_mac_address,
6132 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306133
Jeff Johnson295189b2012-06-20 16:38:30 -07006134#endif
6135
6136void hdd_set_station_ops( struct net_device *pWlanDev )
6137{
6138#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006139 pWlanDev->netdev_ops = &wlan_drv_ops;
6140#else
6141 pWlanDev->open = hdd_open;
6142 pWlanDev->stop = hdd_stop;
6143 pWlanDev->uninit = hdd_uninit;
6144 pWlanDev->hard_start_xmit = NULL;
6145 pWlanDev->tx_timeout = hdd_tx_timeout;
6146 pWlanDev->get_stats = hdd_stats;
6147 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 pWlanDev->set_mac_address = hdd_set_mac_address;
6149#endif
6150}
6151
Katya Nigam1fd24402015-02-16 14:52:19 +05306152void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6153{
6154 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6155 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6156 #else
6157 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6158 #endif
6159}
6160
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006161static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006162{
6163 struct net_device *pWlanDev = NULL;
6164 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 /*
6166 * cfg80211 initialization and registration....
6167 */
6168 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6169
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 if(pWlanDev != NULL)
6171 {
6172
6173 //Save the pointer to the net_device in the HDD adapter
6174 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6175
Jeff Johnson295189b2012-06-20 16:38:30 -07006176 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6177
6178 pAdapter->dev = pWlanDev;
6179 pAdapter->pHddCtx = pHddCtx;
6180 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306181 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006182
6183 init_completion(&pAdapter->session_open_comp_var);
6184 init_completion(&pAdapter->session_close_comp_var);
6185 init_completion(&pAdapter->disconnect_comp_var);
6186 init_completion(&pAdapter->linkup_event_var);
6187 init_completion(&pAdapter->cancel_rem_on_chan_var);
6188 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306189 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006190#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6191 init_completion(&pAdapter->offchannel_tx_event);
6192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006194#ifdef FEATURE_WLAN_TDLS
6195 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006196 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006197 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306198 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 init_completion(&pHddCtx->mc_sus_event_var);
6201 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306202 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006203 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006204 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006205
Rajeev79dbe4c2013-10-05 11:03:42 +05306206#ifdef FEATURE_WLAN_BATCH_SCAN
6207 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6208 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6209 pAdapter->pBatchScanRsp = NULL;
6210 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006211 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006212 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306213 mutex_init(&pAdapter->hdd_batch_scan_lock);
6214#endif
6215
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 pAdapter->isLinkUpSvcNeeded = FALSE;
6217 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6218 //Init the net_device structure
6219 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6220
6221 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6222 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6223 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6224 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6225
6226 hdd_set_station_ops( pAdapter->dev );
6227
6228 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6230 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6231 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 /* set pWlanDev's parent to underlying device */
6233 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006234
6235 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 }
6237
6238 return pAdapter;
6239}
6240
6241VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6242{
6243 struct net_device *pWlanDev = pAdapter->dev;
6244 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6245 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6246 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6247
6248 if( rtnl_lock_held )
6249 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006250 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6252 {
6253 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6254 return VOS_STATUS_E_FAILURE;
6255 }
6256 }
6257 if (register_netdevice(pWlanDev))
6258 {
6259 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6260 return VOS_STATUS_E_FAILURE;
6261 }
6262 }
6263 else
6264 {
6265 if(register_netdev(pWlanDev))
6266 {
6267 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6268 return VOS_STATUS_E_FAILURE;
6269 }
6270 }
6271 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6272
6273 return VOS_STATUS_SUCCESS;
6274}
6275
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006276static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006277{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006278 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006279
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006280 if (NULL == pAdapter)
6281 {
6282 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6283 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006285
6286 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6287 {
6288 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6289 return eHAL_STATUS_NOT_INITIALIZED;
6290 }
6291
6292 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6293
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006294#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006295 /* need to make sure all of our scheduled work has completed.
6296 * This callback is called from MC thread context, so it is safe to
6297 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006298 *
6299 * Even though this is called from MC thread context, if there is a faulty
6300 * work item in the system, that can hang this call forever. So flushing
6301 * this global work queue is not safe; and now we make sure that
6302 * individual work queues are stopped correctly. But the cancel work queue
6303 * is a GPL only API, so the proprietary version of the driver would still
6304 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006305 */
6306 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006307#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006308
6309 /* We can be blocked while waiting for scheduled work to be
6310 * flushed, and the adapter structure can potentially be freed, in
6311 * which case the magic will have been reset. So make sure the
6312 * magic is still good, and hence the adapter structure is still
6313 * valid, before signaling completion */
6314 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6315 {
6316 complete(&pAdapter->session_close_comp_var);
6317 }
6318
Jeff Johnson295189b2012-06-20 16:38:30 -07006319 return eHAL_STATUS_SUCCESS;
6320}
6321
6322VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6323{
6324 struct net_device *pWlanDev = pAdapter->dev;
6325 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6326 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6327 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6328 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306329 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006330
Nirav Shah7e3c8132015-06-22 23:51:42 +05306331 spin_lock_init( &pAdapter->sta_hash_lock);
6332 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6333
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006335 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 //Open a SME session for future operation
6337 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006338 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6340 {
6341 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006342 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 halStatus, halStatus );
6344 status = VOS_STATUS_E_FAILURE;
6345 goto error_sme_open;
6346 }
6347
6348 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306349 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 &pAdapter->session_open_comp_var,
6351 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306352 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 {
6354 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306355 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 status = VOS_STATUS_E_FAILURE;
6357 goto error_sme_open;
6358 }
6359
6360 // Register wireless extensions
6361 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6362 {
6363 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006364 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 halStatus, halStatus );
6366 status = VOS_STATUS_E_FAILURE;
6367 goto error_register_wext;
6368 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306369
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306371 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6372 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6373 #else
6374 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6375 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006376
6377 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306378 hddLog(VOS_TRACE_LEVEL_INFO,
6379 "%s: Set HDD connState to eConnectionState_NotConnected",
6380 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6382
6383 //Set the default operation channel
6384 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6385
6386 /* Make the default Auth Type as OPEN*/
6387 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6388
6389 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6390 {
6391 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006392 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 status, status );
6394 goto error_init_txrx;
6395 }
6396
6397 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6398
6399 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6400 {
6401 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006402 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006403 status, status );
6404 goto error_wmm_init;
6405 }
6406
6407 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6408
6409 return VOS_STATUS_SUCCESS;
6410
6411error_wmm_init:
6412 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6413 hdd_deinit_tx_rx(pAdapter);
6414error_init_txrx:
6415 hdd_UnregisterWext(pWlanDev);
6416error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006417 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 {
6419 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006420 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306421 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006422 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306424 unsigned long rc;
6425
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306427 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006429 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306430 if (rc <= 0)
6431 hddLog(VOS_TRACE_LEVEL_ERROR,
6432 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 }
6434}
6435error_sme_open:
6436 return status;
6437}
6438
Jeff Johnson295189b2012-06-20 16:38:30 -07006439void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6440{
6441 hdd_cfg80211_state_t *cfgState;
6442
6443 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6444
6445 if( NULL != cfgState->buf )
6446 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306447 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6449 rc = wait_for_completion_interruptible_timeout(
6450 &pAdapter->tx_action_cnf_event,
6451 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306452 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306455 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6456 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 }
6458 }
6459 return;
6460}
Jeff Johnson295189b2012-06-20 16:38:30 -07006461
c_hpothu002231a2015-02-05 14:58:51 +05306462void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006463{
6464 ENTER();
6465 switch ( pAdapter->device_mode )
6466 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306467 case WLAN_HDD_IBSS:
6468 {
6469 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6470 {
6471 hdd_ibss_deinit_tx_rx( pAdapter );
6472 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6473 }
6474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 case WLAN_HDD_INFRA_STATION:
6476 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006477 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 {
6479 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6480 {
6481 hdd_deinit_tx_rx( pAdapter );
6482 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6483 }
6484
6485 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6486 {
6487 hdd_wmm_adapter_close( pAdapter );
6488 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6489 }
6490
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 break;
6493 }
6494
6495 case WLAN_HDD_SOFTAP:
6496 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006497 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306498
6499 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6500 {
6501 hdd_wmm_adapter_close( pAdapter );
6502 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6503 }
6504
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006506
c_hpothu002231a2015-02-05 14:58:51 +05306507 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006508 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 break;
6510 }
6511
6512 case WLAN_HDD_MONITOR:
6513 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6515 {
6516 hdd_deinit_tx_rx( pAdapter );
6517 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6518 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 break;
6520 }
6521
6522
6523 default:
6524 break;
6525 }
6526
6527 EXIT();
6528}
6529
6530void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6531{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006532 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306533
6534 ENTER();
6535 if (NULL == pAdapter)
6536 {
6537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6538 "%s: HDD adapter is Null", __func__);
6539 return;
6540 }
6541
6542 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006543
Rajeev79dbe4c2013-10-05 11:03:42 +05306544#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306545 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6546 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006547 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306548 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6549 )
6550 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006551 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306552 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006553 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6554 {
6555 hdd_deinit_batch_scan(pAdapter);
6556 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306557 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006558 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306559#endif
6560
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6562 if( rtnl_held )
6563 {
6564 unregister_netdevice(pWlanDev);
6565 }
6566 else
6567 {
6568 unregister_netdev(pWlanDev);
6569 }
6570 // note that the pAdapter is no longer valid at this point
6571 // since the memory has been reclaimed
6572 }
6573
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306574 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006575}
6576
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006577void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6578{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306579 VOS_STATUS status;
6580 hdd_adapter_t *pAdapter = NULL;
6581 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006582
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306583 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006584
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306585 /*loop through all adapters.*/
6586 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006587 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306588 pAdapter = pAdapterNode->pAdapter;
6589 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6590 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006591
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306592 { // we skip this registration for modes other than STA and P2P client modes.
6593 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6594 pAdapterNode = pNext;
6595 continue;
6596 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006597
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306598 //Apply Dynamic DTIM For P2P
6599 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6600 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6601 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6602 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6603 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6604 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6605 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6606 (eConnectionState_Associated ==
6607 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6608 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6609 {
6610 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006611
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306612 powerRequest.uIgnoreDTIM = 1;
6613 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6614
6615 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6616 {
6617 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6618 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6619 }
6620 else
6621 {
6622 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6623 }
6624
6625 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6626 * specified during Enter/Exit BMPS when LCD off*/
6627 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6628 NULL, eANI_BOOLEAN_FALSE);
6629 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6630 NULL, eANI_BOOLEAN_FALSE);
6631
6632 /* switch to the DTIM specified in cfg.ini */
6633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6634 "Switch to DTIM %d", powerRequest.uListenInterval);
6635 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6636 break;
6637
6638 }
6639
6640 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6641 pAdapterNode = pNext;
6642 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006643}
6644
6645void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6646{
6647 /*Switch back to DTIM 1*/
6648 tSirSetPowerParamsReq powerRequest = { 0 };
6649
6650 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6651 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006652 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006653
6654 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6655 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6656 NULL, eANI_BOOLEAN_FALSE);
6657 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6658 NULL, eANI_BOOLEAN_FALSE);
6659
6660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6661 "Switch to DTIM%d",powerRequest.uListenInterval);
6662 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6663
6664}
6665
Jeff Johnson295189b2012-06-20 16:38:30 -07006666VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6667{
6668 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306669 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6670 {
6671 hddLog( LOGE, FL("Wlan Unload in progress"));
6672 return VOS_STATUS_E_PERM;
6673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6675 {
6676 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6677 }
6678
6679 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6680 {
6681 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6682 }
6683
6684 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6685 {
6686 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6687 }
6688
6689 return status;
6690}
6691
6692VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6693{
6694 hdd_adapter_t *pAdapter = NULL;
6695 eHalStatus halStatus;
6696 VOS_STATUS status = VOS_STATUS_E_INVAL;
6697 v_BOOL_t disableBmps = FALSE;
6698 v_BOOL_t disableImps = FALSE;
6699
6700 switch(session_type)
6701 {
6702 case WLAN_HDD_INFRA_STATION:
6703 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 case WLAN_HDD_P2P_CLIENT:
6705 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 //Exit BMPS -> Is Sta/P2P Client is already connected
6707 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6708 if((NULL != pAdapter)&&
6709 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6710 {
6711 disableBmps = TRUE;
6712 }
6713
6714 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6715 if((NULL != pAdapter)&&
6716 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6717 {
6718 disableBmps = TRUE;
6719 }
6720
6721 //Exit both Bmps and Imps incase of Go/SAP Mode
6722 if((WLAN_HDD_SOFTAP == session_type) ||
6723 (WLAN_HDD_P2P_GO == session_type))
6724 {
6725 disableBmps = TRUE;
6726 disableImps = TRUE;
6727 }
6728
6729 if(TRUE == disableImps)
6730 {
6731 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6732 {
6733 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6734 }
6735 }
6736
6737 if(TRUE == disableBmps)
6738 {
6739 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6740 {
6741 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6742
6743 if(eHAL_STATUS_SUCCESS != halStatus)
6744 {
6745 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006746 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 VOS_ASSERT(0);
6748 return status;
6749 }
6750 }
6751
6752 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6753 {
6754 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6755
6756 if(eHAL_STATUS_SUCCESS != halStatus)
6757 {
6758 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006759 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 VOS_ASSERT(0);
6761 return status;
6762 }
6763 }
6764 }
6765
6766 if((TRUE == disableBmps) ||
6767 (TRUE == disableImps))
6768 {
6769 /* Now, get the chip into Full Power now */
6770 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6771 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6772 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6773
6774 if(halStatus != eHAL_STATUS_SUCCESS)
6775 {
6776 if(halStatus == eHAL_STATUS_PMC_PENDING)
6777 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306778 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306780 ret = wait_for_completion_interruptible_timeout(
6781 &pHddCtx->full_pwr_comp_var,
6782 msecs_to_jiffies(1000));
6783 if (ret <= 0)
6784 {
6785 hddLog(VOS_TRACE_LEVEL_ERROR,
6786 "%s: wait on full_pwr_comp_var failed %ld",
6787 __func__, ret);
6788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 }
6790 else
6791 {
6792 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006793 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 VOS_ASSERT(0);
6795 return status;
6796 }
6797 }
6798
6799 status = VOS_STATUS_SUCCESS;
6800 }
6801
6802 break;
6803 }
6804 return status;
6805}
Katya Nigame7b69a82015-04-28 15:24:06 +05306806void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6807 {
6808 hdd_mon_ctx_t *pMonCtx = NULL;
6809 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6810
6811 pMonCtx->state = 0;
6812 pMonCtx->ChannelNo = 1;
6813 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306814 pMonCtx->crcCheckEnabled = 1;
6815 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6816 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306817 pMonCtx->numOfMacFilters = 0;
6818 }
6819
Jeff Johnson295189b2012-06-20 16:38:30 -07006820
6821hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006822 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006823 tANI_U8 rtnl_held )
6824{
6825 hdd_adapter_t *pAdapter = NULL;
6826 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6827 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6828 VOS_STATUS exitbmpsStatus;
6829
Arif Hussain6d2a3322013-11-17 19:50:10 -08006830 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006831
Nirav Shah436658f2014-02-28 17:05:45 +05306832 if(macAddr == NULL)
6833 {
6834 /* Not received valid macAddr */
6835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6836 "%s:Unable to add virtual intf: Not able to get"
6837 "valid mac address",__func__);
6838 return NULL;
6839 }
6840
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 //Disable BMPS incase of Concurrency
6842 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6843
6844 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6845 {
6846 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306847 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 VOS_ASSERT(0);
6849 return NULL;
6850 }
6851
6852 switch(session_type)
6853 {
6854 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006856 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 {
6858 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6859
6860 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306861 {
6862 hddLog(VOS_TRACE_LEVEL_FATAL,
6863 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306865 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006866
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306867#ifdef FEATURE_WLAN_TDLS
6868 /* A Mutex Lock is introduced while changing/initializing the mode to
6869 * protect the concurrent access for the Adapters by TDLS module.
6870 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306871 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306872#endif
6873
Jeff Johnsone7245742012-09-05 17:12:55 -07006874 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6875 NL80211_IFTYPE_P2P_CLIENT:
6876 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006877
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306879#ifdef FEATURE_WLAN_TDLS
6880 mutex_unlock(&pHddCtx->tdls_lock);
6881#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306882
6883 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006884 if( VOS_STATUS_SUCCESS != status )
6885 goto err_free_netdev;
6886
6887 status = hdd_register_interface( pAdapter, rtnl_held );
6888 if( VOS_STATUS_SUCCESS != status )
6889 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306890#ifdef FEATURE_WLAN_TDLS
6891 mutex_lock(&pHddCtx->tdls_lock);
6892#endif
c_hpothu002231a2015-02-05 14:58:51 +05306893 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306894#ifdef FEATURE_WLAN_TDLS
6895 mutex_unlock(&pHddCtx->tdls_lock);
6896#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 goto err_free_netdev;
6898 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306899
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306900 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306901 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306902
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306903#ifdef WLAN_NS_OFFLOAD
6904 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306905 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306906#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306908 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006909 netif_tx_disable(pAdapter->dev);
6910 //netif_tx_disable(pWlanDev);
6911 netif_carrier_off(pAdapter->dev);
6912
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306913 if (WLAN_HDD_P2P_CLIENT == session_type ||
6914 WLAN_HDD_P2P_DEVICE == session_type)
6915 {
6916 /* Initialize the work queue to defer the
6917 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306918 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306919 hdd_p2p_roc_work_queue);
6920 }
6921
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 break;
6923 }
6924
Jeff Johnson295189b2012-06-20 16:38:30 -07006925 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 case WLAN_HDD_SOFTAP:
6927 {
6928 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6929 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306930 {
6931 hddLog(VOS_TRACE_LEVEL_FATAL,
6932 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006935
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6937 NL80211_IFTYPE_AP:
6938 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006939 pAdapter->device_mode = session_type;
6940
6941 status = hdd_init_ap_mode(pAdapter);
6942 if( VOS_STATUS_SUCCESS != status )
6943 goto err_free_netdev;
6944
Nirav Shah7e3c8132015-06-22 23:51:42 +05306945 status = hdd_sta_id_hash_attach(pAdapter);
6946 if (VOS_STATUS_SUCCESS != status)
6947 {
6948 hddLog(VOS_TRACE_LEVEL_FATAL,
6949 FL("failed to attach hash for session %d"), session_type);
6950 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6951 goto err_free_netdev;
6952 }
6953
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 status = hdd_register_hostapd( pAdapter, rtnl_held );
6955 if( VOS_STATUS_SUCCESS != status )
6956 {
c_hpothu002231a2015-02-05 14:58:51 +05306957 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 goto err_free_netdev;
6959 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306960 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 netif_tx_disable(pAdapter->dev);
6962 netif_carrier_off(pAdapter->dev);
6963
6964 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306965
6966 if (WLAN_HDD_P2P_GO == session_type)
6967 {
6968 /* Initialize the work queue to
6969 * defer the back to back RoC request */
6970 INIT_DELAYED_WORK(&pAdapter->roc_work,
6971 hdd_p2p_roc_work_queue);
6972 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 break;
6974 }
6975 case WLAN_HDD_MONITOR:
6976 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6978 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306979 {
6980 hddLog(VOS_TRACE_LEVEL_FATAL,
6981 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006984
Katya Nigame7b69a82015-04-28 15:24:06 +05306985 // Register wireless extensions
6986 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6987 {
6988 hddLog(VOS_TRACE_LEVEL_FATAL,
6989 "hdd_register_wext() failed with status code %08d [x%08x]",
6990 status, status );
6991 status = VOS_STATUS_E_FAILURE;
6992 }
6993
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6995 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006996#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6997 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6998#else
6999 pAdapter->dev->open = hdd_mon_open;
7000 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307001 pAdapter->dev->stop = hdd_mon_stop;
7002 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007003#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307004 status = hdd_register_interface( pAdapter, rtnl_held );
7005 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 hdd_init_tx_rx( pAdapter );
7007 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307008 //Stop the Interface TX queue.
7009 netif_tx_disable(pAdapter->dev);
7010 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 }
7012 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 case WLAN_HDD_FTM:
7014 {
7015 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7016
7017 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307018 {
7019 hddLog(VOS_TRACE_LEVEL_FATAL,
7020 FL("failed to allocate adapter for session %d"), session_type);
7021 return NULL;
7022 }
7023
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7025 * message while loading driver in FTM mode. */
7026 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7027 pAdapter->device_mode = session_type;
7028 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307029
7030 hdd_init_tx_rx( pAdapter );
7031
7032 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307033 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307034 netif_tx_disable(pAdapter->dev);
7035 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 }
7037 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 default:
7039 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307040 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7041 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 VOS_ASSERT(0);
7043 return NULL;
7044 }
7045 }
7046
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 if( VOS_STATUS_SUCCESS == status )
7048 {
7049 //Add it to the hdd's session list.
7050 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7051 if( NULL == pHddAdapterNode )
7052 {
7053 status = VOS_STATUS_E_NOMEM;
7054 }
7055 else
7056 {
7057 pHddAdapterNode->pAdapter = pAdapter;
7058 status = hdd_add_adapter_back ( pHddCtx,
7059 pHddAdapterNode );
7060 }
7061 }
7062
7063 if( VOS_STATUS_SUCCESS != status )
7064 {
7065 if( NULL != pAdapter )
7066 {
7067 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7068 pAdapter = NULL;
7069 }
7070 if( NULL != pHddAdapterNode )
7071 {
7072 vos_mem_free( pHddAdapterNode );
7073 }
7074
7075 goto resume_bmps;
7076 }
7077
7078 if(VOS_STATUS_SUCCESS == status)
7079 {
7080 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7081
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007082 //Initialize the WoWL service
7083 if(!hdd_init_wowl(pAdapter))
7084 {
7085 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7086 goto err_free_netdev;
7087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 return pAdapter;
7090
7091err_free_netdev:
7092 free_netdev(pAdapter->dev);
7093 wlan_hdd_release_intf_addr( pHddCtx,
7094 pAdapter->macAddressCurrent.bytes );
7095
7096resume_bmps:
7097 //If bmps disabled enable it
7098 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7099 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307100 if (pHddCtx->hdd_wlan_suspended)
7101 {
7102 hdd_set_pwrparams(pHddCtx);
7103 }
7104 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 }
7106 return NULL;
7107}
7108
7109VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7110 tANI_U8 rtnl_held )
7111{
7112 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7113 VOS_STATUS status;
7114
7115 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7116 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307117 {
7118 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7119 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307121 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007122
7123 while ( pCurrent->pAdapter != pAdapter )
7124 {
7125 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7126 if( VOS_STATUS_SUCCESS != status )
7127 break;
7128
7129 pCurrent = pNext;
7130 }
7131 pAdapterNode = pCurrent;
7132 if( VOS_STATUS_SUCCESS == status )
7133 {
7134 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7135 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307136
7137#ifdef FEATURE_WLAN_TDLS
7138
7139 /* A Mutex Lock is introduced while changing/initializing the mode to
7140 * protect the concurrent access for the Adapters by TDLS module.
7141 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307142 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307143#endif
7144
Jeff Johnson295189b2012-06-20 16:38:30 -07007145 hdd_remove_adapter( pHddCtx, pAdapterNode );
7146 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007147 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007148
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307149#ifdef FEATURE_WLAN_TDLS
7150 mutex_unlock(&pHddCtx->tdls_lock);
7151#endif
7152
Jeff Johnson295189b2012-06-20 16:38:30 -07007153
7154 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307155 if ((!vos_concurrent_open_sessions_running()) &&
7156 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7157 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307159 if (pHddCtx->hdd_wlan_suspended)
7160 {
7161 hdd_set_pwrparams(pHddCtx);
7162 }
7163 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 }
7165
7166 return VOS_STATUS_SUCCESS;
7167 }
7168
7169 return VOS_STATUS_E_FAILURE;
7170}
7171
7172VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7173{
7174 hdd_adapter_list_node_t *pHddAdapterNode;
7175 VOS_STATUS status;
7176
7177 ENTER();
7178
7179 do
7180 {
7181 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7182 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7183 {
7184 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7185 vos_mem_free( pHddAdapterNode );
7186 }
7187 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7188
7189 EXIT();
7190
7191 return VOS_STATUS_SUCCESS;
7192}
7193
7194void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7195{
7196 v_U8_t addIE[1] = {0};
7197
7198 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7199 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7200 eANI_BOOLEAN_FALSE) )
7201 {
7202 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007203 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 }
7205
7206 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7207 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7208 eANI_BOOLEAN_FALSE) )
7209 {
7210 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007211 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007212 }
7213
7214 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7215 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7216 eANI_BOOLEAN_FALSE) )
7217 {
7218 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007219 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007220 }
7221}
7222
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307223VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7224 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007225{
7226 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7227 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307228 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307230 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307231 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307232 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007233
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307234 if (pHddCtx->isLogpInProgress) {
7235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7236 "%s:LOGP in Progress. Ignore!!!",__func__);
7237 return VOS_STATUS_E_FAILURE;
7238 }
7239
Jeff Johnson295189b2012-06-20 16:38:30 -07007240 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307241
Nirav Shah7e3c8132015-06-22 23:51:42 +05307242 status = hdd_sta_id_hash_detach(pAdapter);
7243 if (status != VOS_STATUS_SUCCESS)
7244 hddLog(VOS_TRACE_LEVEL_ERROR,
7245 FL("sta id hash detach failed"));
7246
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307247 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007248 switch(pAdapter->device_mode)
7249 {
7250 case WLAN_HDD_INFRA_STATION:
7251 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007252 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307253 {
7254 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307255#ifdef FEATURE_WLAN_TDLS
7256 mutex_lock(&pHddCtx->tdls_lock);
7257 wlan_hdd_tdls_exit(pAdapter, TRUE);
7258 mutex_unlock(&pHddCtx->tdls_lock);
7259#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307260 if( hdd_connIsConnected(pstation) ||
7261 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 {
7263 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7264 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7265 pAdapter->sessionId,
7266 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7267 else
7268 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7269 pAdapter->sessionId,
7270 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7271 //success implies disconnect command got queued up successfully
7272 if(halStatus == eHAL_STATUS_SUCCESS)
7273 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307274 ret = wait_for_completion_interruptible_timeout(
7275 &pAdapter->disconnect_comp_var,
7276 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7277 if (ret <= 0)
7278 {
7279 hddLog(VOS_TRACE_LEVEL_ERROR,
7280 "%s: wait on disconnect_comp_var failed %ld",
7281 __func__, ret);
7282 }
7283 }
7284 else
7285 {
7286 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7287 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 }
7289 memset(&wrqu, '\0', sizeof(wrqu));
7290 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7291 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7292 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7293 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307294 else if(pstation->conn_info.connState ==
7295 eConnectionState_Disconnecting)
7296 {
7297 ret = wait_for_completion_interruptible_timeout(
7298 &pAdapter->disconnect_comp_var,
7299 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7300 if (ret <= 0)
7301 {
7302 hddLog(VOS_TRACE_LEVEL_ERROR,
7303 FL("wait on disconnect_comp_var failed %ld"), ret);
7304 }
7305 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307306 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007307 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307308 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307309 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007310 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307311 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7312 {
7313 while (pAdapter->is_roc_inprogress)
7314 {
7315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7316 "%s: ROC in progress for session %d!!!",
7317 __func__, pAdapter->sessionId);
7318 // waiting for ROC to expire
7319 msleep(500);
7320 /* In GO present case , if retry exceeds 3,
7321 it means something went wrong. */
7322 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7323 {
7324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7325 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307326 if (eHAL_STATUS_SUCCESS !=
7327 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7328 pAdapter->sessionId ))
7329 {
7330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7331 FL("Failed to Cancel Remain on Channel"));
7332 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307333 wait_for_completion_interruptible_timeout(
7334 &pAdapter->cancel_rem_on_chan_var,
7335 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7336 break;
7337 }
7338 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307339 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307340 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307341#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307342 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307343#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307344
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307345 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307346
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307347 /* It is possible that the caller of this function does not
7348 * wish to close the session
7349 */
7350 if (VOS_TRUE == bCloseSession &&
7351 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 {
7353 INIT_COMPLETION(pAdapter->session_close_comp_var);
7354 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307355 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307356 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007357 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307358 unsigned long ret;
7359
Jeff Johnson295189b2012-06-20 16:38:30 -07007360 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307361 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307362 &pAdapter->session_close_comp_var,
7363 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307364 if ( 0 >= ret)
7365 {
7366 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307367 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 }
7370 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307371 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 break;
7373
7374 case WLAN_HDD_SOFTAP:
7375 case WLAN_HDD_P2P_GO:
7376 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307377 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7378 while (pAdapter->is_roc_inprogress) {
7379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7380 "%s: ROC in progress for session %d!!!",
7381 __func__, pAdapter->sessionId);
7382 msleep(500);
7383 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7385 "%s: ROC completion is not received.!!!", __func__);
7386 WLANSAP_CancelRemainOnChannel(
7387 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7388 wait_for_completion_interruptible_timeout(
7389 &pAdapter->cancel_rem_on_chan_var,
7390 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7391 break;
7392 }
7393 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307394
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307395 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307396 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007397 mutex_lock(&pHddCtx->sap_lock);
7398 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7399 {
7400 VOS_STATUS status;
7401 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7402
7403 //Stop Bss.
7404 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7405 if (VOS_IS_STATUS_SUCCESS(status))
7406 {
7407 hdd_hostapd_state_t *pHostapdState =
7408 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7409
7410 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7411
7412 if (!VOS_IS_STATUS_SUCCESS(status))
7413 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307414 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7415 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007416 }
7417 }
7418 else
7419 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007420 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 }
7422 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307423 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007424
7425 if (eHAL_STATUS_FAILURE ==
7426 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7427 0, NULL, eANI_BOOLEAN_FALSE))
7428 {
7429 hddLog(LOGE,
7430 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007431 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 }
7433
7434 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7435 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7436 eANI_BOOLEAN_FALSE) )
7437 {
7438 hddLog(LOGE,
7439 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7440 }
7441
7442 // Reset WNI_CFG_PROBE_RSP Flags
7443 wlan_hdd_reset_prob_rspies(pAdapter);
7444 kfree(pAdapter->sessionCtx.ap.beacon);
7445 pAdapter->sessionCtx.ap.beacon = NULL;
7446 }
7447 mutex_unlock(&pHddCtx->sap_lock);
7448 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007449
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 case WLAN_HDD_MONITOR:
7451 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007452
Jeff Johnson295189b2012-06-20 16:38:30 -07007453 default:
7454 break;
7455 }
7456
7457 EXIT();
7458 return VOS_STATUS_SUCCESS;
7459}
7460
7461VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7462{
7463 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7464 VOS_STATUS status;
7465 hdd_adapter_t *pAdapter;
7466
7467 ENTER();
7468
7469 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7470
7471 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7472 {
7473 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007474
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307475 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007476
7477 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7478 pAdapterNode = pNext;
7479 }
7480
7481 EXIT();
7482
7483 return VOS_STATUS_SUCCESS;
7484}
7485
Rajeev Kumarf999e582014-01-09 17:33:29 -08007486
7487#ifdef FEATURE_WLAN_BATCH_SCAN
7488/**---------------------------------------------------------------------------
7489
7490 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7491 structures
7492
7493 \param - pAdapter Pointer to HDD adapter
7494
7495 \return - None
7496
7497 --------------------------------------------------------------------------*/
7498void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7499{
7500 tHddBatchScanRsp *pNode;
7501 tHddBatchScanRsp *pPrev;
7502
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307503 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007504 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307505 hddLog(VOS_TRACE_LEVEL_ERROR,
7506 "%s: Adapter context is Null", __func__);
7507 return;
7508 }
7509
7510 pNode = pAdapter->pBatchScanRsp;
7511 while (pNode)
7512 {
7513 pPrev = pNode;
7514 pNode = pNode->pNext;
7515 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007516 }
7517
7518 pAdapter->pBatchScanRsp = NULL;
7519 pAdapter->numScanList = 0;
7520 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7521 pAdapter->prev_batch_id = 0;
7522
7523 return;
7524}
7525#endif
7526
7527
Jeff Johnson295189b2012-06-20 16:38:30 -07007528VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7529{
7530 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7531 VOS_STATUS status;
7532 hdd_adapter_t *pAdapter;
7533
7534 ENTER();
7535
7536 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7537
7538 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7539 {
7540 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307541 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 netif_tx_disable(pAdapter->dev);
7543 netif_carrier_off(pAdapter->dev);
7544
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007545 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7546
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307548
Katya Nigam1fd24402015-02-16 14:52:19 +05307549 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7550 hdd_ibss_deinit_tx_rx(pAdapter);
7551
Nirav Shah7e3c8132015-06-22 23:51:42 +05307552 status = hdd_sta_id_hash_detach(pAdapter);
7553 if (status != VOS_STATUS_SUCCESS)
7554 hddLog(VOS_TRACE_LEVEL_ERROR,
7555 FL("sta id hash detach failed for session id %d"),
7556 pAdapter->sessionId);
7557
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307558 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7559
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307560 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7561 {
7562 hdd_wmm_adapter_close( pAdapter );
7563 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7564 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007565
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307566 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7567 {
7568 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7569 }
7570
Rajeev Kumarf999e582014-01-09 17:33:29 -08007571#ifdef FEATURE_WLAN_BATCH_SCAN
7572 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7573 {
7574 hdd_deinit_batch_scan(pAdapter);
7575 }
7576#endif
7577
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307578#ifdef FEATURE_WLAN_TDLS
7579 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307580 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307581 mutex_unlock(&pHddCtx->tdls_lock);
7582#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007583 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7584 pAdapterNode = pNext;
7585 }
7586
7587 EXIT();
7588
7589 return VOS_STATUS_SUCCESS;
7590}
7591
7592VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7593{
7594 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7595 VOS_STATUS status;
7596 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307597 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007598
7599 ENTER();
7600
7601 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7602
7603 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7604 {
7605 pAdapter = pAdapterNode->pAdapter;
7606
Kumar Anand82c009f2014-05-29 00:29:42 -07007607 hdd_wmm_init( pAdapter );
7608
Jeff Johnson295189b2012-06-20 16:38:30 -07007609 switch(pAdapter->device_mode)
7610 {
7611 case WLAN_HDD_INFRA_STATION:
7612 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007613 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307614
7615 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7616
Jeff Johnson295189b2012-06-20 16:38:30 -07007617 hdd_init_station_mode(pAdapter);
7618 /* Open the gates for HDD to receive Wext commands */
7619 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007620 pHddCtx->scan_info.mScanPending = FALSE;
7621 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007622
7623 //Trigger the initial scan
7624 hdd_wlan_initial_scan(pAdapter);
7625
7626 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307627 if (eConnectionState_Associated == connState ||
7628 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 {
7630 union iwreq_data wrqu;
7631 memset(&wrqu, '\0', sizeof(wrqu));
7632 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7633 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7634 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007635 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007636
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 /* indicate disconnected event to nl80211 */
7638 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7639 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307641 else if (eConnectionState_Connecting == connState)
7642 {
7643 /*
7644 * Indicate connect failure to supplicant if we were in the
7645 * process of connecting
7646 */
7647 cfg80211_connect_result(pAdapter->dev, NULL,
7648 NULL, 0, NULL, 0,
7649 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7650 GFP_KERNEL);
7651 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 break;
7653
7654 case WLAN_HDD_SOFTAP:
7655 /* softAP can handle SSR */
7656 break;
7657
7658 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007659 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007660 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007661 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 break;
7663
7664 case WLAN_HDD_MONITOR:
7665 /* monitor interface start */
7666 break;
7667 default:
7668 break;
7669 }
7670
7671 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7672 pAdapterNode = pNext;
7673 }
7674
7675 EXIT();
7676
7677 return VOS_STATUS_SUCCESS;
7678}
7679
7680VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7681{
7682 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7683 hdd_adapter_t *pAdapter;
7684 VOS_STATUS status;
7685 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307686 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007687
7688 ENTER();
7689
7690 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7691
7692 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7693 {
7694 pAdapter = pAdapterNode->pAdapter;
7695
7696 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7697 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7698 {
7699 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7700 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7701
Abhishek Singhf4669da2014-05-26 15:07:49 +05307702 hddLog(VOS_TRACE_LEVEL_INFO,
7703 "%s: Set HDD connState to eConnectionState_NotConnected",
7704 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007705 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7706 init_completion(&pAdapter->disconnect_comp_var);
7707 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7708 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7709
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307710 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007711 &pAdapter->disconnect_comp_var,
7712 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307713 if (0 >= ret)
7714 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7715 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007716
7717 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7718 pHddCtx->isAmpAllowed = VOS_FALSE;
7719 sme_RoamConnect(pHddCtx->hHal,
7720 pAdapter->sessionId, &(pWextState->roamProfile),
7721 &roamId);
7722 }
7723
7724 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7725 pAdapterNode = pNext;
7726 }
7727
7728 EXIT();
7729
7730 return VOS_STATUS_SUCCESS;
7731}
7732
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007733void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7734{
7735 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7736 VOS_STATUS status;
7737 hdd_adapter_t *pAdapter;
7738 hdd_station_ctx_t *pHddStaCtx;
7739 hdd_ap_ctx_t *pHddApCtx;
7740 hdd_hostapd_state_t * pHostapdState;
7741 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7742 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7743 const char *p2pMode = "DEV";
7744 const char *ccMode = "Standalone";
7745 int n;
7746
7747 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7748 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7749 {
7750 pAdapter = pAdapterNode->pAdapter;
7751 switch (pAdapter->device_mode) {
7752 case WLAN_HDD_INFRA_STATION:
7753 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7754 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7755 staChannel = pHddStaCtx->conn_info.operationChannel;
7756 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7757 }
7758 break;
7759 case WLAN_HDD_P2P_CLIENT:
7760 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7761 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7762 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7763 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7764 p2pMode = "CLI";
7765 }
7766 break;
7767 case WLAN_HDD_P2P_GO:
7768 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7769 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7770 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7771 p2pChannel = pHddApCtx->operatingChannel;
7772 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7773 }
7774 p2pMode = "GO";
7775 break;
7776 case WLAN_HDD_SOFTAP:
7777 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7778 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7779 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7780 apChannel = pHddApCtx->operatingChannel;
7781 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7782 }
7783 break;
7784 default:
7785 break;
7786 }
7787 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7788 pAdapterNode = pNext;
7789 }
7790 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7791 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7792 }
7793 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7794 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7795 if (p2pChannel > 0) {
7796 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7797 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7798 }
7799 if (apChannel > 0) {
7800 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7801 apChannel, MAC_ADDR_ARRAY(apBssid));
7802 }
7803
7804 if (p2pChannel > 0 && apChannel > 0) {
7805 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7806 }
7807}
7808
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007809bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007810{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007811 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007812}
7813
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007814/* Once SSR is disabled then it cannot be set. */
7815void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007816{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007817 if (HDD_SSR_DISABLED == isSsrRequired)
7818 return;
7819
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 isSsrRequired = value;
7821}
7822
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307823void hdd_set_pre_close( hdd_context_t *pHddCtx)
7824{
7825 sme_PreClose(pHddCtx->hHal);
7826}
7827
Jeff Johnson295189b2012-06-20 16:38:30 -07007828VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7829 hdd_adapter_list_node_t** ppAdapterNode)
7830{
7831 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307832 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7834 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307835 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 return status;
7837}
7838
7839VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7840 hdd_adapter_list_node_t* pAdapterNode,
7841 hdd_adapter_list_node_t** pNextAdapterNode)
7842{
7843 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307844 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7846 (hdd_list_node_t*) pAdapterNode,
7847 (hdd_list_node_t**)pNextAdapterNode );
7848
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307849 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 return status;
7851}
7852
7853VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7854 hdd_adapter_list_node_t* pAdapterNode)
7855{
7856 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307857 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7859 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307860 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 return status;
7862}
7863
7864VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7865 hdd_adapter_list_node_t** ppAdapterNode)
7866{
7867 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307868 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7870 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307871 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 return status;
7873}
7874
7875VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7876 hdd_adapter_list_node_t* pAdapterNode)
7877{
7878 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307879 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7881 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307882 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007883 return status;
7884}
7885
7886VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7887 hdd_adapter_list_node_t* pAdapterNode)
7888{
7889 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307890 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7892 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307893 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 return status;
7895}
7896
7897hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7898 tSirMacAddr macAddr )
7899{
7900 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7901 hdd_adapter_t *pAdapter;
7902 VOS_STATUS status;
7903
7904 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7905
7906 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7907 {
7908 pAdapter = pAdapterNode->pAdapter;
7909
7910 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7911 macAddr, sizeof(tSirMacAddr) ) )
7912 {
7913 return pAdapter;
7914 }
7915 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7916 pAdapterNode = pNext;
7917 }
7918
7919 return NULL;
7920
7921}
7922
7923hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7924{
7925 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7926 hdd_adapter_t *pAdapter;
7927 VOS_STATUS status;
7928
7929 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7930
7931 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7932 {
7933 pAdapter = pAdapterNode->pAdapter;
7934
7935 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7936 IFNAMSIZ ) )
7937 {
7938 return pAdapter;
7939 }
7940 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7941 pAdapterNode = pNext;
7942 }
7943
7944 return NULL;
7945
7946}
7947
7948hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7949{
7950 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7951 hdd_adapter_t *pAdapter;
7952 VOS_STATUS status;
7953
7954 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7955
7956 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7957 {
7958 pAdapter = pAdapterNode->pAdapter;
7959
7960 if( pAdapter && (mode == pAdapter->device_mode) )
7961 {
7962 return pAdapter;
7963 }
7964 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7965 pAdapterNode = pNext;
7966 }
7967
7968 return NULL;
7969
7970}
7971
7972//Remove this function later
7973hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7974{
7975 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7976 hdd_adapter_t *pAdapter;
7977 VOS_STATUS status;
7978
7979 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7980
7981 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7982 {
7983 pAdapter = pAdapterNode->pAdapter;
7984
7985 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7986 {
7987 return pAdapter;
7988 }
7989
7990 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7991 pAdapterNode = pNext;
7992 }
7993
7994 return NULL;
7995
7996}
7997
Jeff Johnson295189b2012-06-20 16:38:30 -07007998/**---------------------------------------------------------------------------
7999
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308000 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008001
8002 This API returns the operating channel of the requested device mode
8003
8004 \param - pHddCtx - Pointer to the HDD context.
8005 - mode - Device mode for which operating channel is required
8006 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8007 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8008 \return - channel number. "0" id the requested device is not found OR it is not connected.
8009 --------------------------------------------------------------------------*/
8010v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8011{
8012 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8013 VOS_STATUS status;
8014 hdd_adapter_t *pAdapter;
8015 v_U8_t operatingChannel = 0;
8016
8017 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8018
8019 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8020 {
8021 pAdapter = pAdapterNode->pAdapter;
8022
8023 if( mode == pAdapter->device_mode )
8024 {
8025 switch(pAdapter->device_mode)
8026 {
8027 case WLAN_HDD_INFRA_STATION:
8028 case WLAN_HDD_P2P_CLIENT:
8029 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8030 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8031 break;
8032 case WLAN_HDD_SOFTAP:
8033 case WLAN_HDD_P2P_GO:
8034 /*softap connection info */
8035 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8036 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8037 break;
8038 default:
8039 break;
8040 }
8041
8042 break; //Found the device of interest. break the loop
8043 }
8044
8045 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8046 pAdapterNode = pNext;
8047 }
8048 return operatingChannel;
8049}
8050
8051#ifdef WLAN_FEATURE_PACKET_FILTERING
8052/**---------------------------------------------------------------------------
8053
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308054 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008055
8056 This used to set the multicast address list.
8057
8058 \param - dev - Pointer to the WLAN device.
8059 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308060 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008061
8062 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308063static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008064{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308065 hdd_adapter_t *pAdapter;
8066 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308068 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308070
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308071 ENTER();
8072
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308073 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308074 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 {
8076 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308077 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 return;
8079 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308080 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8081 ret = wlan_hdd_validate_context(pHddCtx);
8082 if (0 != ret)
8083 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308084 return;
8085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 if (dev->flags & IFF_ALLMULTI)
8087 {
8088 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008089 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308090 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308092 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 {
8094 mc_count = netdev_mc_count(dev);
8095 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008096 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8098 {
8099 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008100 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308101 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 return;
8103 }
8104
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308105 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008106
8107 netdev_for_each_mc_addr(ha, dev) {
8108 if (i == mc_count)
8109 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308110 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8111 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308113 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308114 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 i++;
8116 }
8117 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308118
8119 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 return;
8121}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308122
8123static void hdd_set_multicast_list(struct net_device *dev)
8124{
8125 vos_ssr_protect(__func__);
8126 __hdd_set_multicast_list(dev);
8127 vos_ssr_unprotect(__func__);
8128}
Jeff Johnson295189b2012-06-20 16:38:30 -07008129#endif
8130
8131/**---------------------------------------------------------------------------
8132
8133 \brief hdd_select_queue() -
8134
8135 This function is registered with the Linux OS for network
8136 core to decide which queue to use first.
8137
8138 \param - dev - Pointer to the WLAN device.
8139 - skb - Pointer to OS packet (sk_buff).
8140 \return - ac, Queue Index/access category corresponding to UP in IP header
8141
8142 --------------------------------------------------------------------------*/
8143v_U16_t hdd_select_queue(struct net_device *dev,
8144 struct sk_buff *skb)
8145{
8146 return hdd_wmm_select_queue(dev, skb);
8147}
8148
8149
8150/**---------------------------------------------------------------------------
8151
8152 \brief hdd_wlan_initial_scan() -
8153
8154 This function triggers the initial scan
8155
8156 \param - pAdapter - Pointer to the HDD adapter.
8157
8158 --------------------------------------------------------------------------*/
8159void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8160{
8161 tCsrScanRequest scanReq;
8162 tCsrChannelInfo channelInfo;
8163 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008164 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8166
8167 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8168 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8169 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8170
8171 if(sme_Is11dSupported(pHddCtx->hHal))
8172 {
8173 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8174 if ( HAL_STATUS_SUCCESS( halStatus ) )
8175 {
8176 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8177 if( !scanReq.ChannelInfo.ChannelList )
8178 {
8179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8180 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008181 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008182 return;
8183 }
8184 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8185 channelInfo.numOfChannels);
8186 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8187 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008188 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 }
8190
8191 scanReq.scanType = eSIR_PASSIVE_SCAN;
8192 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8193 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8194 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8195 }
8196 else
8197 {
8198 scanReq.scanType = eSIR_ACTIVE_SCAN;
8199 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8200 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8201 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8202 }
8203
8204 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8205 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8206 {
8207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8208 __func__, halStatus );
8209 }
8210
8211 if(sme_Is11dSupported(pHddCtx->hHal))
8212 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8213}
8214
mukul sharmabab477d2015-06-11 17:14:55 +05308215void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8216{
8217 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8218 VOS_STATUS status;
8219 hdd_adapter_t *pAdapter;
8220
8221 ENTER();
8222
8223 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8224
8225 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8226 {
8227 pAdapter = pAdapterNode->pAdapter;
8228
8229 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8230 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8231 pAdapterNode = pNext;
8232 }
8233
8234 EXIT();
8235}
Jeff Johnson295189b2012-06-20 16:38:30 -07008236/**---------------------------------------------------------------------------
8237
8238 \brief hdd_full_power_callback() - HDD full power callback function
8239
8240 This is the function invoked by SME to inform the result of a full power
8241 request issued by HDD
8242
8243 \param - callbackcontext - Pointer to cookie
8244 \param - status - result of request
8245
8246 \return - None
8247
8248 --------------------------------------------------------------------------*/
8249static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8250{
Jeff Johnson72a40512013-12-19 10:14:15 -08008251 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008252
8253 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308254 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008255
8256 if (NULL == callbackContext)
8257 {
8258 hddLog(VOS_TRACE_LEVEL_ERROR,
8259 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008260 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008261 return;
8262 }
8263
Jeff Johnson72a40512013-12-19 10:14:15 -08008264 /* there is a race condition that exists between this callback
8265 function and the caller since the caller could time out either
8266 before or while this code is executing. we use a spinlock to
8267 serialize these actions */
8268 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008269
8270 if (POWER_CONTEXT_MAGIC != pContext->magic)
8271 {
8272 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008273 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 hddLog(VOS_TRACE_LEVEL_WARN,
8275 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008276 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008277 return;
8278 }
8279
Jeff Johnson72a40512013-12-19 10:14:15 -08008280 /* context is valid so caller is still waiting */
8281
8282 /* paranoia: invalidate the magic */
8283 pContext->magic = 0;
8284
8285 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008287
8288 /* serialization is complete */
8289 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008290}
8291
Katya Nigamf0511f62015-05-05 16:40:57 +05308292void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8293{
8294 pMonCtx->typeSubtypeBitmap = 0;
8295 if( type%10 ) /* Management Packets */
8296 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8297 type/=10;
8298 if( type%10 ) /* Control Packets */
8299 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8300 type/=10;
8301 if( type%10 ) /* Data Packets */
8302 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8303}
8304
8305VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8306{
8307 vos_msg_t monMsg;
8308
8309 monMsg.type = WDA_MON_START_REQ;
8310 monMsg.reserved = 0;
8311 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8312 monMsg.bodyval = 0;
8313
8314 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8315 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8316 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8317 return VOS_STATUS_E_FAILURE;
8318 }
8319
8320 return VOS_STATUS_SUCCESS;
8321}
8322
8323void wlan_hdd_mon_poststopmsg(void)
8324{
8325 vos_msg_t monMsg;
8326
8327 monMsg.type = WDA_MON_STOP_REQ;
8328 monMsg.reserved = 0;
8329 monMsg.bodyptr = NULL;
8330 monMsg.bodyval = 0;
8331
8332 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8333 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8334 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8335 }
8336}
8337
Katya Nigame7b69a82015-04-28 15:24:06 +05308338void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8339{
8340 VOS_STATUS vosStatus;
8341 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8342 struct wiphy *wiphy = pHddCtx->wiphy;
8343
8344 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8345 if(pAdapter == NULL || pVosContext == NULL)
8346 {
8347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8348 return ;
8349 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308350
8351 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308352 hdd_UnregisterWext(pAdapter->dev);
8353
8354 vos_mon_stop( pVosContext );
8355
8356 vosStatus = vos_sched_close( pVosContext );
8357 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8358 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8359 "%s: Failed to close VOSS Scheduler",__func__);
8360 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8361 }
8362
8363 vosStatus = vos_nv_close();
8364 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8365 {
8366 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8367 "%s: Failed to close NV", __func__);
8368 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8369 }
8370
8371 vos_close(pVosContext);
8372
8373 #ifdef WLAN_KD_READY_NOTIFIER
8374 nl_srv_exit(pHddCtx->ptt_pid);
8375 #else
8376 nl_srv_exit();
8377 #endif
8378
8379 if (pHddCtx->cfg_ini)
8380 {
8381 kfree(pHddCtx->cfg_ini);
8382 pHddCtx->cfg_ini= NULL;
8383 }
8384 hdd_close_all_adapters( pHddCtx );
8385
8386 wiphy_free(wiphy) ;
8387
8388}
Jeff Johnson295189b2012-06-20 16:38:30 -07008389/**---------------------------------------------------------------------------
8390
8391 \brief hdd_wlan_exit() - HDD WLAN exit function
8392
8393 This is the driver exit point (invoked during rmmod)
8394
8395 \param - pHddCtx - Pointer to the HDD Context
8396
8397 \return - None
8398
8399 --------------------------------------------------------------------------*/
8400void hdd_wlan_exit(hdd_context_t *pHddCtx)
8401{
8402 eHalStatus halStatus;
8403 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8404 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308405 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008406 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008407 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308409 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008410
8411 ENTER();
8412
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308413
Katya Nigame7b69a82015-04-28 15:24:06 +05308414 if (VOS_MONITOR_MODE == hdd_get_conparam())
8415 {
8416 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8417 wlan_hdd_mon_close(pHddCtx);
8418 return;
8419 }
8420 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008421 {
8422 // Unloading, restart logic is no more required.
8423 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008424
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308425#ifdef FEATURE_WLAN_TDLS
8426 /* At the time of driver unloading; if tdls connection is present;
8427 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8428 * wlan_hdd_tdls_find_peer always checks for valid context;
8429 * as load/unload in progress there can be a race condition.
8430 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8431 * when tdls state is enabled.
8432 * As soon as driver set load/unload flag; tdls flag also needs
8433 * to be disabled so that hdd_rx_packet_cbk won't call
8434 * wlan_hdd_tdls_find_peer.
8435 */
8436 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8437#endif
8438
c_hpothu5ab05e92014-06-13 17:34:05 +05308439 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8440 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308442 pAdapter = pAdapterNode->pAdapter;
8443 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308445 /* Disable TX on the interface, after this hard_start_xmit() will
8446 * not be called on that interface
8447 */
8448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8449 netif_tx_disable(pAdapter->dev);
8450
8451 /* Mark the interface status as "down" for outside world */
8452 netif_carrier_off(pAdapter->dev);
8453
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308454 /* DeInit the adapter. This ensures that all data packets
8455 * are freed.
8456 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308457#ifdef FEATURE_WLAN_TDLS
8458 mutex_lock(&pHddCtx->tdls_lock);
8459#endif
c_hpothu002231a2015-02-05 14:58:51 +05308460 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308461#ifdef FEATURE_WLAN_TDLS
8462 mutex_unlock(&pHddCtx->tdls_lock);
8463#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308464
c_hpothu5ab05e92014-06-13 17:34:05 +05308465 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8466 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8467 {
8468 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8469 hdd_UnregisterWext(pAdapter->dev);
8470 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308471
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308473 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8474 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 }
mukul sharmabab477d2015-06-11 17:14:55 +05308476
8477 //Purge all sme cmd's for all interface
8478 hdd_purge_cmd_list_all_adapters(pHddCtx);
8479
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308480 // Cancel any outstanding scan requests. We are about to close all
8481 // of our adapters, but an adapter structure is what SME passes back
8482 // to our callback function. Hence if there are any outstanding scan
8483 // requests then there is a race condition between when the adapter
8484 // is closed and when the callback is invoked.We try to resolve that
8485 // race condition here by canceling any outstanding scans before we
8486 // close the adapters.
8487 // Note that the scans may be cancelled in an asynchronous manner,
8488 // so ideally there needs to be some kind of synchronization. Rather
8489 // than introduce a new synchronization here, we will utilize the
8490 // fact that we are about to Request Full Power, and since that is
8491 // synchronized, the expectation is that by the time Request Full
8492 // Power has completed all scans will be cancelled.
8493 if (pHddCtx->scan_info.mScanPending)
8494 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308495 if(NULL != pAdapter)
8496 {
8497 hddLog(VOS_TRACE_LEVEL_INFO,
8498 FL("abort scan mode: %d sessionId: %d"),
8499 pAdapter->device_mode,
8500 pAdapter->sessionId);
8501 }
8502 hdd_abort_mac_scan(pHddCtx,
8503 pHddCtx->scan_info.sessionId,
8504 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308505 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008506 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308507 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008508 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308509 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308510 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8511 {
8512 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8514 "%s: in middle of FTM START", __func__);
8515 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8516 msecs_to_jiffies(20000));
8517 if(!lrc)
8518 {
8519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8520 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8521 }
8522 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008523 wlan_hdd_ftm_close(pHddCtx);
8524 goto free_hdd_ctx;
8525 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308526
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 /* DeRegister with platform driver as client for Suspend/Resume */
8528 vosStatus = hddDeregisterPmOps(pHddCtx);
8529 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8530 {
8531 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8532 VOS_ASSERT(0);
8533 }
8534
8535 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8536 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8537 {
8538 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8539 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008540
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008541 //Stop the traffic monitor timer
8542 if ( VOS_TIMER_STATE_RUNNING ==
8543 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8544 {
8545 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8546 }
8547
8548 // Destroy the traffic monitor timer
8549 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8550 &pHddCtx->tx_rx_trafficTmr)))
8551 {
8552 hddLog(VOS_TRACE_LEVEL_ERROR,
8553 "%s: Cannot deallocate Traffic monitor timer", __func__);
8554 }
8555
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 //Disable IMPS/BMPS as we do not want the device to enter any power
8557 //save mode during shutdown
8558 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8559 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8560 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8561
8562 //Ensure that device is in full power as we will touch H/W during vos_Stop
8563 init_completion(&powerContext.completion);
8564 powerContext.magic = POWER_CONTEXT_MAGIC;
8565
8566 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8567 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8568
8569 if (eHAL_STATUS_SUCCESS != halStatus)
8570 {
8571 if (eHAL_STATUS_PMC_PENDING == halStatus)
8572 {
8573 /* request was sent -- wait for the response */
8574 lrc = wait_for_completion_interruptible_timeout(
8575 &powerContext.completion,
8576 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 if (lrc <= 0)
8578 {
8579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008580 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008581 }
8582 }
8583 else
8584 {
8585 hddLog(VOS_TRACE_LEVEL_ERROR,
8586 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008587 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 /* continue -- need to clean up as much as possible */
8589 }
8590 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308591 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8592 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8593 {
8594 /* This will issue a dump command which will clean up
8595 BTQM queues and unblock MC thread */
8596 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8597 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008598
Jeff Johnson72a40512013-12-19 10:14:15 -08008599 /* either we never sent a request, we sent a request and received a
8600 response or we sent a request and timed out. if we never sent a
8601 request or if we sent a request and got a response, we want to
8602 clear the magic out of paranoia. if we timed out there is a
8603 race condition such that the callback function could be
8604 executing at the same time we are. of primary concern is if the
8605 callback function had already verified the "magic" but had not
8606 yet set the completion variable when a timeout occurred. we
8607 serialize these activities by invalidating the magic while
8608 holding a shared spinlock which will cause us to block if the
8609 callback is currently executing */
8610 spin_lock(&hdd_context_lock);
8611 powerContext.magic = 0;
8612 spin_unlock(&hdd_context_lock);
8613
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308614 /* If Device is shutdown, no point for SME to wait for responses
8615 from device. Pre Close SME */
8616 if(wcnss_device_is_shutdown())
8617 {
8618 sme_PreClose(pHddCtx->hHal);
8619 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008620 hdd_debugfs_exit(pHddCtx);
8621
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308622#ifdef WLAN_NS_OFFLOAD
8623 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8624 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8625#endif
8626 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8627 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8628
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 // Unregister the Net Device Notifier
8630 unregister_netdevice_notifier(&hdd_netdev_notifier);
8631
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 hdd_stop_all_adapters( pHddCtx );
8633
Jeff Johnson295189b2012-06-20 16:38:30 -07008634#ifdef WLAN_BTAMP_FEATURE
8635 vosStatus = WLANBAP_Stop(pVosContext);
8636 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8637 {
8638 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8639 "%s: Failed to stop BAP",__func__);
8640 }
8641#endif //WLAN_BTAMP_FEATURE
8642
8643 //Stop all the modules
8644 vosStatus = vos_stop( pVosContext );
8645 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8646 {
8647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8648 "%s: Failed to stop VOSS",__func__);
8649 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8650 }
8651
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008653 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008654
8655 //Close the scheduler before calling vos_close to make sure no thread is
8656 // scheduled after the each module close is called i.e after all the data
8657 // structures are freed.
8658 vosStatus = vos_sched_close( pVosContext );
8659 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8660 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8661 "%s: Failed to close VOSS Scheduler",__func__);
8662 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8663 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008664#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8665 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308666 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008667#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008668 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308669 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008670
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308671#ifdef CONFIG_ENABLE_LINUX_REG
8672 vosStatus = vos_nv_close();
8673 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8674 {
8675 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8676 "%s: Failed to close NV", __func__);
8677 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8678 }
8679#endif
8680
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 //Close VOSS
8682 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8683 vos_close(pVosContext);
8684
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 //Close Watchdog
8686 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8687 vos_watchdog_close(pVosContext);
8688
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308689 //Clean up HDD Nlink Service
8690 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308691
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308692#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308693 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308694 {
8695 wlan_logging_sock_deactivate_svc();
8696 }
8697#endif
8698
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308699#ifdef WLAN_KD_READY_NOTIFIER
8700 nl_srv_exit(pHddCtx->ptt_pid);
8701#else
8702 nl_srv_exit();
8703#endif /* WLAN_KD_READY_NOTIFIER */
8704
8705
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 hdd_close_all_adapters( pHddCtx );
8707
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 /* free the power on lock from platform driver */
8709 if (free_riva_power_on_lock("wlan"))
8710 {
8711 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8712 __func__);
8713 }
8714
Jeff Johnson88ba7742013-02-27 14:36:02 -08008715free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308716
8717 //Free up dynamically allocated members inside HDD Adapter
8718 if (pHddCtx->cfg_ini)
8719 {
8720 kfree(pHddCtx->cfg_ini);
8721 pHddCtx->cfg_ini= NULL;
8722 }
8723
Leo Changf04ddad2013-09-18 13:46:38 -07008724 /* FTM mode, WIPHY did not registered
8725 If un-register here, system crash will happen */
8726 if (VOS_FTM_MODE != hdd_get_conparam())
8727 {
8728 wiphy_unregister(wiphy) ;
8729 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008731 if (hdd_is_ssr_required())
8732 {
8733 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008734 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 msleep(5000);
8736 }
8737 hdd_set_ssr_required (VOS_FALSE);
8738}
8739
8740
8741/**---------------------------------------------------------------------------
8742
8743 \brief hdd_update_config_from_nv() - Function to update the contents of
8744 the running configuration with parameters taken from NV storage
8745
8746 \param - pHddCtx - Pointer to the HDD global context
8747
8748 \return - VOS_STATUS_SUCCESS if successful
8749
8750 --------------------------------------------------------------------------*/
8751static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8752{
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 v_BOOL_t itemIsValid = VOS_FALSE;
8754 VOS_STATUS status;
8755 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8756 v_U8_t macLoop;
8757
8758 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8759 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8760 if(status != VOS_STATUS_SUCCESS)
8761 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008762 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 return VOS_STATUS_E_FAILURE;
8764 }
8765
8766 if (itemIsValid == VOS_TRUE)
8767 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008768 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8770 VOS_MAX_CONCURRENCY_PERSONA);
8771 if(status != VOS_STATUS_SUCCESS)
8772 {
8773 /* Get MAC from NV fail, not update CFG info
8774 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008775 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 return VOS_STATUS_E_FAILURE;
8777 }
8778
8779 /* If first MAC is not valid, treat all others are not valid
8780 * Then all MACs will be got from ini file */
8781 if(vos_is_macaddr_zero(&macFromNV[0]))
8782 {
8783 /* MAC address in NV file is not configured yet */
8784 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8785 return VOS_STATUS_E_INVAL;
8786 }
8787
8788 /* Get MAC address from NV, update CFG info */
8789 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8790 {
8791 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8792 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308793 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008794 /* This MAC is not valid, skip it
8795 * This MAC will be got from ini file */
8796 }
8797 else
8798 {
8799 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8800 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8801 VOS_MAC_ADDR_SIZE);
8802 }
8803 }
8804 }
8805 else
8806 {
8807 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8808 return VOS_STATUS_E_FAILURE;
8809 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008810
Jeff Johnson295189b2012-06-20 16:38:30 -07008811
8812 return VOS_STATUS_SUCCESS;
8813}
8814
8815/**---------------------------------------------------------------------------
8816
8817 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8818
8819 \param - pAdapter - Pointer to the HDD
8820
8821 \return - None
8822
8823 --------------------------------------------------------------------------*/
8824VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8825{
8826 eHalStatus halStatus;
8827 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308828 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008829
Jeff Johnson295189b2012-06-20 16:38:30 -07008830
8831 // Send ready indication to the HDD. This will kick off the MAC
8832 // into a 'running' state and should kick off an initial scan.
8833 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8834 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8835 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308836 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 "code %08d [x%08x]",__func__, halStatus, halStatus );
8838 return VOS_STATUS_E_FAILURE;
8839 }
8840
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308841 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8843 // And RIVA will crash
8844 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8845 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308846 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8847 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8848
8849
Jeff Johnson295189b2012-06-20 16:38:30 -07008850 return VOS_STATUS_SUCCESS;
8851}
8852
Jeff Johnson295189b2012-06-20 16:38:30 -07008853/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308854void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008855{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308856
8857 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8858
Jeff Johnson295189b2012-06-20 16:38:30 -07008859}
8860
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308861void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008862{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308863
8864 vos_wake_lock_release(&wlan_wake_lock, reason);
8865
Jeff Johnson295189b2012-06-20 16:38:30 -07008866}
8867
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308868void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008869{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308870
8871 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8872 reason);
8873
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008874}
8875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876/**---------------------------------------------------------------------------
8877
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008878 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8879 information between Host and Riva
8880
8881 This function gets reported version of FW
8882 It also finds the version of Riva headers used to compile the host
8883 It compares the above two and prints a warning if they are different
8884 It gets the SW and HW version string
8885 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8886 indicating the features they support through a bitmap
8887
8888 \param - pHddCtx - Pointer to HDD context
8889
8890 \return - void
8891
8892 --------------------------------------------------------------------------*/
8893
8894void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8895{
8896
8897 tSirVersionType versionCompiled;
8898 tSirVersionType versionReported;
8899 tSirVersionString versionString;
8900 tANI_U8 fwFeatCapsMsgSupported = 0;
8901 VOS_STATUS vstatus;
8902
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008903 memset(&versionCompiled, 0, sizeof(versionCompiled));
8904 memset(&versionReported, 0, sizeof(versionReported));
8905
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008906 /* retrieve and display WCNSS version information */
8907 do {
8908
8909 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8910 &versionCompiled);
8911 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8912 {
8913 hddLog(VOS_TRACE_LEVEL_FATAL,
8914 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008915 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008916 break;
8917 }
8918
8919 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8920 &versionReported);
8921 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8922 {
8923 hddLog(VOS_TRACE_LEVEL_FATAL,
8924 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008925 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008926 break;
8927 }
8928
8929 if ((versionCompiled.major != versionReported.major) ||
8930 (versionCompiled.minor != versionReported.minor) ||
8931 (versionCompiled.version != versionReported.version) ||
8932 (versionCompiled.revision != versionReported.revision))
8933 {
8934 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8935 "Host expected %u.%u.%u.%u\n",
8936 WLAN_MODULE_NAME,
8937 (int)versionReported.major,
8938 (int)versionReported.minor,
8939 (int)versionReported.version,
8940 (int)versionReported.revision,
8941 (int)versionCompiled.major,
8942 (int)versionCompiled.minor,
8943 (int)versionCompiled.version,
8944 (int)versionCompiled.revision);
8945 }
8946 else
8947 {
8948 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8949 WLAN_MODULE_NAME,
8950 (int)versionReported.major,
8951 (int)versionReported.minor,
8952 (int)versionReported.version,
8953 (int)versionReported.revision);
8954 }
8955
8956 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8957 versionString,
8958 sizeof(versionString));
8959 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8960 {
8961 hddLog(VOS_TRACE_LEVEL_FATAL,
8962 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008963 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008964 break;
8965 }
8966
8967 pr_info("%s: WCNSS software version %s\n",
8968 WLAN_MODULE_NAME, versionString);
8969
8970 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8971 versionString,
8972 sizeof(versionString));
8973 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8974 {
8975 hddLog(VOS_TRACE_LEVEL_FATAL,
8976 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008977 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008978 break;
8979 }
8980
8981 pr_info("%s: WCNSS hardware version %s\n",
8982 WLAN_MODULE_NAME, versionString);
8983
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008984 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8985 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008986 send the message only if it the riva is 1.1
8987 minor numbers for different riva branches:
8988 0 -> (1.0)Mainline Build
8989 1 -> (1.1)Mainline Build
8990 2->(1.04) Stability Build
8991 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008992 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008993 ((versionReported.minor>=1) && (versionReported.version>=1)))
8994 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8995 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008996
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008997 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008998 {
8999#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9000 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9001 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9002#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009003 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9004 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9005 {
9006 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9007 }
9008
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009009 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009010 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009011
9012 } while (0);
9013
9014}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309015void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9016{
9017 struct sk_buff *skb;
9018 struct nlmsghdr *nlh;
9019 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309020 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309021
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309022 if (in_interrupt() || irqs_disabled() || in_atomic())
9023 flags = GFP_ATOMIC;
9024
9025 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309026
9027 if(skb == NULL) {
9028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9029 "%s: alloc_skb failed", __func__);
9030 return;
9031 }
9032
9033 nlh = (struct nlmsghdr *)skb->data;
9034 nlh->nlmsg_pid = 0; /* from kernel */
9035 nlh->nlmsg_flags = 0;
9036 nlh->nlmsg_seq = 0;
9037 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9038
9039 ani_hdr = NLMSG_DATA(nlh);
9040 ani_hdr->type = type;
9041
9042 switch(type) {
9043 case WLAN_SVC_SAP_RESTART_IND:
9044 ani_hdr->length = 0;
9045 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9046 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9047 break;
9048 default:
9049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9050 "Attempt to send unknown nlink message %d", type);
9051 kfree_skb(skb);
9052 return;
9053 }
9054
9055 nl_srv_bcast(skb);
9056
9057 return;
9058}
9059
9060
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009061
9062/**---------------------------------------------------------------------------
9063
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309064 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9065
9066 \param - pHddCtx - Pointer to the hdd context
9067
9068 \return - true if hardware supports 5GHz
9069
9070 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309071boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309072{
9073 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9074 * then hardware support 5Ghz.
9075 */
9076 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9077 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309079 return true;
9080 }
9081 else
9082 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309084 __func__);
9085 return false;
9086 }
9087}
9088
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309089/**---------------------------------------------------------------------------
9090
9091 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9092 generate function
9093
9094 This is generate the random mac address for WLAN interface
9095
9096 \param - pHddCtx - Pointer to HDD context
9097 idx - Start interface index to get auto
9098 generated mac addr.
9099 mac_addr - Mac address
9100
9101 \return - 0 for success, < 0 for failure
9102
9103 --------------------------------------------------------------------------*/
9104
9105static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9106 int idx, v_MACADDR_t mac_addr)
9107{
9108 int i;
9109 unsigned int serialno;
9110 serialno = wcnss_get_serial_number();
9111
9112 if (0 != serialno)
9113 {
9114 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9115 bytes of the serial number that can be used to generate
9116 the other 3 bytes of the MAC address. Mask off all but
9117 the lower 3 bytes (this will also make sure we don't
9118 overflow in the next step) */
9119 serialno &= 0x00FFFFFF;
9120
9121 /* we need a unique address for each session */
9122 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9123
9124 /* autogen other Mac addresses */
9125 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9126 {
9127 /* start with the entire default address */
9128 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9129 /* then replace the lower 3 bytes */
9130 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9131 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9132 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9133
9134 serialno++;
9135 hddLog(VOS_TRACE_LEVEL_ERROR,
9136 "%s: Derived Mac Addr: "
9137 MAC_ADDRESS_STR, __func__,
9138 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9139 }
9140
9141 }
9142 else
9143 {
9144 hddLog(LOGE, FL("Failed to Get Serial NO"));
9145 return -1;
9146 }
9147 return 0;
9148}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309149
Katya Nigame7b69a82015-04-28 15:24:06 +05309150int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9151{
9152 VOS_STATUS status;
9153 v_CONTEXT_t pVosContext= NULL;
9154 hdd_adapter_t *pAdapter= NULL;
9155
9156 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9157
9158 if (NULL == pVosContext)
9159 {
9160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9161 "%s: Trying to open VOSS without a PreOpen", __func__);
9162 VOS_ASSERT(0);
9163 return VOS_STATUS_E_FAILURE;
9164 }
9165
9166 status = vos_nv_open();
9167 if (!VOS_IS_STATUS_SUCCESS(status))
9168 {
9169 /* NV module cannot be initialized */
9170 hddLog( VOS_TRACE_LEVEL_FATAL,
9171 "%s: vos_nv_open failed", __func__);
9172 return VOS_STATUS_E_FAILURE;
9173 }
9174
9175 status = vos_init_wiphy_from_nv_bin();
9176 if (!VOS_IS_STATUS_SUCCESS(status))
9177 {
9178 /* NV module cannot be initialized */
9179 hddLog( VOS_TRACE_LEVEL_FATAL,
9180 "%s: vos_init_wiphy failed", __func__);
9181 goto err_vos_nv_close;
9182 }
9183
9184 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9185 if ( !VOS_IS_STATUS_SUCCESS( status ))
9186 {
9187 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9188 goto err_vos_nv_close;
9189 }
9190
9191 status = vos_mon_start( pVosContext );
9192 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9193 {
9194 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9195 goto err_vosclose;
9196 }
9197
9198 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9199 WDA_featureCapsExchange(pVosContext);
9200 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9201
9202 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9203 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9204 if( pAdapter == NULL )
9205 {
9206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9207 goto err_close_adapter;
9208 }
9209
9210 //Initialize the nlink service
9211 if(nl_srv_init() != 0)
9212 {
9213 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9214 goto err_close_adapter;
9215 }
9216 return VOS_STATUS_SUCCESS;
9217
9218err_close_adapter:
9219 hdd_close_all_adapters( pHddCtx );
9220 vos_mon_stop( pVosContext );
9221err_vosclose:
9222 status = vos_sched_close( pVosContext );
9223 if (!VOS_IS_STATUS_SUCCESS(status)) {
9224 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9225 "%s: Failed to close VOSS Scheduler", __func__);
9226 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9227 }
9228 vos_close(pVosContext );
9229
9230err_vos_nv_close:
9231 vos_nv_close();
9232
9233return status;
9234}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309235/**---------------------------------------------------------------------------
9236
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309237 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9238 completed to flush out the scan results
9239
9240 11d scan is done during driver load and is a passive scan on all
9241 channels supported by the device, 11d scans may find some APs on
9242 frequencies which are forbidden to be used in the regulatory domain
9243 the device is operating in. If these APs are notified to the supplicant
9244 it may try to connect to these APs, thus flush out all the scan results
9245 which are present in SME after 11d scan is done.
9246
9247 \return - eHalStatus
9248
9249 --------------------------------------------------------------------------*/
9250static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9251 tANI_U32 scanId, eCsrScanStatus status)
9252{
9253 ENTER();
9254
9255 sme_ScanFlushResult(halHandle, 0);
9256
9257 EXIT();
9258
9259 return eHAL_STATUS_SUCCESS;
9260}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309261/**---------------------------------------------------------------------------
9262
9263 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9264 logging is completed successfully.
9265
9266 \return - None
9267
9268 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309269void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309270{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309271 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309272
9273 if (NULL == pHddCtx)
9274 {
9275 hddLog(VOS_TRACE_LEVEL_ERROR,
9276 "%s: HDD context is NULL",__func__);
9277 return;
9278 }
9279
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309280 if ((VOS_STATUS_SUCCESS == status) &&
9281 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309282 {
9283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9284 pHddCtx->mgmt_frame_logging = TRUE;
9285 }
9286 else
9287 {
9288 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9289 pHddCtx->mgmt_frame_logging = FALSE;
9290 }
9291
9292 return;
9293}
9294/**---------------------------------------------------------------------------
9295
9296 \brief hdd_init_frame_logging - function to initialize frame logging.
9297 Currently only Mgmt Frames are logged in both TX
9298 and Rx direction and are sent to userspace
9299 application using logger thread when queried.
9300
9301 \return - None
9302
9303 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309304void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309305{
9306 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309307 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309308
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309309 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9310 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309311 {
9312 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9313 return;
9314 }
9315
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309316 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9317 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309318 {
9319 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9320 return;
9321 }
9322
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309323 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309324
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9326 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9327 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9328 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309329
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309330 if (pHddCtx->cfg_ini->enableFWLogging ||
9331 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309332 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309333 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309334 }
9335
Sushant Kaushik46804902015-07-08 14:46:03 +05309336 if (pHddCtx->cfg_ini->enableMgmtLogging)
9337 {
9338 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9339 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309340 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9341 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309342 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309343 }
9344
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309345 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9346 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9347 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9348 wlanFWLoggingInitParam->continuousFrameLogging =
9349 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309350
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309351 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309352
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309353 wlanFWLoggingInitParam->minLogBufferSize =
9354 pHddCtx->cfg_ini->minLoggingBufferSize;
9355 wlanFWLoggingInitParam->maxLogBufferSize =
9356 pHddCtx->cfg_ini->maxLoggingBufferSize;
9357 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9358 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309359
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309360 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309361
9362 if (eHAL_STATUS_SUCCESS != halStatus)
9363 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309364 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309365 }
9366
9367 return;
9368}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309369
9370/**---------------------------------------------------------------------------
9371
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 \brief hdd_wlan_startup() - HDD init function
9373
9374 This is the driver startup code executed once a WLAN device has been detected
9375
9376 \param - dev - Pointer to the underlying device
9377
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009378 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009379
9380 --------------------------------------------------------------------------*/
9381
9382int hdd_wlan_startup(struct device *dev )
9383{
9384 VOS_STATUS status;
9385 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009386 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 hdd_context_t *pHddCtx = NULL;
9388 v_CONTEXT_t pVosContext= NULL;
9389#ifdef WLAN_BTAMP_FEATURE
9390 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9391 WLANBAP_ConfigType btAmpConfig;
9392 hdd_config_t *pConfig;
9393#endif
9394 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309396 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009397
9398 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 /*
9400 * cfg80211: wiphy allocation
9401 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309402 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009403
9404 if(wiphy == NULL)
9405 {
9406 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009407 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 pHddCtx = wiphy_priv(wiphy);
9410
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 //Initialize the adapter context to zeros.
9412 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9413
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309415 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309416 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009417
9418 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9419
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309420 /* register for riva power on lock to platform driver
9421 * Locking power early to ensure FW doesn't reset by kernel while
9422 * host driver is busy initializing itself */
9423 if (req_riva_power_on_lock("wlan"))
9424 {
9425 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9426 __func__);
9427 goto err_free_hdd_context;
9428 }
9429
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 /*Get vos context here bcoz vos_open requires it*/
9431 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9432
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009433 if(pVosContext == NULL)
9434 {
9435 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9436 goto err_free_hdd_context;
9437 }
9438
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 //Save the Global VOSS context in adapter context for future.
9440 pHddCtx->pvosContext = pVosContext;
9441
9442 //Save the adapter context in global context for future.
9443 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9444
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 pHddCtx->parent_dev = dev;
9446
9447 init_completion(&pHddCtx->full_pwr_comp_var);
9448 init_completion(&pHddCtx->standby_comp_var);
9449 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009450 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009451 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309452 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309453 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009454
9455#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009456 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009457#else
9458 init_completion(&pHddCtx->driver_crda_req);
9459#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009460
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309461 spin_lock_init(&pHddCtx->schedScan_lock);
9462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9464
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309465#ifdef FEATURE_WLAN_TDLS
9466 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9467 * invoked by other instances also) to protect the concurrent
9468 * access for the Adapters by TDLS module.
9469 */
9470 mutex_init(&pHddCtx->tdls_lock);
9471#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309472 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309473 mutex_init(&pHddCtx->wmmLock);
9474
Agarwal Ashish1f422872014-07-22 00:11:55 +05309475 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309476
Agarwal Ashish1f422872014-07-22 00:11:55 +05309477 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 // Load all config first as TL config is needed during vos_open
9479 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9480 if(pHddCtx->cfg_ini == NULL)
9481 {
9482 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9483 goto err_free_hdd_context;
9484 }
9485
9486 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9487
9488 // Read and parse the qcom_cfg.ini file
9489 status = hdd_parse_config_ini( pHddCtx );
9490 if ( VOS_STATUS_SUCCESS != status )
9491 {
9492 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9493 __func__, WLAN_INI_FILE);
9494 goto err_config;
9495 }
Arif Hussaind5218912013-12-05 01:10:55 -08009496#ifdef MEMORY_DEBUG
9497 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9498 vos_mem_init();
9499
9500 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9501 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9502#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009503
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309504 /* INI has been read, initialise the configuredMcastBcastFilter with
9505 * INI value as this will serve as the default value
9506 */
9507 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9508 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9509 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309510
9511 if (false == hdd_is_5g_supported(pHddCtx))
9512 {
9513 //5Ghz is not supported.
9514 if (1 != pHddCtx->cfg_ini->nBandCapability)
9515 {
9516 hddLog(VOS_TRACE_LEVEL_INFO,
9517 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9518 pHddCtx->cfg_ini->nBandCapability = 1;
9519 }
9520 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309521
9522 /* If SNR Monitoring is enabled, FW has to parse all beacons
9523 * for calcaluting and storing the average SNR, so set Nth beacon
9524 * filter to 1 to enable FW to parse all the beaocons
9525 */
9526 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9527 {
9528 /* The log level is deliberately set to WARN as overriding
9529 * nthBeaconFilter to 1 will increase power cosumption and this
9530 * might just prove helpful to detect the power issue.
9531 */
9532 hddLog(VOS_TRACE_LEVEL_WARN,
9533 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9534 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309537 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009539 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009541 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9542 {
9543 hddLog(VOS_TRACE_LEVEL_FATAL,
9544 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9545 goto err_config;
9546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009548
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009549 // Update VOS trace levels based upon the cfg.ini
9550 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9551 pHddCtx->cfg_ini->vosTraceEnableBAP);
9552 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9553 pHddCtx->cfg_ini->vosTraceEnableTL);
9554 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9555 pHddCtx->cfg_ini->vosTraceEnableWDI);
9556 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9557 pHddCtx->cfg_ini->vosTraceEnableHDD);
9558 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9559 pHddCtx->cfg_ini->vosTraceEnableSME);
9560 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9561 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309562 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9563 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009564 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9565 pHddCtx->cfg_ini->vosTraceEnableWDA);
9566 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9567 pHddCtx->cfg_ini->vosTraceEnableSYS);
9568 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9569 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009570 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9571 pHddCtx->cfg_ini->vosTraceEnableSAP);
9572 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9573 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009574
Jeff Johnson295189b2012-06-20 16:38:30 -07009575 // Update WDI trace levels based upon the cfg.ini
9576 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9577 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9578 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9579 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9580 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9581 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9582 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9583 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009584
Jeff Johnson88ba7742013-02-27 14:36:02 -08009585 if (VOS_FTM_MODE == hdd_get_conparam())
9586 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9588 {
9589 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9590 goto err_free_hdd_context;
9591 }
9592 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309593 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309594 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009596 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009597
Katya Nigame7b69a82015-04-28 15:24:06 +05309598 if( VOS_MONITOR_MODE == hdd_get_conparam())
9599 {
9600 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9601 {
9602 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9603 goto err_free_hdd_context;
9604 }
9605 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9606 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9607 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9608 return VOS_STATUS_SUCCESS;
9609 }
9610
Jeff Johnson88ba7742013-02-27 14:36:02 -08009611 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9613 {
9614 status = vos_watchdog_open(pVosContext,
9615 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9616
9617 if(!VOS_IS_STATUS_SUCCESS( status ))
9618 {
9619 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309620 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 }
9622 }
9623
9624 pHddCtx->isLogpInProgress = FALSE;
9625 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9626
Amar Singhala49cbc52013-10-08 18:37:44 -07009627#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009628 /* initialize the NV module. This is required so that
9629 we can initialize the channel information in wiphy
9630 from the NV.bin data. The channel information in
9631 wiphy needs to be initialized before wiphy registration */
9632
9633 status = vos_nv_open();
9634 if (!VOS_IS_STATUS_SUCCESS(status))
9635 {
9636 /* NV module cannot be initialized */
9637 hddLog( VOS_TRACE_LEVEL_FATAL,
9638 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309639 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009640 }
9641
9642 status = vos_init_wiphy_from_nv_bin();
9643 if (!VOS_IS_STATUS_SUCCESS(status))
9644 {
9645 /* NV module cannot be initialized */
9646 hddLog( VOS_TRACE_LEVEL_FATAL,
9647 "%s: vos_init_wiphy failed", __func__);
9648 goto err_vos_nv_close;
9649 }
9650
Amar Singhala49cbc52013-10-08 18:37:44 -07009651#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309652 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309653 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 if ( !VOS_IS_STATUS_SUCCESS( status ))
9655 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009656 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309657 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 }
9659
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9661
9662 if ( NULL == pHddCtx->hHal )
9663 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009664 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 goto err_vosclose;
9666 }
9667
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009668 status = vos_preStart( pHddCtx->pvosContext );
9669 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9670 {
9671 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309672 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009673 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009674
Arif Hussaineaf68602013-12-30 23:10:44 -08009675 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9676 {
9677 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9679 __func__, enable_dfs_chan_scan);
9680 }
9681 if (0 == enable_11d || 1 == enable_11d)
9682 {
9683 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9685 __func__, enable_11d);
9686 }
9687
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009688 /* Note that the vos_preStart() sequence triggers the cfg download.
9689 The cfg download must occur before we update the SME config
9690 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 status = hdd_set_sme_config( pHddCtx );
9692
9693 if ( VOS_STATUS_SUCCESS != status )
9694 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009695 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309696 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009698
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 /* In the integrated architecture we update the configuration from
9700 the INI file and from NV before vOSS has been started so that
9701 the final contents are available to send down to the cCPU */
9702
9703 // Apply the cfg.ini to cfg.dat
9704 if (FALSE == hdd_update_config_dat(pHddCtx))
9705 {
9706 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309707 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 }
9709
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309710 // Get mac addr from platform driver
9711 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9712
9713 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309715 /* Store the mac addr for first interface */
9716 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9717
9718 hddLog(VOS_TRACE_LEVEL_ERROR,
9719 "%s: WLAN Mac Addr: "
9720 MAC_ADDRESS_STR, __func__,
9721 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9722
9723 /* Here, passing Arg2 as 1 because we do not want to change the
9724 last 3 bytes (means non OUI bytes) of first interface mac
9725 addr.
9726 */
9727 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9728 {
9729 hddLog(VOS_TRACE_LEVEL_ERROR,
9730 "%s: Failed to generate wlan interface mac addr "
9731 "using MAC from ini file ", __func__);
9732 }
9733 }
9734 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9735 {
9736 // Apply the NV to cfg.dat
9737 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009738#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9739 /* There was not a valid set of MAC Addresses in NV. See if the
9740 default addresses were modified by the cfg.ini settings. If so,
9741 we'll use them, but if not, we'll autogenerate a set of MAC
9742 addresses based upon the device serial number */
9743
9744 static const v_MACADDR_t default_address =
9745 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009746
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309747 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9748 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 {
9750 /* cfg.ini has the default address, invoke autogen logic */
9751
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309752 /* Here, passing Arg2 as 0 because we want to change the
9753 last 3 bytes (means non OUI bytes) of all the interfaces
9754 mac addr.
9755 */
9756 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9757 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309759 hddLog(VOS_TRACE_LEVEL_ERROR,
9760 "%s: Failed to generate wlan interface mac addr "
9761 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9762 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009764 }
9765 else
9766#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9767 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009768 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 "%s: Invalid MAC address in NV, using MAC from ini file "
9770 MAC_ADDRESS_STR, __func__,
9771 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9772 }
9773 }
9774 {
9775 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309776
9777 /* Set the MAC Address Currently this is used by HAL to
9778 * add self sta. Remove this once self sta is added as
9779 * part of session open.
9780 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9782 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9783 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309784
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 if (!HAL_STATUS_SUCCESS( halStatus ))
9786 {
9787 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9788 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309789 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 }
9791 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009792
9793 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9794 Note: Firmware image will be read and downloaded inside vos_start API */
9795 status = vos_start( pHddCtx->pvosContext );
9796 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9797 {
9798 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309799 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 }
9801
Leo Chang6cec3e22014-01-21 15:33:49 -08009802#ifdef FEATURE_WLAN_CH_AVOID
9803 /* Plug in avoid channel notification callback
9804 * This should happen before ADD_SELF_STA
9805 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309806
9807 /* check the Channel Avoidance is enabled */
9808 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9809 {
9810 sme_AddChAvoidCallback(pHddCtx->hHal,
9811 hdd_hostapd_ch_avoid_cb);
9812 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009813#endif /* FEATURE_WLAN_CH_AVOID */
9814
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009815 /* Exchange capability info between Host and FW and also get versioning info from FW */
9816 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009817
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309818#ifdef CONFIG_ENABLE_LINUX_REG
9819 status = wlan_hdd_init_channels(pHddCtx);
9820 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9821 {
9822 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9823 __func__);
9824 goto err_vosstop;
9825 }
9826#endif
9827
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 status = hdd_post_voss_start_config( pHddCtx );
9829 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9830 {
9831 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9832 __func__);
9833 goto err_vosstop;
9834 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009835
9836#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309837 wlan_hdd_cfg80211_update_reg_info( wiphy );
9838
9839 /* registration of wiphy dev with cfg80211 */
9840 if (0 > wlan_hdd_cfg80211_register(wiphy))
9841 {
9842 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9843 goto err_vosstop;
9844 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009845#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009846
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309847#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309848 /* registration of wiphy dev with cfg80211 */
9849 if (0 > wlan_hdd_cfg80211_register(wiphy))
9850 {
9851 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9852 goto err_vosstop;
9853 }
9854
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309855 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309856 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9857 {
9858 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9859 __func__);
9860 goto err_unregister_wiphy;
9861 }
9862#endif
9863
c_hpothu4a298be2014-12-22 21:12:51 +05309864 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9865
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9867 {
9868 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9869 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9870 }
9871 else
9872 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9874 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9875 if (pAdapter != NULL)
9876 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309877 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309879 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9880 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9881 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009882
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309883 /* Generate the P2P Device Address. This consists of the device's
9884 * primary MAC address with the locally administered bit set.
9885 */
9886 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009887 }
9888 else
9889 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309890 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9891 if (p2p_dev_addr != NULL)
9892 {
9893 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9894 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9895 }
9896 else
9897 {
9898 hddLog(VOS_TRACE_LEVEL_FATAL,
9899 "%s: Failed to allocate mac_address for p2p_device",
9900 __func__);
9901 goto err_close_adapter;
9902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009904
9905 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9906 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9907 if ( NULL == pP2pAdapter )
9908 {
9909 hddLog(VOS_TRACE_LEVEL_FATAL,
9910 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009911 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009912 goto err_close_adapter;
9913 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009916
9917 if( pAdapter == NULL )
9918 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9920 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009922
Arif Hussain66559122013-11-21 10:11:40 -08009923 if (country_code)
9924 {
9925 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009926 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009927 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9928#ifndef CONFIG_ENABLE_LINUX_REG
9929 hdd_checkandupdate_phymode(pAdapter, country_code);
9930#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009931 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9932 (void *)(tSmeChangeCountryCallback)
9933 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009934 country_code,
9935 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309936 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009937 if (eHAL_STATUS_SUCCESS == ret)
9938 {
Arif Hussaincb607082013-12-20 11:57:42 -08009939 ret = wait_for_completion_interruptible_timeout(
9940 &pAdapter->change_country_code,
9941 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9942
9943 if (0 >= ret)
9944 {
9945 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9946 "%s: SME while setting country code timed out", __func__);
9947 }
Arif Hussain66559122013-11-21 10:11:40 -08009948 }
9949 else
9950 {
Arif Hussaincb607082013-12-20 11:57:42 -08009951 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9952 "%s: SME Change Country code from module param fail ret=%d",
9953 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009954 }
9955 }
9956
Jeff Johnson295189b2012-06-20 16:38:30 -07009957#ifdef WLAN_BTAMP_FEATURE
9958 vStatus = WLANBAP_Open(pVosContext);
9959 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9960 {
9961 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9962 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009963 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 }
9965
9966 vStatus = BSL_Init(pVosContext);
9967 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9968 {
9969 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9970 "%s: Failed to Init BSL",__func__);
9971 goto err_bap_close;
9972 }
9973 vStatus = WLANBAP_Start(pVosContext);
9974 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9975 {
9976 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9977 "%s: Failed to start TL",__func__);
9978 goto err_bap_close;
9979 }
9980
9981 pConfig = pHddCtx->cfg_ini;
9982 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9983 status = WLANBAP_SetConfig(&btAmpConfig);
9984
9985#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009986
Mihir Shete9c238772014-10-15 14:35:16 +05309987 /*
9988 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9989 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9990 * which is greater than 0xf. So the below check is safe to make
9991 * sure that there is no entry for UapsdMask in the ini
9992 */
9993 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9994 {
9995 if(IS_DYNAMIC_WMM_PS_ENABLED)
9996 {
9997 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9998 __func__);
9999 pHddCtx->cfg_ini->UapsdMask =
10000 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10001 }
10002 else
10003 {
10004 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10005 __func__);
10006 pHddCtx->cfg_ini->UapsdMask =
10007 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10008 }
10009 }
10010
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010011#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10012 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10013 {
10014 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10015 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10016 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10017 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10018 }
10019#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010020
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010021 wlan_hdd_tdls_init(pHddCtx);
10022
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010023 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10024
Jeff Johnson295189b2012-06-20 16:38:30 -070010025 /* Register with platform driver as client for Suspend/Resume */
10026 status = hddRegisterPmOps(pHddCtx);
10027 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10028 {
10029 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10030#ifdef WLAN_BTAMP_FEATURE
10031 goto err_bap_stop;
10032#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010033 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010034#endif //WLAN_BTAMP_FEATURE
10035 }
10036
Yue Ma0d4891e2013-08-06 17:01:45 -070010037 /* Open debugfs interface */
10038 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10039 {
10040 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10041 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010042 }
10043
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 /* Register TM level change handler function to the platform */
10045 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10046 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10047 {
10048 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10049 goto err_unregister_pmops;
10050 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010051
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 // register net device notifier for device change notification
10053 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10054
10055 if(ret < 0)
10056 {
10057 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010058 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 }
10060
10061 //Initialize the nlink service
10062 if(nl_srv_init() != 0)
10063 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010064 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 goto err_reg_netdev;
10066 }
10067
Leo Chang4ce1cc52013-10-21 18:27:15 -070010068#ifdef WLAN_KD_READY_NOTIFIER
10069 pHddCtx->kd_nl_init = 1;
10070#endif /* WLAN_KD_READY_NOTIFIER */
10071
Jeff Johnson295189b2012-06-20 16:38:30 -070010072 //Initialize the BTC service
10073 if(btc_activate_service(pHddCtx) != 0)
10074 {
10075 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10076 goto err_nl_srv;
10077 }
10078
10079#ifdef PTT_SOCK_SVC_ENABLE
10080 //Initialize the PTT service
10081 if(ptt_sock_activate_svc(pHddCtx) != 0)
10082 {
10083 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10084 goto err_nl_srv;
10085 }
10086#endif
10087
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010088#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10089 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10090 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010091 if(wlan_logging_sock_activate_svc(
10092 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10093 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10094 {
10095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10096 " failed", __func__);
10097 goto err_nl_srv;
10098 }
10099 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10100 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010101 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10102 pHddCtx->cfg_ini->gEnableDebugLog =
10103 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010104 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010105
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010106 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10107 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010108 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010109 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010110 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010111 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010112 }
10113 else
10114 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010115 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010116 }
10117
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010118#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010119
10120
Sushant Kaushik215778f2015-05-21 14:05:36 +053010121 if (vos_is_multicast_logging())
10122 wlan_logging_set_log_level();
10123
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010127 /* Action frame registered in one adapter which will
10128 * applicable to all interfaces
10129 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010130 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010132
10133 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010134 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010135
Jeff Johnsone7245742012-09-05 17:12:55 -070010136#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10137 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010138 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010139 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010140
Jeff Johnsone7245742012-09-05 17:12:55 -070010141#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010142 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010143 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010144 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010145
Jeff Johnsone7245742012-09-05 17:12:55 -070010146
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010147 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10148 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010149
Katya Nigam5c306ea2014-06-19 15:39:54 +053010150 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010152 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010153
10154#ifdef FEATURE_WLAN_SCAN_PNO
10155 /*SME must send channel update configuration to RIVA*/
10156 sme_UpdateChannelConfig(pHddCtx->hHal);
10157#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010158 /* Send the update default channel list to the FW*/
10159 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010160
10161 /* Fwr capabilities received, Set the Dot11 mode */
10162 sme_SetDefDot11Mode(pHddCtx->hHal);
10163
Abhishek Singha306a442013-11-07 18:39:01 +053010164#ifndef CONFIG_ENABLE_LINUX_REG
10165 /*updating wiphy so that regulatory user hints can be processed*/
10166 if (wiphy)
10167 {
10168 regulatory_hint(wiphy, "00");
10169 }
10170#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010171 // Initialize the restart logic
10172 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010173
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010174 //Register the traffic monitor timer now
10175 if ( pHddCtx->cfg_ini->dynSplitscan)
10176 {
10177 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10178 VOS_TIMER_TYPE_SW,
10179 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10180 (void *)pHddCtx);
10181 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010182 wlan_hdd_cfg80211_nan_init(pHddCtx);
10183
Dino Mycle6fb96c12014-06-10 11:52:40 +053010184#ifdef WLAN_FEATURE_EXTSCAN
10185 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10186 wlan_hdd_cfg80211_extscan_callback,
10187 pHddCtx);
10188#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010189
10190#ifdef WLAN_NS_OFFLOAD
10191 // Register IPv6 notifier to notify if any change in IP
10192 // So that we can reconfigure the offload parameters
10193 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10194 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10195 if (ret)
10196 {
10197 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10198 }
10199 else
10200 {
10201 hddLog(LOGE, FL("Registered IPv6 notifier"));
10202 }
10203#endif
10204
10205 // Register IPv4 notifier to notify if any change in IP
10206 // So that we can reconfigure the offload parameters
10207 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10208 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10209 if (ret)
10210 {
10211 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10212 }
10213 else
10214 {
10215 hddLog(LOGE, FL("Registered IPv4 notifier"));
10216 }
10217
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 goto success;
10219
10220err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010221#ifdef WLAN_KD_READY_NOTIFIER
10222 nl_srv_exit(pHddCtx->ptt_pid);
10223#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010224 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010225#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010226err_reg_netdev:
10227 unregister_netdevice_notifier(&hdd_netdev_notifier);
10228
Jeff Johnson295189b2012-06-20 16:38:30 -070010229err_unregister_pmops:
10230 hddDevTmUnregisterNotifyCallback(pHddCtx);
10231 hddDeregisterPmOps(pHddCtx);
10232
Yue Ma0d4891e2013-08-06 17:01:45 -070010233 hdd_debugfs_exit(pHddCtx);
10234
Jeff Johnson295189b2012-06-20 16:38:30 -070010235#ifdef WLAN_BTAMP_FEATURE
10236err_bap_stop:
10237 WLANBAP_Stop(pVosContext);
10238#endif
10239
10240#ifdef WLAN_BTAMP_FEATURE
10241err_bap_close:
10242 WLANBAP_Close(pVosContext);
10243#endif
10244
Jeff Johnson295189b2012-06-20 16:38:30 -070010245err_close_adapter:
10246 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010247#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010248err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010249#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010250 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010251err_vosstop:
10252 vos_stop(pVosContext);
10253
Amar Singhala49cbc52013-10-08 18:37:44 -070010254err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 status = vos_sched_close( pVosContext );
10256 if (!VOS_IS_STATUS_SUCCESS(status)) {
10257 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10258 "%s: Failed to close VOSS Scheduler", __func__);
10259 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10260 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010261 vos_close(pVosContext );
10262
Amar Singhal0a402232013-10-11 20:57:16 -070010263err_vos_nv_close:
10264
c_hpothue6a36282014-03-19 12:27:38 +053010265#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010266 vos_nv_close();
10267
c_hpothu70f8d812014-03-22 22:59:23 +053010268#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010269
10270err_wdclose:
10271 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10272 vos_watchdog_close(pVosContext);
10273
Jeff Johnson295189b2012-06-20 16:38:30 -070010274err_config:
10275 kfree(pHddCtx->cfg_ini);
10276 pHddCtx->cfg_ini= NULL;
10277
10278err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010279 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010280 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010281 wiphy_free(wiphy) ;
10282 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 VOS_BUG(1);
10284
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010285 if (hdd_is_ssr_required())
10286 {
10287 /* WDI timeout had happened during load, so SSR is needed here */
10288 subsystem_restart("wcnss");
10289 msleep(5000);
10290 }
10291 hdd_set_ssr_required (VOS_FALSE);
10292
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010293 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010294
10295success:
10296 EXIT();
10297 return 0;
10298}
10299
10300/**---------------------------------------------------------------------------
10301
Jeff Johnson32d95a32012-09-10 13:15:23 -070010302 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010303
Jeff Johnson32d95a32012-09-10 13:15:23 -070010304 This is the driver entry point - called in different timeline depending
10305 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010306
10307 \param - None
10308
10309 \return - 0 for success, non zero for failure
10310
10311 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010312static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010313{
10314 VOS_STATUS status;
10315 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 struct device *dev = NULL;
10317 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010318#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10319 int max_retries = 0;
10320#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010321#ifdef HAVE_CBC_DONE
10322 int max_cbc_retries = 0;
10323#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010324
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010325#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10326 wlan_logging_sock_init_svc();
10327#endif
10328
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 ENTER();
10330
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010331 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010332
10333 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10334 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10335
Jeff Johnson295189b2012-06-20 16:38:30 -070010336#ifdef ANI_BUS_TYPE_PCI
10337
10338 dev = wcnss_wlan_get_device();
10339
10340#endif // ANI_BUS_TYPE_PCI
10341
10342#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010343
10344#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10345 /* wait until WCNSS driver downloads NV */
10346 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10347 msleep(1000);
10348 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010349
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010350 if (max_retries >= 5) {
10351 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010352 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010353#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10354 wlan_logging_sock_deinit_svc();
10355#endif
10356
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010357 return -ENODEV;
10358 }
10359#endif
10360
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010361#ifdef HAVE_CBC_DONE
10362 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10363 msleep(1000);
10364 }
10365 if (max_cbc_retries >= 10) {
10366 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10367 }
10368#endif
10369
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 dev = wcnss_wlan_get_device();
10371#endif // ANI_BUS_TYPE_PLATFORM
10372
10373
10374 do {
10375 if (NULL == dev) {
10376 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10377 ret_status = -1;
10378 break;
10379 }
10380
Jeff Johnson295189b2012-06-20 16:38:30 -070010381#ifdef TIMER_MANAGER
10382 vos_timer_manager_init();
10383#endif
10384
10385 /* Preopen VOSS so that it is ready to start at least SAL */
10386 status = vos_preOpen(&pVosContext);
10387
10388 if (!VOS_IS_STATUS_SUCCESS(status))
10389 {
10390 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10391 ret_status = -1;
10392 break;
10393 }
10394
Sushant Kaushik02beb352015-06-04 15:15:01 +053010395 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010396#ifndef MODULE
10397 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10398 */
10399 hdd_set_conparam((v_UINT_t)con_mode);
10400#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010401
10402 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010403 if (hdd_wlan_startup(dev))
10404 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010406 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 vos_preClose( &pVosContext );
10408 ret_status = -1;
10409 break;
10410 }
10411
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 } while (0);
10413
10414 if (0 != ret_status)
10415 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010416#ifdef TIMER_MANAGER
10417 vos_timer_exit();
10418#endif
10419#ifdef MEMORY_DEBUG
10420 vos_mem_exit();
10421#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010422 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010423#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10424 wlan_logging_sock_deinit_svc();
10425#endif
10426
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10428 }
10429 else
10430 {
10431 //Send WLAN UP indication to Nlink Service
10432 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10433
10434 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 }
10436
10437 EXIT();
10438
10439 return ret_status;
10440}
10441
Jeff Johnson32d95a32012-09-10 13:15:23 -070010442/**---------------------------------------------------------------------------
10443
10444 \brief hdd_module_init() - Init Function
10445
10446 This is the driver entry point (invoked when module is loaded using insmod)
10447
10448 \param - None
10449
10450 \return - 0 for success, non zero for failure
10451
10452 --------------------------------------------------------------------------*/
10453#ifdef MODULE
10454static int __init hdd_module_init ( void)
10455{
10456 return hdd_driver_init();
10457}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010458#else /* #ifdef MODULE */
10459static int __init hdd_module_init ( void)
10460{
10461 /* Driver initialization is delayed to fwpath_changed_handler */
10462 return 0;
10463}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010464#endif /* #ifdef MODULE */
10465
Jeff Johnson295189b2012-06-20 16:38:30 -070010466
10467/**---------------------------------------------------------------------------
10468
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010469 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010470
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010471 This is the driver exit point (invoked when module is unloaded using rmmod
10472 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010473
10474 \param - None
10475
10476 \return - None
10477
10478 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010479static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010480{
10481 hdd_context_t *pHddCtx = NULL;
10482 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010483 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010484 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010485
10486 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10487
10488 //Get the global vos context
10489 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10490
10491 if(!pVosContext)
10492 {
10493 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10494 goto done;
10495 }
10496
10497 //Get the HDD context.
10498 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10499
10500 if(!pHddCtx)
10501 {
10502 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10503 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010504 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10505 {
10506 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10507 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10508 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10509 hdd_wlan_exit(pHddCtx);
10510 vos_preClose( &pVosContext );
10511 goto done;
10512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 else
10514 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010515 /* We wait for active entry threads to exit from driver
10516 * by waiting until rtnl_lock is available.
10517 */
10518 rtnl_lock();
10519 rtnl_unlock();
10520
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010521 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10522 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10523 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10524 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010526 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010527 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10528 msecs_to_jiffies(30000));
10529 if(!rc)
10530 {
10531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10532 "%s:SSR timedout, fatal error", __func__);
10533 VOS_BUG(0);
10534 }
10535 }
10536
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010537 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10538 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010539
c_hpothu8adb97b2014-12-08 19:38:20 +053010540 /* Driver Need to send country code 00 in below condition
10541 * 1) If gCountryCodePriority is set to 1; and last country
10542 * code set is through 11d. This needs to be done in case
10543 * when NV country code is 00.
10544 * This Needs to be done as when kernel store last country
10545 * code and if stored country code is not through 11d,
10546 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10547 * in next load/unload as soon as we get any country through
10548 * 11d. In sme_HandleChangeCountryCodeByUser
10549 * pMsg->countryCode will be last countryCode and
10550 * pMac->scan.countryCode11d will be country through 11d so
10551 * due to mismatch driver will disable 11d.
10552 *
10553 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010554
c_hpothu8adb97b2014-12-08 19:38:20 +053010555 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010556 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010557 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010558 {
10559 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010560 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010561 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10562 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010563
c_hpothu8adb97b2014-12-08 19:38:20 +053010564 //Do all the cleanup before deregistering the driver
10565 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 }
10567
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 vos_preClose( &pVosContext );
10569
10570#ifdef TIMER_MANAGER
10571 vos_timer_exit();
10572#endif
10573#ifdef MEMORY_DEBUG
10574 vos_mem_exit();
10575#endif
10576
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010577#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10578 wlan_logging_sock_deinit_svc();
10579#endif
10580
Jeff Johnson295189b2012-06-20 16:38:30 -070010581done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010582 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010583
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10585}
10586
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010587/**---------------------------------------------------------------------------
10588
10589 \brief hdd_module_exit() - Exit function
10590
10591 This is the driver exit point (invoked when module is unloaded using rmmod)
10592
10593 \param - None
10594
10595 \return - None
10596
10597 --------------------------------------------------------------------------*/
10598static void __exit hdd_module_exit(void)
10599{
10600 hdd_driver_exit();
10601}
10602
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010603#ifdef MODULE
10604static int fwpath_changed_handler(const char *kmessage,
10605 struct kernel_param *kp)
10606{
Jeff Johnson76052702013-04-16 13:55:05 -070010607 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010608}
10609
10610static int con_mode_handler(const char *kmessage,
10611 struct kernel_param *kp)
10612{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010613 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010614}
10615#else /* #ifdef MODULE */
10616/**---------------------------------------------------------------------------
10617
Jeff Johnson76052702013-04-16 13:55:05 -070010618 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010619
Jeff Johnson76052702013-04-16 13:55:05 -070010620 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010621 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010622 - invoked when module parameter fwpath is modified from userspace to signal
10623 initializing the WLAN driver or when con_mode is modified from userspace
10624 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010625
10626 \return - 0 for success, non zero for failure
10627
10628 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010629static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010630{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010631 int ret_status;
10632
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010633 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010634 ret_status = hdd_driver_init();
10635 wlan_hdd_inited = ret_status ? 0 : 1;
10636 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010637 }
10638
10639 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010640
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010641 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010642
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010643 ret_status = hdd_driver_init();
10644 wlan_hdd_inited = ret_status ? 0 : 1;
10645 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010646}
10647
Jeff Johnson295189b2012-06-20 16:38:30 -070010648/**---------------------------------------------------------------------------
10649
Jeff Johnson76052702013-04-16 13:55:05 -070010650 \brief fwpath_changed_handler() - Handler Function
10651
10652 Handle changes to the fwpath parameter
10653
10654 \return - 0 for success, non zero for failure
10655
10656 --------------------------------------------------------------------------*/
10657static int fwpath_changed_handler(const char *kmessage,
10658 struct kernel_param *kp)
10659{
10660 int ret;
10661
10662 ret = param_set_copystring(kmessage, kp);
10663 if (0 == ret)
10664 ret = kickstart_driver();
10665 return ret;
10666}
10667
10668/**---------------------------------------------------------------------------
10669
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010670 \brief con_mode_handler() -
10671
10672 Handler function for module param con_mode when it is changed by userspace
10673 Dynamically linked - do nothing
10674 Statically linked - exit and init driver, as in rmmod and insmod
10675
Jeff Johnson76052702013-04-16 13:55:05 -070010676 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010677
Jeff Johnson76052702013-04-16 13:55:05 -070010678 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010679
10680 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010681static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010682{
Jeff Johnson76052702013-04-16 13:55:05 -070010683 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010684
Jeff Johnson76052702013-04-16 13:55:05 -070010685 ret = param_set_int(kmessage, kp);
10686 if (0 == ret)
10687 ret = kickstart_driver();
10688 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010689}
10690#endif /* #ifdef MODULE */
10691
10692/**---------------------------------------------------------------------------
10693
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 \brief hdd_get_conparam() -
10695
10696 This is the driver exit point (invoked when module is unloaded using rmmod)
10697
10698 \param - None
10699
10700 \return - tVOS_CON_MODE
10701
10702 --------------------------------------------------------------------------*/
10703tVOS_CON_MODE hdd_get_conparam ( void )
10704{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010705#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010707#else
10708 return (tVOS_CON_MODE)curr_con_mode;
10709#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010710}
10711void hdd_set_conparam ( v_UINT_t newParam )
10712{
10713 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010714#ifndef MODULE
10715 curr_con_mode = con_mode;
10716#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010717}
10718/**---------------------------------------------------------------------------
10719
10720 \brief hdd_softap_sta_deauth() - function
10721
10722 This to take counter measure to handle deauth req from HDD
10723
10724 \param - pAdapter - Pointer to the HDD
10725
10726 \param - enable - boolean value
10727
10728 \return - None
10729
10730 --------------------------------------------------------------------------*/
10731
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010732VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10733 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010734{
Jeff Johnson295189b2012-06-20 16:38:30 -070010735 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010736 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010737
10738 ENTER();
10739
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010740 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10741 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010742
10743 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010744 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010745 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010746
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010747 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010748
10749 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010750 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010751}
10752
10753/**---------------------------------------------------------------------------
10754
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010755 \brief hdd_del_all_sta() - function
10756
10757 This function removes all the stations associated on stopping AP/P2P GO.
10758
10759 \param - pAdapter - Pointer to the HDD
10760
10761 \return - None
10762
10763 --------------------------------------------------------------------------*/
10764
10765int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10766{
10767 v_U16_t i;
10768 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010769 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10770 ptSapContext pSapCtx = NULL;
10771 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10772 if(pSapCtx == NULL){
10773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10774 FL("psapCtx is NULL"));
10775 return 1;
10776 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010777 ENTER();
10778
10779 hddLog(VOS_TRACE_LEVEL_INFO,
10780 "%s: Delete all STAs associated.",__func__);
10781 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10782 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10783 )
10784 {
10785 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10786 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010787 if ((pSapCtx->aStaInfo[i].isUsed) &&
10788 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010789 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010790 struct tagCsrDelStaParams delStaParams;
10791
10792 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010793 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010794 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10795 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010796 &delStaParams);
10797 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010798 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010799 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010800 }
10801 }
10802 }
10803
10804 EXIT();
10805 return 0;
10806}
10807
10808/**---------------------------------------------------------------------------
10809
Jeff Johnson295189b2012-06-20 16:38:30 -070010810 \brief hdd_softap_sta_disassoc() - function
10811
10812 This to take counter measure to handle deauth req from HDD
10813
10814 \param - pAdapter - Pointer to the HDD
10815
10816 \param - enable - boolean value
10817
10818 \return - None
10819
10820 --------------------------------------------------------------------------*/
10821
10822void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10823{
10824 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10825
10826 ENTER();
10827
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010828 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010829
10830 //Ignore request to disassoc bcmc station
10831 if( pDestMacAddress[0] & 0x1 )
10832 return;
10833
10834 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10835}
10836
10837void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10838{
10839 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10840
10841 ENTER();
10842
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010843 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010844
10845 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10846}
10847
Jeff Johnson295189b2012-06-20 16:38:30 -070010848/**---------------------------------------------------------------------------
10849 *
10850 * \brief hdd_get__concurrency_mode() -
10851 *
10852 *
10853 * \param - None
10854 *
10855 * \return - CONCURRENCY MODE
10856 *
10857 * --------------------------------------------------------------------------*/
10858tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10859{
10860 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10861 hdd_context_t *pHddCtx;
10862
10863 if (NULL != pVosContext)
10864 {
10865 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10866 if (NULL != pHddCtx)
10867 {
10868 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10869 }
10870 }
10871
10872 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010873 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 return VOS_STA;
10875}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010876v_BOOL_t
10877wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10878{
10879 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010880
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010881 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10882 if (pAdapter == NULL)
10883 {
10884 hddLog(VOS_TRACE_LEVEL_INFO,
10885 FL("GO doesn't exist"));
10886 return TRUE;
10887 }
10888 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10889 {
10890 hddLog(VOS_TRACE_LEVEL_INFO,
10891 FL("GO started"));
10892 return TRUE;
10893 }
10894 else
10895 /* wait till GO changes its interface to p2p device */
10896 hddLog(VOS_TRACE_LEVEL_INFO,
10897 FL("Del_bss called, avoid apps suspend"));
10898 return FALSE;
10899
10900}
Jeff Johnson295189b2012-06-20 16:38:30 -070010901/* Decide whether to allow/not the apps power collapse.
10902 * Allow apps power collapse if we are in connected state.
10903 * if not, allow only if we are in IMPS */
10904v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10905{
10906 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010907 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010908 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010909 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10910 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10911 hdd_adapter_t *pAdapter = NULL;
10912 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010913 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010914
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10916 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010917
Yathish9f22e662012-12-10 14:21:35 -080010918 concurrent_state = hdd_get_concurrency_mode();
10919
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010920 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10921 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10922 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010923#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010924
Yathish9f22e662012-12-10 14:21:35 -080010925 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010926 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010927 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10928 return TRUE;
10929#endif
10930
Jeff Johnson295189b2012-06-20 16:38:30 -070010931 /*loop through all adapters. TBD fix for Concurrency */
10932 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10933 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10934 {
10935 pAdapter = pAdapterNode->pAdapter;
10936 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10937 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10938 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010939 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010940 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010941 && pmcState != STOPPED && pmcState != STANDBY &&
10942 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010943 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10944 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010946 if(pmcState == FULL_POWER &&
10947 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10948 {
10949 /*
10950 * When SCO indication comes from Coex module , host will
10951 * enter in to full power mode, but this should not prevent
10952 * apps processor power collapse.
10953 */
10954 hddLog(LOG1,
10955 FL("Allow apps power collapse"
10956 "even when sco indication is set"));
10957 return TRUE;
10958 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010959 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010960 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10961 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010962 return FALSE;
10963 }
10964 }
10965 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10966 pAdapterNode = pNext;
10967 }
10968 return TRUE;
10969}
10970
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010971/* Decides whether to send suspend notification to Riva
10972 * if any adapter is in BMPS; then it is required */
10973v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10974{
10975 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10976 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10977
10978 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10979 {
10980 return TRUE;
10981 }
10982 return FALSE;
10983}
10984
Jeff Johnson295189b2012-06-20 16:38:30 -070010985void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10986{
10987 switch(mode)
10988 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010989 case VOS_STA_MODE:
10990 case VOS_P2P_CLIENT_MODE:
10991 case VOS_P2P_GO_MODE:
10992 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010993 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010994 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010995 break;
10996 default:
10997 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010998 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010999 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11000 "Number of open sessions for mode %d = %d"),
11001 pHddCtx->concurrency_mode, mode,
11002 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011003}
11004
11005
11006void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11007{
11008 switch(mode)
11009 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011010 case VOS_STA_MODE:
11011 case VOS_P2P_CLIENT_MODE:
11012 case VOS_P2P_GO_MODE:
11013 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011014 pHddCtx->no_of_open_sessions[mode]--;
11015 if (!(pHddCtx->no_of_open_sessions[mode]))
11016 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 break;
11018 default:
11019 break;
11020 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011021 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11022 "Number of open sessions for mode %d = %d"),
11023 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11024
11025}
11026/**---------------------------------------------------------------------------
11027 *
11028 * \brief wlan_hdd_incr_active_session()
11029 *
11030 * This function increments the number of active sessions
11031 * maintained per device mode
11032 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11033 * Incase of SAP/P2P GO upon bss start it is incremented
11034 *
11035 * \param pHddCtx - HDD Context
11036 * \param mode - device mode
11037 *
11038 * \return - None
11039 *
11040 * --------------------------------------------------------------------------*/
11041void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11042{
11043 switch (mode) {
11044 case VOS_STA_MODE:
11045 case VOS_P2P_CLIENT_MODE:
11046 case VOS_P2P_GO_MODE:
11047 case VOS_STA_SAP_MODE:
11048 pHddCtx->no_of_active_sessions[mode]++;
11049 break;
11050 default:
11051 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11052 break;
11053 }
11054 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11055 mode,
11056 pHddCtx->no_of_active_sessions[mode]);
11057}
11058
11059/**---------------------------------------------------------------------------
11060 *
11061 * \brief wlan_hdd_decr_active_session()
11062 *
11063 * This function decrements the number of active sessions
11064 * maintained per device mode
11065 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11066 * Incase of SAP/P2P GO upon bss stop it is decremented
11067 *
11068 * \param pHddCtx - HDD Context
11069 * \param mode - device mode
11070 *
11071 * \return - None
11072 *
11073 * --------------------------------------------------------------------------*/
11074void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11075{
11076 switch (mode) {
11077 case VOS_STA_MODE:
11078 case VOS_P2P_CLIENT_MODE:
11079 case VOS_P2P_GO_MODE:
11080 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011081 if (pHddCtx->no_of_active_sessions[mode] > 0)
11082 pHddCtx->no_of_active_sessions[mode]--;
11083 else
11084 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11085 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011086 break;
11087 default:
11088 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11089 break;
11090 }
11091 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11092 mode,
11093 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011094}
11095
Jeff Johnsone7245742012-09-05 17:12:55 -070011096/**---------------------------------------------------------------------------
11097 *
11098 * \brief wlan_hdd_restart_init
11099 *
11100 * This function initalizes restart timer/flag. An internal function.
11101 *
11102 * \param - pHddCtx
11103 *
11104 * \return - None
11105 *
11106 * --------------------------------------------------------------------------*/
11107
11108static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11109{
11110 /* Initialize */
11111 pHddCtx->hdd_restart_retries = 0;
11112 atomic_set(&pHddCtx->isRestartInProgress, 0);
11113 vos_timer_init(&pHddCtx->hdd_restart_timer,
11114 VOS_TIMER_TYPE_SW,
11115 wlan_hdd_restart_timer_cb,
11116 pHddCtx);
11117}
11118/**---------------------------------------------------------------------------
11119 *
11120 * \brief wlan_hdd_restart_deinit
11121 *
11122 * This function cleans up the resources used. An internal function.
11123 *
11124 * \param - pHddCtx
11125 *
11126 * \return - None
11127 *
11128 * --------------------------------------------------------------------------*/
11129
11130static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11131{
11132
11133 VOS_STATUS vos_status;
11134 /* Block any further calls */
11135 atomic_set(&pHddCtx->isRestartInProgress, 1);
11136 /* Cleanup */
11137 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11138 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011139 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011140 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11141 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011142 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011143
11144}
11145
11146/**---------------------------------------------------------------------------
11147 *
11148 * \brief wlan_hdd_framework_restart
11149 *
11150 * This function uses a cfg80211 API to start a framework initiated WLAN
11151 * driver module unload/load.
11152 *
11153 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11154 *
11155 *
11156 * \param - pHddCtx
11157 *
11158 * \return - VOS_STATUS_SUCCESS: Success
11159 * VOS_STATUS_E_EMPTY: Adapter is Empty
11160 * VOS_STATUS_E_NOMEM: No memory
11161
11162 * --------------------------------------------------------------------------*/
11163
11164static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11165{
11166 VOS_STATUS status = VOS_STATUS_SUCCESS;
11167 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011168 int len = (sizeof (struct ieee80211_mgmt));
11169 struct ieee80211_mgmt *mgmt = NULL;
11170
11171 /* Prepare the DEAUTH managment frame with reason code */
11172 mgmt = kzalloc(len, GFP_KERNEL);
11173 if(mgmt == NULL)
11174 {
11175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11176 "%s: memory allocation failed (%d bytes)", __func__, len);
11177 return VOS_STATUS_E_NOMEM;
11178 }
11179 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011180
11181 /* Iterate over all adapters/devices */
11182 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011183 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11184 {
11185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11186 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11187 goto end;
11188 }
11189
Jeff Johnsone7245742012-09-05 17:12:55 -070011190 do
11191 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011192 if(pAdapterNode->pAdapter &&
11193 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011194 {
11195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11196 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11197 pAdapterNode->pAdapter->dev->name,
11198 pAdapterNode->pAdapter->device_mode,
11199 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011200 /*
11201 * CFG80211 event to restart the driver
11202 *
11203 * 'cfg80211_send_unprot_deauth' sends a
11204 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11205 * of SME(Linux Kernel) state machine.
11206 *
11207 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11208 * the driver.
11209 *
11210 */
11211
11212 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011213 }
11214 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11215 pAdapterNode = pNext;
11216 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11217
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011218 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011219 /* Free the allocated management frame */
11220 kfree(mgmt);
11221
Jeff Johnsone7245742012-09-05 17:12:55 -070011222 /* Retry until we unload or reach max count */
11223 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11224 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11225
11226 return status;
11227
11228}
11229/**---------------------------------------------------------------------------
11230 *
11231 * \brief wlan_hdd_restart_timer_cb
11232 *
11233 * Restart timer callback. An internal function.
11234 *
11235 * \param - User data:
11236 *
11237 * \return - None
11238 *
11239 * --------------------------------------------------------------------------*/
11240
11241void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11242{
11243 hdd_context_t *pHddCtx = usrDataForCallback;
11244 wlan_hdd_framework_restart(pHddCtx);
11245 return;
11246
11247}
11248
11249
11250/**---------------------------------------------------------------------------
11251 *
11252 * \brief wlan_hdd_restart_driver
11253 *
11254 * This function sends an event to supplicant to restart the WLAN driver.
11255 *
11256 * This function is called from vos_wlanRestart.
11257 *
11258 * \param - pHddCtx
11259 *
11260 * \return - VOS_STATUS_SUCCESS: Success
11261 * VOS_STATUS_E_EMPTY: Adapter is Empty
11262 * VOS_STATUS_E_ALREADY: Request already in progress
11263
11264 * --------------------------------------------------------------------------*/
11265VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11266{
11267 VOS_STATUS status = VOS_STATUS_SUCCESS;
11268
11269 /* A tight check to make sure reentrancy */
11270 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11271 {
Mihir Shetefd528652014-06-23 19:07:50 +053011272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011273 "%s: WLAN restart is already in progress", __func__);
11274
11275 return VOS_STATUS_E_ALREADY;
11276 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011277 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011278#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011279 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011280#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011281
Jeff Johnsone7245742012-09-05 17:12:55 -070011282 return status;
11283}
11284
Mihir Shetee1093ba2014-01-21 20:13:32 +053011285/**---------------------------------------------------------------------------
11286 *
11287 * \brief wlan_hdd_init_channels
11288 *
11289 * This function is used to initialize the channel list in CSR
11290 *
11291 * This function is called from hdd_wlan_startup
11292 *
11293 * \param - pHddCtx: HDD context
11294 *
11295 * \return - VOS_STATUS_SUCCESS: Success
11296 * VOS_STATUS_E_FAULT: Failure reported by SME
11297
11298 * --------------------------------------------------------------------------*/
11299static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11300{
11301 eHalStatus status;
11302
11303 status = sme_InitChannels(pHddCtx->hHal);
11304 if (HAL_STATUS_SUCCESS(status))
11305 {
11306 return VOS_STATUS_SUCCESS;
11307 }
11308 else
11309 {
11310 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11311 __func__, status);
11312 return VOS_STATUS_E_FAULT;
11313 }
11314}
11315
Mihir Shete04206452014-11-20 17:50:58 +053011316#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011317VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011318{
11319 eHalStatus status;
11320
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011321 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011322 if (HAL_STATUS_SUCCESS(status))
11323 {
11324 return VOS_STATUS_SUCCESS;
11325 }
11326 else
11327 {
11328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11329 __func__, status);
11330 return VOS_STATUS_E_FAULT;
11331 }
11332}
Mihir Shete04206452014-11-20 17:50:58 +053011333#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011334/*
11335 * API to find if there is any STA or P2P-Client is connected
11336 */
11337VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11338{
11339 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11340}
Jeff Johnsone7245742012-09-05 17:12:55 -070011341
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011342
11343/*
11344 * API to find if the firmware will send logs using DXE channel
11345 */
11346v_U8_t hdd_is_fw_logging_enabled(void)
11347{
11348 hdd_context_t *pHddCtx;
11349
11350 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11351 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11352
Sachin Ahuja084313e2015-05-21 17:57:10 +053011353 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011354}
11355
Agarwal Ashish57e84372014-12-05 18:26:53 +053011356/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011357 * API to find if the firmware will send trace logs using DXE channel
11358 */
11359v_U8_t hdd_is_fw_ev_logging_enabled(void)
11360{
11361 hdd_context_t *pHddCtx;
11362
11363 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11364 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11365
11366 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11367}
11368/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011369 * API to find if there is any session connected
11370 */
11371VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11372{
11373 return sme_is_any_session_connected(pHddCtx->hHal);
11374}
11375
11376
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011377int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11378{
11379 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11380 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011381 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011382 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011383
11384 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011385 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011386 if (pScanInfo->mScanPending)
11387 {
c_hpothua3d45d52015-01-05 14:11:17 +053011388 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11389 eCSR_SCAN_ABORT_DEFAULT);
11390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11391 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011392
c_hpothua3d45d52015-01-05 14:11:17 +053011393 /* If there is active scan command lets wait for the completion else
11394 * there is no need to wait as scan command might be in the SME pending
11395 * command list.
11396 */
11397 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11398 {
c_hpothua3d45d52015-01-05 14:11:17 +053011399 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011400 &pScanInfo->abortscan_event_var,
11401 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011402 if (0 >= status)
11403 {
11404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011405 "%s: Timeout or Interrupt occurred while waiting for abort"
11406 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011407 return -ETIMEDOUT;
11408 }
11409 }
11410 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11411 {
11412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11413 FL("hdd_abort_mac_scan failed"));
11414 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011415 }
11416 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011417 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011418}
11419
c_hpothu225aa7c2014-10-22 17:45:13 +053011420VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11421{
11422 hdd_adapter_t *pAdapter;
11423 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11424 VOS_STATUS vosStatus;
11425
11426 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11427 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11428 {
11429 pAdapter = pAdapterNode->pAdapter;
11430 if (NULL != pAdapter)
11431 {
11432 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11433 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11434 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11435 {
11436 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11437 pAdapter->device_mode);
11438 if (VOS_STATUS_SUCCESS !=
11439 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11440 {
11441 hddLog(LOGE, FL("failed to abort ROC"));
11442 return VOS_STATUS_E_FAILURE;
11443 }
11444 }
11445 }
11446 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11447 pAdapterNode = pNext;
11448 }
11449 return VOS_STATUS_SUCCESS;
11450}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011451
Mihir Shete0be28772015-02-17 18:42:14 +053011452hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11453{
11454 hdd_adapter_t *pAdapter;
11455 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11456 hdd_cfg80211_state_t *cfgState;
11457 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11458 VOS_STATUS vosStatus;
11459
11460 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11461 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11462 {
11463 pAdapter = pAdapterNode->pAdapter;
11464 if (NULL != pAdapter)
11465 {
11466 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11467 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11468 if (pRemainChanCtx)
11469 break;
11470 }
11471 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11472 pAdapterNode = pNext;
11473 }
11474 return pRemainChanCtx;
11475}
11476
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011477/**
11478 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11479 *
11480 * @pHddCtx: HDD context within host driver
11481 * @dfsScanMode: dfsScanMode passed from ioctl
11482 *
11483 */
11484
11485VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11486 tANI_U8 dfsScanMode)
11487{
11488 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11489 hdd_adapter_t *pAdapter;
11490 VOS_STATUS vosStatus;
11491 hdd_station_ctx_t *pHddStaCtx;
11492 eHalStatus status = eHAL_STATUS_SUCCESS;
11493
11494 if(!pHddCtx)
11495 {
11496 hddLog(LOGE, FL("HDD context is Null"));
11497 return eHAL_STATUS_FAILURE;
11498 }
11499
11500 if (pHddCtx->scan_info.mScanPending)
11501 {
11502 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11503 pHddCtx->scan_info.sessionId);
11504 hdd_abort_mac_scan(pHddCtx,
11505 pHddCtx->scan_info.sessionId,
11506 eCSR_SCAN_ABORT_DEFAULT);
11507 }
11508
11509 if (!dfsScanMode)
11510 {
11511 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11512 while ((NULL != pAdapterNode) &&
11513 (VOS_STATUS_SUCCESS == vosStatus))
11514 {
11515 pAdapter = pAdapterNode->pAdapter;
11516
11517 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11518 {
11519 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11520
11521 if(!pHddStaCtx)
11522 {
11523 hddLog(LOGE, FL("HDD STA context is Null"));
11524 return eHAL_STATUS_FAILURE;
11525 }
11526
11527 /* if STA is already connected on DFS channel,
11528 disconnect immediately*/
11529 if (hdd_connIsConnected(pHddStaCtx) &&
11530 (NV_CHANNEL_DFS ==
11531 vos_nv_getChannelEnabledState(
11532 pHddStaCtx->conn_info.operationChannel)))
11533 {
11534 status = sme_RoamDisconnect(pHddCtx->hHal,
11535 pAdapter->sessionId,
11536 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11537 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11538 "sme_RoamDisconnect returned with status: %d"
11539 "for sessionid: %d"), pHddStaCtx->conn_info.
11540 operationChannel, status, pAdapter->sessionId);
11541 }
11542 }
11543
11544 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11545 &pNext);
11546 pAdapterNode = pNext;
11547 }
11548 }
11549
11550 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11551 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11552 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11553
11554 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11555 if (!HAL_STATUS_SUCCESS(status))
11556 {
11557 hddLog(LOGE,
11558 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11559 return status;
11560 }
11561
11562 return status;
11563}
11564
Nirav Shah7e3c8132015-06-22 23:51:42 +053011565static int hdd_log2_ceil(unsigned value)
11566{
11567 /* need to switch to unsigned math so that negative values
11568 * will right-shift towards 0 instead of -1
11569 */
11570 unsigned tmp = value;
11571 int log2 = -1;
11572
11573 if (value == 0)
11574 return 0;
11575
11576 while (tmp) {
11577 log2++;
11578 tmp >>= 1;
11579 }
11580 if (1U << log2 != value)
11581 log2++;
11582
11583 return log2;
11584}
11585
11586/**
11587 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11588 * @pAdapter: adapter handle
11589 *
11590 * Return: vos status
11591 */
11592VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11593{
11594 int hash_elem, log2, i;
11595
11596 spin_lock_bh( &pAdapter->sta_hash_lock);
11597 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11598 spin_unlock_bh( &pAdapter->sta_hash_lock);
11599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11600 "%s: hash already attached for session id %d",
11601 __func__, pAdapter->sessionId);
11602 return VOS_STATUS_SUCCESS;
11603 }
11604 spin_unlock_bh( &pAdapter->sta_hash_lock);
11605
11606 hash_elem = WLAN_MAX_STA_COUNT;
11607 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11608 log2 = hdd_log2_ceil(hash_elem);
11609 hash_elem = 1 << log2;
11610
11611 pAdapter->sta_id_hash.mask = hash_elem - 1;
11612 pAdapter->sta_id_hash.idx_bits = log2;
11613 pAdapter->sta_id_hash.bins =
11614 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11615 if (!pAdapter->sta_id_hash.bins) {
11616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11617 "%s: malloc failed for session %d",
11618 __func__, pAdapter->sessionId);
11619 return VOS_STATUS_E_NOMEM;
11620 }
11621
11622 for (i = 0; i < hash_elem; i++)
11623 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11624
11625 spin_lock_bh( &pAdapter->sta_hash_lock);
11626 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11627 spin_unlock_bh( &pAdapter->sta_hash_lock);
11628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11629 "%s: Station ID Hash attached for session id %d",
11630 __func__, pAdapter->sessionId);
11631
11632 return VOS_STATUS_SUCCESS;
11633}
11634
11635/**
11636 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11637 * @pAdapter: adapter handle
11638 *
11639 * Return: vos status
11640 */
11641VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11642{
11643 int hash_elem, i;
11644 v_SIZE_t size;
11645
11646 spin_lock_bh( &pAdapter->sta_hash_lock);
11647 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11648 spin_unlock_bh( &pAdapter->sta_hash_lock);
11649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11650 "%s: hash not initialized for session id %d",
11651 __func__, pAdapter->sessionId);
11652 return VOS_STATUS_SUCCESS;
11653 }
11654
11655 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11656 spin_unlock_bh( &pAdapter->sta_hash_lock);
11657
11658 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11659
11660 /* free all station info*/
11661 for (i = 0; i < hash_elem; i++) {
11662 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11663 if (size != 0) {
11664 VOS_STATUS status;
11665 hdd_staid_hash_node_t *sta_info_node = NULL;
11666 hdd_staid_hash_node_t *next_node = NULL;
11667 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11668 (hdd_list_node_t**) &sta_info_node );
11669
11670 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11671 {
11672 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11673 &sta_info_node->node);
11674 vos_mem_free(sta_info_node);
11675
11676 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11677 (hdd_list_node_t*)sta_info_node,
11678 (hdd_list_node_t**)&next_node);
11679 sta_info_node = next_node;
11680 }
11681 }
11682 }
11683
11684 vos_mem_free(pAdapter->sta_id_hash.bins);
11685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11686 "%s: Station ID Hash detached for session id %d",
11687 __func__, pAdapter->sessionId);
11688 return VOS_STATUS_SUCCESS;
11689}
11690
11691/**
11692 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11693 * @pAdapter: adapter handle
11694 * @mac_addr_in: input mac address
11695 *
11696 * Return: index derived from mac address
11697 */
11698int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11699 v_MACADDR_t *mac_addr_in)
11700{
11701 uint16 index;
11702 struct hdd_align_mac_addr_t * mac_addr =
11703 (struct hdd_align_mac_addr_t *)mac_addr_in;
11704
11705 index = mac_addr->bytes_ab ^
11706 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11707 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11708 index &= pAdapter->sta_id_hash.mask;
11709 return index;
11710}
11711
11712/**
11713 * hdd_sta_id_hash_add_entry() - add entry in hash
11714 * @pAdapter: adapter handle
11715 * @sta_id: station id
11716 * @mac_addr: mac address
11717 *
11718 * Return: vos status
11719 */
11720VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11721 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11722{
11723 uint16 index;
11724 hdd_staid_hash_node_t *sta_info_node = NULL;
11725
11726 spin_lock_bh( &pAdapter->sta_hash_lock);
11727 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11728 spin_unlock_bh( &pAdapter->sta_hash_lock);
11729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11730 "%s: hash is not initialized for session id %d",
11731 __func__, pAdapter->sessionId);
11732 return VOS_STATUS_E_FAILURE;
11733 }
11734
11735 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11736 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11737 if (!sta_info_node) {
11738 spin_unlock_bh( &pAdapter->sta_hash_lock);
11739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11740 "%s: malloc failed", __func__);
11741 return VOS_STATUS_E_NOMEM;
11742 }
11743
11744 sta_info_node->sta_id = sta_id;
11745 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11746
11747 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11748 (hdd_list_node_t*) sta_info_node );
11749 spin_unlock_bh( &pAdapter->sta_hash_lock);
11750 return VOS_STATUS_SUCCESS;
11751}
11752
11753/**
11754 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11755 * @pAdapter: adapter handle
11756 * @sta_id: station id
11757 * @mac_addr: mac address
11758 *
11759 * Return: vos status
11760 */
11761VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11762 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11763{
11764 uint16 index;
11765 VOS_STATUS status;
11766 hdd_staid_hash_node_t *sta_info_node = NULL;
11767 hdd_staid_hash_node_t *next_node = NULL;
11768
11769 spin_lock_bh( &pAdapter->sta_hash_lock);
11770 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11771 spin_unlock_bh( &pAdapter->sta_hash_lock);
11772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11773 "%s: hash is not initialized for session id %d",
11774 __func__, pAdapter->sessionId);
11775 return VOS_STATUS_E_FAILURE;
11776 }
11777
11778 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11779 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11780 (hdd_list_node_t**) &sta_info_node );
11781
11782 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11783 {
11784 if (sta_info_node->sta_id == sta_id) {
11785 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11786 &sta_info_node->node);
11787 vos_mem_free(sta_info_node);
11788 break;
11789 }
11790 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11791 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11792 sta_info_node = next_node;
11793 }
11794 spin_unlock_bh( &pAdapter->sta_hash_lock);
11795 return status;
11796}
11797
11798/**
11799 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11800 * @pAdapter: adapter handle
11801 * @mac_addr_in: mac address
11802 *
11803 * Return: station id
11804 */
11805int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11806 v_MACADDR_t *mac_addr_in)
11807{
11808 uint8 is_found = 0;
11809 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11810 uint16 index;
11811 VOS_STATUS status;
11812 hdd_staid_hash_node_t *sta_info_node = NULL;
11813 hdd_staid_hash_node_t *next_node = NULL;
11814
11815 spin_lock_bh( &pAdapter->sta_hash_lock);
11816 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11817 spin_unlock_bh( &pAdapter->sta_hash_lock);
11818 hddLog(VOS_TRACE_LEVEL_ERROR,
11819 FL("hash is not initialized for session id %d"),
11820 pAdapter->sessionId);
11821 return HDD_WLAN_INVALID_STA_ID;
11822 }
11823
11824 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11825 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11826 (hdd_list_node_t**) &sta_info_node );
11827
11828 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11829 {
11830 if (vos_mem_compare(&sta_info_node->mac_addr,
11831 mac_addr_in, sizeof(v_MACADDR_t))) {
11832 is_found = 1;
11833 sta_id = sta_info_node->sta_id;
11834 break;
11835 }
11836 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11837 (hdd_list_node_t*)sta_info_node,
11838 (hdd_list_node_t**)&next_node);
11839 sta_info_node = next_node;
11840 }
11841 spin_unlock_bh( &pAdapter->sta_hash_lock);
11842 return sta_id;
11843}
11844
Jeff Johnson295189b2012-06-20 16:38:30 -070011845//Register the module init/exit functions
11846module_init(hdd_module_init);
11847module_exit(hdd_module_exit);
11848
11849MODULE_LICENSE("Dual BSD/GPL");
11850MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11851MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11852
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011853module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11854 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011855
Jeff Johnson76052702013-04-16 13:55:05 -070011856module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011857 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011858
11859module_param(enable_dfs_chan_scan, int,
11860 S_IRUSR | S_IRGRP | S_IROTH);
11861
11862module_param(enable_11d, int,
11863 S_IRUSR | S_IRGRP | S_IROTH);
11864
11865module_param(country_code, charp,
11866 S_IRUSR | S_IRGRP | S_IROTH);